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

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

export let CvMenuBase = {}

export interface CvMenuState extends CvState {
}

export interface CvMenuProps extends CvProps {
    actionListeners?:Array<(event:CvEvent<CvActionFiredResult>)=>void>
    menuDef?:MenuDef;
    title?:string;
    navigationListeners?:Array<(event:CvEvent<CvNavigationResult>)=>void>
    stateChangeListeners?:Array<(event:CvEvent<CvStateChangeResult>)=>void>
    navTarget?:string;
    paneContext?:PaneContext;
    selectionProvider?:CvValueProvider<Array<string>>;
    actionHandler?:CvValueListener<CvActionHandlerParams>;
    initOpen?:boolean;
    launchMenuElement?:ReactElement<any>;
    openLeft?:boolean;
}

/*
 ***************************************************
 * Render a Menu
 ***************************************************
 */

export let CvDropdownMenu = React.createClass<CvMenuProps, CvMenuState>({

    mixins: [CvBaseMixin, CvMenuBase],

    getDefaultProps: function () {
        return {
            paneContext: null,
            navTarget: null,
            menuDef: null,
            title: null,
            actionListeners: [],
            navigationListeners: [],
            stateChangeListeners: [],
            selectionProvider: null,
            actionHandler: null,
            initOpen: false,
            launchMenuElement: null,
            openLeft: false
        }
    },

    render: function () {

        const itemProps:CvMenuItemProps = {
            paneContext: this.props.paneContext,
            navTarget: this.props.navTarget,
            actionListeners: this.props.actionListeners,
            navigationListeners: this.props.navigationListeners,
            stateChangeListeners: this.props.stateChangeListeners,
            selectionProvider: this.props.selectionProvider,
            actionHandler: this.props.actionHandler,
            catavolt: this.props.catavolt,
            eventRegistry: this.props.eventRegistry
        };

        let menuItemClassName = 'dropdown-menu cv-dropdown-menu';
        if (this.props.openLeft) menuItemClassName += ' dropdown-menu-right';

        const itemRenderer = (cvContext:CvContext, callback:CvActionCallback)=> {
            const menuDef:MenuDef = cvContext.scopeCtx.scopeObj;
            if (menuDef.isSeparator) {
                return <li>
                    <div className="cv-menu-sep"/>
                </li>
            } else if (menuDef.menuDefs && menuDef.menuDefs.length > 0) {
                return <li className="cv-dropdown-submenu">
                    <a>{menuDef.label}</a>
                    <CvMenuItem {...itemProps}
                        wrapperElemName='ul'
                        wrapperElemProps={{className: menuItemClassName}}
                        menuDef={menuDef}
                        subMenuItemRenderer={(cvContext:CvContext, menuItem:MenuDef)=>{
                            return <CvMenuItem {...itemProps} menuDef={menuItem} renderer={itemRenderer}/>
                        }}/>
                </li>
            } else {
                return <li onClick={()=>{callback.fireAction()}}><a className="cv-target">{menuDef.label}</a></li>
            }
        };
        return (
            <span className="dropdown">
                <a className="cv-menu-button" data-toggle="dropdown"
                   ref={(d:any)=>{ if(this.props.initOpen) { ($(d) as any).dropdown('toggle'); } }}>
                    {(()=>{
                        if(this.props.launchMenuElement) {
                            return this.props.launchMenuElement;
                            } else {
                            return <div>{this.props.title}<span className="glyphicon glyphicon-menu-hamburger"/></div>
                            }
                        })()}
                </a>
                <CvMenuItem {...itemProps}
                    wrapperElemName='ul'
                    wrapperElemProps={{className: menuItemClassName}}
                    menuDef={this.props.menuDef}
                    subMenuItemRenderer={(cvContext:CvContext, menuItem:MenuDef)=>{
                        return <CvMenuItem {...itemProps} menuDef={menuItem} renderer={itemRenderer}/>
                    }}/>
            </span>
        );
    }
});

/*
 ***************************************************
 * Render a Toolbar
 ***************************************************
 */

export let CvToolbarMenu = React.createClass<CvMenuProps, CvMenuState>({

    mixins: [CvBaseMixin, CvMenuBase],

    getDefaultProps: function () {
        return {
            paneContext: null,
            navTarget: null,
            menuDef: null,
            title: null,
            actionListeners: [],
            navigationListeners: [],
            stateChangeListeners: [],
            selectionProvider: null,
            actionHandler: null
        }
    },

    render: function () {

        const itemProps:CvMenuItemProps = {
            paneContext: this.props.paneContext,
            navTarget: this.props.navTarget,
            actionListeners: this.props.actionListeners,
            navigationListeners: this.props.navigationListeners,
            stateChangeListeners: this.props.stateChangeListeners,
            selectionProvider: this.props.selectionProvider,
            actionHandler: this.props.actionHandler,
            catavolt: this.props.catavolt,
            eventRegistry: this.props.eventRegistry
        };

        const itemRenderer = (cvContext:CvContext, callback:CvActionCallback)=> {
            const menuDef:MenuDef = cvContext.scopeCtx.scopeObj;
            if (menuDef.isSeparator) {
                return <li>
                    <div className="cv-htool-sep"/>
                </li>
            } else if (menuDef.menuDefs && menuDef.menuDefs.length > 0) {
                return null;   // Not supporting a tool that is a menu
            } else {
                // return <li onClick={()=>{callback.fireAction()}}><a className="cv-target">{menuDef.label}</a></li>
                return <button className="btn btn-default cv-toolbar-button" onClick={()=>{callback.fireAction()}} title={menuDef.label}>
                        <img src={menuDef.iconName}/>
                    </button>
            }
        };
        let tools = [];
        if (this.props.menuDef && this.props.menuDef.menuDefs) {
            this.props.menuDef.menuDefs.forEach((md: MenuDef, i: number) => {
                tools.push(
                    <CvMenuItem {...itemProps}
                                wrapperElemName='span'
                                menuDef={md}
                                renderer={itemRenderer}
                    />
                );
            });
        }
        return (
            <div>{tools}</div>
        );
    }
});
