﻿var AssignedRelation = function (key, source, selected, url) {
    this.setKey(key);
    this.setSource(source);
    this.setSelectedSource(selected);
    this.setUrl(url);
}

/**
* Constant
*/
AssignedRelation.ATTACHED_NAME = "AssignedRelation";

AssignedRelation.from = function (key) {
    return AttachedControls.from("#" + key + "Container").get(AssignedRelation.ATTACHED_NAME);
}

/**
* Create grid and attach to HTML element
*/
AssignedRelation.attach = function (key, source, selected, url) {
    var item = new AssignedRelation(key, source, selected, url);

    AttachedControls.from("#" + key + "Container").attach(AssignedRelation.ATTACHED_NAME, item);
    return item;
}



AssignedRelation.prototype = {
    key: null,

    source: null,

    baseUrl: null,

    selected: null,

    setKey: function (key) {
        this.key = key;
        return this;
    },

    setSource: function (source) {
        this.source = source;
        return this;
    },

    setSelectedSource: function (source) {
        this.selected = source;
        return this;
    },

    setUrl: function (url) {
        this.baseUrl = url;
        return this;
    },

    init: function () {
        this.loadSelectedItems();
        this.categoryChanged();
        var cat = $('#' + this.key + "Category");
        var add = $('#add' + this.key);
        var remove = $('#remove' + this.key);
        var save = $('#save' + this.key);
        var cancel = $('#cancel' + this.key);
        cat.unbind('change');
        add.unbind('click');
        remove.unbind('click');
        save.unbind('click');
        cancel.unbind('click');

        var tmp = this;
        cat.bind('change', Function.reference(this, this.categoryChanged));
        add.bind('click', Function.reference(this, this.add));
        remove.bind('click', Function.reference(this, this.remove));
        save.bind('click', Function.reference(this, this.saveItems));
        cancel.bind('click', Function.reference(this, this.cancelClick));
    },


    categoryChanged: function () {
        var value = $('#' + this.key + "Category").val();
        var container = $('#source' + this.key);
        container.html('');
        for (var i = 0; i < this.source.length; i++) {
            var item = this.source[i];
            if (item.CategoryId == value && !this.alreadyExist(item.Id))
                container.append("<option value='" + item.Id + "'>" + item.Name + "</option>");
        }
        container.find('option').unbind('dblclick');
        container.find('option').bind('dblclick', Function.reference(this, this.addItem));
    },


    cancelClick: function () {
        this.loadItems();
        $('#' + this.key + 'Container').find('p[class="collapse"]>a').trigger('click');
    },

    alreadyExist: function (id) {
        for (var i = 0; i < this.selected.length; i++) {
            if (this.selected[i].Id == id)
                return true;
        }

        return false;
    },

    add: function () {
        var items = $('#source' + this.key + ' :selected');
        var container = $('#destination' + this.key);
        for (var i = 0; i < items.length; i++) {
            this.pushItem(items[i]);

        }
        container.html('');
        items.remove();
        this.loadSelectedItems();
        return false;
    },


    pushItem: function (item) {
        var exist = false;
        for (var j = 0; j < this.selected.length; j++) {
            if (this.selected[j].Id == item.value)
                exist = true;
        }
        if (!exist) {
            for (var j = 0; j < this.source.length; j++) {
                if (this.source[j].Id == item.value)
                    this.selected.push(this.source[j]);
            }
        }
    },

    addItem: function (ev) {
        var item = $(ev.currentTarget);
        this.pushItem(item.get(0));
        this.loadSelectedItems();
        item.remove();
        return false;
    },

    remove: function () {
        var items = $('#destination' + this.key + " :selected");
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            var isCategory = item.classList.contains("category");
            var categoryId = isCategory ? this.getCategoryId(item.value) : 0;
            for (var j = this.selected.length - 1; j >= 0; j--) {
                if (jQuery.trim(item.value) == jQuery.trim(this.selected[j].Name) || categoryId == this.selected[j].CategoryId)
                    this.selected.splice(j, 1);
            }
        }
        this.loadSelectedItems();
        this.categoryChanged();
        return false;
    },

    removeItem: function (ev) {
        var item = $(ev.currentTarget);
        var isCategory = item.hasClass("category");
        var categoryId = isCategory ? this.getCategoryId(item.text()) : 0;
        for (var j = 0; j < this.selected.length; j++) {
            if (item.text() == this.selected[j].Name || categoryId == this.selected[j].CategoryId)
                this.selected.splice(j, 1);
        }
        this.loadSelectedItems();
        this.categoryChanged();
        return false;
    },


    loadSelectedItems: function () {
        $('#success' + this.key).hide();
        var container = $('#destination' + this.key);
        container.html('');
        for (var i = 0; i < this.selected.length; i++) {
            var item = this.selected[i];
            var cat_name = this.getCategoryName(item.CategoryId);
            var top_option = container.find("option.category:contains('" + cat_name + "')");
            if (top_option.length < 1) {
                container.append("<option class='category'>" + cat_name + "</option>");
                top_option = container.find("option[class='category'][value='" + cat_name + "']");
            }
            top_option.after("<option>" + item.Name + "</option>");
        }
        container.find('option').unbind('dblclick');
        container.find('option').bind('dblclick', Function.reference(this, this.removeItem));
    },


    getCategoryName: function (id) {
        return $('#' + this.key + "Category").find("option[value='" + id + "']").get(0).text;
    },

    getCategoryId: function (name) {
        return $('#' + this.key + "Category").find("option[text='" + name + "']").get(0).value;
    },

    saveItems: function () {
        $('#loading' + this.key).show();
        $('#success' + this.key).hide();
        Request.named("saveValues").post(this.baseUrl + 'save' + this.key + 's').addParams({ values: JSON.stringify(this.selected) }).addSuccess('refresh', Function.reference(this, function (result) {
            $('#loading' + this.key).hide();
            $('#success' + this.key).html(result.messages.messages.Success[0].message);
            $('#success' + this.key).show();
            $().trigger(this.key + "Items.Saved");
        })).send();
        $('#' + this.key + 'Container').find('p[class="collapse"] > a').trigger('click');
        $('#' + this.key + 'Container').find('p[class="collapse"] > a').trigger('click');
    },


    loadItems: function () {
        var tmp = this;
        $('#loading' + this.key).show();
        $('#success' + this.key).hide();
        Request.named("getValues").get(this.baseUrl + 'get' + this.key + 's').addSuccess('refresh', Function.reference(this, function (result) {
            tmp.setSelectedSource(result.getJson("Items"));
            tmp.loadSelectedItems();
            $('#loading' + tmp.key).hide();
            $('#success' + tmp.key).html(result.messages.messages.Success[0].message);
            $('#success' + tmp.key).show();
            $().trigger(tmp.key + '.itemsLoaded');
        })).send();
    }
}
