﻿// ------------ device panel helper class ------------ //
Ext.ux.GenericDeviceContentPanelHelper = 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: g_default_xPOPropertyId,
    m_deviceName: null,
    m_lastPlaylistId: g_default_xPOPropertyId,
    m_lastPlaylistName: g_resourceStrings['Js_PlaylistsGrid_PopupMenu_NoPlaylistSelected'],

    m_query: "",
    m_gridPanel0Type: "",
    m_gridPanel1Type: "",


    // external delegates
    m_getDeviceIdDelegate: null,

    // delegate setters
    setGetDeviceIdDelegate: function(theDelegate) {
        this.m_getDeviceIdDelegate = theDelegate;
    },

    // set the current device name
    setDeviceName: function(deviceName) {
        this.m_deviceName = deviceName;
        this.setDescription(this.m_deviceName);
    },

    // standard constructor
    constructor: function(
        contentElementId, footerElementId, descriptionElementId,
        playSmallInactiveImageUrl, playSmallHoverImageUrl,
        playWarningSmallInactiveImageUrl, playWarningSmallHoverImageUrl) {

        this.m_playSmallInactiveImageUrl = playSmallInactiveImageUrl;
        this.m_playSmallHoverImageUrl = playSmallHoverImageUrl;
        this.m_playWarningSmallInactiveImageUrl = playWarningSmallInactiveImageUrl;
        this.m_playWarningSmallHoverImageUrl = playWarningSmallHoverImageUrl;

        // add custom events
        this.addEvents(g_customEvent_genericDeviceContentPanelHelper_playlistChangesSaved);

        Ext.ux.GenericDeviceContentPanelHelper.superclass.constructor.call(this, contentElementId, footerElementId, descriptionElementId);
    },

    // standard initializer
    initComponent: function() {
        Ext.ux.GenericDeviceContentPanelHelper.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.GenericDeviceContentPanelHelper.superclass.initialize.call(this, tabs, delegate(this, this.handleTabClick));
    },

    // get current tab id
    getCurrentTabId: function() {
        return this.m_currentTabId;
    },

    // get current device id
    getDeviceId: function() {
        return this.m_deviceId;
    },

    // get the current playlist id
    getCurrentPlaylistId: function() {
        return this.m_lastPlaylistId;
    },

    // gets the current query
    getQuery: function() {
        return this.m_query;
    },

    // get the total number of records in the detail view
    getDetailTotalCount: function() {
        return this.m_gridPanel1.getTotalCount();
    },

    // do the search click logic
    doSearchClick: function() {

        var newTabId = g_extJsGrid_propertyNameArtist;
        this.doTabClick(newTabId, false);
    },

    // do the reset click logic
    doResetClick: function() {

        // reset search
        this.setSearchParams("");

        // reload all data for current tab
        this.doTabClick(this.getCurrentTabId(), false);
    },

    // do the tab click logic
    // overrides the version in ContentPanelHelper.js
    doTabClick: function(newTabId, forceRefresh) {

        // call external delegate
        if (this.m_getDeviceIdDelegate)
            this.m_deviceId = this.m_getDeviceIdDelegate();

        this.setDescriptionByTabId(newTabId);

        var tabClickParams = { id: this.m_deviceId };
        this.setTabClickParams(tabClickParams);

        // call base class
        Ext.ux.GenericDeviceContentPanelHelper.superclass.doTabClick.call(this, newTabId, forceRefresh);
    },

    // set the panel description
    setDescriptionByTabId: function(tabId) {

        if (tabId === g_musicTab_playlist) {
            this.setDescription(this.m_lastPlaylistName);
        }
        else {
            this.setDescription(this.m_deviceName);
        }
    },

    // do any additional tab click bits and pieces
    doTabClickEx: function() {

        // reset grids
        this.m_gridPanel0 = null;
        this.m_gridPanel1 = null;
    },

    // set the search params
    setSearchParams: function(query) {
        this.m_query = query;
    },

    // display the specified playlist
    displayPlaylist: function(playlistId, playlistName) {

        if (playlistId !== g_default_xPOPropertyId) {
            // valid playlist id
            var newTabId = g_musicTab_playlist;

            this.m_lastPlaylistId = playlistId;
            this.m_lastPlaylistName = playlistName;

            this.doTabClick(newTabId, false);
        }
        else {
            // invalid playlist id
            this.m_lastPlaylistId = playlistId;
            this.m_lastPlaylistName = g_resourceStrings['Js_PlaylistsGrid_PopupMenu_NoPlaylistSelected'];

            if ((this.getCurrentTabId() === g_musicTab_playlist)) {

                // hide any visible confirmation
                if (this.m_gridPanel1 !== null) {
                    this.m_gridPanel1.hideConfirm(0);
                }

                // we're already on the playlist page, so display a warning & set the description
                this.displayPlaylistWarning();
                this.setDescriptionByTabId(g_musicTab_playlist);
            }
        }
    },

    // reload the current playlist
    reloadPlaylist: function() {
        this.doTabClick(g_musicTab_playlist, true);
    },

    // remove the selected playlist entries
    removeSelectedPlaylistEntries: function() {
        if (this.m_gridPanel1.isEditable) {
            this.m_gridPanel1.removeSelectedRows();
            this.m_gridPanel1.showConfirm();
        }
    },

    // save the modified playlist
    savePlaylistChanges: function() {
        this.m_gridPanel1.saveChanges();
    },

    // cancel the playlist modifications
    cancelPlaylistChanges: function() {
        this.m_gridPanel1.cancelChanges();
    },

    // info detail grid configuration
    configureInfoDetailGrids: function(tabData) {

        var params = {
            id: this.getDeviceId(),
            playlistId: this.getCurrentPlaylistId()
        };

        //fine for now as playlists only thing to use info detail grids
        if (this.getCurrentPlaylistId() === g_default_xPOPropertyId) {
            // display warning message
            this.displayPlaylistWarning();
        }
        else {
            $("#music_tracks_cp_message_div_wrapper").css("display", "none");
            $("#music_tracks_cp_detail_message_div_wrapper").css("display", "none");
            $("#music_tracks_cp_grid_detail").css("display", "block");
            $("#music_playlists_cp_info").css("display", "block");
            $("#music_tracks_cp_paging_detail").css("display", "block");

            this.loadInfoDetail_infoData(tabData.additionalUrls[0], params);
            this.loadInfoDetail_detailGridData(tabData.additionalUrls[1], params);
        }
    },

    // info detail dragdrop configuration
    configureInfoDetailDragDrop: function() {
        var ddAddGroups;

        ddAddGroups = new Array(
            g_dragDropGroup_playlistEntryUpload,
            g_dragDropGroup_playlistEntryDownload,
            g_dragDropGroup_playlistInternal);

        // add dragdrop groups
        if (this.m_gridPanel0 !== null) {
            if (this.m_gridPanel0.getView().dragZone !== null) {
                this.m_gridPanel0.getView().dragZone.isTarget = false;
            }
        }

        if (this.m_gridPanel1 !== null) {
            if (this.m_gridPanel1.getView().dragZone !== null) {
                this.m_gridPanel1.getView().dragZone.isTarget = true;
            }

            this.m_gridPanel1.setDdAddGroups(ddAddGroups);
            this.m_gridPanel1.configureDragDrop(g_dragDropGroup_playlistInternal);
        }
    },

    // display a warning about no playlist being selected
    displayPlaylistWarning: function() {
        $("#music_playlists_cp_info").css("display", "none");
        $("#music_tracks_cp_grid_detail").css("display", "none");
        $("#music_tracks_cp_detail_message_div_wrapper").css("display", "none");
        $("#music_tracks_cp_message_div").html(g_resourceStrings['Js_DevicePanel_NoPlaylistSelected']);
        $("#music_tracks_cp_message_div_wrapper").css("display", "block");
        $("#music_tracks_cp_paging_detail").css("display", "none");
    },

    // info detail footer configuration
    configureInfoDetailFooter: function() {
        $("#music_tracks_cp_paging_master").css("display", "none");
        $("#music_tracks_cp_paging_detail").removeClass("cp_paging_single");
        $("#music_tracks_cp_paging_detail").addClass("cp_paging_detail");
        this.m_pagingBar2 = null; // ensure we set this to null, otherwise it won't get recreated the next time we need to display it
    },

    // load data into the info panel
    loadInfoDetail_infoData: function(url, params) {

        $.ajax({
            url: url,
            type: g_method_get, // get so the server can distinguish between display and update of action with same name
            dataType: g_dataType_json,
            data: params,
            success: delegate(this, this.loadInfoDetail_infoDataLoadSuccess),
            error: jQuery_ajaxRequestFailed
        });
    },

    // called when store has retrieved data
    loadInfoDetail_infoDataLoadSuccess: function(data, textStatus) {

        if (data) {
            // set the info subpanel data
            if (data.name) {
                $("#music_playlists_playlist_name").html(data.name);
                this.m_lastPlaylistName = data.name;
                this.setDescription(this.m_lastPlaylistName);
            }

            if (data.count) {
                $("#music_playlists_playlist_track_count").html(data.count);
            }

            if (data.createdat) {
                // see http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx for more info
                var createdat1 = data.createdat;
                var createdat2 = eval(createdat1.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
                var createdat3 = createdat2.getDate() + "/" + (createdat2.getMonth() + 1) + "/" + createdat2.getFullYear();
                $("#music_playlists_playlist_created_at").html(createdat3);
            }
        }
    },

    // load data into the detail grid
    loadInfoDetail_detailGridData: function(url, params) {

        // remove any listener that is already hooked up to prevent hooking up multiple identical ones
        // hook back up on load success
        if (this.m_gridPanel1 !== null) {
            this.m_gridPanel1.removeListener(
                g_customEvent_playlistEntryGrid_changesSaved,
                this.playlistEntryGridChangesSaved,
                this);
        }

        this.m_store1 = extJsStore_createStore(
            this.m_store1,
            url,
            g_playlistGrid_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']);

        if ((this.m_gridPanel1 === null) || (this.m_gridPanel1Type !== "playlist")) {
            this.m_gridPanel1Type = "playlist";

            this.m_gridPanel1 = new Ext.ux.PlaylistEntryGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                store: this.m_store1,
                autoHeight: true,
                enableDragDrop: true,
                isEditable: true,
                renderTemp: "music_tracks_cp_grid_temp_1",
                renderTarget: "music_tracks_cp_grid_detail",
                dragDropHighlightType: g_dragDropHighlightType_betweenRows,
                confirmPanelId: "music_tracks_confirm"
            });

            extJsStore_hookUpStoreEventHandlers(this.m_store1);
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel1, this.m_store1);
        }
        else {
            // hide the confirmation box (it may or may not be currently visible)
            this.m_gridPanel1.hideConfirm(0);
        }

        // set playlist & device ids
        this.m_gridPanel1.setCurrentId(this.getCurrentPlaylistId());
        this.m_gridPanel1.setDeviceId(this.getDeviceId());

        extJsStore_loadData(this.m_store1, this.loadInfoDetail_detailGridLoadSuccess, this);
    },

    // callback called after store has loaded infodetail detail grid
    loadInfoDetail_detailGridLoadSuccess: function(r, options, success) {

        // hook up changesSaved handler
        this.m_gridPanel1.addListener(
            g_customEvent_playlistEntryGrid_changesSaved,
            this.playlistEntryGridChangesSaved,
            this);

        if (r.length === 0) {
            // display warning message
            $("#music_tracks_cp_grid_detail").css("display", "none");
            $("#music_tracks_cp_detail_message_div").html(g_resourceStrings['Js_DevicePanel_NoTracks']);
            $("#music_tracks_cp_detail_message_div_wrapper").css("display", "block");
        }
        else {
            // display grid / hide message
            $("#music_tracks_cp_detail_message_div_wrapper").css("display", "none");
            $("#music_tracks_cp_grid_detail").css("display", "block");
        }

        // show the footer
        this.showFooter(true);
    },

    // raised when the playlist entry grid save changes button is pressed
    playlistEntryGridChangesSaved: function() {
        // fire playlistChangesSaved 'wrapper' event
        this.fireEvent(g_customEvent_genericDeviceContentPanelHelper_playlistChangesSaved);
    },

    // master detail grid configuration
    configureMasterDetailGrids: function(tabData) {

        var masterParams = {
            id: this.getDeviceId(),
            query: this.getQuery()
        };

        var detailParams = {
            id: this.getDeviceId(),
            query: this.getQuery(),
            filterField: this.getCurrentTabId()
        };

        // load the grid based on the type of thing we're displaying the content of (cloud or client device)
        if (this.getDeviceId() == g_cloud_deviceId) {
            this.loadMasterDetail_cloudMasterGridData(tabData.additionalUrls[0], masterParams);
            this.loadMasterDetail_clientTrackDetailGridData(tabData.additionalUrls[1], detailParams);
        }
        else {
            this.loadMasterDetail_clientDeviceMasterGridData(tabData.additionalUrls[0], masterParams);
            this.loadMasterDetail_clientDeviceFileDetailGridData(tabData.additionalUrls[2], detailParams);
        }
    },

    // master detail dragdrop configuration
    configureMasterDetailDragDrop: function() {
        var ddAddGroups;

        if (this.getDeviceId() == 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
        if (this.m_gridPanel0 !== null) {
            if (this.m_gridPanel0.getView().dragZone !== null) {
                this.m_gridPanel0.getView().dragZone.isTarget = false;
            }

            this.m_gridPanel0.setDdAddGroups(ddAddGroups);
        }

        if (this.m_gridPanel1 !== null) {
            if (this.m_gridPanel1.getView().dragZone !== null) {
                this.m_gridPanel1.getView().dragZone.isTarget = false;
            }

            this.m_gridPanel1.setDdAddGroups(ddAddGroups);
        }
    },

    // master detail footer configuration
    configureMasterDetailFooter: function() {
        $("#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.m_pagingBar2 = null; // ensure we set this to null, otherwise it won't get recreated the next time we need to display it
    },

    // load data into the master grid
    loadMasterDetail_clientDeviceMasterGridData: function(url, params) {

        // remove any listen that is already hooked up to prevent hooking up multiple identical listeners
        // hook back up on load success
        if (this.m_gridPanel0 !== null) {
            this.m_gridPanel0.getSelectionModel().removeListener(
                'selectionchange',
                this.masterGridSelectionChanged,
                this);

            // clear any selection
            this.m_gridPanel0.clearSelection();
        }

        this.m_store0 = extJsStore_createStore(
            this.m_store0,
            url,
            this.getCurrentTabId(), // 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());

        if ((this.m_gridPanel0 === null) || (this.m_gridPanel0Type !== "clientdevicemetadata")) {
            this.m_gridPanel0Type = "clientdevicemetadata";

            this.m_gridPanel0 = new Ext.ux.ClientDeviceMetadataGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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);
        }

        // set device id
        this.m_gridPanel0.setDeviceId(this.getDeviceId());

        extJsStore_loadData(this.m_store0, this.loadMasterDetail_masterGridLoadSuccess, this);
    },

    // load data into the master grid
    loadMasterDetail_cloudMasterGridData: function(url, params) {

        // remove any listen that is already hooked up to prevent hooking up multiple identical listeners
        // hook back up on load success
        if (this.m_gridPanel0 !== null) {
            this.m_gridPanel0.getSelectionModel().removeListener(
                'selectionchange',
                this.masterGridSelectionChanged,
                this);

            // clear any selection
            this.m_gridPanel0.clearSelection();
        }

        this.m_store0 = extJsStore_createStore(
            this.m_store0,
            url,
            this.getCurrentTabId(), // 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());

        if ((this.m_gridPanel0 === null) || (this.m_gridPanel0Type !== "cloudmetadata")) {
            this.m_gridPanel0Type = "cloudmetadata";

            this.m_gridPanel0 = new Ext.ux.CloudMetadataGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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);
        }

        // set device id
        this.m_gridPanel0.setDeviceId(this.getDeviceId());

        extJsStore_loadData(this.m_store0, this.loadMasterDetail_masterGridLoadSuccess, this);
    },

    // callback called after store has loaded masterdetail detail grid
    loadMasterDetail_masterGridLoadSuccess: function(r, options, success) {

        // 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().addListener(
            'selectionchange',
            this.masterGridSelectionChanged,
            this,
            { buffer: 150 });

        if (r.length === 0) {
            // display warning message
            $("#music_tracks_cp_grid_master").css("display", "none");

            // display appropriate text
            var message;

            if (this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) {
                message = g_resourceStrings['Js_DevicePanel_NoArtists'];
            }
            else if (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum) {
                message = g_resourceStrings['Js_DevicePanel_NoAlbums'];
            }
            else if (this.getCurrentTabId() == g_extJsGrid_propertyNameGenre) {
                message = g_resourceStrings['Js_DevicePanel_NoGenres'];
            }
            else {
                // should never get here since we only have artist / album / genre master grids
                g_resourceStrings['Js_DevicePanel_NoData'];
            }

            $("#music_tracks_cp_master_message_div").html(message);
            $("#music_tracks_cp_master_message_div_wrapper").css("display", "block");
        }
        else {
            // display grid / hide message
            $("#music_tracks_cp_master_message_div_wrapper").css("display", "none");
            $("#music_tracks_cp_grid_master").css("display", "block");
        }
    },

    // 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());

        var params = {
            id: this.getDeviceId(),
            query: this.getQuery(),
            filterField: this.getCurrentTabId(),
            filterIds: filterIdCsv
        };

        // load the grid based on the type of thing we're displaying the content of (cloud or client device)
        if (this.getDeviceId() == g_cloud_deviceId) {
            this.loadMasterDetail_clientTrackDetailGridData(tabData.additionalUrls[1], params);
        }
        else {
            this.loadMasterDetail_clientDeviceFileDetailGridData(tabData.additionalUrls[2], params);
        }
    },

    // load ClientDeviceFile data into the detail grid
    loadMasterDetail_clientDeviceFileDetailGridData: function(url, params) {

        // send the appropriate default sort field
        var defaultSortField;
        if ((this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum)) {
            defaultSortField = this.getCurrentTabId();
        }
        else {
            // Genre: sort by artist
            defaultSortField = g_extJsGrid_propertyNameArtist;
        }

        this.m_store1 = extJsStore_createStore(
            this.m_store1,
            url,
            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']);

        if ((this.m_gridPanel1 === null) || (this.m_gridPanel1Type !== "clientdevicefile")) {
            this.m_gridPanel1Type = "clientdevicefile";

            this.m_gridPanel1 = new Ext.ux.ClientDeviceFileGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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.getDeviceId());

        extJsStore_loadData(this.m_store1, this.loadMasterDetail_detailGridLoadSuccess, this);
    },

    // load ClientTrack data into the detail grid
    loadMasterDetail_clientTrackDetailGridData: function(url, params) {

        // send the appropriate default sort field
        var defaultSortField;
        if ((this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum)) {
            defaultSortField = this.getCurrentTabId();
        }
        else {
            // Genre: sort by artist
            defaultSortField = g_extJsGrid_propertyNameArtist;
        }

        this.m_store1 = extJsStore_createStore(
            this.m_store1,
            url,
            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']);

        if ((this.m_gridPanel1 === null) || (this.m_gridPanel1Type !== "clientfile")) {
            this.m_gridPanel1Type = "clientfile";

            this.m_gridPanel1 = new Ext.ux.ClientTrackGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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.getDeviceId());

        extJsStore_loadData(this.m_store1, this.loadMasterDetail_detailGridLoadSuccess, this);
    },

    // callback called after store has loaded masterdetail detail grid
    loadMasterDetail_detailGridLoadSuccess: function(r, options, success) {
        if (r.length === 0) {
            // display warning message
            $("#music_tracks_cp_grid_detail").css("display", "none");
            $("#music_tracks_cp_detail_message_div").html(g_resourceStrings['Js_DevicePanel_NoTracks']);
            $("#music_tracks_cp_detail_message_div_wrapper").css("display", "block");
        }
        else {
            // display grid / hide message
            $("#music_tracks_cp_detail_message_div_wrapper").css("display", "none");
            $("#music_tracks_cp_grid_detail").css("display", "block");
        }

        // show the footer
        this.showFooter(true);
    },

    // clears the selection in the master grid (forcing a reload)
    clearMasterSelection: function() {
        this.m_gridPanel0.clearSelection();
    },

    // reload the detail grid
    reloadDetailGrid: function() {
        if ((this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameGenre)) {
            if (this.m_gridPanel1) {
                // load and call our event handler afterwards
                extJsStore_loadData(this.m_store1, this.loadMasterDetail_detailGridLoadSuccess, this);

            }
        }
    },

    // transfers grid configuration
    configureTwinHorizontalGrids: function(tabData) {

        var params = {
            id: this.getDeviceId()
        };

        this.loadTwinHorizontal_topGridData(tabData, params);
        this.loadTwinHorizontal_bottomGridData(tabData, params);
    },

    // twin horizontal dragdrop configuration
    configureTwinHorizontalDragDrop: function() {
    },

    // transfers footer configuration
    configureTwinHorizontalFooter: function() {
        $("#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");
    },

    // load data into the uploads grid
    loadTwinHorizontal_topGridData: function(tabData, params) {

        // send the appropriate default sort field
        var defaultSortField;
        if (this.getDeviceId() == 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,
            params);

        // 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']);

        if ((this.m_gridPanel0 === null) || (this.m_gridPanel0Type !== "upload")) {
            this.m_gridPanel0Type = "upload";

            this.m_gridPanel0 = new Ext.ux.UploadGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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.getDeviceId());

        extJsStore_loadData(this.m_store0, this.loadTwinHorizontal_topGridLoadSuccess, this);
    },

    // callback called after store has loaded transfers upload grid
    loadTwinHorizontal_topGridLoadSuccess: function(r, options, success) {
        if (r.length === 0) {
            // display warning message
            $("#music_transfers_cp_grid_uploads").css("display", "none");
            $("#music_tracks_cp_top_message_div").html(g_resourceStrings['Js_DevicePanel_NoTracks']);
            $("#music_transfers_cp_top_message_div_wrapper").css("display", "block");
        }
        else {
            // display grid / hide message
            $("#music_transfers_cp_top_message_div_wrapper").css("display", "none");
            $("#music_transfers_cp_grid_uploads").css("display", "block");
        }
    },

    // load data into the downloads grid
    loadTwinHorizontal_bottomGridData: function(tabData, params) {

        // send the appropriate default sort field
        var defaultSortField;
        if (this.getDeviceId() === 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,
            params);

        // 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']);

        if ((this.m_gridPanel1 === null) || (this.m_gridPanel1Type !== "download")) {
            this.m_gridPanel1Type = "download";

            this.m_gridPanel1 = new Ext.ux.DownloadGridPanel({
                playSmallHoverImageUrl: this.m_playSmallHoverImageUrl,
                playSmallInactiveImageUrl: this.m_playSmallInactiveImageUrl,
                playWarningSmallHoverImageUrl: this.m_playWarningSmallHoverImageUrl,
                playWarningSmallInactiveImageUrl: this.m_playWarningSmallInactiveImageUrl,
                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.getDeviceId());

        extJsStore_loadData(this.m_store1, this.loadTwinHorizontal_bottomGridLoadSuccess, this);
    },

    // callback called after store has loaded transfers download grid
    loadTwinHorizontal_bottomGridLoadSuccess: function(r, options, success) {
        if (r.length === 0) {
            // display warning message
            $("#music_transfers_cp_grid_downloads").css("display", "none");
            $("#music_tracks_cp_bottom_message_div").html(g_resourceStrings['Js_DevicePanel_NoTracks']);
            $("#music_transfers_cp_bottom_message_div_wrapper").css("display", "block");
        }
        else {
            // display grid / hide message
            $("#music_transfers_cp_bottom_message_div_wrapper").css("display", "none");
            $("#music_transfers_cp_grid_downloads").css("display", "block");
        }

        // show the footer
        this.showFooter(true);
    },

    // form configuration
    configureForm: function(tabData) {
    },

    // form dragdrop configuration
    configureFormDragDrop: function() {
    },

    // form footer configuration
    configureFormFooter: function() {
        this.m_pagingBar2 = null; // ensure we set this to null, otherwise it won't get recreated the next time we need to display it
    },

    // 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);
        }
    },

    // show or hide the footer
    showFooter: function(show) {
        if (show) {
            $("#" + this.m_footerElementId).show();
            $("#music_tracks_paging_top").css("display", "block");
        }
        else {
            $("#" + this.m_footerElementId).hide();
            $("#music_tracks_paging_top").css("display", "none");
        }
    },

    // 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;
    },

    // retrieve the ids of the selected items in the detail list
    getSelectedDetailIds: function() {
        var aSelectedIds = [];

        // only return a list of selected ids if we're in albums / artists / genres
        if ((this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameGenre)) {
            if (this.m_gridPanel1) {
                aSelectedIds = this.m_gridPanel1.createSelectedIdArray();
            }
        }

        return aSelectedIds;
    },

    // retrieve the trackids of the selected tracks in the detail list
    getSelectedDetailTrackIds: function() {
        var aSelectedIds = [];

        // only return a list of selected track ids if we're in albums / artists / genres
        if ((this.getCurrentTabId() == g_extJsGrid_propertyNameArtist) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameAlbum) ||
            (this.getCurrentTabId() == g_extJsGrid_propertyNameGenre)) {
            if (this.m_gridPanel1) {
                aSelectedIds = this.m_gridPanel1.createSelectedTrackIdArray();
            }
        }

        return aSelectedIds;
    },

    // retrieve the ids of the selected items in the master list
    getSelectedPlaylistEntryIds: function() {
        var aSelectedIds = Array();

        // only return a list of selected track ids if we're in playlist display mode
        if ((this.getCurrentTabId() == g_musicTab_playlist)) {
            if (this.m_gridPanel1) {
                aSelectedIds = this.m_gridPanel1.createSelectedIdArray();
            }
        }

        return aSelectedIds;
    },

    // retrieve the ids of the selected FileHashes in the upload queue
    getSelectedUploadQueueIds: function() {
        var aSelectedIds = [];

        // only return a list of selected filehash ids if we're in transfers display mode
        if (this.getCurrentTabId() === g_musicTab_transfers) {
            if (this.m_gridPanel0) {
                aSelectedIds = this.m_gridPanel0.createSelectedIdArray();
            }
        }

        return aSelectedIds;
    },

    // retrieve the ids of the selected FileHashes in the download queue
    getSelectedDownloadQueueIds: function() {
        var aSelectedIds = [];

        // only return a list of selected filehash ids if we're in transfers display mode
        if (this.getCurrentTabId() === g_musicTab_transfers) {
            if (this.m_gridPanel1) {
                aSelectedIds = this.m_gridPanel1.createSelectedIdArray();
            }
        }

        return aSelectedIds;
    },

    // reload the upload queue
    reloadUploadQueue: function() {
        if (this.getCurrentTabId() === g_musicTab_transfers) {
            if (this.m_gridPanel0) {
                // load and call our event handler afterwards
                extJsStore_loadData(this.m_store0, this.loadTwinHorizontal_bottomGridLoadSuccess, this);
            }
        }
    },

    // reload the download queue
    reloadDownloadQueue: function() {
        if (this.getCurrentTabId() === g_musicTab_transfers) {
            if (this.m_gridPanel1) {
                // load and call our event handler afterwards
                extJsStore_loadData(this.m_store1, this.loadTwinHorizontal_bottomGridLoadSuccess, this);
            }
        }
    }
});