dojo.provide("parus.balanceIndexConsComparation");

dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojo.data.ItemFileWriteStore");

dojo.require("dijit.Dialog");
dojo.require("dijit.form.Button");

dojo.require("dojox.grid.cells.dijit");

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

dojo.require("parus.parus8");
dojo.require("parus.dialog");

dojo.require("parus.gridExtraRow");

dojo.declare("parus.balanceIndexConsComparation", [parus.Dialog], {

  onShow: function() {

    var formatter = (parus.parus8.consComparationData.dataType == "1") ?
    function(data, rowIndex, column) {
      return data ?

      parus.parus8.formatIndexConsValue((data.toString()).split(".").join(","), parus.parus8.consComparationData.intPart, parus.parus8.consComparationData.skipUnsignificantZeroes ? null : parus.parus8.consComparationData.fracPart) : data;
    } : parus.parus8.formatFloat;

    this.consItemsGridPopupMenu.bindDomNode(this.consItemsGrid.viewsNode);
    parus.balance._createActionsButton(this.consItemsGridPopupMenu, this.headerPane);

    var settings = parus.userdata.get(this.declaredClass);
    if (settings) {
      if (settings.additions) {
        parus.parus8.consComparationData.skipUnsignificantZeroes = settings.additions.skipUnsignificantZeroes;
      }
      parus.gridSettingsDialog.mergeMenuSettings(this.consItemsGridPopupMenu, settings.actionSettings, settings.userProcsActions, settings.userReportsActions, settings.userAppsActions);
    };

    this.consItemsGrid.onExtraRowValue = function(column, row) {
      var s = "";
      var key = column.field;

      if (key == "CODE") {
        s = (row == 0) ? "Значение показателя" : "Итог по составу";
      }
      else if (key == "NAME") {
        s = ""
      }
      else {
        dojo.forEach(parus.parus8.consComparationData.items, function(item) {
          if (item["ID"] == key) {
            s = (row == 0) ? formatter(item["VALUE"]) : formatter(item["SUMMVALUE"]);
          }
        });
      }

      return "<b style=\"font-size:120%\">" + ((s == null) ? "" : s) + "</b>";
    };

    this.consItemsGrid.extraRowObject.rowCount = (parus.parus8.consComparationData.dataType == "1") ? 2 : 1;

    this.consItemsGrid.showExtraRowBar();

    this.consItemsGrid.attr("structure", this.gridStructure());


    var store = parus.balanceIndexConsComparation.gridStore(parus.parus8.consComparationData);

    dojo.mixin(store, {
      onGetConditions: dojo.hitch(this, function(store) {
        return {
          "DIV": this.withDivergenceCheckBox.attr("checked") ? "1" : "*"
        }
      })
    });

    this.consItemsGrid.attr("store", store);

    this.consItemsGrid.setQuery({});

  },

  gridStructure: function() {

    var structure = [{
      cells: [{
        colSpan: 1,
        field: "CODE",
        name: ((parus.parus8.consComparationData.result == "1") ? "Разрез" : "Контрагент") + "<br/><span style='font-size:80%;'>(мнемокод)</span>",
        dataType: "0",
        width: "121px"
      },
      {
        colSpan: 1,
        field: "NAME",
        name: ((parus.parus8.consComparationData.result == "1") ? "Разрез" : "Контрагент") + "<br/><span style='font-size:80%;'>(наименование)</span>",
        dataType: "0",
        width: "161px"
      }]
    }];

    dojo.forEach(parus.parus8.consComparationData.items, function(item) {
      structure[0].cells.push({
        colSpan: 1,
        field: parus.parus8.nodeField(item, "ID"),
        name: parus.parus8.nodeField(item, "TITLE"),
        width: item["INDEX"] ? "240px" : "121px",
        dataType: parus.parus8.consComparationData.dataType,
        intPart: parus.parus8.consComparationData.intPart,
        fracPart: (parus.parus8.consComparationData.skipUnsignificantZeroes ? null : parus.parus8.consComparationData.fracPart),
        formatter: (parus.parus8.consComparationData.fracPart ?
        function(data, rowIndex, column) {
          return data ? parus.parus8.formatIndexConsValue(data.toString().split(".").join(","), parus.parus8.consComparationData.intPart, (parus.parus8.consComparationData.skipUnsignificantZeroes ? null : parus.parus8.consComparationData.fracPart)) : data;
        } : parus.parus8.formatFloat),
        styles: "text-align:" + ((parus.parus8.consComparationData.dataType == "0") ? "left" : "right") + ";"
      })
    });

    return structure;

  },

  withDivergenceCheckBoxChanged: function() {
    this.consItemsGrid.setQuery({});
  },

  print: function() {

    order = [];

    dojo.forEach(this.consItemsGrid.getSortProps() || [], function(sortProp) {
      order.push({
        field: sortProp.field,
        descending: sortProp.descending
      })
    });

    if (parus.parus8._embeddedMode) {
      this.printForm["htmldata"].value = parus.balanceIndexConsComparation.printRender({
        comparationData: parus.parus8.consComparationData,
        order: order,
        conditions: this.consItemsGrid.store.getConditions() || {}
      }, true);
    }
    else {

      this.printForm["querydata"].value = dojo.toJson({
        comparationData: parus.parus8.consComparationData,
        order: order,
        conditions: this.consItemsGrid.store.getConditions() || {}
      });

      this.printForm["handler"].value = parus.database.connected;
    }

    document.body.appendChild(this.printForm);
    this.printForm.submit();
    document.body.removeChild(this.printForm);

  },

  showItems: function() {

    parus.parus8.showIndexConsComparationItems({
      onClose: dojo.hitch(this, function(dialog) {
        this.close();
        if (!dialog.applied) parus.parus8.performIndexConsComparation()
      })
    });
  },

  settingsAdditions: function() {
    return [{
      title: "Скрыть незначащие нули в дробной части числа",

      id: "skipUnsignificantZeroes",

      get: dojo.hitch(this, function() {
        return parus.parus8.consComparationData.skipUnsignificantZeroes;
      }),

      set: dojo.hitch(this, function(value) {
        parus.parus8.consComparationData.skipUnsignificantZeroes = !! value;

        setTimeout(dojo.hitch(this, function() {
          this.close();
          parus.parus8.performIndexConsComparation();
        }), 600);
      })
    }]
  }


});

dojo.mixin(parus.balanceIndexConsComparation, {

  printRender: function(query, sync) {

    var body = document.createElement("body");

    body.style.width = "260mm";

    body.insertAdjacentHTML("afterBegin", "<div>Сравнение состава показателей</div>");

    var titleNode = body.firstChild;

    titleNode.style.height = "auto";
    titleNode.style.fontWeight = "bold";
    titleNode.style.fontFamily = "Tahoma, Verdana, sans-serif";
    titleNode.style.margin = "10px";

    var table = body.appendChild(document.createElement("table"));

    table.width = "100%";
    table.border = "1";
    table.cellSpacing = "0";

    var row = table.insertRow(-1);
    row.style.fontWeight = "bold";

    var store = parus.balanceIndexConsComparation.gridStore(query.comparationData);

    if (query.comparationData.result == "1") {
      row.insertCell(-1).appendChild(document.createTextNode("Разрез" + String.fromCharCode(160) + "(мнемокод)"));
      row.insertCell(-1).appendChild(document.createTextNode("Разрез" + String.fromCharCode(160) + "(наименование)"));
    }
    else {
      row.insertCell(-1).appendChild(document.createTextNode("Контрагент" + String.fromCharCode(160) + "(мнемокод)"));
      row.insertCell(-1).appendChild(document.createTextNode("Контрагент" + String.fromCharCode(160) + "(наименование)"));
    };

    var formatter = (query.comparationData.dataType == "1") ?

    (query.comparationData.fracPart ?
    function(data, rowIndex, column) {
      return data ?

      parus.parus8.formatIndexConsValue((data.toString()).split(".").join(","), query.comparationData.intPart, query.comparationData.skipUnsignificantZeroes ? null : query.comparationData.fracPart) : data;
    } : parus.parus8.formatFloat) : function(x) {
      return x
    };

    dojo.forEach(query.comparationData.items, function(item) {
      row.insertCell(-1).appendChild(document.createTextNode(parus.parus8.nodeField(item, "TITLE")));
    });


    var row = table.insertRow(-1);
    row.style.fontWeight = "bold";
    var cell = row.insertCell(-1)
    cell.appendChild(document.createTextNode("Значение" + String.fromCharCode(160) + "показателя"));
    cell.colSpan = 2;
    dojo.forEach(query.comparationData.items, function(item) {
      var cell = row.insertCell(-1);
      if (query.comparationData.dataType == "1") cell.align = "right";
      cell.appendChild(document.createTextNode(
      parus.parus8.nodeField(item, "VALUE") == null ? "" : formatter(parus.parus8.nodeField(item, "VALUE"))));
    });

    if (query.comparationData.dataType == "1") {

      var row = table.insertRow(-1);
      row.style.fontWeight = "bold";
      var cell = row.insertCell(-1);
      cell.appendChild(document.createTextNode("Итог" + String.fromCharCode(160) + "по" + String.fromCharCode(160) + "составу"));
      cell.colSpan = 2;
      dojo.forEach(query.comparationData.items, function(item) {
        var cell = row.insertCell(-1);
        if (query.comparationData.dataType == "1") cell.align = "right";
        cell.appendChild(document.createTextNode(parus.parus8.nodeField(item, "SUMMVALUE") == null ? "" : formatter(parus.parus8.nodeField(item, "SUMMVALUE"))));
      });

    }

    store.sync = sync;
    store.fetch({
      sort: query.order,
      query: query.conditions,
      onItem: function(dataItem) {

        var row = table.insertRow(-1);
        row.insertCell(-1).appendChild(document.createTextNode(parus.parus8.nodeField(dataItem, "CODE") || String.fromCharCode(160)));
        row.insertCell(-1).appendChild(document.createTextNode(parus.parus8.nodeField(dataItem, "NAME") || String.fromCharCode(160)));

        dojo.forEach(query.comparationData.items, function(item) {
          var cell = row.insertCell(-1);
          if (query.comparationData.dataType == "1") cell.align = "right";
          v = parus.parus8.nodeField(dataItem, item["ID"]);
          cell.appendChild(document.createTextNode(v == null ? "" : formatter(v)));
        });

      }

    });

    return body.innerHTML;

  },

  gridStore: function(comparationData) {

    var data = [];
    data._byKey = {};

    var args = [];
    var argkeys = [];
    var argIndexVals = [];
    var argSumVals = [];

    var errors = [];

    dojo.forEach(comparationData.items, function(item) {

      if (item["INDEX"]) {

        var summValue = 0;
        var hasSummValue = false;
        var frac = null;

        var conditions = {
          "REPORT": item["REPORT"],
          "SUBREPORT": item["SUBREPORT"],
          "INDEX": item["INDEX"],
          "TABLE": item["TABLE"],
          "ROWID": item["ROWID"]
        };

        item["VALUE"] = parus.parus8.externalStringToValue(parus.parus8.nodeField(parus.parus8.rowNodes(parus.database.execute("IndexConsValue", conditions))[0], "VALUE"), comparationData.dataType);
        if (comparationData.dataType == "1") item["VALUE"] = parus.parus8.formatIndexConsValue(item["VALUE"] || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));

        var response = parus.database.execute("IndexCons", conditions);

        if (response) {

          var consItems = response.documentElement.childNodes[0].childNodes[0].childNodes.length ? parus.parus8.rowNodes(response.documentElement.childNodes[0].childNodes[0].childNodes[0]) : [];

          dojo.forEach(consItems, function(consItem) {
            var key;
            var code;
            var name;

            if (comparationData.result == "1") {
              key = parus.parus8.nodeField(consItem, "BALSECTION");
              code = parus.parus8.nodeField(consItem, "CODE");
              name = parus.parus8.nodeField(consItem, "NAME");
            }
            else {
              key = parus.parus8.nodeField(consItem, "AGENT");
              code = parus.parus8.nodeField(consItem, "AGNABBR");
              name = parus.parus8.nodeField(consItem, "AGNNAME");
            };

            var dataItem = data._byKey[key];

            if (!dataItem) {
              dataItem = {
                "ID": key,
                "CODE": code,
                "NAME": name
              };
              data._byKey[key] = dataItem;
              data.push(dataItem);
            };

            var v = parus.parus8.externalStringToValue(parus.parus8.nodeField(consItem, "VALUE"), comparationData.dataType);
            if (comparationData.dataType == "1") v = parus.parus8.formatIndexConsValue(v || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));

            dataItem[parus.parus8.nodeField(item, "ID")] = v;

            if (comparationData.dataType == "1") {
              var value = (parus.parus8.externalStringToValue(v, comparationData.dataType) || 0);
              var s = value.toString();
              var p = s.indexOf(".");
              var f = (p < 0) ? 0 : s.length - p - 1;
              if ((frac || f) <= f) frac = f;
              summValue = summValue + value;
              hasSummValue = true;
            }
          });

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

          item["SUMMVALUE"] = hasSummValue ? summValue : null;
          if (comparationData.dataType == "1") item["SUMMVALUE"] = parus.parus8.formatIndexConsValue(item["SUMMVALUE"] || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));
        };

        args.push(item["IDENTIFIER"]);
        argkeys.push(item["ID"]);
        argIndexVals.push(parus.parus8.externalStringToValue(item["VALUE"], comparationData.dataType));
        argSumVals.push(parus.parus8.externalStringToValue(item["SUMMVALUE"], comparationData.dataType));
      }
    });

    dojo.forEach(comparationData.items, function(item) {
      if (!item["INDEX"]) {
        try {
          item._func = Function.apply(this, args.concat("return (" + item["EXPRESSION"] + ")"));
        }
        catch (e) {
          item._func = function() {
            return e.toString();
          };
        }

        try {
          item["VALUE"] = item._func.apply(this, argIndexVals);
          if (comparationData.dataType == "1") item["VALUE"] = parus.parus8.formatIndexConsValue(item["VALUE"] || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));
        }
        catch (e) {
          errors.push(e.toString());
          item["VALUE"] = null;
        };

        try {
          item["SUMMVALUE"] = item._func.apply(this, argSumVals);
          if (comparationData.dataType == "1") item["SUMMVALUE"] = parus.parus8.formatIndexConsValue(item["SUMMVALUE"] || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));

        }
        catch (e) {

          errors.push(e.toString());
          item["SUMMVALUE"] = null;

        };

      }
    });

    dojo.forEach(data, function(dataItem) {

      var argValues = dojo.map(argkeys, function(key) {
        return parus.parus8.externalStringToValue(dataItem[key] || 0, comparationData.dataType);
      });

      var hasDivergence = false;
      var checkedDivergence = false;
      var divergenceValue = null;

      dojo.forEach(comparationData.items, function(item) {

        var key = parus.parus8.nodeField(item, "ID");

        if (!item["INDEX"]) {
          try {
            dataItem[key] = item._func.apply(this, argValues);
            if (comparationData.dataType == "1") dataItem[key] = parus.parus8.formatIndexConsValue(dataItem[key] || 0, comparationData.intPart, (comparationData.skipUnsignificantZeroes ? null : comparationData.fracPart));
          }
          catch (e) {
            errors.push(e.toString());
            dataItem[key] = null;
          }
        }

        if (!checkedDivergence) {
          checkedDivergence = true;
          divergenceValue = dataItem[key] || null

        }
        else {

          if (parus.parus8.nodeField(item, "INCLUDEDIFF")) if (!hasDivergence) {
            if ((divergenceValue || null) != (dataItem[key] || null)) hasDivergence = true
            else divergenceValue = dataItem[key] || null;
          };

        }

      });

      dataItem["DIV"] = hasDivergence ? "1" : "0";

    });

    dojo.forEach(comparationData.items, function(item) {
      if (!item["INDEX"]) delete item._func;
    });

    if (errors.length) {
      errors.unshift("Ошибки расчётов:");
      setTimeout(function() {
        parus.parus8.errorMessage(errors.join("\n"));
      }, 1000);
    };

    return new parus.gridData({
      persistent: true,
      _data: data
    });

  },

  _templates: null,

  _templatesTimeoutID: null,

  _loadTemplates: function() {
    this._templates = [];

    var data;

    nodes = parus.parus8.rowNodes(parus.database.execute("loadIndexConsTemplates", {}))[0];
    if (nodes) {
      nodes = nodes.firstChild;
      if (nodes) {
        nodes = parus.parus8.getTextContent(nodes);
        if (nodes) {
          data = dojo.fromJson(nodes);
          if (data && data.length && (data[0]["user"] === null)) {
            var r = [];
            dojo.forEach(data, function(d) {
              var u = d.user;
              dojo.forEach(d.data, function(dd) {
                dd.user = u;
                r.push(dd);
              });
            });
            data = r;
          }
        }
      }
    }

    if (data) if (data.length) this._templates = data;
  },

  getTemplates: function(dataType, result) {
    if (!this._templates) this._loadTemplates();

    return dojo.filter(this._templates, function(t) {
      return ((dataType == null) || (t.dataType == dataType)) && ((result == null) || (t.result == result));
    });
  },

  clearTemplates: function(all) {

    if (all) this._templates = [];
    else this._templates = dojo.filter(this._templates, function(t) {
      return !!t.user;
    });

    parus.database.execute("clearIndexConsTemplates", {
      "ALL": all ? 1 : 0
    }, function() {});

  },

  deleteTemplate: function(name) {
    if (!this._templates) this._loadTemplates();
    this._templates = dojo.filter(this._templates, function(t) {
      return !!t.user || (t.name != name);
    });
    this._saveTemplates();
  },

  saveTemplate: function(template) {

    if (!this._templates) this._loadTemplates();
    this._templates = dojo.filter(this._templates, function(t) {
      return !!t.user || (t.name != template.name);
    });
    this._templates.push(template);

    this._templates.sort(function(a, b) {

      if ((a.user || "") > (b.user || "")) return 1
      else if ((a.user || "") < (b.user || "")) return -1
      else if (a.name > b.name) return 1
      else if (a.name < b.name) return -1
      else return 0;
    });

    this._saveTemplates();


  },

  _templateApplyIndex: 0,

  templateApplyIndex: function() {
    return this._templateApplyIndex++;
  },

  _saveTemplates: function() {
    if (this._templatesTimeoutID) clearTimeout(this._templatesTimeoutID);
    this._templatesTimeoutID = setTimeout(dojo.hitch(this, function() {
      this._templatesTimeoutID = null;

      var t = dojo.map(dojo.filter(this._templates, function(t) {
        return !t.user;
      }), function(t) {
        return {
          name: t.name,
          result: t.result,
          dataType: t.dataType,
          intPart: t.intPart,
          fracPart: t.fracPart,
          items: t.items
        };
      });

      parus.database.execute("saveIndexConsTemplates", {
        clobDATA: {
          data: dojo.toJson(t)
        }
      }, function() {});

    }), 1000);
  }

});