/**
 * Created by rburson on 5/10/16.
 */

import * as React from 'react'
import {CvState, CvProps, CvBaseMixin, CvContext} from 'catreact'
import {CvHtmlResource} from './catreact-html'
import {Prop, PropDef, EntityRec, EntityRecDef, PaneContext, ObjUtil} from 'catavolt-sdk'

export interface CvDataAnnoState extends CvState {
}

export interface CvDataAnnoProps extends CvProps {
    propName?:string;
    entityRec?:EntityRec;
    dataAnnoStyle?:CvDataAnnoStyle;
    paneContext?:PaneContext;
    wrapperElem?:any;
    wrapperElemProps?:any;
}

export interface CvDataAnnoStyle {
    cssStyle?:{}
    imageName?:string,
    imagePlacementRight?:boolean;
    imagePlacementLeft?:boolean;
    imagePlacementCenter?:boolean;
    imagePlacementUnder?:boolean;
    imagePlacementStretchUnder?:boolean;
    overrideText?:string;
    tipText?:string,
}

/*
 ***************************************************
 * Render a Property
 ***************************************************
 */
export var CvDataAnno = React.createClass<CvDataAnnoProps, CvDataAnnoState>({

    mixins: [CvBaseMixin],

    entityRec: function():EntityRec {
        return this.props.entityRec || this.findEntityRec();
    },

    entityRecDef: function():EntityRecDef {
        return this.paneContext().entityRecDef;
    },

    getChildContext: function () {
        const ctx = this.getDefaultChildContext();
        ctx.cvContext.scopeCtx.scopeObj = this.props.dataAnnoStyle;
        return ctx;
    },

    getDefaultProps: function () {
        return {propName:null, entityRec:null, paneContext:null, dataAnnoStyle: null, wrapperElem:'span', wrapperElemProps: {}}
    },

    paneContext: function():PaneContext {
        return this.findPaneContext();
    },

    prop: function():Prop {
        return this.entityRec().propAtName(this.props.propName)
    },

    render: function () {

        if (this.props.renderer) {
            return this.props.renderer(this.getChildContext().cvContext);
        } else {
            let children = this.props.children;

            let dataAnnoStyle = null;
            if (this.props.dataAnnoStyle) {
                dataAnnoStyle = this.props.dataAnnoStyle;
            } else {
                let annotated = null;
                if (this.props.propName) {
                    annotated = this.prop();
                } else {
                    //we're duck-typing EntityRec here, as it has all the same properties as a Prop...
                    annotated = this.entityRec();
                }
                dataAnnoStyle = (CvDataAnno as any).generateStyleInfo(annotated);
            }

            const newProps = ObjUtil.addAllProps(this.props.wrapperElemProps, {});
            if (dataAnnoStyle.cssStyle) {
                const style = newProps.style ? newProps.style : {};
                newProps['style'] = ObjUtil.addAllProps(dataAnnoStyle.cssStyle, style);
            }
            if (dataAnnoStyle.tipText) {
                newProps['title'] = dataAnnoStyle.tipText;

                /* currently relying on browser 'title' attribute for tool tips */
                /* alternatively, the code below sets up a customer tool tip based on css */
                /* do some shuffling to avoid overwriting any existing classes */
                //newProps['data-tooltip'] = dataAnnoStyle.tipText;
                //const className = newProps.className ? newProps.className + ' ' : '';
                //newProps['className'] = className + 'cv-tooltip cv-tooltip-top';
            }

            if (dataAnnoStyle.imageName) {
                children =<CvDataAnnoImage dataAnnoStyle={dataAnnoStyle}
                                           contentArray={React.Children.toArray(this.props.children)}/>
            }

            if (this.props.wrapperElem) {
                return React.createElement(this.props.wrapperElem, newProps, children);
            } else {
                return this.props.children;
            }
        }
    },
    
    statics: {

        /*
         Duck typing either a Prop or an EntityRec here,
         as both adhere to the same api regarding DataAnnotations
         */
        generateStyleInfo: function (obj:Prop):CvDataAnnoStyle {

            if (obj) {
                const fgColor = obj.foregroundColor;
                const bgColor = obj.backgroundColor;
                const isBold = obj.isBoldText;
                const isItalic = obj.isItalicText;
                const isUnderline = obj.isUnderline;

                const overrideText = obj.overrideText;
                const tipText = obj.tipText;
                const imageName = obj.imageName;
                const imagePlacementLeft = obj.isPlacementLeft;
                const imagePlacementRight = obj.isPlacementRight;
                const imagePlacementCenter = obj.isPlacementCenter;
                const imagePlacementUnder = obj.isPlacementUnder;
                const imagePlacementStretchUnder= obj.isPlacementStretchUnder;

                const style = {};
                if (fgColor) style['color'] = fgColor;
                if (bgColor) style['backgroundColor'] = bgColor;
                if (isBold) style['fontWeight'] = 'bold';
                if (isItalic) style['fontStyle'] = 'italic';
                if (isUnderline) style['textDecoration'] = 'underline';

                return {
                    cssStyle: style,
                    tipText: tipText,
                    imageName: imageName,
                    imagePlacementLeft: imagePlacementLeft,
                    imagePlacementRight: imagePlacementRight,
                    imagePlacementCenter: imagePlacementCenter,
                    imagePlacementUnder: imagePlacementUnder,
                    imagePlacementStretchUnder: imagePlacementStretchUnder,
                    overrideText: overrideText
                }
            } else {
                return {} as CvDataAnnoStyle;
            }

        }
    }
});

export interface CvDataAnnoImageState extends CvState {
}

export interface CvDataAnnoImageProps extends CvProps {
    dataAnnoStyle:CvDataAnnoStyle;
    contentArray?:Array<any>
}


export var CvDataAnnoImage = React.createClass<CvDataAnnoImageProps, CvDataAnnoImageState>({
    
    mixins: [CvBaseMixin],

    getDefaultProps: function() {
       return {dataAnnoStyle:{}, contentArray:[]} 
    },
    
    render: function() {
        const dataAnnoStyle = this.props.dataAnnoStyle;
        if(dataAnnoStyle && dataAnnoStyle.imageName) {
            if(dataAnnoStyle.imagePlacementLeft) {
                return <div>{[<CvHtmlResource className="cv-annotation-image" resourceUrl={dataAnnoStyle.imageName}/>, ...this.props.contentArray]}</div>
            } else if(dataAnnoStyle.imagePlacementRight) {
                return <div>{[...this.props.contentArray, <CvHtmlResource className="cv-annotation-image" resourceUrl={dataAnnoStyle.imageName}/>]}</div>
            } else if(dataAnnoStyle.imagePlacementUnder) {
               return <div className="cv-annotation-bg-image cv-annotation-bg-image-under"
                           style={{backgroundImage: 'url("' + dataAnnoStyle.imageName + '")'}}>{this.props.contentArray}</div>
            } else if(dataAnnoStyle.imagePlacementStretchUnder) {
                return <div className="cv-annotation-bg-image cv-annotation-bg-image-stretch-under"
                            style={{backgroundImage: 'url("' + dataAnnoStyle.imageName + '")'}}>{this.props.contentArray}</div>
            } else if(dataAnnoStyle.imagePlacementCenter) {
                return <div><CvHtmlResource className="cv-annotation-image" resourceUrl={dataAnnoStyle.imageName}/></div>
            } else {
                return <div>{[<CvHtmlResource className="cv-annotation-image" resourceUrl={dataAnnoStyle.imageName}/>, ...this.props.contentArray]}</div>
            }
        }
        return <div>{this.props.contentArray}</div>
        
    }
    
});
