﻿// ------------ device panel helper class ------------ //
Ext.ux.DeviceContentPanelHelper = Ext.extend(Ext.ux.ContentPanelHelper, {

    // internal fields
    m_currentTabId: "",
    m_gridPanel0: null,
    m_pagingBar0: null,
    m_gridPanel1: null,
    m_pagingBar1: null,
    m_pagingBar2: null, // uploads
    m_store0: null,
    m_store1: null,
    m_deviceId: -1,
    m_searchField: "",
    m_searchText: "",

    // external delegates
    m_getDeviceIdDelegate: null,

    // delegate setters
    setGetDeviceIdDelegate: function(theDelegate) {
        this.m_getDeviceIdDelegate = theDelegate;
    },


    // standard constructor
    constructor: function(contentElementId, footerElementId, descriptionElementId) {
        Ext.ux.DeviceContentPanelHelper.superclass.constructor.call(this, contentElementId, footerElementId, descriptionElementId);
    },

    // standard initializer
    initComponent: function() {
        Ext.ux.DeviceContentPanelHelper.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);
    },


    // initialization
    initialize: function(tabs) {
        Ext.ux.DeviceContentPanelHelper.superclass.initialize.call(this, 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.getDefaultTabId();
        this.doTabClick(newTabId, false);
    },

    // do the search click logic
    doSearchClick: function() {

        var newTabId;

        // find out which tab to activate
        if (this.m_searchField == g_extJsGrid_propertyNameAlbum) {
            // select album tab
            newTabId = g_extJsGrid_propertyNameAlbum;
        }
        else {
            // ((searchField == g_extJsGrid_propertyNameArtist) || (searchField == g_extJsGrid_dataTypeTrack) || (searchField == g_searchField_all))
            // select artist tab
            newTabId = g_extJsGrid_propertyNameArtist;
        }

        this.doTabClick(newTabId, false);
    },

    // do the reset click logic
    doResetClick: function() {

        // reset search
        this.m_searchField = "";
        this.m_searchText = "";

        // reload all data for current tab
        this.doTabClick(this.getCurrentTabId(), false);
    },

    // do the tab click logic
    doTabClick: function(newTabId, forceRefresh) {

        // call external delegate
        if (this.m_getDeviceIdDelegate)
            this.m_deviceId = this.m_getDeviceIdDelegate();

        var params = { id: this.m_deviceId };

        // reset the grids, etc
        var newTabData = this.getTabDataById(newTabId);
        var currentTabData = this.getTabDataById(this.getCurrentTabId());

        this.setCurrentTabId(newTabId);

        // call base class
        Ext.ux.DeviceContentPanelHelper.superclass.doTabClick.call(this, this.getCurrentTabId());

        // load panel (if necessary)
        if ((this.getLoadPanelContent() === true && newTabData && newTabData['url'] && (newTabData['url'] !== "")) &&
           (!currentTabData || (currentTabData && ((currentTabData['url'] != newTabData['url']) || forceRefresh)))) {

            // reset grids & change initial flag
            this.m_gridPanel0 = null;
            this.m_gridPanel1 = null;

            // load new panel - when load is complete, it calls loadData()
            // from the $(document).ready(function() {}); in the .ascx file itself
            this.loadPanelContent(newTabId, params);
        }
        else {
            // just load the data if panel is already loaded
            if (this.getLoadPanelContent() === true) {
                this.loadData();
            }
        }

        this.setLoadPanelContent(true);

        return false;
    },

    // set the search params
    setSearchParams: function(searchField, searchText) {
        this.m_searchField = searchField;
        this.m_searchText = searchText;
    },

    // load data into the tracks grids
    loadData: function() {
        var tabData = this.getTabDataById(this.getCurrentTabId());
        if (tabData) {

            if (tabData.tabPanelType == g_masterDetailGrids) {
                this.configureMasterDetailGrids(tabData); // params are only passed in here
                this.configureMasterDetailFooters();
            }
            else if (tabData.tabPanelType == g_twinHorizontalGrids) {
                this.configureTwinHorizontalGrids(tabData);
                this.configureTwinHorizontalFooters();
            }
            else if (tabData.tabPanelType == g_form) {
                this.configureForm(tabData);
                this.configureFormFooter();
            }
        }
    },

    /* master detail grid configuration */
    configureMasterDetailGrids: function(tabData) {
        this.loadMasterGridData(tabData.additionalUrls[0]);
        this.loadDetailGridData(tabData.additionalUrls[1]);

        this.configureDragDrop(this.m_gridPanel0, this.m_deviceId);
        this.configureDragDrop(this.m_gridPanel1, this.m_deviceId);
    },

    // configure grid drag/drop
    configureDragDrop: 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;

        if (this.m_deviceId == g_cloud_deviceId) {
            // cloud selelected - can only drop on devices or playlist
            ddAddGroups = new Array(
                g_dragDropGroup_trackDownload,
                g_dragDropGroup_trackToPlaylist);
        }
        else {
            // device selected - can drop on cloud, device or playlist
            ddAddGroups = new Array(
                g_dragDropGroup_trackUpload,
                g_dragDropGroup_trackDownload,
                g_dragDropGroup_trackToPlaylist);
        }

        // add dragdrop groups
        grid.setDdAddGroups(ddAddGroups);
    },

    // load data into the master grid
    loadMasterGridData: function(url) {

        var params = {
            id: this.m_deviceId,
            searchField: this.m_searchField,
            searchText: this.m_searchText
        };

        this.m_store0 = extJsStore_createStore(
            this.m_store0,
            url,
            this.m_currentTabId, // default sort field is tab id
            g_extjsGrid_defaultSortDirection,
            params);

        this.m_pagingBar0 = extJsPagingBar_createPagingBar(
            this.m_pagingBar0,
            "music_tracks_paging_master",
            "music_tracks_cp_paging_master",
            this.m_store0,
            this.getCurrentTabId().toLowerCase());

        // create new gridPanel if necessary
        if (this.m_gridPanel0 === null) {
            this.m_gridPanel0 = new Ext.ux.TracksMasterGridPanel({
                store: this.m_store0,
                autoHeight: true,
                enableDragDrop: true,
                renderTemp: "music_tracks_cp_grid_temp_0",
                renderTarget: "music_tracks_cp_grid_master"
            });

            extJsStore_hookUpStoreEventHandlers(this.m_store0);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel0, this.m_store0);

            // hook up row selection changed handler. we don't want all selection changed events
            // in the case of a multi-select, so we buffer the events.
            // see: https://extjs.com/forum/showthread.php?t=9292 for more info
            this.m_gridPanel0.getSelectionModel().on('selectionchange', this.masterGridSelectionChanged, this, { buffer: 150 });
        }

        // set device id
        this.m_gridPanel0.setDeviceId(this.m_deviceId);

        extJsStore_loadData(this.m_store0);
    },

    // a cell in the master grid was clicked
    masterGridSelectionChanged: function(selectionModel) {
        var selectedRows = selectionModel.getSelections();
        var filterIds = [];
        var filterIdCsv;

        // retrieve values of id field (returned from server) stored in selected rows & pass through to grid
        // to enable filtering by selected row
        for (var i = 0; i < selectedRows.length; i++) {
            if ((selectedRows[i].data) && (selectedRows[i].data.id)) {
                filterIds.push(selectedRows[i].data.id);
            }
        }
        filterIdCsv = filterIds.join(",");

        // reload the detail grid with filter field (this.getCurrentTabId()) and selection data to enable server to filter
        var tabData = this.getTabDataById(this.getCurrentTabId());
        this.loadDetailGridData(tabData.additionalUrls[1], filterIdCsv);
    },

    // load data into the detail grid
    loadDetailGridData: function(url, filterIdCsv) {

        var params = {
            id: this.m_deviceId,
            searchField: this.m_searchField,
            searchText: this.m_searchText,
            filterField: this.m_currentTabId,
            filterIds: filterIdCsv
        };

        this.m_store1 = extJsStore_createStore(
            this.m_store1,
            url,
            g_tracksGrid_defaultSortField,
            g_extjsGrid_defaultSortDirection,
            params);

        this.m_pagingBar1 = extJsPagingBar_createPagingBar(
            this.m_pagingBar1,
            "music_tracks_paging_detail",
            "music_tracks_cp_paging_detail",
            this.m_store1,
            g_resourceStrings['Js_TracksGrid_DetailPagingBar_Track']);

        // create new gridPanel if necessary
        if (this.m_gridPanel1 === null) {
            this.m_gridPanel1 = new Ext.ux.TracksDetailGridPanel({
                store: this.m_store1,
                autoHeight: true,
                enableDragDrop: true,
                renderTemp: "music_tracks_cp_grid_temp_1",
                renderTarget: "music_tracks_cp_grid_detail"
            });

            extJsStore_hookUpStoreEventHandlers(this.m_store1);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel1, this.m_store1);
        }

        // set device id
        this.m_gridPanel1.setDeviceId(this.m_deviceId);

        extJsStore_loadData(this.m_store1);
    },

    // refresh the grids
    refresh: function() {
        if (this.m_gridPanel0 !== null) {
            this.m_gridPanel0.getView().refresh(true);
        }

        if (this.m_gridPanel1 !== null) {
            this.m_gridPanel1.getView().refresh(true);
        }
    },

    /* master detail footer configuration */
    configureMasterDetailFooters: function() {
        this.showFooter(false);
        $("#music_tracks_cp_paging_master").css("display", "block");
        $("#music_tracks_cp_paging_detail").removeClass("cp_paging_single");
        $("#music_tracks_cp_paging_detail").addClass("cp_paging_detail");
        this.showFooter(true);
        this.m_pagingBar2 = null; // ensure we set this to null, otherwise it won't get recreated the next time we need to display it
    },

    /* twin horizontal grid configuration */
    configureTwinHorizontalGrids: function(tabData) {

        this.loadUploadsData(tabData);
        this.loadDownloadsData(tabData);
    },

    // load data into the uploads grid
    loadUploadsData: function(tabData) {

        // send the appropriate default sort field
        var defaultSortField;
        if (this.m_deviceId == g_cloud_deviceId) {
            defaultSortField = g_cloudUploadsGrid_defaultSortField;
        }
        else {
            defaultSortField = g_deviceUploadsGrid_defaultSortField;
        }

        // create store
        this.m_store0 = extJsStore_createStore(
            this.m_store0,
            tabData.additionalUrls[0],
            defaultSortField,
            g_extjsGrid_defaultSortDirection,
            { id: this.m_deviceId });

        // create paging bar
        this.m_pagingBar2 = extJsPagingBar_createPagingBar(
            this.m_pagingBar2,
            "music_tracks_paging_top",
            "music_tracks_cp_paging_top",
            this.m_store0,
            g_resourceStrings['Js_TracksGrid_PagingBar_PendingUpload']);

        // create new gridPanel if necessary
        if (this.m_gridPanel0 === null) {
            this.m_gridPanel0 = new Ext.ux.TransfersGridPanel({
                id: "music_transfers_grid_uploads",
                store: this.m_store0,
                autoHeight: true,
                enableDragDrop: false,
                renderTemp: "music_tracks_cp_grid_temp_0",
                renderTarget: "music_transfers_cp_grid_uploads"
            });

            extJsStore_hookUpStoreEventHandlers(this.m_store0);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel0, this.m_store0);
        }

        // set device id
        this.m_gridPanel0.setDeviceId(this.m_deviceId);
        this.m_gridPanel0.setGridType(g_extJsGrid_gridTypeUpload);

        extJsStore_loadData(this.m_store0);
    },

    // load data into the downloads grid
    loadDownloadsData: function(tabData) {

        // send the appropriate default sort field
        var defaultSortField;
        if (this.m_deviceId === 0) {
            defaultSortField = g_cloudDownloadsGrid_defaultSortField;
        }
        else {
            defaultSortField = g_deviceDownloadsGrid_defaultSortField;
        }

        // create the store
        this.m_store1 = extJsStore_createStore(
            this.m_store1,
            tabData.additionalUrls[1],
            defaultSortField,
            g_extjsGrid_defaultSortDirection,
            { id: this.m_deviceId });

        // create the paging bar
        this.m_pagingBar1 = extJsPagingBar_createPagingBar(
            this.m_pagingBar1,
            "music_tracks_paging_detail",
            "music_tracks_cp_paging_detail",
            this.m_store1,
            g_resourceStrings['Js_TracksGrid_PagingBar_PendingDownload']);

        // create new gridPanel if necessary
        if (this.m_gridPanel1 === null) {
            this.m_gridPanel1 = new Ext.ux.TransfersGridPanel({
                id: "music_transfers_grid_downloads",
                store: this.m_store1,
                autoHeight: true,
                enableDragDrop: false,
                renderTemp: "music_tracks_cp_grid_temp_1",
                renderTarget: "music_transfers_cp_grid_downloads"
            });

            extJsStore_hookUpStoreEventHandlers(this.m_store1);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel1, this.m_store1);
        }

        // set device id
        this.m_gridPanel1.setDeviceId(this.m_deviceId);
        this.m_gridPanel1.setGridType(g_extJsGrid_gridTypeDownload);

        extJsStore_loadData(this.m_store1);
    },

    // determine if one or more of the currently selected tracks can be streamed
    isOneOrMoreSelectedDetailTracksStreamable: function() {
        var isStreamable = false;

        if (this.m_gridPanel1) {
            isStreamable = this.m_gridPanel1.isOneOrMoreSelectedTracksStreamable();
        }

        return isStreamable;
    },

    // TODO: refactor the following four functions into one nice one
    // retrieve the ids of the selected items in the master list
    getSelectedMasterIds: function() {
        var aSelectedIds = [];

        // only return a list of selected track ids if we're in albums / artists / genres
        if ((this.getCurrentTabId() == "artist") ||
            (this.getCurrentTabId() == "album") ||
            (this.getCurrentTabId() == "genre")) {
            if (this.m_gridPanel0) {
                var selections = this.m_gridPanel0.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 items in the master list
    getSelectedDetailTrackIds: function() {
        var aSelectedIds = [];

        // only return a list of selected track ids if we're in albums / artists / genres
        if ((this.getCurrentTabId() == "artist") ||
            (this.getCurrentTabId() == "album") ||
            (this.getCurrentTabId() == "genre")) {
            if (this.m_gridPanel1) {
                var selections = this.m_gridPanel1.getSelectionModel().getSelections();
                if (selections) {
                    for (var iSelection = 0; iSelection < selections.length; iSelection++) {
                        aSelectedIds.push(selections[iSelection].data.filehashid);
                    }
                }
            }
        }

        return aSelectedIds;
    },

    // retrieve the ids of the selected tracks in the upload queue
    getSelectedUploadQueueTrackIds: function() {
        var aSelectedIds = [];

        // only return a list of selected track ids if we're in transfers display mode      
        if (this.getCurrentTabId() == "Transfers") {
            if (this.m_gridPanel0) {
                var selections = this.m_gridPanel0.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 tracks in the download queue
    getSelectedDownloadQueueTrackIds: function() {
        var aSelectedIds = [];

        // only return a list of selected track ids if we're in transfers display mode      
        if (this.getCurrentTabId() == "Transfers") {
            if (this.m_gridPanel1) {
                var selections = this.m_gridPanel1.getSelectionModel().getSelections();
                if (selections) {
                    for (var iSelection = 0; iSelection < selections.length; iSelection++) {
                        aSelectedIds.push(selections[iSelection].data.id);
                    }
                }
            }
        }

        return aSelectedIds;
    },

    // get current tab id
    getCurrentTabId: function() {
        return this.m_currentTabId;
    },

    // reload the upload queue
    reloadUploadQueue: function() {
        if (this.getCurrentTabId() == "Transfers") {
            if (this.m_gridPanel0) {
                this.m_gridPanel0.reload();
            }
        }
    },

    // reload the download queue
    reloadDownloadQueue: function() {
        if (this.getCurrentTabId() == "Transfers") {
            if (this.m_gridPanel1) {
                this.m_gridPanel1.reload();
            }
        }
    },

    /* master detail footer configuration */
    configureTwinHorizontalFooters: function() {
        this.showFooter(false);
        $("#music_tracks_cp_paging_master").css("display", "none");
        $("#music_tracks_cp_paging_detail").removeClass("cp_paging_detail");
        $("#music_tracks_cp_paging_detail").addClass("cp_paging_single");
        this.showFooter(true);
    },

    /* form configuration */
    configureForm: function(tabData) {
        this.showFooter(false);
    },

    /* form footer configuration */
    configureFormFooter: function() {
        this.showFooter(false);
        this.m_pagingBar2 = null; // ensure we set this to null, otherwise it won't get recreated the next time we need to display it
    }
});