/// class ProspectDirector.Web.UI.Queries.FilterListValueFeature
/// using ProspectDirector.Web.UI.Queries.FilterValueFeature

/**
@class FilterListValueFeature
@constructor
@namespace Web.UI.Queries
@extends Web.UI.Queries.FilterValueFeature
**/
ProspectDirector.Web.UI.Queries.FilterListValueFeature = ProspectDirector.Web.UI.Queries.FilterValueFeature.extend({

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

    get_listTree: function () {
        return this.get_listTreeNode().data("kendoTreeView");
    },

    get_listTreeNode: function () {
        return this.get_valueWrapper().find("DIV[data-id=list]");
    },

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

    _listTree_onSelect: function (e) {

        var checkbox = $(e.node).find("INPUT").first(),
            data = this.get_listTree().dataItem(e.node);

        checkbox.prop("checked", !checkbox.prop("checked"));

        this._triggerCheck(checkbox, data);

        e.preventDefault();

    },

    _listTree_onChecked: function (e) {

        var checkbox = $(e.target),
            data = this.get_listTree().dataItem(checkbox.closest(".k-item"));

        this._triggerCheck(checkbox, data);

        e.stopPropagation();

    },

    //==============================
    // PUBLIC METHODS
    //==============================

    activate: function () {

        this._super();

        var that = this,
            value = new ProspectDirector.Web.List(this.getValue("value")),
            items = new ProspectDirector.Web.List(this.getValue("listItems")),
            data = items.transform(function (item) {
                return {
                    text: item.name,
                    value: item.value,
                    checked: value.contains(item.value)
                };
            });

        data.insert({ text: "(Select All)", value: "__all" }, 0);

        this.get_listTreeNode().kendoTreeView({
            dataSource: new kendo.data.HierarchicalDataSource({
                data: data.toArray()
            }),
            checkboxes: {
                checkChildren: true
            },
            select: $.proxy(this._listTree_onSelect, this)
        });

        this.get_listTreeNode().find("INPUT[type=checkbox]").on("click", $.proxy(this._listTree_onChecked, this));

    },

    commit: function () {

        var that = this,
            values = new ProspectDirector.Web.List();

        this.get_listTreeNode().find("INPUT[type=checkbox]:checked").each(function (index, item) {
            var data = that.get_listTree().dataItem(item);
            if (data.value !== "__all") {
                values.add(data.value);
            }
        });

        this.setValue("value", values.toArray());

    },

    render: function () {

        var content = "" +
            "<label for=\"Value\" class=\"-pd-macro-editor-label\">List</label><br/>" +
            "<div data-id=\"list\" class=\"-pd-filter-list\" style=\"height:125px;\">&nbsp;</div>";

        return this._super(content);

    },

    //==============================
    // PRIVATE METHODS
    //==============================

    _triggerCheck: function (checkbox, data) {

        if (data.value === "__all") {
            this._toggleCheckAll(checkbox);
        }
        else {
            this._setCheckAllIndeterminateState();
        }

    },

    _toggleCheckAll: function (checkbox) {

        var $checkboxes = this.get_listTreeNode().find("INPUT[type=checkbox]:gt(0)"),
            isChecked = checkbox.prop("checked");

        if (checkbox.prop("indeterminate")) {
            checkbox.prop("indeterminate", false);
            checkbox.prop("checked", true);
            isChecked = true;
        }

        $checkboxes.each(function (index, item) {
            $(item).prop("checked", isChecked);
        });

    },

    _setCheckAllIndeterminateState: function () {

        var checkbox = this.get_listTreeNode().find("INPUT[type=checkbox]:first"),
            state = this._getGroupCheckState();

        if (state === undefined) {
            checkbox.prop("indeterminate", true);
        }
        else {
            checkbox.prop("indeterminate", false);
            checkbox.prop("checked", state);
        }

    },

    _getGroupCheckState: function () {

        var $checkboxes = this.get_listTreeNode().find("INPUT[type=checkbox]:gt(0)"),
            result = $checkboxes.first().prop("checked");

        $checkboxes.each(function (index, item) {
            if (result !== $(item).prop("checked")) {
                result = undefined;
                return false;
            }
        });

        return result;

    }

});