
import * as React from 'react'
import {
    CvState,
    CvProps,
    CvBaseMixin,
    CvMenuItem,
    CvMenuItemProps,
    CvEvent,
    CvActionFiredResult,
    CvNavigationResult,
    CvContext,
    CvActionCallback,
    CvValueProvider,
    CvValueListener,
    CvActionHandlerParams,
    CvStateChangeResult,
    ImageUtil, CvImageAction
} from 'catreact'
import {MenuDef, PaneContext, EntityRec} from 'catavolt-sdk'
import ReactElement = React.ReactElement;
import {CSSProperties} from "react";

export interface CvImageState extends CvState {
    imageNaturalHeight:number,
    imageNaturalWidth:number
}

export interface CvImageProps extends CvProps {
    style?:any,
    className?:string,
    imageClassName?:string,
    src?:any,
    actions?:Array<CvImageAction>,
    readOnly?:boolean,
    hasFocus?:boolean;
}

export const CvImageDefaultAddButtonClass:string = "cv-image-control-btn-add";
export const CvImageDefaultRemoveButtonClass:string = "cv-image-control-btn-remove";
export const CvImageDefaultUndoButtonClass:string = "cv-image-control-btn-undo";
export const CvImageDefaultSignatureButtonClass:string = "cv-image-control-btn-signature";

/*
 ***************************************************
 * Render an image preserving aspect ratio
 ***************************************************
 */

export let CvImage = React.createClass<CvImageProps, CvImageState>({

    mixins: [CvBaseMixin ],

    componentDidMount: function () {
        if(this.props.hasFocus) {
            if (this.props.actions && this.props.actions.length == 1) {
                // If auto focus is requested and there is exactly one action, fire it.
                this.props.actions[0].callback();
            }
        }
    },

    componentWillReceiveProps: function (nextProps) {
        if (this.props.src != nextProps.src) {
            // No image, size is not known (may be removed and re-added)
            this.setState({imageNaturalWidth: null, imageNaturalHeight: null});
        }
    },

    render: function () {

        let outterDivStyle = this.props.style ? this.props.style : {};
        const src = this.props.src;
        const knownImageSize:boolean = this._knownImageSize();
        const imageActions:Array<CvImageAction> = this.props.actions ? this.props.actions : new Array<CvImageAction>();
        // If there is an explict width and height, we will nest this image into a div so we can
        // preserve the aspect ratio.
        if (outterDivStyle["width"] && outterDivStyle["height"]) {
            var sw: number = outterDivStyle["width"];
            var sh: number = outterDivStyle["height"];
            var managingFit = true;
        } else {
            managingFit = false;
        }
        let imageTop = 0;
        let imageLeft = 0;
        if (managingFit && knownImageSize) {
            // Alter the width and height styles to preserve the aspect ratio
            var fit = ImageUtil.calculateAspectRatioFit(this.state.imageNaturalWidth, this.state.imageNaturalHeight, sw, sh);
            if (fit.width < sw) {
                imageLeft = (sw - fit.width)/2;
            } else if (fit.height < sh) {
                imageTop = (sh - fit.height)/2;
            }
        }
        let className = "cv-image-controls-wrapper";
        if (this.props.className) { className = className + " " + this.props.className };
        if (src) {
            if (managingFit) {
                // If managing the fit, it requires overriding the maxWidth/maxHeight values that might have been
                // specified to control image sizes.
                if (!fit) { fit  = { width:sw, height:sh } };
                let imageStyle:CSSProperties = { position:'absolute', width:fit.width, height:fit.height, top:imageTop, left:imageLeft,
                    maxWidth:10000000, maxHeight:10000000, pointerEvents:"none" };
                var imageCtl = <img className={this.props.imageClassName} style={imageStyle} src={src} onLoad={this._imageLoaded} />
            } else {
                imageCtl = <img className={this.props.imageClassName} src={src} style={{pointerEvents:'none'}} />
            }
        } else {
            this.knownImageSize = null;
            className = className + " cv-no-image";
            if (this.props.className) { className = className + " " + this.props.className };
        }
        if (this.props.readOnly != null) {
            this.props.readOnly ? className = className + " cv-readOnly" : className = className + " cv-maintainable";
        }
        return <div style={outterDivStyle} className={className} >
            <div className="cv-image-controls" >
                {imageActions.map((a, i)=>{
                    return <div className={"cv-image-control-btn"} onClick={a.callback} key={i}>
                        <div className={a.buttonClassName} />
                    </div>})}
            </div>
            {imageCtl}
        </div>

    },

    _imageLoaded(e: any) {
        if (!this._knownImageSize()) {
            this.setState({imageNaturalWidth: e.target.naturalWidth, imageNaturalHeight: e.target.naturalHeight});
        }
    },

    _knownImageSize():boolean {
        return this.state && this.state.imageNaturalHeight;
    }

});

