﻿// ------------ content panel helper class ------------ //
Ext.ux.ContentPanelHelper = Ext.extend(Ext.util.Observable, {

    // internal fields
    // NOTE: if they are initialised here, they are shared between all instances of ContentPanelHelper
    m_tabData: null,
    m_aTabImageIds: null,
    m_defaultTabId: null,
    m_currentTabId: null,
    m_tabClickParams: 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, descriptionElementId) {

        // args passed in
        this.m_contentElementId = contentElementId;
        this.m_footerElementId = footerElementId;
        this.m_descriptionElementId = descriptionElementId;

        // add custom events
        this.addEvents(g_customEvent_contentPanelHelper_displayPanelContent);

        Ext.ux.ContentPanelHelper.superclass.constructor.call(this);
    },

    // standard initializer
    initComponent: function() {
        Ext.ux.ContentPanelHelper.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);
    },


    // initialize the content panel menu with the specified array of tabs (only the ones which aren't disabled)
    initialize: function(tabs, clickHandler) {
        this.m_loadPanelContent = false;
        this.m_aTabImageIds = [];

        this.m_tabData = tabs;

        for (var i = 0; i < tabs.length; i++) {
            if (!tabs[i].isDisabled) {
                $("#" + tabs[i].handlerLinkId + "").bind("click", tabs[i].stringData, clickHandler);
                $.preloadImages(tabs[i].activeImagePath, tabs[i].hoverImagePath, tabs[i].inactiveImagePath);
                $.merge(this.m_aTabImageIds, [[tabs[i].imageId, tabs[i].handlerImageId, tabs[i].inactiveImagePath]]);

                // bind standard hover images
                $.bindHoverImages(
                    tabs[i].imageId,
                    tabs[i].hoverImagePath,
                    tabs[i].inactiveImagePath,
                    tabs[i].stringData,
                    delegate(this, this.checkIsActive),
                    null, null, null, null, null);

                // bind handler hover images
                $.bindHoverImages(
                    tabs[i].handlerImageId,
                    tabs[i].hoverImagePath,
                    tabs[i].inactiveImagePath,
                    tabs[i].stringData,
                    delegate(this, this.checkIsActive),
                    null, null, null, null, null);

                // store default tab settings so when a new device is clicked, we can execute the correct function
                if (tabs[i].isDefault !== 0) {
                    this.m_defaultTabId = tabs[i].stringData;

                    // also store current tab for hover handler
                    this.m_currentTabId = tabs[i].stringData;
                }
            }
        }
    },

    // set tab-click parameters
    setTabClickParams: function(tabClickParams) {
        this.m_tabClickParams = tabClickParams;
    },

    // retrieve tab-click parameters
    getTabClickParams: function() {
        return this.m_tabClickParams;
    },

    // get the flag indicating if we need to load the panel content
    getLoadPanelContent: function() {
        return this.m_loadPanelContent;
    },

    // set the flag indicating if we need to load the panel content
    setLoadPanelContent: function(loadPanelContent) {
        this.m_loadPanelContent = loadPanelContent;
    },

    // retrieve the set of tabdata given its id
    getTabDataById: function(tabId) {
        var tabData = null;

        for (var i = 0; i < this.m_tabData.length; i++) {
            if (this.m_tabData[i].stringData.toLowerCase() == tabId.toLowerCase()) {
                tabData = this.m_tabData[i];
                break;
            }
        }

        return tabData;
    },

    // get the default tabId
    getDefaultTabId: function() {
        return this.m_defaultTabId;
    },

    // get the current tabId
    getCurrentTabId: function() {
        return this.m_currentTabId;
    },

    // set the current tabId
    setCurrentTabId: function(currentTabId) {
        this.m_currentTabId = currentTabId;
    },

    // asynchronously set the content panel body to the contents of the user fron the specified tab
    // typically used to retrieve a ViewUserControl rendered by a controller
    // call the success callback when completed
    loadPanelContent: function(tabId, params) {

        var tabData = this.getTabDataById(tabId);

        if (tabData && tabData['url'] && (tabData['url'] !== "")) {
            $.ajax({
                url: tabData['url'],
                type: g_method_get, // get so the server can distinguish between display and update of action with same name
                dataType: g_dataType_html,
                data: params,
                success: delegate(this, this.onLoadPanelContentSuccess),
                error: jQuery_ajaxRequestFailed_redirectToLogin
            });
        }
    },

    // load the returned html content into the specified element
    onLoadPanelContentSuccess: function(data) {
        var tabId = this.getCurrentTabId();

        // check the tab we loaded data for is still active since the user may have clicked on another tab
        // while the request was fetching the content for the old tab
        // in which case we should throw away the returned html     
        if (tabId == this.m_currentTabId) {
            $("#" + this.m_contentElementId + "").html(data);
        }

        // fire an event so listeners can update
        this.fireEvent(g_customEvent_contentPanelHelper_displayPanelContent, tabId);
    },

    // return true if the specified tab is the currently active one
    checkIsActive: function(tabId) {
        return tabId.toLowerCase() == this.m_currentTabId.toLowerCase();
    },

    // 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.getDefaultTabId();
        this.doTabClick(newTabId, false);
    },

    // do the tab click logic
    doTabClick: function(newTabId, forceRefresh) {

        // reset the grid, etc
        var newTabData = this.getTabDataById(newTabId);
        var currentTabData = this.getTabDataById(this.getCurrentTabId());

        this.setCurrentTabId(newTabId);

        // change images
        if (newTabData) {
            $("#" + newTabData.imageId + "").attr("src", newTabData.activeImagePath);                 // change image clicked on
            $("#" + newTabData.handlerImageId + "").attr("src", newTabData.activeImagePath);          // change handler image clicked on

            $.showInactiveImages(newTabData.imageId, newTabData.handlerImageId, this.m_aTabImageIds); // change other images to inactive
        }

        // load panel (if necessary)
        if ((this.getLoadPanelContent() === true && newTabData && newTabData['url'] && (newTabData['url'] !== "")) &&
            (!currentTabData || (currentTabData && ((currentTabData['url'] != newTabData['url']) || forceRefresh)))) {

            // reset grids
            this.m_gridPanel = null;

            // do any additional tab click bits and pieces
            // this is meant to be overriden in derived classes
            this.doTabClickEx();

            // load new panel - when load is complete, it calls loadData()
            // from the $(document).ready(function() {}); in the .ascx file itself
            this.loadPanelContent(newTabId, this.m_tabClickParams);
        }
        else {
            // load the data if it's not the very first time
            if (this.getLoadPanelContent() === true) {
                this.loadData();
            }
        }

        this.setLoadPanelContent(true);

        return false;
    },

    // do any additional tab click bits and pieces
    // this is meant to be overriden in derived classes
    // (it's the equivalent of a virtual function in C#)
    doTabClickEx: function() {
    },

    // set the panel description
    setDescription: function(description) {
        if (description && (description !== "")) {
            $("#" + this.m_descriptionElementId).text(description);
        }
    },

    // show or hide the footer
    showFooter: function(show) {
        if (show) {
            $("#" + this.m_footerElementId).show();
        }
        else {
            $("#" + this.m_footerElementId).hide();
        }
    },

    // load data into grids/panels etc.
    loadData: function() {
        var tabData = this.getTabDataById(this.getCurrentTabId());
        if (tabData) {
            if (tabData.tabPanelType == g_singleGrid) {
                this.configureSingleGrid(tabData);
                this.configureSingleDragDrop();
                this.showFooter(false);
                this.configureSingleGridFooter(tabData);
            }
            else if (tabData.tabPanelType == g_masterDetailGrids) {
                this.configureMasterDetailGrids(tabData);
                this.configureMasterDetailDragDrop();
                this.showFooter(false);
                this.configureMasterDetailFooter(tabData);
            }
            else if (tabData.tabPanelType == g_infoDetailGrids) {
                this.configureInfoDetailGrids(tabData);
                this.configureInfoDetailDragDrop();
                this.showFooter(false);
                this.configureInfoDetailFooter(tabData);
            }
            else if (tabData.tabPanelType == g_twinHorizontalGrids) {
                this.configureTwinHorizontalGrids(tabData);
                this.configureTwinHorizontalDragDrop();
                this.showFooter(false);
                this.configureTwinHorizontalFooter(tabData);
            }
            else if (tabData.tabPanelType == g_form) {
                this.configureForm(tabData);
                this.configureFormDragDrop();
                this.showFooter(false);
                this.configureFormFooter(tabData);
            }
        }
    },

    // placeholder configuration functions
    // these are meant to be overriden in derived classes
    // (they're the equivalent of virtual functions in C#)
    configureSingleGrid: function(tabData) { },
    configureSingleDragDrop: function() { },
    configureSingleGridFooter: function() { },
    loadSingle_singleGridData: function(url) { },
    loadSingle_singleGridDataSuccess: function(r, options, success) { },

    configureMasterDetailGrids: function(tabData) { },
    configureMasterDetailDragDrop: function() { },
    configureMasterDetailFooter: function() { },
    loadMasterDetail_masterGridData: function(url, params) { },
    loadMasterDetail_detailGridData: function(url, params) { },
    loadMasterDetail_masterGridLoadSuccess: function(r, options, success) { },
    loadMasterDetail_detailGridLoadSuccess: function(r, options, success) { },

    configureInfoDetailGrids: function(tabData) { },
    configureInfoDetailDragDrop: function() { },
    configureInfoDetailFooter: function() { },
    loadInfoDetail_infoData: function(url, params) { },
    loadInfoDetail_detailGridData: function(url, params) { },
    loadInfoDetail_infoDataLoadSuccess: function(data, textStatus) { },
    loadInfoDetail_detailGridLoadSuccess: function(r, options, success) { },

    configureTwinHorizontalGrids: function(tabData) { },
    configureTwinHorizontalDragDrop: function() { },
    configureTwinHorizontalFooter: function() { },
    loadTwinHorizontal_topGridData: function(tabData, params) { },
    loadTwinHorizontal_bottomGridData: function(tabData, params) { },
    loadTwinHorizontal_topGridLoadSuccess: function(r, options, success) { },
    loadTwinHorizontal_bottomGridLoadSuccess: function(r, options, success) { },

    configureForm: function(tabData) { },
    configureFormDragDrop: function() { },
    configureFormFooter: function() { }
});