/**
 * Created by rburson on 3/15/16.
 */

import * as React from 'react'
import {
    CvState,
    CvWorkbench,
    CvProps,
    CvBaseMixin,
    CvEvent,
    CvNavigationResult,
    CvLauncher,
    CvLaunchActionCallback,
    CvContext,
    CvValueProvider,
    CvActionFiredResult
} from './../core/catreact-core'
import {Workbench, AppWinDef, WorkbenchLaunchAction} from 'catavolt-sdk'

export interface CvGraphicalWorkbenchState extends CvState {
    workbench?:Workbench;
}

export interface CvGraphicalWorkbenchProps extends CvProps {
    /**
     * The sdk {AppWinDef} from which to retrieve the workbenches 
     */
    appWinDef?:AppWinDef;
    /**
     * Register to receive {@link CvEvent}s of type {@link CvNavigationResult}
     */
    launchListeners?:Array<(event:CvEvent<CvNavigationResult>)=>void>
    /**
     * Register to receive {@link CvEvent}s of type {@link CvActionFiredResult}
     */
    actionListeners?:Array<(event:CvEvent<CvActionFiredResult>)=>void>
    /**
     * The workbench id of the initial workbench to show.
     * Should not be used if the initialWorkbench property is provided
     */
    initialWorkbenchId?:string;
    /**
     * The initial workbench to show
     * Should not be used if the initialWorkbenchId property is provided
     */
    initialWorkbench?:Workbench;
    /**
     * Number of columns to use for the workbench launcher display
     */
    numCols?:number;
    /**
     * A workbench selection provider, to which this component will 'listen' and display workbench selection changes
     */
    selectionProvider?:CvValueProvider<Workbench>;
}

/*
 ***************************************************
 * Render a Workbench with Icons
 ***************************************************
 */

export var CvGraphicalWorkbench = React.createClass<CvGraphicalWorkbenchProps, CvGraphicalWorkbenchState>({

    mixins: [CvBaseMixin],

    componentDidMount: function () {
        this.refresh(this.props);
    },

    componentWillReceiveProps: function (nextProps) {
        this.refresh(nextProps);
    },

    appWinDef: function ():AppWinDef {
        return this.props.appWinDef || this.firstInScope(AppWinDef);
    },

    getDefaultProps: function () {
        return {
            appWinDef: null,
            launchListeners: [],
            actionListeners: [],
            numCols: 3,
            selectionProvider: null,
            initialWorkbench: null,
            initialWorkbenchId: null
        }
    },

    getInitialState: function () {
        return {workbench: null}
    },

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

    refresh: function (props:CvGraphicalWorkbenchProps) {

        if (props.initialWorkbench) {
            this.setState({workbench: props.initialWorkbench});
        } else if (props.initialWorkbenchId) {
            const workbench = this._workbenchForId(props.initialWorkbenchId);
            if(workbench) {
                this.setState({workbench: workbench});
            } else {
                this.setState({workbench: this.appWinDef().workbenches[0]})
            }
        } else {
            this.setState({workbench: this.appWinDef().workbenches[0]})
        } 
        const selectionProvider:CvValueProvider<Workbench> = props.selectionProvider;
        if (selectionProvider) {
            selectionProvider.subscribe(this._updateWorkbench);
        }

    },


    render: function () {

        const workbench:Workbench = this.workbench();

        if (workbench) {
            return (
                <CvWorkbench workbench={workbench} appWinDef={this.appWinDef()} renderer={(cvContext:CvContext)=>{

                const cssCols = Math.floor(12/this.props.numCols);
                const workbench:Workbench = cvContext.scopeCtx.scopeObj as Workbench;
                const newChildren = [];
                let rowElems = [];
                workbench.workbenchLaunchActions.forEach((launchAction:WorkbenchLaunchAction, i:number) => {
                    rowElems.push(<CvLauncher launchAction={launchAction} key={launchAction.actionId}
                            launchListeners={this.props.launchListeners} actionListeners={this.props.actionListeners}
                            renderer={(cvContext:CvContext, callback:CvLaunchActionCallback)=>{
                                const launcher = cvContext.scopeCtx.scopeObj as WorkbenchLaunchAction;
                                return (
                                    <div onClick={callback.fireLaunchAction} className={"col-sm-" + cssCols + " cv-launcher-container cv-target animated fadeIn"}>
                                        <img className="cv-launcher-icon img-responsive center-block" src={launcher.iconBase} onError={this._loadPlaceholder}/>
                                        <h4 className="cv-launcher-text small text-center">{launcher.name}</h4>
                                    </div>);
                            }}
                     />);
                    if(i % this.props.numCols == this.props.numCols-1) {
                        newChildren.push(React.createElement('div', {className:'row', key: i}, rowElems));
                        rowElems = [];
                    }
                });
                if(rowElems.length > 0){
                    newChildren.push(React.createElement('div', {className:'row', key: '00'}, rowElems));
                }

                return <div>{newChildren}</div>
                
            }}/>
            );
        } else {
            return null;
        }
    },

    workbench: function () {
        return this.state.workbench;
    },

    _loadPlaceholder: function (e) {
        e.preventDefault();
        e.target.src = 'http://cdn.churchm.ag/wp-content/uploads/2013/06/404-Space-Invaders.png'
    },

    _updateWorkbench: function (workbench:Workbench) {
        this.setState({workbench: workbench});
    },

    _workbenchForId: function(id:string) {
        const appWinDef = this.appWinDef();
        let workbench = null;
        appWinDef.workbenches.some((wb)=> {
            if (wb.workbenchId == id) {
                workbench = wb;
                return true;
            } else {
                return false;
            }
        });
        return workbench;
    }

});
