// Generated by CoffeeScript 1.12.7
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  hasProp = {}.hasOwnProperty,
  indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

ez5.DetailLinkedMaskSplitter = (function(superClass) {
  extend(DetailLinkedMaskSplitter, superClass);

  function DetailLinkedMaskSplitter() {
    return DetailLinkedMaskSplitter.__super__.constructor.apply(this, arguments);
  }

  DetailLinkedMaskSplitter.NAVIGATION_LIMIT = 10;

  DetailLinkedMaskSplitter.prototype.getOptions = function() {
    var i, len, objecttype, objecttypeOptions, objecttypes, options;
    objecttypes = this.__getObjecttypesWithLinkToTable(this.maskEditor.current_mask.table.table_id);
    objecttypeOptions = [];
    for (i = 0, len = objecttypes.length; i < len; i++) {
      objecttype = objecttypes[i];
      objecttypeOptions.push({
        value: objecttype.name,
        text: objecttype._name_localized
      });
    }
    options = [
      {
        form: {
          label: $$("detail.linked.mask.splitter.options.mode")
        },
        type: CUI.Select,
        name: "mode",
        options: [
          {
            text: $$("detail.linked.mask.splitter.options.mode.standard"),
            value: "standard"
          }, {
            text: $$("detail.linked.mask.splitter.options.mode.short"),
            value: "short"
          }, {
            text: $$("detail.linked.mask.splitter.options.mode.text"),
            value: "text"
          }
        ]
      }, {
        form: {
          label: $$("detail.linked.mask.splitter.options.objecttypes")
        },
        type: CUI.Options,
        name: "objecttypes",
        options: objecttypeOptions,
        onDataInit: (function(_this) {
          return function(_, data) {
            var j, len1, table;
            if (!CUI.util.isUndef(data.objecttypes)) {
              return;
            }
            data.objecttypes = [];
            objecttypes = _this.__getObjecttypesWithLinkToTable(_this.maskEditor.current_mask.table.table_id);
            for (j = 0, len1 = objecttypes.length; j < len1; j++) {
              table = objecttypes[j];
              data.objecttypes.push(table.name);
            }
          };
        })(this)
      }
    ];
    if (ez5.version("6")) {
      options.push({
        form: {
          label: $$("detail.linked.mask.splitter.options.include_inherited")
        },
        type: CUI.Checkbox,
        name: "include_inherited"
      });
      options.push({
        form: {
          label: $$("detail.linked.mask.splitter.options.show_fields")
        },
        type: CUI.Checkbox,
        name: "show_fields"
      });
    }
    return options;
  };

  DetailLinkedMaskSplitter.prototype.getDefaultOptions = function() {
    var defaultOptions;
    defaultOptions = {
      mode: "standard"
    };
    return defaultOptions;
  };

  DetailLinkedMaskSplitter.prototype.renderField = function(opts) {
    var dataOptions, globalObjectId, idTable, linkedFieldNames, mainContent, objecttype, ref, showFields, spinner;
    if (opts == null) {
      opts = {};
    }
    if (opts.mode !== "detail") {
      return;
    }
    globalObjectId = (ref = opts.top_level_data) != null ? ref._global_object_id : void 0;
    if (!globalObjectId) {
      return;
    }
    objecttype = opts.top_level_data._objecttype;
    if (!objecttype) {
      return;
    }
    dataOptions = this.getDataOptions();
    idTable = ez5.schema.CURRENT._objecttype_by_name[objecttype].table_id;
    linkedFieldNames = this.__getLinkedFieldNames(idTable, dataOptions.objecttypes);
    if (CUI.util.isEmpty(linkedFieldNames)) {
      return;
    }
    mainContent = CUI.dom.div("ez5-detail-linked-mask-splitter-content");
    spinner = new LocaLabel({
      loca_key: "detail.linked.mask.splitter.detail.spinner"
    });
    CUI.dom.append(mainContent, spinner);
    showFields = ez5.version("6") && dataOptions.show_fields;
    this.__searchByLinkedFieldNames(linkedFieldNames, globalObjectId, dataOptions.mode).done((function(_this) {
      return function(dataByObjecttype) {
        var content, data, fieldLocalizedName, i, j, len, len1, localized_objecttype, object, ref1, ref2, resultObjects;
        CUI.dom.empty(mainContent);
        dataByObjecttype.sort(function(a, b) {
          var cmp, fieldA, fieldB, objecttypeA, objecttypeB, ref1, ref2;
          objecttypeA = ((ref1 = a.objecttypes) != null ? ref1[0] : void 0) || "";
          objecttypeB = ((ref2 = b.objecttypes) != null ? ref2[0] : void 0) || "";
          cmp = objecttypeA.localeCompare(objecttypeB);
          if (cmp !== 0) {
            return cmp;
          }
          if (showFields) {
            fieldA = a._fieldLocalizedName || "";
            fieldB = b._fieldLocalizedName || "";
            return fieldA.localeCompare(fieldB);
          }
          return 0;
        });
        for (i = 0, len = dataByObjecttype.length; i < len; i++) {
          data = dataByObjecttype[i];
          if (data.objects.length === 0) {
            continue;
          }
          data.objects.sort(function(a, b) {
            var ref1, ref2, ref3, ref4, standardNameA, standardNameB;
            standardNameA = ez5.loca.getBestFrontendValue((ref1 = a._standard) != null ? (ref2 = ref1["1"]) != null ? ref2.text : void 0 : void 0);
            standardNameB = ez5.loca.getBestFrontendValue((ref3 = b._standard) != null ? (ref4 = ref3["1"]) != null ? ref4.text : void 0 : void 0);
            if (standardNameA && standardNameB) {
              return standardNameA.localeCompare(standardNameB);
            }
            return 0;
          });
          objecttype = data.objecttypes[0];
          resultObjects = [];
          ref1 = data.objects;
          for (j = 0, len1 = ref1.length; j < len1; j++) {
            object = ref1[j];
            resultObjects.push(new ResultObject().setData(object));
          }
          localized_objecttype = (ref2 = resultObjects[0]) != null ? ref2.objecttypeLocalized() : void 0;
          fieldLocalizedName = showFields ? data._fieldLocalizedName : null;
          content = _this.__renderObjects(localized_objecttype, resultObjects, dataOptions.mode, opts, fieldLocalizedName);
          CUI.dom.append(mainContent, content);
        }
      };
    })(this)).fail((function(_this) {
      return function(err) {
        console.error("DetailLinkedMaskSplitter :: Error when fetching objects.", err);
        return CUI.dom.empty(mainContent);
      };
    })(this));
    return mainContent;
  };

  DetailLinkedMaskSplitter.prototype.__renderObjects = function(objecttype, resultObjects, mode, opts, fieldLocalizedName) {
    var content, currentPage, label, length, limit, navigationToolbar, objectsContent, objecttypeHeader, renderObjects, titleDiv;
    if (opts == null) {
      opts = {};
    }
    if (fieldLocalizedName == null) {
      fieldLocalizedName = null;
    }
    objecttypeHeader = CUI.dom.div("ez5-field-block-header");
    objectsContent = CUI.dom.div("ez5-field-block-content");
    titleDiv = CUI.dom.div("ez5-field-block-title");
    if (fieldLocalizedName) {
      label = new CUI.Label({
        text: $$("detail.linked.mask.splitter.header.objecttype.field.title", {
          objecttype: objecttype,
          field: fieldLocalizedName
        }),
        "class": "ez5-field-label"
      });
    } else {
      label = new CUI.Label({
        text: $$("detail.linked.mask.splitter.header.objecttype.title", {
          objecttype: objecttype
        }),
        "class": "ez5-field-label"
      });
    }
    CUI.dom.append(titleDiv, label);
    CUI.dom.append(objecttypeHeader, titleDiv);
    limit = ez5.DetailLinkedMaskSplitter.NAVIGATION_LIMIT;
    length = resultObjects.length;
    currentPage = 0;
    renderObjects = function(page) {
      var condensedContainer, detailTools, div, horizontalLayout, i, index, itemDiv, itemField, offset, ref, ref1, resultObject, toIndex;
      if (page == null) {
        page = currentPage;
      }
      CUI.dom.empty(objectsContent);
      currentPage = page;
      offset = page * limit;
      toIndex = offset + limit;
      if (toIndex > length) {
        toIndex = length;
      }
      if (mode === "short") {
        condensedContainer = CUI.dom.div("ez5-nested--condensed ez5-nested--single-column");
        CUI.dom.append(objectsContent, condensedContainer);
      }
      for (index = i = ref = offset, ref1 = toIndex; ref <= ref1 ? i < ref1 : i > ref1; index = ref <= ref1 ? ++i : --i) {
        resultObject = resultObjects[index];
        div = (function() {
          switch (mode) {
            case "short":
              return resultObject.renderCardLinkedObjectShort();
            case "text":
              return resultObject.renderTextDetail();
            case "standard":
              return resultObject.renderCardLinkedObjectStandard();
          }
        })();
        if (mode === "short") {
          itemDiv = CUI.dom.div("ez5-nested-fields");
          itemField = CUI.dom.div("ez5-field");
          CUI.dom.append(itemDiv, itemField);
          CUI.dom.append(itemField, div);
          CUI.dom.append(condensedContainer, itemDiv);
        } else {
          horizontalLayout = new CUI.HorizontalLayout({
            maximize_horizontal: true,
            maximize_vertical: false,
            "class": "ez5-linked-object-detail ez5-linked-object linked-object-popover",
            right: {}
          });
          horizontalLayout.replace(div, "center");
          if (opts.detail) {
            detailTools = resultObject.getDetailTools({
              detail: opts.detail,
              getElement: (function(_this) {
                return function() {
                  return horizontalLayout;
                };
              })(this)
            });
            horizontalLayout.replace(Toolbox.getFlyoutButtonbar(detailTools, {
              appearance: "flat"
            }), "right");
          }
          CUI.dom.append(objectsContent, horizontalLayout);
        }
      }
      if (navigationToolbar) {
        navigationToolbar.update({
          count: length,
          offset: offset,
          limit: limit
        });
      }
    };
    content = [objecttypeHeader, objectsContent];
    if (length > limit) {
      navigationToolbar = new NavigationToolbar({
        size: "mini",
        append_count_label: false,
        onLoadPage: renderObjects
      });
      content.push(navigationToolbar);
    }
    renderObjects();
    return content;
  };

  DetailLinkedMaskSplitter.prototype.__getLinkedFieldNames = function(idTable, objecttypes) {
    var columnSchema, field, fieldLocalizedName, fieldName, fn, i, len, linkedFieldNames, nestedName, objecttype, objecttypeManager, ref, showFields, table, table_name;
    if (objecttypes == null) {
      objecttypes = [];
    }
    linkedFieldNames = {};
    showFields = ez5.version("6") && this.getDataOptions().show_fields;
    objecttypeManager = new ObjecttypeManager();
    objecttypeManager.addObjecttypes((function(_this) {
      return function(table, mask) {
        var ref;
        if (ref = table.name(), indexOf.call(objecttypes, ref) < 0) {
          return false;
        }
        return mask.schema.is_preferred;
      };
    })(this));
    ref = objecttypeManager.getAllFields();
    for (i = 0, len = ref.length; i < len; i++) {
      field = ref[i];
      columnSchema = field.ColumnSchema;
      if (!this.__hasColumnLinkToTable(columnSchema, idTable)) {
        continue;
      }
      if (!this.__isFieldSearchable(field)) {
        continue;
      }
      table = field.table.schema;
      table_name = table.name;
      fieldName = table_name + "." + columnSchema.name + "._global_object_id";
      if (table.owned_by) {
        nestedName = this.__getNestedLinkedFieldName(table);
        fieldName = "" + nestedName + fieldName;
      }
      objecttype = fieldName.split(".")[0];
      fieldLocalizedName = null;
      if (showFields) {
        fieldLocalizedName = field.nameLocalized();
      }
      if (ez5.version("6") && !this.getDataOptions().include_inherited && field.isInherited()) {
        fn = fieldName.replace("._global_object_id", "");
        if (linkedFieldNames[objecttype] == null) {
          linkedFieldNames[objecttype] = [];
        }
        linkedFieldNames[objecttype].push({
          fieldName: fn + ":inherited",
          localizedName: fieldLocalizedName,
          isInherited: true
        });
      }
      if (linkedFieldNames[objecttype] == null) {
        linkedFieldNames[objecttype] = [];
      }
      linkedFieldNames[objecttype].push({
        fieldName: fieldName,
        localizedName: fieldLocalizedName,
        isInherited: false
      });
    }
    return linkedFieldNames;
  };

  DetailLinkedMaskSplitter.prototype.__searchByLinkedFieldNames = function(linkedFieldNamesPerObjecttype, globalObjectId, mode) {
    var dfr, fieldInfo, fieldLocalizedNames, fieldName, fn1, hasInheritedField, i, inheritedFieldName, inheritedLinkeds, j, len, len1, linkedFieldInfos, objecttype, regularFields, results, searchData, searchPromise, searches, showFields;
    dfr = new CUI.Deferred();
    searches = [];
    results = [];
    mode = mode === "text" ? "long" : mode;
    showFields = ez5.version("6") && this.getDataOptions().show_fields;
    for (objecttype in linkedFieldNamesPerObjecttype) {
      linkedFieldInfos = linkedFieldNamesPerObjecttype[objecttype];
      inheritedLinkeds = [];
      regularFields = [];
      fieldLocalizedNames = {};
      for (i = 0, len = linkedFieldInfos.length; i < len; i++) {
        fieldInfo = linkedFieldInfos[i];
        if (fieldInfo.isInherited) {
          inheritedLinkeds.push(fieldInfo.fieldName);
        } else {
          regularFields.push(fieldInfo.fieldName);
          if (fieldInfo.localizedName) {
            fieldLocalizedNames[fieldInfo.fieldName] = fieldInfo.localizedName;
          }
        }
      }
      if (showFields) {
        fn1 = (function(_this) {
          return function(fieldName, fieldLocalizedNames) {
            var searchPromise;
            searchPromise = ez5.api.search({
              data: {
                debug: "DetailMaskSplitterSearch"
              },
              json_data: searchData
            });
            searchPromise.done(function(result) {
              result._fieldName = fieldName;
              result._fieldLocalizedName = fieldLocalizedNames[fieldName];
              return results.push(result);
            });
            return searches.push(searchPromise);
          };
        })(this);
        for (j = 0, len1 = regularFields.length; j < len1; j++) {
          fieldName = regularFields[j];
          inheritedFieldName = fieldName.replace("._global_object_id", "") + ":inherited";
          hasInheritedField = indexOf.call(inheritedLinkeds, inheritedFieldName) >= 0;
          searchData = {
            limit: 1000,
            format: mode,
            objecttypes: [objecttype]
          };
          if (hasInheritedField) {
            searchData.search = [
              {
                type: "complex",
                bool: "must",
                search: [
                  {
                    type: "in",
                    fields: [fieldName],
                    "in": [globalObjectId]
                  }, {
                    type: "in",
                    fields: [inheritedFieldName],
                    "in": [false]
                  }
                ]
              }
            ];
          } else {
            searchData.search = [
              {
                type: "in",
                fields: [fieldName],
                "in": [globalObjectId]
              }
            ];
          }
          fn1(fieldName, fieldLocalizedNames);
        }
      } else {
        if (inheritedLinkeds.length > 0) {
          searchPromise = ez5.api.search({
            data: {
              debug: "DetailMaskSplitterSearch"
            },
            json_data: {
              limit: 1000,
              format: mode,
              objecttypes: [objecttype],
              search: [
                {
                  type: "complex",
                  bool: "must",
                  search: [
                    {
                      type: "in",
                      fields: regularFields,
                      "in": [globalObjectId]
                    }, {
                      type: "in",
                      fields: inheritedLinkeds,
                      "in": [false]
                    }
                  ]
                }
              ]
            }
          });
          searchPromise.done((function(_this) {
            return function(result) {
              return results.push(result);
            };
          })(this));
        } else {
          searchPromise = ez5.api.search({
            data: {
              debug: "DetailMaskSplitterSearch"
            },
            json_data: {
              limit: 1000,
              format: mode,
              objecttypes: [objecttype],
              search: [
                {
                  type: "in",
                  fields: regularFields,
                  "in": [globalObjectId]
                }
              ]
            }
          });
          searchPromise.done((function(_this) {
            return function(result) {
              return results.push(result);
            };
          })(this));
        }
        searches.push(searchPromise);
      }
    }
    CUI.when(searches).done((function(_this) {
      return function() {
        return dfr.resolve(results);
      };
    })(this)).fail((function(_this) {
      return function(err) {
        return dfr.reject(err);
      };
    })(this));
    return dfr.promise();
  };

  DetailLinkedMaskSplitter.prototype.__getObjecttypesWithLinkToTable = function(idTable) {
    var columnSchema, field, i, len, objecttype, objecttypeManager, objecttypes, ref;
    objecttypes = [];
    objecttypeManager = new ObjecttypeManager({
      version: "HEAD"
    });
    objecttypeManager.addObjecttypes((function(_this) {
      return function(table, mask) {
        return mask.schema.is_preferred;
      };
    })(this));
    ref = objecttypeManager.getAllFields();
    for (i = 0, len = ref.length; i < len; i++) {
      field = ref[i];
      columnSchema = field.ColumnSchema;
      if (this.__hasColumnLinkToTable(columnSchema, idTable) && this.__isFieldSearchable(field)) {
        objecttype = field.getMainMask().table.schema;
        if (indexOf.call(objecttypes, objecttype) >= 0) {
          continue;
        }
        objecttypes.push(objecttype);
      }
    }
    return objecttypes;
  };

  DetailLinkedMaskSplitter.prototype.__getNestedLinkedFieldName = function(table) {
    var ownerTable;
    if (!table) {
      return;
    }
    if (!table.owned_by) {
      return "";
    }
    ownerTable = ez5.schema.CURRENT._table_by_id[table.owned_by.other_table_id];
    return this.__getNestedLinkedFieldName(ownerTable) + ownerTable.name + "._nested:";
  };

  DetailLinkedMaskSplitter.prototype.hasContent = function() {
    return true;
  };

  DetailLinkedMaskSplitter.prototype.__hasColumnLinkToTable = function(column, idTable) {
    return column && column.type === "link" && column._foreign_key.referenced_table.table_id === idTable;
  };

  DetailLinkedMaskSplitter.prototype.__isFieldSearchable = function(field) {
    var fatherField;
    if (!field) {
      return true;
    }
    fatherField = field.getFatherField();
    return this.__isFieldSearchable(fatherField) && field.isVisible("expert");
  };

  DetailLinkedMaskSplitter.prototype.isSimpleSplit = function() {
    return true;
  };

  DetailLinkedMaskSplitter.prototype.renderAsField = function() {
    return true;
  };

  DetailLinkedMaskSplitter.prototype.isEnabledForNested = function() {
    return false;
  };

  return DetailLinkedMaskSplitter;

})(CustomMaskSplitter);

MaskSplitter.plugins.registerPlugin(ez5.DetailLinkedMaskSplitter);
