dojo.provide("parus.gridStatus");

dojo.require("parus.parus8");

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

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

  name: "status",

  visible: true,

  _oldCreateView: null,

  _afterRowConnect: null,

  _table: null,

  _statusBarRow: null,

  _items: null,

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

    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");

      _this.visible = false;
      var arr = g.structure[0].cells ? g.structure[0].cells[0] : g.structure;
      dojo.forEach(arr, dojo.hitch(this, function(column) {
        if (column.aggregate) _this.visible = true;
      }));
      _this._items = null;

      return view;
    };

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

    this._connects.push(dojo.connect(g.selection, "onSelected", this, "_selected"));
    this._connects.push(dojo.connect(g.selection, "onDeselected", this, "_selected"));

  },


  _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._statusBarRow) {
      if (this._statusBarRow.parentNode) this._statusBarRow.parentNode.removeChild(this._statusBarRow);
      this._statusBarRow = null;
      //      this._items = null;
    };
  },

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

  __formatAggregateText: function(title, vselected, vitem) {

    var text = [];

    if (vselected || vitem || (vselected == "0") || (vitem == "0")) {

      text.push("<div style=\"height:18px;white-space: nowrap;overflow:hidden\">");
      text.push("<div align=\"left\" class=\"dojoxGridStatusBarLabel\">");
      text.push(title)
      text.push(": ");
      text.push("</div>");

      text.push("<div align=\"right\" class=\"dojoxGridStatusBarValue\" style=\"position:relative;top:-18px\">");

      if (vselected || (vselected == "0")) {
        text.push(parus.parus8.valueToExternalString(vselected));
        if (vitem || (vitem == "0")) text.push(String.fromCharCode(160) + "/" + String.fromCharCode(160));
      }
      if (vitem || (vitem == "0")) text.push(parus.parus8.valueToExternalString(vitem));

      text.push("</div>");

      text.push("</div>");

    };
    return text.join("");
  },

  __valueToFrac: function(n, frac) {

    var a = ["1"];
    for (var i = 0; i < frac; i++)
    a.push("0");
    return Math.round(n * parseInt(a.join(""))) / parseInt(a.join(""));

  },

  _selected: function(index) {
    var _this = this;
    dojo.forEach(this._items, function(thisitem) {
      if (thisitem.column.aggregate) {
        var count = null;
        var sum = null;
        var min = null;
        var max = null;
        var frac = null;

        var item = _this.grid.selection.getFirstSelected();
        if (item) for (var i = 0; i < _this.grid.selection.getSelectedCount(); i++) {
          var value = _this.__extractValue(item, thisitem, _this.grid.store, 0);
          if (value || (value == "0")) {
            if (value == "0") value = 0;
            count = (count || 0) + 1;
            if (typeof value == "number") {
              sum = (sum || 0) + value;
              var s = value.toString();
              var p = s.indexOf(".");
              var f = (p < 0) ? 0 : s.length - p - 1;
              if ((frac || f) <= f) frac = f;
            }
            if ((max || value) <= value) max = value;
            if ((min || value) >= value) min = value;
          };
          item = _this.grid.selection.getNextSelected(item);
        };

        if ((frac || thisitem.frac) <= thisitem.frac) frac = thisitem.frac;

        if (thisitem.column.aggregate == 1) thisitem.cell.innerHTML = _this.__formatAggregateText("Количество", count, thisitem.count);
        else if (thisitem.column.aggregate == 2) thisitem.cell.innerHTML = _this.__formatAggregateText("Сумма", count ? dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(_this.__valueToFrac(sum, frac)) : null, dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(_this.__valueToFrac(thisitem.sum, frac)));
        else if (thisitem.column.aggregate == 3) thisitem.cell.innerHTML = _this.__formatAggregateText("Минимум", count ? dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(min) : null, dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(thisitem.min));
        else if (thisitem.column.aggregate == 4) thisitem.cell.innerHTML = _this.__formatAggregateText("Максимум", count ? dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(max) : null, dojo.hitch(thisitem.column, parus.parus8.formatFloatIntFrac)(thisitem.max));
        else if (thisitem.column.aggregate == 5) thisitem.cell.innerHTML = _this.__formatAggregateText("Среднее", count ? _this.__valueToFrac(sum / count, frac) : null, thisitem.count ? _this.__valueToFrac(thisitem.sum / thisitem.count, frac) : null);

      }
      else thisitem.cell.innerHTML = "";
    });
  },

  __extractValue: function(item, thisitem, store, idx) {

    var value = null;

    if (item) {

      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 {
        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) {
        if (thisitem.column.dataType) value = parus.parus8.externalStringToValue(value, thisitem.column.dataType)
        else {

          var vn = dojo.number.parse(value);

          if (vn) value = vn
          else {

            var vd = dojo.date.locale.parse(value, {
              selector: "date",
              datePattern: "dd.MM.yyyy"
            });

            if (vd) value = vd;
          };
        };
      };
    };

    return value;

  },

  _fetchBegin: function(size, req) {

    var _this = this;

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

      dojo.mixin(thisitem, {
        count: null,
        sum: null,
        min: null,
        max: null,
        frac: null
      });
    });

    if (this.grid.store.forEach)

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

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

        if (!thisitem.column.aggregate) return;

        var value = _this.__extractValue(item, thisitem, store, idx);

        if (value || (value == "0")) {
          if (value == "0") value = 0;
          thisitem.count = (thisitem.count || 0) + 1;
          if (typeof value == "number") {
            thisitem.sum = (thisitem.sum || 0) + value;
            var s = value.toString();
            var p = s.indexOf(".");
            var frac = (p < 0) ? 0 : s.length - p - 1;
            if ((thisitem.frac || frac) <= frac) thisitem.frac = frac;
          }
          if ((thisitem.max || value) <= value) thisitem.max = value;
          if ((thisitem.min || value) >= value) thisitem.min = value;
        };

      });
    }), false);

    this._selected();
  },

  _render: function() {


    if (!this.visible) return;

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


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

    var idx = -1;

    if (!this._items) {

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

      this._items = [];

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

      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._statusBarRow.cells[idx];
          var item = byKey[column.field] || {};
          dojo.mixin(item, {
            column: column,
            cell: cell,
            count: null,
            min: null,
            max: null,
            sum: null
          });

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

      }));
    }
    else {

      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._statusBarRow.cells[idx];
          this._items.byKey[column.field].cell = cell;


        }

      }));

    };

    this._selected();
    setTimeout(dojo.hitch(this, function() {
      this.grid.adaptHeight();
    }), 150);

  },

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

});


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