export default class TFPComponentRender {
	
	constructor(__tfp, _dataModel, _level) {
    if(!__tfp) {
      throw new Error("请提供tfp对象！");
      return;
    }
    if(!_dataModel) {
      throw new Error("请提供组件数据模型！");
      return;
    }
    
    this._tfp = __tfp;
    this.dataModel = _dataModel;
    this.metadata = this._tfp.type(this.dataModel.type);
    this.level = 0;  //组件相对页面组件的层次
    if(_level) this.level = _level;
  }

  get cpt() {
    return this._tfp.components[this.dataModel.id];
  }

  get isContainer() {
  	return this._tfp.components[this.dataModel.id].isContainer;
  }

  getHtmlIndent() {
    return this.cpt.getHtmlIndent();
  }

  getAttrHtml() {
    let attrHtml = "";
    let attrs = this.metadata.attrs;
    let arrAttr = [];
    for(let i=0;i<attrs.length;i++) {
      let attrInfo = attrs[i];
      if(attrInfo.type=="group") {
        for(let j=0;j<attrInfo.items.length;j++) {
          arrAttr.push(attrInfo.items[j]);
        }
      } else {
        arrAttr.push(attrInfo);
      }
    }
    for(let i=0;i<arrAttr.length;i++) {
      let attrInfo = arrAttr[i];
      if(attrInfo.isHtmlAttr && attrInfo.name in this.dataModel) {
        let attrVal = this.dataModel[attrInfo.name];
        if(!(attrVal || attrVal==0 || attrVal==false)) continue;
        //如果是特殊属性，则调用自定义方法获得属性html
        if(attrInfo.special && this.getCustomAttrHtml) {
          attrHtml += this.getCustomAttrHtml(attrInfo.name);
          continue;
        }
        //设计时组件不能禁用，否则无法点击获得焦点
        if(this._tfp.isDesigning && attrInfo.name=="disabled") continue;
        if(attrInfo.name=="disabled" || attrInfo.name=="readonly") {
          attrHtml += " "+attrInfo.name;
          if(attrVal==false || attrVal=="false") attrHtml += "=\"false\"";
        } else {
          //HTML标签的属性名必须小写
          attrHtml += " "+attrInfo.name.toLowerCase()+"=\""+this.dataModel[attrInfo.name]+"\"";
        }
      }
    }
    //事件
    if(!this._tfp.isDesigning && this.metadata.events) {
      for(var i=0;i<this.metadata.events.length;i++) {
        let eventInfo = this.metadata.events[i];
        //input type=text 的onchange事件在代码里修改值不会触发，需要在各个组件里处理
        //页面加载事件不能直接写在body标签的属性里，因为需要等tfp组件解析完毕
        if(eventInfo.name.toLowerCase()=="onchange" || 
          (this.cpt.type=="Page" && eventInfo.name.toLowerCase()=="onload")) continue;
        for(let propName in this.dataModel) {
          //事件名称忽略大小写
          if(eventInfo.name.toLowerCase()==propName.toLowerCase()) {
            let eventFunc = this.dataModel[propName];
            if(eventFunc.indexOf("(")<0 || eventFunc.indexOf(")")<0) eventFunc += "()";
            attrHtml += " "+eventInfo.name.toLowerCase()+"=\""+eventFunc+"\"";
            break;
          }
        }
      }
    }
    return attrHtml;
  }

  getStyleHtml(isGetHead, retainStyleAttr) {
    let styleHtml = "";
    if(this.dataModel.styles) {
      for(let styleName in this.dataModel.styles) {
        styleHtml += " "+styleName+":"+this.dataModel.styles[styleName]+";";
      }
    }
    if(this.dataModel.style) styleHtml += this.dataModel.style;
    if(this.getCustomStyleHtml) styleHtml += this.getCustomStyleHtml();
    
    if(this._tfp.isDesigning) {
      styleHtml += "user-select:none;";
      
      //设计时，如果容器组件没有设置边框，则为其添加一个轮廓线，以便查看
      //不能直接设置border样式，因为会造成面板组件的内容宽度和高度与实际不一致
      //导致设计时可能会出现滚动条，而实际运行时没有
      if((this.isContainer || this.dataModel.components) 
        && styleHtml.indexOf("border:")<0 
        && styleHtml.indexOf("border-width:")<0) 
        styleHtml += "outline:#cccccc dashed 1px;";
    }

    //如果是在后台编译时获得样式信息，则将组件样式抽取到页面头部style标签中，以便统一查看
    if(isGetHead) {
      //
    } else if(this._tfp.isDesigning || retainStyleAttr) {
      styleHtml = " style=\""+styleHtml+" \"";
    } else {
      styleHtml = "";
    }
    return styleHtml;
  }

  getComponentsHtml(getComponentsHtml, indent, retainStyleAttr) {
    let html = "";
    if(!indent) indent = "";
    for(var i=0;i<this.dataModel.components.length;i++) {
      let cdm = this.dataModel.components[i];
      let Render = this._tfp.renders[cdm.type];
      if(!Render) continue;
      let render = new Render(this._tfp, cdm, this.level+1);
      html += render.getHtml(getComponentsHtml, indent, retainStyleAttr);
    }
    return html;
  }

  getHtml(tagName, getComponentsHtml, parentIndent, retainStyleAttr) {
    if(!tagName) return "";
    let indent = this.getHtmlIndent();
    //有些容器组件由多级html元素构成，他们子组件的代码缩进
    //需要根据父组件的容器元素的代码缩进进行相应的增加
    if(parentIndent) {
      indent = parentIndent+"\t";
      this.indent = indent;
    }
    let cptHtml = indent+"<"+tagName+" id=\""+this.dataModel.id
      +"\" class=\"tfp-"+this.dataModel.type.toLowerCase().replace("_", "-");
    if(this.getSpecialClass) cptHtml += this.getSpecialClass();
    if(this.dataModel.class) cptHtml += " "+this.dataModel.class;
    cptHtml += "\""+this.getAttrHtml()+this.getStyleHtml(false, retainStyleAttr);
    if(this.getBodyHtml) {
      cptHtml += ">";
      cptHtml += this.getBodyHtml(getComponentsHtml, retainStyleAttr);
      cptHtml += "</"+tagName+">\r\n";
    } else if(this.isContainer || this.dataModel.components) {
      cptHtml += ">\r\n";
      if(getComponentsHtml && this.dataModel.components) {
        cptHtml += this.getComponentsHtml(getComponentsHtml, indent, retainStyleAttr);
      }
      cptHtml += indent+"</"+tagName+">\r\n";
    } else {
      cptHtml += "/>\r\n";
    }
    //if(this.dataModel.type=="Button") console.log(cptHtml);
    return cptHtml;
  }
}