﻿// see http://www.extjs.com/products/extcore/manual/content/classsystem.html for more info
// ----------- content panel helper wrapper class ----------- //
Ext.ux.ContentPanelHelperWrapper = Ext.extend(Ext.util.Observable, {

    // internal fields
    m_currentTabId: "",
    m_gridPanelList: null,
    m_gridPanelSingle: null,
    m_pagingBar: null,
    m_storeList: null,
    m_storeSingle: null,
    m_deviceId: g_cloud_deviceId, // see comment in doTabClick(), below
    m_listParams: null,
    m_singleParams: null,

    // flag to indicate we don't load panel content first time around
    // since the panel for the default tab is rendered by the ContentPanelUserControl
    // (we actually specify the ascx control itself in the ContentPanelSettings to save an additional round-trip)
    m_loadPanelContent: false,


    // standard constructor
    constructor: function(
        contentElementId, footerElementId,
        pagingBarId, pagingHtmlElement,
        listRenderTemp, listRenderTarget,
        singleRenderTemp, singleRenderTarget,
        listDefaultSortField, singleDefaultSortField,
        listFooterCaption, singleFooterCaption,
        listDragDropGroups, listDragDropGroup,
        singleDragDropGroups, singleDragDropGroup,
        listEmptySpaceDblClickHandler, singleEmptySpaceDblClickHandler,
        listGridPanelType, singleGridPanelType) {

        // args passed in
        this.m_pagingBarId = pagingBarId;
        this.m_pagingHtmlElement = pagingHtmlElement;
        this.m_listRenderTemp = listRenderTemp;
        this.m_listRenderTarget = listRenderTarget;
        this.m_singleRenderTemp = singleRenderTemp;
        this.m_singleRenderTarget = singleRenderTarget;
        this.m_listDefaultSortField = listDefaultSortField;
        this.m_singleDefaultSortField = singleDefaultSortField;
        this.m_listFooterCaption = listFooterCaption;
        this.m_singleFooterCaption = singleFooterCaption;
        this.m_listDragDropGroups = listDragDropGroups;
        this.m_listDragDropGroup = listDragDropGroup;
        this.m_singleDragDropGroups = singleDragDropGroups;
        this.m_singleDragDropGroup = singleDragDropGroup;
        this.m_listEmptySpaceDblClickHandler = listEmptySpaceDblClickHandler;
        this.m_singleEmptySpaceDblClickHandler = singleEmptySpaceDblClickHandler;
        this.m_listGridPanelType = listGridPanelType;
        this.m_singleGridPanelType = singleGridPanelType;

        // wrapped helper classes
        this.m_contentPanelHelper = new Ext.ux.ContentPanelHelper(contentElementId, footerElementId, null);
        this.m_contentPanelSubpanelHelper = null;

        Ext.ux.ContentPanelHelperWrapper.superclass.constructor.call(this);
    },

    // standard initializer
    initComponent: function() {
        Ext.ux.ContentPanelHelperWrapper.superclass.initComponent.apply(this, arguments);

        // extra args have to go here as base class initComponent doesn't get called for some reason
        var config = {};

        Ext.apply(this, config);
        Ext.apply(this.initialConfig, config);
    },


    // wrapped functions
    setDescription: function(description) {
        this.m_contentPanelHelper.setDescription(description);
    },

    // set subpanel helper
    setSubpanelHelper: function(subpanelHelper) {
        var me = this; // can't use 'this'
        this.m_contentPanelSubpanelHelper = subpanelHelper;
        this.m_contentPanelSubpanelHelper.setLoadListDisplayModeDataDelegate(delegate(me, me.loadData));
        this.m_contentPanelSubpanelHelper.setLoadPreviousDataDelegate(delegate(me, me.loadPreviousData));
        this.m_contentPanelSubpanelHelper.setLoadNextDataDelegate(delegate(me, me.loadNextData));
        this.m_contentPanelSubpanelHelper.setRefreshDelegate(delegate(me, me.refresh));
    },

    // set parameters to be used when retrieving the list grid data
    setListParams: function(params) {
        this.m_listParams = params;
    },

    // set parameters to be used when retrieving the single grid data
    setSingleParams: function(params) {
        this.m_singleParams = params;
    },

    // initialization
    initialize: function(tabs) {
        this.m_contentPanelHelper.initialize(tabs, delegate(this, this.handleTabClick));
    },

    // handle a tab click
    handleTabClick: function(event) {
        var newTabId = event.data;
        this.doTabClick(newTabId, false);
    },

    // simulate click on default tab
    doDefaultTabClick: function() {
        var newTabId = this.m_contentPanelHelper.getDefaultTabId();
        this.doTabClick(newTabId, false);
    },

    // do the tab click logic
    doTabClick: function(newTabId, forceRefresh) {
        // the global list panel always displays lists from the cloud
        // we will need this if we display lists on a per-device basis
        // this.m_deviceId = clientDevicesPanelHelper.getDeviceId();
        var tabRetrievalParams = { id: this.m_deviceId };

        // reset the grid, etc
        var newTabData = this.m_contentPanelHelper.getTabDataById(newTabId);
        var currentTabData = this.m_contentPanelHelper.getTabDataById(this.m_contentPanelHelper.getCurrentTabId());

        this.m_currentTabId = newTabId;
        this.m_contentPanelHelper.setCurrentTabId(this.m_currentTabId);

        // call content panel functions to change button states, load panel (if necessary) & execute callback once done
        this.m_contentPanelHelper.doTabClick(this.m_currentTabId);

        if ((this.m_loadPanelContent && newTabData && newTabData['url'] && (newTabData['url'] !== "")) &&
               (!currentTabData || (currentTabData && ((currentTabData['url'] != newTabData['url']) || forceRefresh)))) {

            // reset grids & change initial flag
            this.m_gridPanelList = null;
            this.m_gridPanelSingle = null;

            // load new panel
            this.m_contentPanelHelper.loadPanelContent(this.m_currentTabId, tabRetrievalParams);
        }
        else {
            // load the data if it's not the very first time
            if (this.m_loadPanelContent === true) {
                this.loadData();
            }
        }

        this.m_loadPanelContent = true;

        return false;
    },

    // load default data
    loadData: function() {
        this.loadListData();

        if (this.m_storeSingle) {
            this.m_storeSingle.removeAll(); // clear the single grid
        }
    },

    // load previous single data
    loadPreviousData: function() {
        var recordId = this.m_gridPanelList.getPreviousRecordId();

        if (recordId != g_default_xPOPropertyId) {
            this.loadSingleData(recordId);
            this.populateInfoSubpanel(recordId);
        }
    },

    // load next single data
    loadNextData: function() {
        var recordId = this.m_gridPanelList.getNextRecordId();

        if (recordId != g_default_xPOPropertyId) {
            this.loadSingleData(recordId);
            this.populateInfoSubpanel(recordId);
        }
    },

    // load list data into the tracks grids
    loadListData: function() {

        var params = {};

        // add device id to params
        if ((typeof (this.m_listParams) !== "undefined") && (this.m_listParams !== null)) {
            params = this.m_listParams;
        }
        params.id = this.m_deviceId;

        var tabData = this.m_contentPanelHelper.getTabDataById(this.m_currentTabId);
        if (tabData) {
            if (tabData.tabPanelType == g_singleGrid) {

                this.loadListGridData(tabData.additionalUrls[0], params, this.m_listFooterCaption);
                this.configureListDragDrop(this.m_gridPanelList);
                this.m_gridPanelList.configureDragDrop(this.m_listDragDropGroup);
                this.m_contentPanelHelper.showFooter(true);
            }
        }
    },

    // load data into the grid
    loadListGridData: function(url, params, footerCaption) {

        this.m_storeList = extJsStore_createStore(
                this.m_storeList,
                url,
                this.m_listDefaultSortField,
                g_extjsGrid_defaultSortDirection,
                params);

        this.m_pagingBar = extJsPagingBar_createPagingBar(
                this.m_pagingBar,
                this.m_pagingBarId,
                this.m_pagingHtmlElement,
                this.m_storeList,
                footerCaption);

        // create new gridPanel if necessary
        if (this.m_gridPanelList === null) {

            var args = {
                store: this.m_storeList,
                autoHeight: true,
                enableDragDrop: true,
                renderTemp: this.m_listRenderTemp,
                renderTarget: this.m_listRenderTarget, // don't have to call render() if we set this
                dragDropHighlightType: g_dragDropHighlightType_row
            };

            // create a new instance of the specified type
            this.m_gridPanelList = new this.m_listGridPanelType(Ext.apply(args));

            extJsStore_hookUpStoreEventHandlers(this.m_storeList);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanelList, this.m_storeList);

            // hook up double-click listeners (pass 'this' in as scope)
            this.m_gridPanelList.on('rowdblclick', this.listGridRowDblClick, this);
            this.m_gridPanelList.on('dblclick', this.listGridDblClick, this);
        }

        extJsStore_loadData(this.m_storeList);
    },

    // configure list grid drag/drop
    configureListDragDrop: function(grid) {
        var ddAddGroups;

        if (grid === null)
            return;

        var gridView = grid.getView();
        if (gridView === null)
            return;

        var gridDragZone = gridView.dragZone;
        if (gridDragZone === null)
            return;

        // can't drop onto grid
        gridDragZone.isTarget = false;

        ddAddGroups = this.m_listDragDropGroups;
        grid.setDdAddGroups(ddAddGroups);
    },

    // load single data into the tracks grids
    loadSingleData: function(recordId) {
        
        var params = {};

        // add device id to params
        if ((typeof (this.m_singleParams) !== "undefined") && (this.m_singleParams !== null)) {
            params = this.m_singleParams;
        }
        params.id = recordId;

        var tabData = this.m_contentPanelHelper.getTabDataById(this.m_currentTabId);
        if (tabData) {
            if (tabData.tabPanelType == g_singleGrid) {

                this.loadSingleGridData(tabData.additionalUrls[1], params, this.m_singleFooterCaption);
                this.configureSingleDragDrop(this.m_gridPanelSingle);
                this.m_gridPanelSingle.setCurrentId(recordId);
                this.m_gridPanelSingle.configureDragDrop(this.m_singleDragDropGroup);
                this.m_contentPanelHelper.showFooter(true);
            }
        }
    },

    // configure grid drag/drop
    configureSingleDragDrop: function(grid) {
        var ddAddGroups;

        if (grid === null)
            return;

        var gridView = grid.getView();
        if (gridView === null)
            return;

        var gridDragZone = gridView.dragZone;
        if (gridDragZone === null)
            return;

        // can drop onto grid
        gridDragZone.isTarget = true;

        ddAddGroups = this.m_singleDragDropGroups;
        grid.setDdAddGroups(ddAddGroups);
    },

    // load data into the grid
    loadSingleGridData: function(url, params, footerCaption) {

        this.m_storeSingle = extJsStore_createStore(
                this.m_storeSingle,
                url,
                this.m_singleDefaultSortField,
                g_extjsGrid_defaultSortDirection,
                params);

        this.m_pagingBar = extJsPagingBar_createPagingBar(
                this.m_pagingBar,
                this.m_pagingBarId,
                this.m_pagingHtmlElement,
                this.m_storeSingle,
                footerCaption);

        // create new gridPanel if necessary
        if (this.m_gridPanelSingle === null) {

            var args = {
                store: this.m_storeSingle,
                autoHeight: true,
                enableDragDrop: true,
                renderTemp: this.m_singleRenderTemp,
                renderTarget: this.m_singleRenderTarget, // don't have to call render() if we set this
                dragDropHighlightType: g_dragDropHighlightType_betweenRows
            };

            // create a new instance of the specified type
            this.m_gridPanelSingle = new this.m_singleGridPanelType(Ext.apply(args));

            extJsStore_hookUpStoreEventHandlers(this.m_storeSingle);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanelSingle, this.m_storeSingle);

            // hook up double-click listeners
            this.m_gridPanelSingle.on('dblclick', this.singleGridDblClick, this);
        }

        extJsStore_loadData(this.m_storeSingle);
    },

    // refresh the visible grid
    refresh: function() {
        var displayMode = g_contentPanelDisplayMode_list;

        if (this.m_contentPanelSubpanelHelper !== null) {
            displayMode = this.m_contentPanelSubpanelHelper.getDisplayMode();
        }

        // refresh the visible grid
        if ((displayMode == g_contentPanelDisplayMode_list) && (this.m_gridPanelList !== null)) {
            this.m_gridPanelList.getView().refresh(true);
        }
        else if ((displayMode == g_contentPanelDisplayMode_single) && (this.m_gridPanelSingle !== null)) {
            this.m_gridPanelSingle.getView().refresh(true);
        }
    },

    // reload data in the visible grid
    reload: function() {
        var displayMode = g_contentPanelDisplayMode_list;

        if (this.m_contentPanelSubpanelHelper !== null) {
            displayMode = this.m_contentPanelSubpanelHelper.getDisplayMode();
        }

        // refresh the visible grid
        if ((displayMode == g_contentPanelDisplayMode_list) && (this.m_gridPanelList !== null)) {
            this.m_gridPanelList.reload();
        }
        else if ((displayMode == g_contentPanelDisplayMode_single) && (this.m_gridPanelSingle !== null)) {
            var record = this.m_gridPanelList.getCurrentRecord();
            this.m_gridPanelSingle.reload();
            this.populateInfoSubpanel(record.data.id);
        }
    },

    // row double-click event handler
    listGridRowDblClick: function(grid, rowIndex, e) {

        // update flexcroll
        var scrollTargetElementId = this.m_gridPanelList.getView().scroller.id;

        // set the display mode to single and show the nav and info subpanels
        this.m_gridPanelList.setCurrentRowIndex(rowIndex);

        var record = this.m_gridPanelList.getCurrentRecord();
        //var me        = this; // can't use this
        //var delegate  = delegateWithArguments(me, me.loadSingleData, record.data.id)

        // convert to 'single' display mode
        if (this.m_contentPanelSubpanelHelper !== null) {
            this.m_contentPanelSubpanelHelper.setSingleDisplayMode(record.data.id, scrollTargetElementId); // pass through id of record to whose data is to be displayed in single mode
            this.populateInfoSubpanel(record.data.id);
            this.loadSingleData(record.data.id);
        }
    },

    // list grid double-click handler
    listGridDblClick: function(e) {
        var selections = this.m_gridPanelList.getSelectionModel().getSelections();
        if ((selections === false) || (selections.length === 0)) {

            // call the callback, if valid
            if (this.m_listEmptySpaceDblClickHandler !== null) {
                this.m_listEmptySpaceDblClickHandler();
            }
        }
    },

    // single grid double-click handler
    singleGridDblClick: function(e) {
        var selections = this.m_gridPanelList.getSelectionModel().getSelections();
        if ((selections === false) || (selections.length === 0)) {

            // call the callback, if valid
            if (this.m_singleEmptySpaceDblClickHandler !== null) {
                this.m_singleEmptySpaceDblClickHandler();
            }
        }
    },

    // show all (set to list mode)
    showList: function() {
        if (this.m_contentPanelSubpanelHelper !== null) {
            this.m_contentPanelSubpanelHelper.setListDisplayMode(delegate(this, this.loadData));
        }
    },

    // show single (set to single mode)
    showSingle: function(recordId) {

        // update flexcroll
        var scrollTargetElementId = this.m_gridPanelList.getView().scroller.id;
        //var me                    = this; // can't use this
        //var delegate              = delegateWithArguments(me, me.loadSingleData, recordId)

        if (this.m_contentPanelSubpanelHelper !== null) {
            this.m_contentPanelSubpanelHelper.setSingleDisplayMode(recordId, scrollTargetElementId); // pass through id of record to whose data is to be displayed in single mode
            this.populateInfoSubpanel(recordId);
            this.loadSingleData(recordId);
        }
    },

    // populate the info subpanel
    populateInfoSubpanel: function(recordId) {
        var tabData = this.m_contentPanelHelper.getTabDataById(this.m_currentTabId);
        if (tabData && (this.m_contentPanelSubpanelHelper !== null)) {
            this.m_contentPanelSubpanelHelper.populateInfoSubpanel(tabData.additionalUrls[2], recordId);
        }
    },

    // get the id of the current item
    getCurrentId: function() {
        var currentId = g_default_xPOPropertyId;

        if ((this.m_contentPanelSubpanelHelper !== null) && (this.m_contentPanelSubpanelHelper.getDisplayMode() == g_contentPanelDisplayMode_single)) {
            currentId = this.m_gridPanelSingle.getCurrentId();
        }

        return currentId;
    },

    // retrieve the ids of the selected items
    getSelectedIds: function() {
        var aSelectedIds = [];

        // only return a list of selected ids if we're in list display mode
        if ((this.m_contentPanelSubpanelHelper === null) ||
                ((this.m_contentPanelSubpanelHelper !== null) && (this.m_contentPanelSubpanelHelper.getDisplayMode() == g_contentPanelDisplayMode_list))) {
            if (this.m_gridPanelList) {
                var selections = this.m_gridPanelList.getSelectionModel().getSelections();
                if (selections) {
                    for (var iSelection = 0; iSelection < selections.length; iSelection++) {
                        aSelectedIds.push(selections[iSelection].data.id);
                    }
                }
            }
        }

        return aSelectedIds;
    },

    // retrieve the ids of the selected entries)
    getSelectedEntryIds: function() {
        var aSelectedIds = [];

        // only return a list of selected entry ids if we're in single display mode
        if ((this.m_contentPanelSubpanelHelper !== null) && (this.m_contentPanelSubpanelHelper.getDisplayMode() == g_contentPanelDisplayMode_single)) {
            if (this.m_gridPanelSingle) {
                var selections = this.m_gridPanelSingle.getSelectionModel().getSelections();
                if (selections) {
                    for (var iSelection = 0; iSelection < selections.length; iSelection++) {
                        aSelectedIds.push(selections[iSelection].data.id);
                    }
                }
            }
        }

        return aSelectedIds;
    },

    // get the current display mode
    getDisplayMode: function() {
        var displayMode = g_contentPanelDisplayMode_list;

        if (this.m_contentPanelSubpanelHelper !== null) {
            displayMode = this.m_contentPanelSubpanelHelper.getDisplayMode();
        }

        return displayMode;
    }
});