dojo.provide("parus.gridColumnsFilter");

dojo.require("parus.parus8");

dojo.require("dijit.form.ComboBox");
dojo.require("dojox.grid.enhanced._Plugin");
dojo.require("dojox.grid.EnhancedGrid");

dojo.declare("dojox.grid.enhanced.plugins.columnsFilter", dojox.grid.enhanced._Plugin, {

  name: "columnsFilter",

  visible: true,

  _oldCreateView: null,

  _afterRowConnect: null,

  _table: null,

  _filterBarRow: null,

  _items: null,

  values: null,

  constructor: function(grid, args) {
    this.inherited(arguments);
    dojo.mixin(this, args);

    this.values = {};

    var _this = this;
    var g = this.grid;

    var old_func = this._oldCreateView = dojo.hitch(this.grid, this.grid.createView);
    this.grid.createView = function() {
      _this._cleanUp();
      var view = old_func.apply(g, arguments);;
      _this._afterRowConnect = dojo.connect(view, "onAfterRow", _this, "_afterRow");
      return view;
    };

    this._connects.push(dojo.connect(g, "_onFetchBegin", _this, "_fetchBegin"));

    dojo.mixin(g, {
      showFilterBar: dojo.hitch(_this, this.show),
      hideFilterBar: dojo.hitch(_this, this.hide),
      getFilterBarVisible: dojo.hitch(_this, function() {
        return this.visible
      }),
      columnsFilterObject: _this
    });
  },

  show: function() {
    this.visible = true;
    this._render();
    this.grid.setQuery(this.grid.query || {});
  },

  hide: function() {
    this.visible = false;
    this._cleanUpBar();
    this.grid.setQuery(this.grid.query || {});
  },

  valuesChanged: function() {
    if (this._items) for (key in this.values) if (this._items.byKey[key]) this._items.byKey[key].value = this.values[key];
  },

  _afterRow: function(inRowIndex, cells, inRowNode) {
    if (inRowIndex == -1) dojo.query("table", inRowNode).forEach(dojo.hitch(this, function(table) {
      this._cleanUpBar();
      this._table = table;
      if (this.visible) {
        this._render();
      }
    }));
  },

  _cleanUpEvent: function() {
    this._table = null;
    if (this._afterRowConnect) {
      dojo.disconnect(this._afterRowConnect);
      this._afterRowConnect = null;
    };
  },

  _cleanUpBar: function() {
    if (this._filterBarRow) {
      if (this._filterBarRow.parentNode) this._filterBarRow.parentNode.removeChild(this._filterBarRow);
      this._filterBarRow = null;
      if (this._items) dojo.forEach(this._items, function(item) {
        item.widget.destroyRecursive();
      });
      //      this._items = null;
    };
  },

  _cleanUp: function() {
    this._cleanUpEvent();
    this._cleanUpBar();
  },

  _filterChanged: function(item, value) {
    if (!this.visible) return;
    this.values[item.column.field] = value;

    dojo.hitch(this.grid, this.grid.onFilterChanged)(this.values, this.grid.sortInfo);

    dojo.mixin(item, {
      value: value
    });
    var query = this.grid.query || {};
    //    this.grid.store.close();
    this.grid.setQuery(query);
  },

  _fetchFilter: function(items) {
    if (!this.visible) return items;

    var filters = [];


    dojo.forEach(this._items, function(thisitem) {
      if (thisitem.value) {



        filters.push(dojo.hitch(thisitem, function(item, idx) {

          var matched = false;

          var v = "";

          if (this.column._props.propRN) {

            v = parus._docPropsValueForGrid(
            parus.parus8.docPropValue(item, this.column._props.propRN), this.column._props.dataType, this.column._props.dataSubType) || "";
          }

          else if (this.column._props.attrRN) {

            v = parus._docPropsValueForGrid(
            parus.parus8.docAttrValue(item, this.column._props.attrRN), this.column._props.dataType, this.column._props.dataSubType) || "";
          }
          else if (this.column.field.substr(0, 3) == "ST$") {
            var rowNodes = parus.parus8.rowNodes(parus.parus8.nodeField(item, "XML_STATUSMODEL"));
            if (rowNodes) if (rowNodes.length) v = parus.parus8.nodeField(rowNodes[0], this.column.field.substr(3));
          }
          else {
            v = this.column.grid.store.getValue(item, this.column.field) || "";
            if (this.column.formatter) v = this.column.formatter(v, idx, this.column._props) || "";
            if (this.column.grid.escapeHTMLInData) {
              var node = document.createElement("div");
              node.innerHTML = v;
              v = parus.parus8.getTextContent(node);
            }
          }

          var masks = this.value.split(";");

          var allNegations = true;

          dojo.forEach(masks, function(mask) {
            if (mask.substring(0, 1) != "!") allNegations = false;
          });

          if (allNegations) matched = true;

          dojo.forEach(masks, dojo.hitch(this, function(mask) {

            if (mask.substring(0, 1) == "!") {
              var matcher = ((mask == "!*") ? /^.+$/m : dojo.data.util.filter.patternToRegExp(mask.substring(1, mask.length), false));

              if (allNegations) {

                if (matched && v.match(matcher)) matched = false;

              } else {
                matched = true;
                if (v.match(matcher)) matched = false;
              }
            }
            else {
              var matcher = ((mask == "*") ? /^.+$/m : dojo.data.util.filter.patternToRegExp(mask, false));
              if (v.match(matcher)) matched = true;
            }
          }));

          return matched;

        }));


      }
    });


    if (!filters.length) return items;

    var doFilter = function(item, idx) {
      for (var i = 0; i < filters.length; i++) {
        if (!filters[i](item, idx)) return false;
      }
      return true;
    }

    return dojo.filter(items, doFilter);
  },

  _fetchBegin: function(size, req) {
    dojo.forEach(this._items, function(thisitem) {
      dojo.mixin(thisitem, {
        _storeItems: []
      });
    });

    if (this.grid.store.forEach)

    this.grid.store.forEach(dojo.hitch(this, function(store, item, idx) {

      dojo.forEach(this._items, function(thisitem) {

        var value = null;

        if (thisitem.column._props.propRN) {

          value = parus._docPropsValueForGrid(
          parus.parus8.docPropValue(item, thisitem.column._props.propRN), thisitem.column._props.dataType, thisitem.column._props.dataSubType);
        }

        else if (thisitem.column._props.attrRN) {

          value = parus._docPropsValueForGrid(
          parus.parus8.docAttrValue(item, thisitem.column._props.attrRN), thisitem.column._props.dataType, thisitem.column._props.dataSubType);
        }
        else if (thisitem.column.field.substr(0, 3) == "ST$") {
          var rowNodes = parus.parus8.rowNodes(parus.parus8.nodeField(item, "XML_STATUSMODEL"));
          if (rowNodes) if (rowNodes.length) value = parus.parus8.nodeField(rowNodes[0], thisitem.column.field.substr(3));
        }

        else {
          value = store.getValue(item, thisitem.column.field) || null;
          if (value && thisitem.column.formatter) value = thisitem.column.formatter(value, idx, thisitem.column._props);
          if (thisitem.column.grid.escapeHTMLInData) {
            var node = document.createElement("div");
            node.innerHTML = value;
            value = parus.parus8.getTextContent(node);
          }
        }

        if (value && dojo.indexOf(thisitem._storeItems, value) == -1) thisitem._storeItems.push(value);
      });
    }), true);


    dojo.forEach(this._items, function(thisitem) {

      thisitem._storeItems.sort(parus.parus8.compareUntypedValues);
      var sorted = false;

      dojo.forEach(thisitem.column.grid.getSortProps(), function(sortInfo) {
        if (thisitem.column.field == sortInfo.field) {
          if (sortInfo.descending) thisitem._storeItems.reverse();
          sorted = true;
        }
      });

      if (!sorted && (thisitem.column.dataType == 2)) thisitem._storeItems.reverse();

      var items = [];

      items.push({
        name: "",
        label: "(Все)"
      });
      items.push({
        name: "*",
        label: "(Не пусто)"
      });
      items.push({
        name: "!*",
        label: "(Пусто)"
      });

      dojo.forEach(thisitem._storeItems, function(name) {
        items.push({
          name: name,
          label: name
        });
      });

      thisitem.store = new dojo.data.ItemFileReadStore({
        data: {
          items: items
        }
      });
      thisitem.widget.attr("store", thisitem.store);

    });


  },

  _render: function() {

    this._filterBarRow = this._table.insertRow(-1);
    dojo.addClass(this._filterBarRow, "dojoxGridStatusBarRow");

    dojo.forEach(this._table.rows[0].cells, dojo.hitch(this, function() {
      this._filterBarRow.insertCell(-1).style.padding = "2px 5px 2px 0px";
    }));


    var byKey = this._items ? this._items.byKey : {};

    this._items = [];

    dojo.mixin(this._items, {
      byKey: byKey
    });

    var idx = -1;

    dojo.forEach(this.grid.views.views[0].structure.cells[0], dojo.hitch(this, function(column) {
      if (column.field && !column.hidden) {


        if (idx == -1) idx = column.index
        else idx++;

        var cell = this._filterBarRow.cells[idx];
        var node = document.createElement("input");
        cell.appendChild(node);
        var item = byKey[column.field] || {};
        dojo.mixin(item, {
          value: this.values[column.field],
          widget: new dojox.grid.enhanced.columnsFilterCombobox({
            style: "width:100%",
            labelAttr: "label",
            grid: this.grid,
            value: this.values[column.field],
            store: item.store,
            onChange: dojo.hitch(this, function() {
              this._filterChanged(item, item.widget.attr("value"));
            })
          }, node),
          column: column
        });

        this._items.push(item);
        this._items.byKey[column.field] = item;
      }

    }));

    dojo.mixin(this.grid.store, {
      fetchFilter: dojo.hitch(this, this._fetchFilter)
    });

  },

  destroy: function() {
    this._cleanUp();
    this.grid.createView = this._oldCreateView;
    this.inherited(arguments);
  }

});


dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.columnsFilter);

dojo.extend(dojox.grid.EnhancedGrid, {
  onFilterChanged: function(values, sortInfo) {
    //do nothing
  },

  setSortInfo: function(inSortInfo) {
    if (this.canSort(inSortInfo)) {
      this.sortInfo = inSortInfo;
      this.sort();
      this.update();
      if (this.columnsFilterObject) this.onFilterChanged(this.columnsFilterObject.values, inSortInfo);
    }
  }

});

dojo.declare("dojox.grid.enhanced.columnsFilterCombobox", dijit.form.ComboBox, {

  grid: null,

  dropDownClass: "dojox.grid.enhanced.columnsFilterDropDown",

  _selectOption: function(evt) {

    var v = "";

    var item = this.dropDown.items[evt.getAttribute("item")];

    if (item.dropDown) dojo.forEach(item.dropDown._checkboxes, function(checkbox) {
      if (checkbox.attr("checked")) v = v + (v ? ";" : "") + checkbox.item.name[0]
    });

    this.inherited(arguments);

    if (v) this.attr("value", v);
  }


});

dojo.declare("dojox.grid.enhanced.columnsFilterDropDown", dijit.form._ComboBoxMenu, {

  _onMouseUp: function(evt) {
    if (evt.target.getAttribute("role") == "option") return this.inherited(arguments);
  },

  _checkboxes: null,

  _comboBox: null,

  postMixInProperties: function() {
    this.inherited(arguments);

    var comboId = this.id;
    comboId = comboId.substring(0, comboId.length - 6);

    this._comboBox = dijit.byId(comboId);

  },


  _createOption: function(item, labelFunc) {


    var listItem = this.inherited(arguments);

    var value = (this._comboBox.value || "").split(";");

    if (item.name[0] && (item.name[0] != "*") && (item.name[0] != "!*")) {
      node = document.createElement("input");
      listItem.insertBefore(node, listItem.firstChild);

      var checkBox = new dojox.grid.enhanced.columnsFilterCheckBox({
        item: item,
        checked: (dojo.indexOf(value, item.name[0]) != -1),
        dropDown: this
      }, node);

      if (!this._checkboxes) this._checkboxes = [];

      dojo.mixin(item, {
        dropDown: this
      });

      this._checkboxes.push(checkBox);
    }

    return listItem;
  }

});


dojo.declare("dojox.grid.enhanced.columnsFilterCheckBox", dijit.form.CheckBox, {

  item: null,

  dropDown: null,

  _onClick: function(e) {
    this.inherited(arguments);
    e.stopPropagation();
    e.preventDefault();
    return false;
  }

});