﻿Ext.ux.PlaylistsGridPanel = Ext.extend(Ext.ux.ContentPanelGridPanel, {

    // standard initializer
    initComponent: function() {
        Ext.ux.PlaylistsGridPanel.superclass.initComponent.apply(this, arguments);

        // args have to go here as base class initComponent doesn't get called for some reason
        var config = {
            view: new Ext.ux.PlaylistsGridView({ scrollOffset: g_gridScrollOffset })
        };

        Ext.apply(this, config);
        Ext.apply(this.initialConfig, config);

        this.on('contextmenu', this.onContextMenu, this);
        this.on('rowdblclick', this.onRowDblClick, this);
    },


    // called when the grid is reconfigured
    reconfigure: function(store, colModel) {

        // set a custom renderer for column 0 (play button)
        colModel.setRenderer(0, delegate(this, this.renderPlayButton));

        // call base class with updated config
        Ext.ux.PlaylistsGridPanel.superclass.reconfigure.call(this, store, colModel);
    },

    // ------ event handler functions ------ //

    // row double-click
    onRowDblClick: function(grid, rowIndex, e) {
        this.setCurrentRowIndex(rowIndex);
        this.autoHighlightCurrentRow();
    },

    // load
    onLoad: function(records, options) {
        Ext.ux.PlaylistsGridPanel.superclass.onLoad.call(this, records, options);
    },

    // context menu
    onContextMenu: function(e) {
        var rowIndex = this.getRowIndexFromEvent(e);

        this.updateSelections(rowIndex);
        this.contextMenu = this.createActionsContextMenu(this, rowIndex);

        Ext.ux.PlaylistsGridPanel.superclass.onContextMenu.call(this, e);
    },

    // key pressed
    onKeyDown: function(e) {

        Ext.ux.PlaylistsGridPanel.superclass.onKeyDown.call(this, e);

        if (e.getKey() == g_keyCode_delete) {
            // show delete playlists confirm form
            music_showDeleteSelectedPlaylistsModalForm();
        }
    },

    // render a play button
    renderPlayButton: function(value, metadata, record, rowIndex, colIndex, store) {

        var columnText = "";

        // show 'play' button if we have a url for the image
        columnText = "<img src=\"" + this.playSmallInactiveImageUrl + "\"" +
            " name=\"playlist_play_image_" + record.data.id + "\"" +
            " id=\"playlist_play_image_" + record.data.id + "\"" +
            " border=\"0\" width=\"27px\" height=\"14px\" style=\"vertical-align: middle;\"" +
            " onClick=\"playlistsGridPanel_handlePlayClicked([" + record.data.id + "]);\"" +
            " onMouseOver=\"setImage('playlist_play_image_" + record.data.id + "', '" + this.playSmallHoverImageUrl + "');\"" +
            " onMouseOut=\"setImage('playlist_play_image_" + record.data.id + "', '" + this.playSmallInactiveImageUrl + "');\"" +
            " alt=\"play now\"" +
            "/>";

        return columnText;
    },

    // configure drop target
    configureDragDrop: function(ddGroup) {
        var dropTargetEl = this.body;
        var grid = this;

        var dropTarget = new Ext.ux.PlaylistsDropTarget(dropTargetEl, {
            ddGroup: ddGroup,
            grid: grid,

            // called when data is dropped
            notifyDrop: function(ddSource, e, data) {
                var type = data.selections[0].data.type;

                // can't drag a playlist onto another playlist
                if (type != g_extJsGrid_dataTypePlaylist) {
                    grid.handleDrop(e, data);
                }

                // don't call base class
            }

            // see PlaylistsDropTarget below for other functions
        });
    },

    // handle the dropping of some records
    handleDrop: function(e, data) {
        var type = data.selections[0].data.type;
        var handleDrop = false;

        if ((type !== g_extJsGrid_dataTypeClientDeviceFile) && (type !== g_extJsGrid_dataTypeClientTrack)) {
            handleDrop = true;
        }
        else {
            var oneOrMoreTracksStreamable = trackHelper_isOneOrMoreTracksStreamable(data.selections);
            if (oneOrMoreTracksStreamable) {
                handleDrop = true;
            }
        }

        if (handleDrop) {
            var iRowIndex = this.getView().findRowIndex(e.getTarget());
            if (iRowIndex === false) {
                // droppped into empty space
                this.handleCreateNew(data);
            }
            else {
                // dropped on a row
                var record = this.store.getAt(iRowIndex);
                this.handleDroppedOnExisting(data, record.data.id);
            }
        }
    },

    // handle the dropping of some records onto empty space
    handleCreateNew: function(data) {
        var sourceDeviceId = data.selections[0].data.deviceid;
        var type = data.selections[0].data.type;
        var idArray = [];

        // create idarray of correct type
        if ((type === g_extJsGrid_dataTypeClientTrack) || (type === g_extJsGrid_dataTypeClientDeviceFile)) {
            idArray = trackHelper_createTrackIdArray(data.selections);
            type = g_extJsGrid_dataTypeTrack;
        }
        else {
            idArray = idHelper_createIdArray(data.selections);
        }

        // show create new playlist form (TODO: convert into extjs event and fire)
        music_showCreateNewPlaylistModalForm(sourceDeviceId, type, idArray);
    },

    // handle the dropping of some records onto an existing playlist
    handleDroppedOnExisting: function(data, droppedOnId) {
        var sourceDeviceId = data.selections[0].data.deviceid;
        var type = data.selections[0].data.type;
        var idArray = [];

        // create idarray of correct type
        if ((type === g_extJsGrid_dataTypeClientTrack) || (type === g_extJsGrid_dataTypeClientDeviceFile)) {
            idArray = trackHelper_createTrackIdArray(data.selections);
            type = g_extJsGrid_dataTypeTrack;
        }
        else {
            idArray = idHelper_createIdArray(data.selections);
        }

        // add to playlist
        ajax_addToPlaylist(droppedOnId, sourceDeviceId, g_positionQualifierEnum_end, g_default_xPOPropertyId, type, idArray, delegate(this, this.reload));
    },


    // ------ context menu creation helper functions ------ //

    // create the context menu
    createActionsContextMenu: function(grid, rowIndex) {
        var selections = this.getSelectionModel().getSelections();
        var contextMenu = this.createEmptyActionsContextMenu();
        var idArray = idHelper_createIdArray(selections);

        if (selections.length > 0) {
            contextMenu.add(new Ext.menu.Item({
                text: g_resourceStrings['Js_Grid_PopupMenu_PlayNow'],
                handler: function() { playlistsGridPanel_handlePlayClicked(idArray); }
            }));

            contextMenu.add(new Ext.menu.Item({
                text: g_resourceStrings['Js_Grid_PopupMenu_AddToNowPlaying'],
                handler: function() { playlistsGridPanel_handleAddToNowPlayingClicked(idArray); }
            }));

            contextMenu.add(new Ext.menu.Item({
                text: g_resourceStrings['Js_PlaylistsGrid_PopupMenu_RenameSelectedPlaylist'],
                handler: function() { playlistsGridPanel_handleRenameSelectedPlaylistClicked(); },
                disabled: selections.length != 1
            }));

            contextMenu.add(new Ext.menu.Item({
                text: g_resourceStrings['Js_PlaylistsGrid_PopupMenu_DeleteSelectedPlaylists'],
                handler: function() { playlistsGridPanel_handleDeleteSelectedPlaylistsClicked(); }
            }));
        }
        else {
            contextMenu.add(new Ext.menu.Item({
                text: g_resourceStrings['Js_PlaylistsGrid_PopupMenu_CreateNewPlaylist'],
                handler: function() { playlistsGridPanel_handleCreateNewPlaylistClicked(); }
            }));
        }

        // add any generic menu items
        contextMenu = this.addGenericMenuItems(grid, contextMenu, rowIndex);

        return contextMenu;
    }
});

Ext.ux.PlaylistsGridView = Ext.extend(Ext.ux.ContentPanelGridView, {

    afterRender: function() {
        Ext.ux.PlaylistsGridView.superclass.afterRender.call(this, arguments);
        this.dragZone = new Ext.ux.PlaylistsGridDragZone(this.grid, { ddGroup: "" });
    }
});

// configure drag & drop
Ext.ux.PlaylistsGridDragZone = Ext.extend(Ext.ux.ContentPanelGridDragZone, {
});

// override to prevent dragging & dropping playlists onto other playlists
Ext.ux.PlaylistsDropTarget = Ext.extend(Ext.ux.ContentPanelDropTarget, {

    notifyOver: function(ddSource, e, data) {
        var type = data.selections[0].data.type;

        // can't drag a playlist onto another playlist
        if (type != g_extJsGrid_dataTypePlaylist) {
            Ext.ux.PlaylistsDropTarget.superclass.notifyOver.call(this, ddSource, e, data);
        }
    },

    notifyEnter: function(ddSource, e, data) {
        var type = data.selections[0].data.type;

        // can't drag a playlist onto another playlist
        if (type !== g_extJsGrid_dataTypePlaylist) {

            if ((type !== g_extJsGrid_dataTypeClientDeviceFile) && (type !== g_extJsGrid_dataTypeClientTrack)) {
                Ext.ux.PlaylistsDropTarget.superclass.notifyEnter.call(this, ddSource, e, data);
            }
            else {
                var oneOrMoreTracksStreamable = trackHelper_isOneOrMoreTracksStreamable(data.selections);
                if (oneOrMoreTracksStreamable) {
                    Ext.ux.PlaylistsDropTarget.superclass.notifyEnter.call(this, ddSource, e, data);
                }
            }
        }
    },

    notifyOut: function(ddSource, e, data) {
        var type = data.selections[0].data.type;

        // can't drag a playlist onto another playlist
        if (type != g_extJsGrid_dataTypePlaylist) {
            Ext.ux.PlaylistsDropTarget.superclass.notifyOut.call(this, ddSource, e, data);
        }
    }
});


// ------ event handler functions ------ //

// 'Play' menu item clicked
function playlistsGridPanel_handlePlayClicked(idArray) {
    eventHandler_handlePlayClickedInt(g_extJsGrid_dataTypePlaylist, idArray, true);
}

// 'Add to now playing' menu item clicked
function playlistsGridPanel_handleAddToNowPlayingClicked(idArray) {
    eventHandler_handleAddToNowPlayingClickedInt(g_extJsGrid_dataTypePlaylist, idArray, true);
}

// 'Rename selected' menu item clicked
function playlistsGridPanel_handleRenameSelectedPlaylistClicked() {
    music_showRenameSelectedPlaylistModalForm();
}

// 'Delete selected' menu item, clicked
function playlistsGridPanel_handleDeleteSelectedPlaylistsClicked() {
    music_showDeleteSelectedPlaylistsModalForm();
}

// 'New playlist' menu item, clicked
function playlistsGridPanel_handleCreateNewPlaylistClicked() {
    music_showCreateNewPlaylistModalForm(null, null, null);
}