import AbstractElement from "./AbstractElement";
import { InputField, TextareaField, RadioField, CheckboxField, SelectField, DataField, DeptField, TreedepartmentField, UserField, SelectaboutField, SuggestField, ButtonField, ViewdialogField, TabField, CalctextField, IncludeField, SurveyField, AttachmentField, KmdataField, FlowreminderhistoryField, FlowhistoryField, HtmleditorField, GenericwordField, MapField, QrcodeField, WeixinrecordField, WeixingpsField, OnlinetakephotoField, ImageuploadField, NoField, SplitField } from "./field/index";
import { Sequence } from "../utility";

class Container extends AbstractElement {
  constructor(panel) {
    super();
    this.panel = panel;
    this.childs = [];
    this.htmlDOM = null;
    this.num = 0;
    this.propValues.id = Sequence.createUuid();
    this.propValues.name = window.formApp.formPanel ? "容器" + window.formApp.formPanel.propValues.nameIndex : "容器" + 1;
    this.width = "100%";
    this.style = {
      padding: "10px",
      "border": "1px solid #000",
      display: "flex",
      "flex-wrap": 'wrap',
      "min-height": "100px",
      width: "100%",
      "border-color": "#000",
      "background-color": "#fff",
      "position": 'relative',
      "vertical-align": "top",
    };
    this.scope = 'container';
    this.propValues.containerHeight = 100;
    this.propValues.borderwidth = 1;//边框宽度
    this.setElem = null;
    this.setElemIndex = null;
    this.setElemIndexPre = null;
  }


  /**
   * 初始化创建dom结构，和其他初始化操作
   */
  rendTo () {
    this.htmlDOM = document.createElement("DIV");
    this.htmlDOM.setAttribute("draggable", true);
    this.isChecked = true;
    this.htmlDOM.setAttribute("name", this.propValues.name);
    this.htmlDOM.setAttribute("id", this.propValues.id);
    this.htmlDOM.setAttribute("scope", this.scope);

    console.log('render', this.htmlDOM )

    if (this.panel.id == "formContainer") {
      this.htmlDOM.setAttribute("class", "empty");
      this.htmlDOM.setAttribute("data-empty-tip", "从左侧拖拽来添加控件");

    } else {
      this.style["border-color"] = "#0DB3A6";
      let div = document.createElement("DIV");
      div.setAttribute("class", "delete")
      div.innerHTML = `<i class="btn-delete" title="删除"></i>`
      this.htmlDOM.appendChild(div);
    }
    Object.assign(this.htmlDOM.style, this.style);

    this.panel.appendChild(this.htmlDOM);
    this._bindEvent(this.htmlDOM);
    this.setnameIndex();

  }
  /**
   * 显示placeholder dom结构
   */
  showPlaceholder () {
    if (this.setElem != null && this.setElemIndex != this.setElemIndexPre) {
      window.formApp.placeholderDom.setAttribute("class", "placeholder");
      this.htmlDOM.insertBefore(window.formApp.placeholderDom, this.setElem.htmlDOM);
    } else {
      window.formApp.placeholderDom.setAttribute("class", "placeholder");
      this.htmlDOM.appendChild(window.formApp.placeholderDom);
    }
  }
  /**
   * 隐藏placeholder dom结构
   */
  hidePlaceholder () {
    console.log("hidePlaceholder")
    window.formApp.formPanel.htmlDOM.appendChild(window.formApp.placeholderDom)
    window.formApp.placeholderDom.setAttribute("class", "placeholder d-none")
  }
  /**
   * 绑定事件
   * @param {} div 
   */
  _bindEvent (div) {
    let that = this;
    div.ondblclick = (e) => {
      return false;
    }
    div.onclick = (e) => {
      e.stopPropagation();
      if (e.target.getAttribute("class") == "btn-delete") {
        let index = this.delContainer();
        if (index != null) {
          window.formApp.formPanel.childs.splice(index, 1);
          window.formApp.formPanel.htmlDOM.removeChild(this.htmlDOM);
          this.renderPropsPanel([], [])
        }
      } else {
        that.triggerClick();
      }
    }
    div.ondragover = (ev) => {
      ev.stopPropagation();
      ev.preventDefault();
      this.getNowField(ev.pageY, 70);
      that.showPlaceholder();
    }
    div.ondrop = (ev) => {
      this.checkSetElem(ev.pageY);
      let result = that.resetAllElemandContainer();
      if (result) {
        ev.preventDefault();
        let data = ev.dataTransfer.getData("Text");
        let have = that.isHave(data);
        if (!have) {
          let element = null;
          switch (data) {
            case 'Input':
              ev.stopPropagation();
              element = new InputField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Textarea':
              ev.stopPropagation();
              element = new TextareaField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Radio':
              ev.stopPropagation();
              element = new RadioField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Checkbox':
              ev.stopPropagation();
              element = new CheckboxField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Select':
              ev.stopPropagation();
              element = new SelectField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Data':
              ev.stopPropagation();
              element = new DataField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Dept':
              ev.stopPropagation();
              element = new DeptField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'TreedepartmentField':
              ev.stopPropagation();
              element = new TreedepartmentField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'UserField':
              ev.stopPropagation();
              element = new UserField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'SelectaboutField':
              ev.stopPropagation();
              element = new SelectaboutField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'SuggestField':
              ev.stopPropagation();
              element = new SuggestField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'ButtonField':
              ev.stopPropagation();
              element = new ButtonField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'ViewdialogField':
              ev.stopPropagation();
              element = new ViewdialogField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'TabField':
              ev.stopPropagation();
              element = new TabField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'CalctextField':
              ev.stopPropagation();
              element = new CalctextField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'IncludeField':
              ev.stopPropagation();
              element = new IncludeField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'SurveyField':
              ev.stopPropagation();
              element = new SurveyField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'AttachmentField':
              ev.stopPropagation();
              element = new AttachmentField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'KmdataField':
              ev.stopPropagation();
              element = new KmdataField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;

            case 'FlowreminderhistoryField':
              ev.stopPropagation();
              element = new FlowreminderhistoryField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'FlowhistoryField':
              ev.stopPropagation();
              element = new FlowhistoryField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'HtmleditorField':
              ev.stopPropagation();
              element = new HtmleditorField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'GenericwordField':
              ev.stopPropagation();
              element = new GenericwordField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'MapField':
              ev.stopPropagation();
              element = new MapField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'QrcodeField':
              ev.stopPropagation();
              element = new QrcodeField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'WeixinrecordField':
              ev.stopPropagation();
              element = new WeixinrecordField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'WeixingpsField':
              ev.stopPropagation();
              element = new WeixingpsField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'OnlinetakephotoField':
              ev.stopPropagation();
              element = new OnlinetakephotoField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'ImageuploadField':
              ev.stopPropagation();
              element = new ImageuploadField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'NoField':
              ev.stopPropagation();
              element = new NoField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'SplitField':
              ev.stopPropagation();
              element = new SplitField(that);
              element.isChecked = true;
              element.creat();
              element.name = element.name + that.num;
              window.formApp.allElements.push(element);
              that.num++;
              break;
            case 'Container':
              element = new Container(div);
              element.isChecked = true;
              element.rendTo();
              that.num++;
              break;
            default:
              // yx 先注释(直接移动框会报错)
              // let index = that.whichChild(data);
              // that.childs.push(that.childs.splice(index, 1)[0]);
              // console.log(that.htmlDOM)
              // that.htmlDOM.insertBefore(that.htmlDOM.children[index], null)
              break;
          }
          if(element){
            element.renderHtml(element.style, 'style');
            element.renderHtml(element.propValues, 'prop')
          }
          if (element instanceof InputField) {
            that.addElement(element);
          } else if (element) {
            ev.stopPropagation();
            that.addElement(element);
          }
          if (that.childs.length > 0 && this.panel.id == "formContainer") {
            that.htmlDOM.setAttribute("class", "");
          } else if (that.childs.length == 0 && this.panel.id == "formContainer") {
            that.htmlDOM.setAttribute("class", "empty");
            that.htmlDOM.setAttribute("data-empty-tip", "从左侧拖拽来添加控件");
          }
          if(element){
            this.renderPropsPanel(element.getPropsDesc(), element.getPropValues(), element.scope)
          }
        } else {
          ev.stopPropagation();
          try {
            let delElem = have.container ? have.container.remove(data) : this.containerFather(data).remove(data);
            delElem.container = that || this.containerFather(data);
            that.addElement(delElem);

            // 获取插入的元素的高度
            let dragEle = this.getDragEle(ev.pageY, 70)
            
            try {
              // 判断如果没有值就执行appendChild
              if (this.setElemIndex != null && this.setElemIndexPre != null) {
                that.htmlDOM.insertBefore(delElem.htmlDOM, dragEle.htmlDOM)
              }else {
                console.log(99)
                that.htmlDOM.appendChild(have.htmlDOM)
              }
            }
            // }
            catch (err) {
              console.log(err)
              console.log("元素未发生移动")
            }
            that.paint();
          } catch (err) {
            console.log("移动失败", err)
          }

        }
      }
      that.hidePlaceholder();

    }
    div.ondragstart = (ev) => {
      ev.dataTransfer.setData("Text", ev.target.id);
    }
  }
  //鼠标放开的时候判断是不是放在最后
  checkSetElem (y) {
    if (this.childs.length > 0) {
      y += document.getElementsByClassName("formContent")[0].scrollTop
      if (y > this.childs[this.childs.length - 1].htmlDOM.offsetTop + this.childs[this.childs.length - 1].htmlDOM.clientHeight) {
        this.setElem = null;
        this.setElemIndexPre = null;
        this.setElemIndex = null;
        this.hidePlaceholder();
        this.showPlaceholder();
        return true;
      }
    }

  }
  //获取当前鼠标在哪个元素的范围内，获取这个元素
  getNowField (y, defaultValue = 0) {
    if (this.scope == 'container') {
      y = y - this.htmlDOM.getBoundingClientRect().top;
      defaultValue = 0;
    }
    y += document.getElementsByClassName("formContent")[0].scrollTop
    let preheight = defaultValue, nextheight = defaultValue;


    console.log('dragNowFieldChilds', this.childs)

    // 选中已有元素进行拖拽的时候触发【可以获取选中的元素】
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].htmlDOM.offsetTop < y && y < this.childs[i].htmlDOM.offsetTop + this.childs[i].htmlDOM.clientHeight && this.setElemIndex != i) {
        this.setElem = this.childs[i];
        this.setElemIndexPre = this.setElemIndex;
        this.setElemIndex = i;
        console.log('nowfieldEle', this.setElem)
        return true;
      }
      // if(preheight>y){
      //     //这个时候 添加的目标元素是第一个不是容器的元素
      //     // if(window.formApp.formPanel.childs[i].scope!='container')
      //     this.setElem=this.childs[i-1];
      //     this.setElemIndex=i-1;
      //     return true;
      //     // return window.formApp.formPanel.childs[i];
      // }else if(nextheight>y){
      //     this.setElem=this.childs[i];
      //     this.setElemIndex=i;
      //     return true;
      // }
      // else {
      //     preheight+=this.childs[i].htmlDOM.clientHeight/2;
      //     nextheight+=this.childs[i].htmlDOM.clientHeight;
      // }
    }

  }

  /**
   * 获取拖拽放置元素
   * @param {*} y 
   * @returns 
   */
  getDragEle (y) {
    y += document.getElementsByClassName("formContent")[0].scrollTop

    // 选中已有元素进行拖拽的时候触发【可以获取选中的元素】
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].htmlDOM.offsetTop < y && y < this.childs[i].htmlDOM.offsetTop + this.childs[i].htmlDOM.clientHeight && this.setElemIndex != i) {
        this.setElemIndex = i;
        console.log('this.setElem',this.setElem)
        return this.setElem
      }
    }

  }
  /**
   * 遍历childs，返回id相同的子元素下标
   * @param {data} 
   */
  whichChild (data) {
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].propValues.id == data) {
        return i;
      }
    }
  }
  /**
   * 获取所有的部门选择框集合，返回一个数组
   */
  getAllDeptInfo () {
    let currElem = window.formApp.propsPanel.getCurrElem();
    let allDeptInfo = [];
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].scope == "deptField" && currElem && currElem.propValues.id != this.childs[i].propValues.id) {
        allDeptInfo.push(this.childs[i])
      } else if (this.childs[i].scope == "container") {
        let dept = this.childs[i].getAllDeptInfo();
        if (dept.length > 0) {
          allDeptInfo = allDeptInfo.concat(dept);
        }

      }
    }
    return allDeptInfo;
  }
  /**
   * 获取所有的日期选择框集合，返回一个数组
   */
  getAllDataInfo () {
    let currElem = window.formApp.propsPanel.getCurrElem();
    let allDataInfo = [];
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].scope == "dataField" && currElem && currElem.propValues.id != this.childs[i].propValues.id) {
        allDataInfo.push(this.childs[i])
      } else if (this.childs[i].scope == "container") {
        let data = this.childs[i].getAllDataInfo();
        if (data.length > 0) {
          allDataInfo = allDataInfo.concat(data);
        }

      }
    }
    return allDataInfo;
  }
  /**
   * 重置childs的ischecked属性和其他涉及到的属性
   */
  resetChildisChecked () {
    if (this.childs.length > 0) {
      for (var i = 0; i < this.childs.length; i++) {
        if (this.childs[i].scope == "container") {
          this.childs[i].resetChildisChecked();
          this.childs[i].isChecked = false;
          this.childs[i].style["border-color"] = "#000";
          this.childs[i].style["background-color"] = "#fff";
          Object.assign(this.childs[i].htmlDOM.style, this.childs[i].style);
          for (let j = 0; j < this.childs[i].htmlDOM.children.length; j++) {
            if (this.childs[i].htmlDOM.children[j].getAttribute("class") && this.childs[i].htmlDOM.children[j].getAttribute("class").indexOf('delete') != -1)
              this.childs[i].htmlDOM.children[j].setAttribute("class", 'delete d-none')
          }
          // this.childs[i].htmlDOM.getElementsByClassName("delete")[0].setAttribute("class",'delete d-none')
        }
        else {
          this.childs[i].isChecked = false;
          this.childs[i].style["border-color"] = "#fff";
          this.childs[i].style["background-color"] = "#fff";
          Object.assign(this.childs[i].htmlDOM.style, this.childs[i].style);
          if (this.childs[i].htmlDOM.getAttribute("class") && this.childs[i].htmlDOM.getAttribute("class").indexOf('delete') != -1) {
            this.childs[i].htmlDOM.setAttribute("class", 'delete d-none')
          }
          // this.childs[i].htmlDOM.getElementsByClassName("delete")[0].setAttribute("class",'delete d-none')
        }
      }
    }
  }
  /**
   * 重置所有元素和容器的ischecked属性和其他涉及到的属性
   */
  resetAllElemandContainer () {
    let result = this.checkField();
    if (result) {
      if (window.formApp.allElements.length > 0) {
        for (let i = 0; i < window.formApp.allElements.length; i++) {
          window.formApp.allElements[i].isChecked = false;
          window.formApp.allElements[i].style["border-color"] = "#fff";
          window.formApp.allElements[i].style["background-color"] = "#fff";
          Object.assign(window.formApp.allElements[i].htmlDOM.style, window.formApp.allElements[i].style);
          window.formApp.allElements[i].htmlDOM.getElementsByClassName("delete")[0].setAttribute("class", 'delete d-none')
        }
      }
      window.formApp.formPanel.isChecked = false;
      window.formApp.formPanel.style["border-color"] = "#fff";
      window.formApp.formPanel.style["background-color"] = "#fff";
      Object.assign(window.formApp.formPanel.htmlDOM.style, window.formApp.formPanel.style);
      if (window.formApp.formPanel.childs.length > 0) {
        for (let j = 0; j < window.formApp.formPanel.childs.length; j++) {
          if (window.formApp.formPanel.childs[j].scope == "container") {
            window.formApp.formPanel.childs[j].resetChildisChecked();
            window.formApp.formPanel.childs[j].isChecked = false;
            window.formApp.formPanel.childs[j].style["border-color"] = "#000";
            window.formApp.formPanel.childs[j].style["background-color"] = "#fff";
            Object.assign(window.formApp.formPanel.childs[j].htmlDOM.style, window.formApp.formPanel.childs[j].style);
            window.formApp.formPanel.childs[j].htmlDOM.getElementsByClassName("delete")[0].setAttribute("class", 'delete d-none')
          }
        }
      }
      return true;
    } else {
      return false;
    }
  }

  //执行当前点击的field的click事件
  triggerClick () {
    let result = this.resetAllElemandContainer();
    if (result) {
      this.isChecked = true;
      this.style["border-color"] = "#0DB3A6";
      this.style["background-color"] = "#EBF8FB";
      Object.assign(this.htmlDOM.style, this.style);
      this.htmlDOM.getElementsByClassName("delete")[0] ? this.htmlDOM.getElementsByClassName("delete")[0].setAttribute("class", 'delete') : "";
      this.renderPropsPanel(this.getPropsDesc(), this.getPropValues(), this.scope)
      // this.htmlDOM.dispatchEvent(new MouseEvent("click"))
    }
  }
  /**
   * 获取自身的属性名集合
   */
  getPropsDesc () {
    return {
      "base": ["myselfrows", "containerHeight", 'borderwidth']
    }
  }
  
  //校验特殊属性
  checkConProp(){
    if(this.propValues.borderwidth<0){
        alert('边框宽度不能为负数')
        return false;
    }
    if(this.propValues.containerHeight<0){
      alert('容器高度不能为负数')
      return false;
    }
    if(this.propValues.containerwidth<0){
      alert('容器宽度不能为负数')
      return false;
    }
    if(this.propValues.myselfrows<0){
      alert('自身占父级百分比不能为负数')
      return false;
    }
    return true;
  }
  /**
   * 获取自身的属性值集合
   */
  getPropValues () {
    return this.propValues;
  }
  //判断在allElement中是否有当前元素
  isHaveInAllElement (data) {
    let arr = window.formApp.allElements;
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].propValues.id == data) {
        return arr[i];
      }
    }
    return false;
  }
  /**
   * 判断在formpanel里是否有当前id元素
   * @param  data 
   */
  isHave (data, self = "") {
    let result = this.isHaveInAllElement(data);
    if (result) return result;
    if (self == "") self = window.formApp.formPanel;
    else self = this
    if (self.childs.length > 0) {
      for (let j = 0; j < self.childs.length; j++) {
        if (self.childs[j].scope == "container") {
          if (self.childs[j].propValues.id == data)
            return self.childs[j];
          else {
            let result = self.childs[j].isHave(data, 'self');
            if (result) return result;
          }

        }
      }
    }

    return false;
  }

  /**
   * 找容器上一级的id
   * @param {} data 
   */
  containerFather (data, self = "") {
    let result = this.isHaveInAllElement(data);
    if (result) return result;
    if (self == "") self = window.formApp.formPanel;
    else self = this
    if (self.childs.length > 0) {
      for (let j = 0; j < self.childs.length; j++) {
        if (self.childs[j].scope == "container") {
          if (self.childs[j].propValues.id == data)
            return self;
          else {
            return self.childs[j].containerFather(data, 'self');
          }

        }
      }
    }
    return self
  }

  /**
   * 移除当前容器的某个childs
   * @param {*} data 
   */
  remove (data) {
    let index = null;
    for (let i = 0; i < this.childs.length; i++) {
      if (this.childs[i].propValues.id == data) {
        index = i;
      }
    }
    let delElem = this.childs[index];
    if (index != null) {
      this.childs.splice(index, 1);
    }
    return delElem;

  }
  //添加元素
  addElement (elm) {
    if (this.panel.id == "formContainer") {
      this.htmlDOM.setAttribute("class", '');
    }
    if (this.setElem != null) {
      this.childs.splice(this.setElemIndex, 0, elm)
    } else {
      this.childs.push(elm);
    }
  }
  //将属性添加到dom中
  paint () {
    for (let propName in this.propValues) {
      this.htmlDOM.setAttribute(propName, this.propValues[propName]);
    }

    if (this.isChecked) {
      this.style["border-color"] = "#0DB3A6";
      this.style["background-color"] = "#EBF8FB";

    } else {
      this.style["border-color"] = "#000";
      this.style["background-color"] = "#fff";

    }
    Object.assign(this.htmlDOM.style, this.style);
    this.childs.forEach(elm => {
      elm.paint();
    });
  }
  //获取选中元素
  getChecked () {
    let currElem = null;
    for (let j = 0; j < this.childs.length; j++) {
      if (this.childs[j].isChecked) {
        currElem = this.childs[j];
        return currElem;
      } else {
        currElem = this.childs[j].getChecked();
      }
    }
    return currElem;
  }
  //重置childs的宽度
  resetElemWidth () {
    for (let i = 0; i < this.childs.length; i++) {
      let width = this.propValues.myselfrows;
      this.childs[i].setBasePropValues({ width: width })
    }
  }
  //初始化解析html
  parseHtml (htmlNode, panel) {
    let that = this;
    let root = htmlNode;
    const traversalNode = (htmlNode2) => {
      //这层的htmlnode2是formpanel进来的子节点了，可以开始解析了
      const tagName = htmlNode2.getAttribute("scope");
      switch (tagName) {
        case 'container':
          let con = new Container(panel)
          con.rendTo()
          this.setallAttribute(con, htmlNode2)
          this.addElement(con);
          if (con.htmlDOM.hasChildNodes()) {
            con.parseHtml(htmlNode2, con.htmlDOM)
          }
          con.renderHtml(con.style, 'style');
          con.renderHtml(con.propValues, 'prop')
          break;
        case 'inputField':
          let input = new InputField(that)
          input.creat()
          this.setallAttribute(input, htmlNode2)
          this.addElement(input);
          window.formApp.allElements.push(input);
          input.renderHtml(input.style, 'style');
          input.renderHtml(input.propValues, 'prop');
          input.renderHtml(input.propValues.id, 'fieldid')
          break;
        case 'textareaField':
          let textarea = new TextareaField(that)
          textarea.creat()
          this.setallAttribute(textarea, htmlNode2)
          this.addElement(textarea);
          window.formApp.allElements.push(textarea);
          textarea.renderHtml(textarea.style, 'style');
          textarea.renderHtml(textarea.propValues, 'prop');
          textarea.renderHtml(textarea.propValues.id, 'fieldid')
          break;
        case 'radioField':
          let radio = new RadioField(that)
          radio.creat()
          this.setallAttribute(radio, htmlNode2)
          this.addElement(radio);
          window.formApp.allElements.push(radio);
          radio.renderHtml(radio.style, 'style');
          radio.renderHtml(radio.propValues, 'prop');
          radio.renderHtml(radio.propValues.id, 'fieldid')
          break;
        case 'checkboxField':
          let checkbox = new CheckboxField(that)
          checkbox.creat()
          this.setallAttribute(checkbox, htmlNode2)
          this.addElement(checkbox);
          window.formApp.allElements.push(checkbox);
          checkbox.renderHtml(checkbox.style, 'style');
          checkbox.renderHtml(checkbox.propValues, 'prop');
          checkbox.renderHtml(checkbox.propValues.id, 'fieldid')
          break;
        case 'selectField':
          let select = new SelectField(that)
          select.creat()
          this.setallAttribute(select, htmlNode2)
          this.addElement(select);
          window.formApp.allElements.push(select);
          select.renderHtml(select.style, 'style');
          select.renderHtml(select.propValues, 'prop');
          select.renderHtml(select.propValues.id, 'fieldid')
          break;
        case 'dataField':
          let data = new DataField(that)
          data.creat()
          this.setallAttribute(data, htmlNode2)
          this.addElement(data);
          window.formApp.allElements.push(data);
          data.renderHtml(data.style, 'style');
          data.renderHtml(data.propValues, 'prop');
          data.renderHtml(data.propValues.id, 'fieldid')
          break;
        case 'deptField':
          let dept = new DeptField(that)
          dept.creat()
          this.setallAttribute(dept, htmlNode2)
          this.addElement(dept);
          window.formApp.allElements.push(dept);
          dept.renderHtml(dept.style, 'style');
          dept.renderHtml(dept.propValues, 'prop');
          dept.renderHtml(dept.propValues.id, 'fieldid')
          break;
        case 'treedepartmentField':
          let treedepartment = new TreedepartmentField(that)
          treedepartment.creat()
          this.setallAttribute(treedepartment, htmlNode2)
          this.addElement(treedepartment);
          window.formApp.allElements.push(treedepartment);
          treedepartment.renderHtml(treedepartment.style, 'style');
          treedepartment.renderHtml(treedepartment.propValues, 'prop');
          treedepartment.renderHtml(treedepartment.propValues.id, 'fieldid')

          break;
        case 'userField':
          let user = new UserField(that)
          user.creat()
          this.setallAttribute(user, htmlNode2)
          this.addElement(user);
          window.formApp.allElements.push(user);
          user.renderHtml(user.style, 'style');
          user.renderHtml(user.propValues, 'prop');
          user.renderHtml(user.propValues.id, 'fieldid')

          break;
        case 'selectaboutField':
          let selectabout = new SelectaboutField(that)
          selectabout.creat()
          this.setallAttribute(selectabout, htmlNode2)
          this.addElement(selectabout);
          window.formApp.allElements.push(selectabout);
          selectabout.renderHtml(selectabout.style, 'style');
          selectabout.renderHtml(selectabout.propValues, 'prop');
          selectabout.renderHtml(selectabout.propValues.id, 'fieldid')

          break;
        case 'suggestField':
          let suggest = new SuggestField(that)
          suggest.creat()
          this.setallAttribute(suggest, htmlNode2)
          this.addElement(suggest);
          window.formApp.allElements.push(suggest);
          suggest.renderHtml(suggest.style, 'style');
          suggest.renderHtml(suggest.propValues, 'prop');
          suggest.renderHtml(suggest.propValues.id, 'fieldid')
          break;
        case 'buttonField':
          let button = new ButtonField(that)
          button.creat()
          this.setallAttribute(button, htmlNode2)
          this.addElement(button);
          window.formApp.allElements.push(button);
          button.renderHtml(button.style, 'style');
          button.renderHtml(button.propValues, 'prop');
          button.renderHtml(button.propValues.id, 'fieldid')
          break;
        case 'viewdialogField':
          let viewdialog = new ViewdialogField(that)
          viewdialog.creat()
          this.setallAttribute(viewdialog, htmlNode2)
          this.addElement(viewdialog);
          window.formApp.allElements.push(viewdialog);
          viewdialog.renderHtml(viewdialog.style, 'style');
          viewdialog.renderHtml(viewdialog.propValues, 'prop');
          viewdialog.renderHtml(viewdialog.propValues.id, 'fieldid')
          break;
        case 'tabField':
          let tab = new TabField(that)
          tab.creat()
          this.setallAttribute(tab, htmlNode2)
          this.addElement(tab);
          window.formApp.allElements.push(tab);
          tab.renderHtml(tab.style, 'style');
          tab.renderHtml(tab.propValues, 'prop');
          tab.renderHtml(tab.propValues.id, 'fieldid')
          break;
        case 'calctextField':
          let calctext = new CalctextField(that)
          calctext.creat()
          this.setallAttribute(calctext, htmlNode2)
          this.addElement(calctext);
          window.formApp.allElements.push(calctext);
          calctext.renderHtml(calctext.style, 'style');
          calctext.renderHtml(calctext.propValues, 'prop');
          calctext.renderHtml(calctext.propValues.id, 'fieldid')
          break;

        case 'includeField':
          let include = new IncludeField(that)
          include.creat()
          this.setallAttribute(include, htmlNode2)
          this.addElement(include);
          window.formApp.allElements.push(include);
          include.renderHtml(include.style, 'style');
          include.renderHtml(include.propValues, 'prop');
          include.renderHtml(include.propValues.id, 'fieldid')
          break;
        case 'surveyField':
          let survey = new SurveyField(that)
          survey.creat()
          this.setallAttribute(survey, htmlNode2)
          this.addElement(survey);
          window.formApp.allElements.push(survey);
          survey.renderHtml(survey.style, 'style');
          survey.renderHtml(survey.propValues, 'prop');
          survey.renderHtml(survey.propValues.id, 'fieldid')
          break;
        case 'attachmentField':
          let attachment = new AttachmentField(that)
          attachment.creat()
          this.setallAttribute(attachment, htmlNode2)
          this.addElement(attachment);
          window.formApp.allElements.push(attachment);
          attachment.renderHtml(attachment.style, 'style');
          attachment.renderHtml(attachment.propValues, 'prop');
          attachment.renderHtml(attachment.propValues.id, 'fieldid')
          break;
        case 'kmdataField':
          let kmdata = new KmdataField(that)
          kmdata.creat()
          this.setallAttribute(kmdata, htmlNode2)
          this.addElement(kmdata);
          window.formApp.allElements.push(kmdata);
          kmdata.renderHtml(kmdata.style, 'style');
          kmdata.renderHtml(kmdata.propValues, 'prop');
          kmdata.renderHtml(kmdata.propValues.id, 'fieldid')
          break;
        case 'flowreminderhistoryField':
          let flowreminderhistory = new FlowreminderhistoryField(that)
          flowreminderhistory.creat()
          this.setallAttribute(flowreminderhistory, htmlNode2)
          this.addElement(flowreminderhistory);
          window.formApp.allElements.push(flowreminderhistory);
          flowreminderhistory.renderHtml(flowreminderhistory.style, 'style');
          flowreminderhistory.renderHtml(flowreminderhistory.propValues, 'prop');
          flowreminderhistory.renderHtml(flowreminderhistory.propValues.id, 'fieldid')
          break;
        case 'flowhistoryField':
          let flowhistory = new FlowhistoryField(that)
          flowhistory.creat()
          this.setallAttribute(flowhistory, htmlNode2)
          this.addElement(flowhistory);
          window.formApp.allElements.push(flowhistory);
          flowhistory.renderHtml(flowhistory.style, 'style');
          flowhistory.renderHtml(flowhistory.propValues, 'prop');
          flowhistory.renderHtml(flowhistory.propValues.id, 'fieldid')
          break;
        case 'htmleditorField':
          let htmleditor = new HtmleditorField(that)
          htmleditor.creat()
          this.setallAttribute(htmleditor, htmlNode2)
          this.addElement(htmleditor);
          window.formApp.allElements.push(htmleditor);
          htmleditor.renderHtml(htmleditor.style, 'style');
          htmleditor.renderHtml(htmleditor.propValues, 'prop');
          htmleditor.renderHtml(htmleditor.propValues.id, 'fieldid')
          break;
        case 'genericwordField':
          let genericword = new GenericwordField(that)
          genericword.creat()
          this.setallAttribute(genericword, htmlNode2)
          this.addElement(genericword);
          window.formApp.allElements.push(genericword);
          genericword.renderHtml(genericword.style, 'style');
          genericword.renderHtml(genericword.propValues, 'prop');
          genericword.renderHtml(genericword.propValues.id, 'fieldid')
          break;
        case 'mapField':
          let map = new MapField(that)
          map.creat()
          this.setallAttribute(map, htmlNode2)
          this.addElement(map);
          window.formApp.allElements.push(map);
          map.renderHtml(map.style, 'style');
          map.renderHtml(map.propValues, 'prop');
          map.renderHtml(map.propValues.id, 'fieldid')
          break;
        case 'qrcodeField':
          let qrcode = new QrcodeField(that)
          qrcode.creat()
          this.setallAttribute(qrcode, htmlNode2)
          this.addElement(qrcode);
          window.formApp.allElements.push(qrcode);
          qrcode.renderHtml(qrcode.style, 'style');
          qrcode.renderHtml(qrcode.propValues, 'prop');
          qrcode.renderHtml(qrcode.propValues.id, 'fieldid')
          break;
        case 'weixinrecordField':
          let weixinrecord = new WeixinrecordField(that)
          weixinrecord.creat()
          this.setallAttribute(weixinrecord, htmlNode2)
          this.addElement(weixinrecord);
          window.formApp.allElements.push(weixinrecord);
          weixinrecord.renderHtml(weixinrecord.style, 'style');
          weixinrecord.renderHtml(weixinrecord.propValues, 'prop');
          weixinrecord.renderHtml(weixinrecord.propValues.id, 'fieldid')
          break;
        case 'weixingpsField':
          let weixingps = new WeixingpsField(that)
          weixingps.creat()
          this.setallAttribute(weixingps, htmlNode2)
          this.addElement(weixingps);
          window.formApp.allElements.push(weixingps);
          weixingps.renderHtml(weixingps.style, 'style');
          weixingps.renderHtml(weixingps.propValues, 'prop');
          weixingps.renderHtml(weixingps.propValues.id, 'fieldid')
          break;
        case 'onlinetakephotoField':
          let onlinetakephoto = new OnlinetakephotoField(that)
          onlinetakephoto.creat()
          this.setallAttribute(onlinetakephoto, htmlNode2)
          this.addElement(onlinetakephoto);
          window.formApp.allElements.push(onlinetakephoto);
          onlinetakephoto.renderHtml(onlinetakephoto.style, 'style');
          onlinetakephoto.renderHtml(onlinetakephoto.propValues, 'prop');
          onlinetakephoto.renderHtml(onlinetakephoto.propValues.id, 'fieldid')
          break;
        case 'imageuploadField':
          let imageupload = new ImageuploadField(that)
          imageupload.creat()
          this.setallAttribute(imageupload, htmlNode2)
          this.addElement(imageupload);
          window.formApp.allElements.push(imageupload);
          imageupload.renderHtml(imageupload.style, 'style');
          imageupload.renderHtml(imageupload.propValues, 'prop');
          imageupload.renderHtml(imageupload.propValues.id, 'fieldid')
          break;
        case 'noField':
          let no = new NoField(that)
          no.creat()
          this.setallAttribute(no, htmlNode2)
          this.addElement(no);
          window.formApp.allElements.push(no);
          no.renderHtml(no.style, 'style');
          no.renderHtml(no.propValues, 'prop');
          no.renderHtml(no.propValues.id, 'fieldid')
          break;
        case 'splitField':
          let split = new SplitField(that)
          split.creat()
          this.setallAttribute(split, htmlNode2)
          this.addElement(split);
          window.formApp.allElements.push(split);
          split.renderHtml(split.style, 'style');
          split.renderHtml(split.propValues, 'prop');
          split.renderHtml(split.propValues.id, 'fieldid')
          break;
        default:
          break;
      }
    }

    if (root.hasChildNodes()) {
      for (let i = 0; i < root.children.length; i++) {
        traversalNode(root.children[i]);
      }
    }
  }
  //删除容器 
  /**
   * 
   * @param {当前遍历的容器对象} obj 
   * @param {要删除的容器节点id} id 
   * 这里从最外层容器formpanel开始遍历，如果删除的容器是formpanel的子节点，
   * 则返回index然后在调用该方法的地方进行删除，
   * 如果不是formpanrl的子节点，则对formpanel的子节点（有孩子）进行遍历，然后在这个方法中进行删除操作
   */
  delContainer (obj = null, id = null) {
    obj == null ? obj = window.formApp.formPanel : obj;
    id == null ? id = this.propValues.id : id;
    let index = null;
    for (let i = 0; i < obj.childs.length; i++) {
      if (obj.childs[i].propValues.id == id) {
        index = i;
        break;
      } else if (obj.childs[i].scope == 'container' && obj.childs[i].childs.length > 0) {
        index = obj.delContainer(obj.childs[i], id);
        if (index != null) {
          obj.childs[i].childs.splice(index, 1);
          obj.childs[i].htmlDOM.removeChild(this.htmlDOM);
          index = null;
        }
      }
    }
    return index

  }
  //重置id
  resetId () {
    this.propValues.id = Sequence.createUuid();
    this.renderHtml({ id: this.propValues.id }, 'prop');
    this.renderHtml(this.propValues.id, 'fieldid');
    this.childs.forEach(elm => {
      if (elm.scope == 'container') {
        elm.resetId();
      }
    })
  }

}
export default Container;