fcf.module({
  name: "fcfDBControls:templates/form.wrapper.js",
  dependencies: ["fcfControls:templates/form.wrapper.js"],
  module: function(Form){
    return class DBForm extends Form{

      constructor(a_initializeOptions){
        super(a_initializeOptions);
      }

      initialize(){
        let self = this;

        let values = this.getArg("value");
        let mode = this.getArg("mode").split(".")[0];
        if (mode === "add"){
          fcf.each(values, (k, value)=>{
            self.setArg(`value["${k}"]`, value);
          })
        }

        return super.initialize()
      }

      attach(a_options) {
        fcf.addDomListener(window, "scroll", this);
        this.onScroll();
        super.attach(a_options);
      }

      onScroll(a_event){
        let panel = this.select("[name='fcf-form-top-panel']")[0];
        if (!panel)
          return;
        var viewportOffset = panel.getBoundingClientRect();
        if (viewportOffset.top < 0){
          panel.style.top = "-1px";
          panel.style.position = "sticky";
          panel.classList.add("scroll");
        } else {
          panel.style.top = "";
          panel.style.position = "";
          panel.classList.remove("scroll");
        }
      }

      check() {
        let self = this;
        let errors = [];
        let languages = this.getArg("languages");
        let defaultLanguage = this.getArg("defaultLanguage");
        let childs = this.getChilds();
        fcf.each(languages, (language)=>{
          let value        = self.getArg("value@"+language);
          let validateInfo = {
            secondPriority: language != defaultLanguage,
          };
          fcf.each(childs, (a_key, a_child)=>{
            let suberrors = [];
            a_child.validate(value[a_child.getAlias()], validateInfo, suberrors);
            fcf.each(suberrors, (a_key, a_suberror)=>{
              a_suberror.language = language;
              errors.push(a_suberror);
            });
          });
        });
        return errors;
      }

      write(){
        let self        = this;
        let value       = this.getArg("value");
        let key         = value && !fcf.empty(value["@key"]) ? value["@key"] : undefined;
        let data        = fcf.append({}, this.getArg("allModify"));
        let mode        = self.getArg("mode").split(".")[0];
        let projection  = self.getArg("projection");
        let languages   = self.getArg("languages");
        let defaultLanguage = this.getArg("defaultLanguage");
        let childs      = this.getChilds();
        let writenValue = {};

        return fcf.actions()
        .then(()=>{
          let errors = self.check();
          if (!fcf.empty(errors))
            throw new fcf.Exception("ERROR_FORM_INPUT", {allErrors: errors});
        })
        .then(() => {
          let valuesInfo = {};
          if (mode == "add")
            data[defaultLanguage] = self.getArg(`value@${defaultLanguage}`);

          for(let lang in data){
            valuesInfo[lang] = {
              value:  data[lang],
              ignore: false,
            };
          }

          this.processWritenValue(valuesInfo, defaultLanguage);

          data = {};
          for(let lang in valuesInfo){
            if (valuesInfo[lang].ignore)
              continue;
            if (!data[lang])
            data[lang] = {};
            data[lang] = valuesInfo[lang].value;
          }
          if (fcf.empty(data)) {
            data[defaultLanguage] = {};
          }
        })
        .then(()=>{
          return self.send({
            type: mode,
            data: data,
            key:  key,
            projection: projection
          })
        });

      }

      onArg(a_argName, a_value, a_editor, a_ignoreRedrawing, a_isInnerCall, a_suffix) {
        if (a_argName.indexOf("value@") == -1)
          return;

        let self = this;
        let pathArr = fcf.parseObjectAddress(a_suffix);
        if (pathArr.length < 1)
          return;

        let languages   = this.getArg("languages");
        let language    = a_argName.substr("value@".length);
        let alias       = pathArr[0];
        let modifyItem  = fcf.resolve(a_value, alias);
        let modify      = this.getArg("allModify");
        let fields      = this.getArg("fields");

        if (!modify[language])
          modify[language] = {};

        let child = this.getChild(alias);
        let multilingual = child && !!child.getArg("@language");

        let index = fcf.find(fields, (k, v)=>{ return v.alias == alias;});
        if (fields[index] && (fields[index].translate || multilingual)){
          modify[language][alias] = modifyItem;
          this._setArg("allModify", modify, false);
        } else {
          fcf.first(modify)[alias] = modifyItem;
          this._setArg("allModify", modify, false);
          fcf.each(languages, (a_lang)=>{
            let values = self.getArg(`value@${a_lang}`);
            self.setArg(`value@${a_lang}["${alias}"]`, modifyItem, true);
          })
        }
      }

      onArgLanguage(a_value){
        this.update();
      }

      onClearElement(a_alias){
        let language  = this.getArg("language");
        this._setArg('value["' + a_alias + '"]', null);
        this._setArg('allModify["' + language + '"]["' + a_alias + '"]', null);
      }


    }
  }

});
