/// class ProspectDirector.Modules.Views.ViewColumnConfiguration
/// using ProspectDirector.Types.Core.Dialog
/// using ProspectDirector.Types.Core.ContextMenu

ProspectDirector.Modules.Views.ViewColumnConfiguration = Class.extend({

    //===========================
    // FIELDS
    //===========================

    _container: null,
    _menu: null,
    _grid: null,

    //===========================
    // CONSTRUCTOR
    //===========================

    init: function (options) {

        this.options = $.extend({
            selector: null,
            data: {
                viewStateId: null,
                columns: []
            }
        }, options);

        this._container = $(this.options.selector);
        this._grid = this._container.find("[data-role=grid]");
        this._menu = this._container.find("[data-role=menu]");

        this.init_container();
        this.init_menu();
        this.init_grid();

    },

    //===========================
    // PROPERTIES
    //===========================

    get_container: function () {
        return this._container;
    },

    get_menu: function () {
        return this._menu;
    },

    get_grid: function () {
        return this._grid;
    },

    //===========================
    // INITIALIZERS
    //===========================

    init_container: function () {

    },

    init_menu: function () {

        this.get_menu().kendoMenu({
            select: $.proxy(this.menu_onSelect, this)
        });

    },

    init_grid: function () {

        var index = 0,
            that = this,
            grid = null;

        grid = this.get_grid().kendoGrid({
            dataSource: new kendo.data.DataSource({
                data: this.options.data.columns
            }),
            resizable: true,
            columns: [
                    {
                        field: "id",
                        title: "&nbsp;",
                        width: "30px",
                        template: function (e) {
                            return (that.get_grid().data("kendoGrid").dataSource.indexOf(e) + 1) + ".";
                        },
                        attributes: {
                            style: "text-align:right;font-weight:bold;background-color:\\#EEEEEE;color:\\#333333;"
                        }
                    },
                    {
                        field: "name",
                        title: "Name",
                        width: this.options.data.isAnchorable ? "200px" : "400px",
                        template: function (e) {

                            var div = $("<div data-role=\"name\"></div>");

                            div.css({
                                whiteSpace: "nowrap",
                                overflow: "hidden",
                                textOverflow: "ellipsis"
                            });

                            if (e.name !== e.defaultName) {
                                div.css({
                                    fontWeight: "bold",
                                    fontStyle: "italic",
                                    color: "darkred"
                                });
                                //div.attr("title", "Default Name: " + e.defaultName);
                            }

                            div.html(e.name);

                            return div[0].outerHTML;

                        },
                        attributes: {
                            style: "white-space:nowrap;"
                        }
                    },
                    {
                        field: "usedBy",
                        title: "Used By",
                        width: "200px",
                        hidden: !this.options.data.isAnchorable,
                        attributes: {
                            style: "white-space:nowrap;"
                        }
                    },
                    {
                        field: "sources",
                        title: "Found In",
                        width: "400px",
                        hidden: !this.options.data.isAnchorable,
                        template: $.proxy(function (e) {
                            var sources = e.sources;
                            if (sources.length > 1) {
                                return "<span data-role=\"locations\" style=\"text-decoration:underline;cursor:pointer;color:cornflowerblue;\">Multiple Locations</span>";
                            }
                            else {
                                return sources[0];
                            }
                        }, this),
                        attributes: {
                            style: "white-space:nowrap;"
                        }
                    },
                    {
                        title: "&nbsp;",
                        width: "1000px"
                    }
                ],
            dataBound: $.proxy(this.grid_onDataBound, this)
        }).data("kendoGrid");

        this.get_grid().data("selection", new ProspectDirector.Types.Core.GridSelectionManager({
            grid: this.get_grid(),
            pk: "id",
            selectionMode: "multiple",
            selectOnRightClick: true
        }));

        this.get_grid().disableTextSelection();

        this.get_grid().on("mousedown", "TR", function (e) {
            that.get_grid().focus();
            that.get_grid().blur();
        });

        this.get_grid().on("dblclick", "TR", $.proxy(this.grid_onDblClick, this));

        this.get_grid().data("scroller", new ProspectDirector.Types.Core.Scroll({
            container: this.get_grid().find(".k-grid-content").first()
        }));

        this.get_grid().kendoDraggable({
            filter: ".k-grid-content .k-state-selected",
            container: this.get_grid().find(".k-grid-content").first(),
            cursorOffset: {
                top: 10,
                left: 10
            },
            hint: $.proxy(function (e) {
                return "<div class=\"drag-tooltip\">" + this.get_grid().data("selection").get_selections().length + " columns</div>";
            }, this),
            drag: function (e) {

                that.get_grid().data("scroller").position(e.pageX, e.pageY);
                that.get_grid().data("scroller").scroll();

            }
        });

        this.get_grid().find(".k-grid-content").kendoDropTargetArea({
            drop: $.proxy(this.grid_onDrop, this),
            filter: "TR[data-uid],.k-grid-content"
        });

        this.get_grid().data("rowContextMenu", new ProspectDirector.Modules.Views.ViewColumnConfiguration.ContextMenu({
            parent: this
        }));

        this.addToolTips();

    },

    //===========================
    // EVENT HANDLERS
    //===========================

    menu_onSelect: function (e) {

        var command = $(e.item).data("command"),
            grid = this.get_grid().data("kendoGrid");

        switch (command) {
            case "add":
                this.showFinderDialog();
                break;
            case "remove":
                this.removeSelectedColumns();
                break;
            case "clear":
                grid.dataSource.data([]);
                this.refreshGrid();
                break;
        }

    },

    finderDialog_onOk: function (e) {

        var index = 0,
            grid = this.get_grid().data("kendoGrid");

        for (index = 0; index < e.length; index++) {
            if (grid.dataSource.get(e[index].id) === undefined) {
                grid.dataSource.add(e[index]);
            }
        };

        this.refreshGrid();

        this.addToolTips();

    },

    grid_onDrop: function (e) {

        var grid = this.get_grid().data("kendoGrid"),
            data = [],
            copy = [],
            item = null,
            indexAt = 0;

        item = this.getDropTargetDataItem(e.dropTarget);

        if (item) {
            indexAt = grid.dataSource.indexOf(item);
        }
        else {
            indexAt = grid.dataSource._data.length;
        }

        copy = this.copyAndRemoveSelections();

        data = this.copyAndReturnNonSelects();

        this.mergeAndSequenceData(copy, data, indexAt);

        grid.dataSource.data(data);
        this.refreshGrid();

    },

    grid_onDblClick: function (e) {

        this.editName($(e.currentTarget));

    },

    grid_onDataBound: function (e) {
        //override
    },

    //===========================
    // METHODS
    //===========================

    copyAndRemoveSelections: function () {

        var result = [],
            index = 0,
            grid = this.get_grid().data("kendoGrid"),
            selections = this.get_grid().data("selection").getSelectionsData();

        for (index; index < selections.length; index++) {
            result[result.length] = selections[index].toJSON();
            grid.dataSource.remove(selections[index]);
        }

        return result;

    },

    copyAndReturnNonSelects: function () {

        var result = [],
            index = 0,
            grid = this.get_grid().data("kendoGrid");

        for (index = 0; index < grid.dataSource._data.length; index++) {
            result[result.length] = grid.dataSource._data[index].toJSON();
        }

        return result;

    },

    mergeAndSequenceData: function (srcData, dstData, indexAt) {

        var index = 0;

        for (index = 0; index < srcData.length; index++) {
            dstData.splice(indexAt, 0, srcData[index]);
        }

        for (index = 0; index < dstData.length; index++) {
            dstData[index].index = index;
        }

    },

    getDropTargetDataItem: function (target) {

        var id = target.closest("TR[data-uid]").attr("data-uid"),
            grid = this.get_grid().data("kendoGrid");

        return id ? grid.dataSource.getByUid(id) : null;

    },

    populate: function (data) {

        var index = 0;

        for (index = 0; index < data.length; index++) {
            this.addColumn(data[index]);
        }

    },

    getData: function () {

        var result = [],
            grid = this.get_grid().data("kendoGrid"),
            data = grid.dataSource.data(),
            index = 0;

        for (index; index < data.length; index++) {
            result[result.length] = data[index].toJSON();
        }

        return result;

    },

    showFinderDialog: function () {
        //must override
    },

    addToolTips: function () {

        var grid = this.get_grid().data("kendoGrid");
        var fn = function (element) {

            var uid = $(element).closest("TR").data("uid"),
                sources = grid.dataSource.getByUid(uid).sources;

            return "<div class=\"title\">Locations</div><div class=\"content\"><ul><li>" + sources.join("</li><li>") + "</li></div>";

        };

        Tipped.create(this.get_grid().selector + " [data-role=locations]", fn, {
            skin: "white",
            maxWidth: 300
        });

    },

    removeSelectedColumns: function () {

        var grid = this.get_grid().data("kendoGrid"),
            selections = this.get_grid().data("selection").get_selections(),
            index = 0,
            item = null;

        for (index; index < selections.length; index++) {
            item = grid.dataSource.get(selections[index]);
            if (item !== undefined) {
                grid.dataSource.remove(item);
            }
        }

        this.refreshGrid();

    },

    refreshGrid: function () {

        var grid = this.get_grid().data("kendoGrid");

        grid.refresh();

        //TODO: This is a hack... could not get the data bound event to fire with a local data source.
        this.grid_onDataBound();

        this.addToolTips();

    },

    editName: function (row) {

        var that = this,
            element = row.find("DIV[data-role=name]");

        if (element.length) {

            element.rename({
                commit: function (e) {
                    e.uid = $(e.target).closest("TR").data("uid");
                    that.commitName(e);
                    if (e.keyCode === 9) {
                        that.editNextName(e);
                    }
                }
            });

        }

    },

    editNextName: function (e) {

        var row = this.get_grid().find("TR[data-uid=" + e.uid + "]");

        row = e.shiftKey ? row.prev() : row.next();

        if (row.length > 0) {
            this.editName(row);
        }

    },

    commitName: function (e) {

        var row = $(e.target).closest("TR"),
            grid = this.get_grid().data("kendoGrid"),
            item = grid.dataSource.getByUid(row.data("uid"));

        if (item) {
            item.set("name", e.newValue);
        }

        this.refreshGrid();

    },

    resetName: function (e) {

        var row = $(e).closest("TR"),
            grid = this.get_grid().data("kendoGrid"),
            item = grid.dataSource.getByUid(row.data("uid"));

        if (item) {
            item.set("name", item.defaultName);
        }

        this.refreshGrid();

    }

});

//===========================
// STATIC METHODS
//===========================

ProspectDirector.Modules.Views.ViewColumnConfiguration.BoundsColumnFinder = 
new (ProspectDirector.Types.Core.Dialog.extend({
    
    init: function () {
        this._super("FindColumnInBounds",
                "Find Column",
                ProspectDirector.RUNTIME.resolveUrl("~/viewcolumn/findinbounds"));
    }

}));

ProspectDirector.Modules.Views.ViewColumnConfiguration.DesignColumnFinder =
new (ProspectDirector.Types.Core.Dialog.extend({
    
    init: function () {
        this._super("FindColumnInDesign",
                "Find Column",
                ProspectDirector.RUNTIME.resolveUrl("~/viewcolumn/findindesign"));
    }

}));

//===========================
// INNER CLASSES
//===========================

ProspectDirector.Modules.Views.ViewColumnConfiguration.ContextMenu = ProspectDirector.Types.Core.ContextMenu.extend({

    //===========================
    // CONSTRUCTOR
    //===========================

    init: function (options) {
        this._super(options);
    },

    //===========================
    // PROPERTIES
    //===========================

    get_parent: function () {
        return this.options.parent;
    },

    get_contextMenuSelector: function () {
        return this.get_parent().get_grid().selector + " TR[data-uid]";
    },

    //===========================
    // PROTECTED METHODS
    //===========================

    _executeCommand: function (command, e) {

        switch (command) {
            case "remove":
                this.get_parent().removeSelectedColumns();
                break;
            case "rename":
                e.$trigger.find("[data-role=name]").trigger("dblclick");
                break;
            case "reset":
                this.get_parent().resetName(e.$trigger);
                break;
        }

    },

    _configureContextMenu: function (sender, e) {

        var items = e.config.items,
            selections = this.get_parent().get_grid().data("selection").getSelectionsData();

        items.remove = {
            name: "Remove"
        };

        if (selections.length === 1) {

            if (selections[0].name === selections[0].defaultName) {

                items.rename = {
                    name: "Rename"
                };

            }
            else {

                items.reset = {
                    name: "Reset Name"
                };

            }

        }

    }

});
