import {VisibleComponent} from "../controller.js";

/**
 * 数据集组件
 * @param {[type]} dataModel [description]
 */
export default class DataSet extends VisibleComponent {

  constructor(__tfp, dataModel, parent) {
    super(__tfp, "DataSet", dataModel, parent);

    if(this._tfp.isDesigning && (!this.dataModel.columns || this.dataModel.columns.length==0)) {
      //默认创建1行3列
      this.dataModel.columns = [{
        id: "col1",
        name: "第1列",
        type: "text",
        width: "60px"
      },{
        id: "col2",
        name: "第2列",
        type: "text",
        width: "60px"
      },{
        id: "col3",
        name: "第3列",
        type: "text",
        width: "60px"
      }];
    }
  }

  //属性
  get loadDataService() { return this.dataModel.loadDataService }
  set loadDataService(value) {this.dataModel.loadDataService = value }

  //属性
  get dataBindingMember() { return this.dataModel.dataBindingMember }
  set dataBindingMember(value) {this.dataModel.dataBindingMember = value }

  get columns() { return this.dataModel.columns }
  set columns(value) { 
    this.dataModel.columns = value;
    if(this._jqObj) {
      this.reRenderBody();
    }
  }

  get rows() { return this.getRows({checkRequired: false}); }
  set rows(value) { 
    this.dataModel.rows = value;
    if(this._jqObj) {
      this.reRenderBody();
    }
  }

  get keyCol() { return this.dataModel.keyCol }
  set keyCol(value) { 
    this.dataModel.keyCol = value;
    if(this._jqObj) {
      //
    }
  }

  get showAddButton() { return this.dataModel.showAddButton }
  set showAddButton(value) { 
    this.dataModel.showAddButton = value ? true : false;
    if(this._jqObj) {
      if(this.dataModel.showAddButton) {
        $(".tfp-dataset-header").css("height", "70px");
        $(".tfp-dataset-list").css("top", "71px");
        $(".tfp-dataset-toolbar").show();
        $(".tfp-dataset-button-add").show();
      } else {
        $(".tfp-dataset-button-add").hide();
        if(!this.dataModel.showAddFromDialogButton) {
          $(".tfp-dataset-toolbar").hide();
          $(".tfp-dataset-header").css("height", "30px");
          $(".tfp-dataset-list").css("top", "31px");
        }
      }
    }
  }

  get addButtonText() { 
    if(!this.dataModel.addButtonText) this.dataModel.addButtonText = "添加";
    return this.dataModel.addButtonText;
  }
  set addButtonText(value) { 
    this.dataModel.addButtonText = value;
    if(this._jqObj) {
      $(".tfp-dataset-button-add").html(value);
    }
  }

  get showAddFromDialogButton() { return this.dataModel.showAddFromDialogButton }
  set showAddFromDialogButton(value) { 
    this.dataModel.showAddFromDialogButton = value ? true : false;
    if(this._jqObj) {
      if(this.dataModel.showAddFromDialogButton) {
        $(".tfp-dataset-header").css("height", "70px");
        $(".tfp-dataset-list").css("top", "71px");
        $(".tfp-dataset-toolbar").show();
        $(".tfp-dataset-button-add-from-dialog").show();
      } else {
        $(".tfp-dataset-button-add-from-dialog").hide();
        if(!this.dataModel.showAddButton) {
          $(".tfp-dataset-toolbar").hide();
          $(".tfp-dataset-header").css("height", "30px");
          $(".tfp-dataset-list").css("top", "31px");
        }
      }
    }
  }

  get addFromDialogButtonText() { 
    if(!this.dataModel.addFromDialogButtonText) this.dataModel.addFromDialogButtonText = "弹窗选择";
    return this.dataModel.addFromDialogButtonText;
  }
  set addFromDialogButtonText(value) { 
    this.dataModel.addFromDialogButtonText = value;
    if(this._jqObj) {
      $(".tfp-dataset-button-add-from-dialog").html(value);
    }
  }

  get addFromDialogPath() { return this.dataModel.addFromDialogPath }
  set addFromDialogPath(value) { 
    this.dataModel.addFromDialogPath = value;
  }

  get showCheckbox() { return this.dataModel.showCheckbox }
  set showCheckbox(value) { 
    this.dataModel.showCheckbox = value ? true : false;
    if(this._jqObj) {
      this.reRenderBody();
    }
  }

  get enableDelete() { return this.dataModel.enableDelete }
  set enableDelete(value) { 
    this.dataModel.enableDelete = value ? true : false;
    if(this._jqObj) {
      this.reRenderBody();
    }
  }

  reRenderBody() {
    this._jqObj.empty();
    this._jqObj.append(this.getBodyHtml());
  }

  getBodyHtml() {
    let indent = this.getHtmlIndent();
    let headerHeight = 30;
    let showToolBar = false;
    if(this.dataModel.showAddButton 
      || this.dataModel.showAddFromDialogButton) {
      showToolBar = true;
      headerHeight = 70;
    }
    let html = indent+"\t<div class=\"tfp-dataset-header\" style=\"height:"+headerHeight+"px;\">\r\n";
    html += indent+"\t\t<div class=\"tfp-dataset-toolbar\"";
    if(!showToolBar) html += " style=\"display:none;\"";
    html += ">\r\n";
    html += indent+"\t\t\t<div class=\"tfp-dataset-button-add\"";
    if(!this.dataModel.showAddButton) html += " style=\"display:none;\"";
    html += ">"+this.addButtonText+"</div>\r\n"; 
    html += indent+"\t\t\t<div class=\"tfp-dataset-button-add-from-dialog\"";
    if(!this.dataModel.showAddFromDialogButton) html += " style=\"display:none;\"";
    html += ">"+this.addFromDialogButtonText+"</div>\r\n"; 
    html += indent+"\t\t</div>\r\n";
    html += indent+"\t\t<div class=\"tfp-dataset-titlerow\" style=\"width:{rowWidth};\">\r\n";
    var rowWidth = 6;
    if(this.dataModel.enableDelete) rowWidth += 30;
    if(this.dataModel.columns) {
      if(this.dataModel.showCheckbox) {
        rowWidth += 24;
        html += indent+"\t\t\t<div style=\"width:24px; text-align: center;\">"
          +"<input type=\"checkbox\" class=\"tfp-checkbox tfp-dataset-checkall\" "
          +"style=\"margin-top:7px;\" onclick=\""
          +this.id+".checkAllOnClick(this)\" /></div>\r\n";
      }
      for(let i=0;i<this.dataModel.columns.length;i++) {
        let col = this.dataModel.columns[i];
        html += indent+"\t\t\t<div";
        if(col.width) {
          html += " style='width:"+col.width+";'";
          rowWidth += parseInt((col.width+'').replace("px", ""));
        } else {
          if(col.type=="switch") {
            html += " style='width:40px;'";
            rowWidth += 40;
          } else {
            html += " style='width:100px;'";
            rowWidth += 100;
          }
        }
        let colName = col.id;
        if(col.name) colName = col.name;
        html += ">"+colName+"</div>\r\n";
      }
    }
    html = html.replace("{rowWidth}", (rowWidth+6)+"px");
    html += indent+"\t\t</div>\r\n";
    html += indent+"\t</div>\r\n";
    html += indent+"\t<div class=\"tfp-dataset-list\" style=\"top:"+(headerHeight+1)+"px;\">\r\n";
    if(this.dataModel.columns) {
      if(this.dataModel.rows && this.dataModel.rows.length>0) {
        for(var i=0;i<this.dataModel.rows.length;i++) {
          html += this.getRowHtml(this.dataModel.rows[i], indent, rowWidth);
        }
      } else if(this._tfp.isDesigning) {
        //设计时添加三行空行
        html += this.getRowHtml(null, indent, rowWidth);
        html += this.getRowHtml(null, indent, rowWidth);
        html += this.getRowHtml(null, indent, rowWidth);
      }
    }
    html += indent+"\t</div>\r\n";
    return html;
  }

  getRowWidth() {
    var rowWidth = 6;
    if(this.dataModel.enableDelete) rowWidth += 30;
    if(this.dataModel.columns) {
      if(this.dataModel.showCheckbox) rowWidth += 30;
      for(let i=0;i<this.dataModel.columns.length;i++) {
        let col = this.dataModel.columns[i];
        if(col.width) {
          rowWidth += parseInt((col.width+'').replace("px", ""));
        } else {
          if(col.type=="switch") {
            rowWidth += 40;
          } else {
            rowWidth += 100;
          }
        }
      }
    }
    return rowWidth;
  }

  /**
   * 添加数据集行
   * @param {[type]} data [description]
   */
  getRowHtml(rowData, indent, rowWidth) {
    if(!this.dataModel.columns) return "";
    var htmlStr = indent+"\t\t<div class=\"tfp-dataset-row\" "
      +"style=\"width:"+ this._tfp.formatPx(rowWidth) +";\">\r\n";
    if(this.dataModel.showCheckbox) {
      htmlStr += indent+"\t\t\t<div style=\"width:24px; text-align: center;\">"
        +"<input type=\"checkbox\" class=\"tfp-checkbox tfp-dataset-checkbox\" "
        +"style=\"margin-top:6px;\" /></div>\r\n";
    }
    for(var i=0;i<this.dataModel.columns.length;i++) {
      let col = this.dataModel.columns[i];
      htmlStr += indent+"\t\t\t<div style=\"";
      if(col.hidden) htmlStr += "display:none;";
      if(col.width) {
        htmlStr += "width:"+this._tfp.formatPx(col.width)+";";
      } else {
        if(col.type=="switch") {
          htmlStr += "width:40px;";
        } else {
          htmlStr += "width:100px;";
        }
      }
      htmlStr += "\"";
      if(this.dataModel.cellOnDoubleClick) 
        htmlStr += " ondblclick='"+this.dataModel.cellOnDoubleClick+"'";
      htmlStr += ">";
      if(col.type=="select" && !col.readonly) {
        htmlStr += "<select>";
        if(!col.required) htmlStr += "<option value=\"\"></option>";
        if(col.options) {
          let options = [];
          if(Array.isArray(col.options)) {
            for(var j=0;j<col.options.length;j++) {
              let option = col.options[j];
              if(typeof(option)=="string") {
                options.push({value:option});
              } else if(Object.prototype.toString.call(option) === '[object Object]') {
                options.push(option);
              }
            }
          } else if(typeof(col.options)=="string") {
            let arr = (col.options+'').split(",");
            for(var j=0;j<arr.length;j++) {
              options.push({value:arr[j]});
            }
          }
          for(var j=0;j<options.length;j++) {
            let option = options[j];
            htmlStr += "<option value='"+option.value+"'";
            if((rowData && rowData[col.id]==option.value) 
              || (col.default==option.value && (!rowData || !rowData[col.id]))) 
              htmlStr += " selected";
            let text = option.value;
            if(option.text) text = option.text;
            htmlStr += ">"+text+"</option>";
          }
        }
        htmlStr += "</select>";
      } else if(col.type=="switch" && !col.readonly) {
        let checked = false;
        if((rowData && (rowData[col.id]+"")=="true")
          ||(col.default && (!rowData || isNull(rowData[col.id])))) 
          checked = true;
        htmlStr += "<div class=\"switch\" value=\""+checked+"\" style=\"height: 16px;\"";
        if(this._tfp.isRuntime) htmlStr += " onclick=\""+this.id+".switchOnClick(this)\"";
        htmlStr += ">";
        htmlStr += "<div";
        if(checked) htmlStr += " style=\"float: right; background-color:#0099ff;\"";
        htmlStr += "></div>";
        htmlStr += "</div>";
      } else {
        let iptType = "text";
        if(col.type=="int") {
          iptType = "number";
        } else if(col.type=="password") {
          iptType = "password";
        }
        htmlStr += "<input type=\""+iptType+"\"";
        //if(col.onchange) htmlStr += " onchange='"+col.onchange+"'";
        if(this._tfp.isDesigning || col.readonly) htmlStr += " readonly";
        if(col.readonly && this._tfp.curPage.bgColorMode=="light") 
          htmlStr += " style=\"background-color:#EEEEEE;\"";
        let cellValue = "";
        if(rowData && !isNull(rowData[col.id])) {
          cellValue = rowData[col.id];
        } else if(col.default) {
          cellValue = col.default;
        }
        if(typeof(cellValue)=="string" && cellValue.indexOf("\"")>=0) {
          htmlStr += " value='"+cellValue+"'";
        } else {
          htmlStr += " value=\""+cellValue+"\"";
        }
        htmlStr += " />";
      }
      htmlStr += "</div>\r\n";
    }
    let delIconUrl = this._tfp.rootPath+"/src/components/dataset/images/delete-blue-24.png";
    if(this.dataModel.enableDelete) {
      htmlStr += indent+"\t\t\t<div style=\"width:30px;\">"
        +"<img src='"+delIconUrl+"' title=\"删除\"";
      if(this._tfp.isRuntime) htmlStr += " onclick=\""+this.id+".deleteRow(this)\"";
      htmlStr += " /></div>\r\n";
    }
    htmlStr += indent+"\t\t</div>\r\n";
    return htmlStr;
  }

  bindEventHandler() {
    var divHeader = this._jqObj.find(".tfp-dataset-header").get(0);
    var divDataList = this._jqObj.find(".tfp-dataset-list").get(0);
    divDataList.scrollTop = 0;
    divDataList.addEventListener('scroll', function(){
      divHeader.scrollLeft = divDataList.scrollLeft;
    });
  }

  switchOnClick(divSwitch) {
    if($(divSwitch).find("div").css("float")=="left") {
      $(divSwitch).find("div").css("float", "right");
      $(divSwitch).find("div").css("background-color", "#0099ff");
      $(divSwitch).attr("value", "true");
    } else {
      $(divSwitch).find("div").css("float", "left");
      if(this._tfp.curPage.bgColorMode=="dark") {
        $(divSwitch).find("div").css("background-color", "#666666");
      } else {
        $(divSwitch).find("div").css("background-color", "#999999");
      }
      $(divSwitch).attr("value", "false");
    }
  }

  exeFormula(colR, rowData, curRowDiv, colIndex) {
    let colRFormula = this._tfp.replaceDataField(rowData, colR.formula);
    var formulaVal = null;
    try {
      formulaVal = eval(colRFormula);
    } catch(error) {
      console.error(error.message);
      return;
    }
    if(colR.type=="text" && colR.dataType!="text") {
      if(colR.dataType=="int") {
        formulaVal = parseInt(formulaVal);
      } else if(colR.dataType=="float") {
        formulaVal = parseFloat(formulaVal);
      } else if(colR.dataType=="money") {
        formulaVal = this._tfp.formatMoney(formulaVal);
      }
    }
    var colRDivIndex = colIndex;
    if (this.dataModel.showCheckbox) colRDivIndex++;
    curRowDiv.children().eq(colRDivIndex).find("input").val(formulaVal);
    this._tfp.iptValueOnChange(this);
  }

  addNewRow(data) {
    let rowWidth = this.getRowWidth();
    let indent = this.getHtmlIndent();
    let rowHtml = this.getRowHtml(data, indent+"\t\t", rowWidth);
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.append(rowHtml);
    var lastRow = dataList.find(".tfp-dataset-row").last();
    if(lastRow.find("input").length>0) {
      lastRow.find("input").eq(0).focus();
    } else if(lastRow.find("select").length>0) {
      lastRow.find("select").eq(0).focus();
    }
    
    let that = this;
    for(var i=0;i<this.dataModel.columns.length;i++) {
      let col = this.dataModel.columns[i];
      //如果当前列设置了值改变后需要执行的脚本
      //或者，与其他列存在计算关系
      if(!col.readonly && (col.onchange || (this.calcCols && this.calcCols[col.id]))) {
        let colDivIndex = i;
        if(this.dataModel.showCheckbox) colDivIndex++;
        lastRow.children().eq(colDivIndex).find("input").blur(function() {
          if(col.onchange) {
            try {
              eval(col.onchange);
            } catch(error) {
              console.error(error);
            }
          }
          if(that.calcCols && that.calcCols[col.id]) {
            //获得当前行的数据
            let curRowDiv = $(this).parent().parent();
            let rowIndex = curRowDiv.index();
            let rowData = that.getRow(rowIndex, {autoFormat: true}).row;
            var arr = that.calcCols[col.id];
            for(var j=0;j<arr.length;j++) {
              for(var k=0;k<that.dataModel.columns.length;k++) {
                var colR = that.dataModel.columns[k];
                if(arr[j]==colR.id && colR.formula) {
                  that.exeFormula(colR, rowData, curRowDiv, k);
                  break;
                }
              }
            }
          }
        });
      }
    }
  }

  deleteRow(img) {
    $(img).parent().parent().remove();
    if(this.dataModel.onRemoveRow) eval(this.dataModel.onRemoveRow);
  }

  checkAllOnClick(cbk) {
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-checkbox").each(function() {
      $(this).get(0).checked = cbk.checked;
    });
  }

  checkAll() {
    if(!this.dataModel.showCheckbox) return;
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-checkbox").each(function() {
      $(this).get(0).checked = true;
    });
  }

  unCheckAll() {
    if(!this.dataModel.showCheckbox) return;
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-checkbox").each(function() {
      $(this).get(0).checked = false;
    });
  }

  checkRows(keys) {
    if(!this.dataModel.showCheckbox || !this.dataModel.keyCol || !keys) return;
    if(typeof(keys) == "string") keys = keys.split(",");
    let keyColIndex = 0;
    for(var i=0;i<this.dataModel.columns.length;i++) {
      let col = this.dataModel.columns[i];
      if(col.id==this.dataModel.keyCol) {
        keyColIndex = i+1;
        break;
      }
    }
    if(keyColIndex==0) return;
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-row").each(function() {
      let keyColDiv = $(this).children("div").eq(keyColIndex);
      let key = keyColDiv.find("input").val();
      if(keys.contains(key)) $(this).find(".tfp-dataset-checkbox").get(0).checked = true;
    });
  }

  getCheckedRows(cb) {
    if(cb) {
      this.getRows({onlyGetChecked: true, checkRequired: true}, cb);
      return;
    }
    return this.getRows({onlyGetChecked: true, checkRequired: true});
  }

  getRow(index, options) {
    let checkRequired = false;
    let onlyGetChecked = false;
    let autoFormat = false;
    if(options) {
      if(options.checkRequired) checkRequired = true;
      if(options.onlyGetChecked) onlyGetChecked = true;
      if(options.autoFormat) autoFormat = true;
    }
    let dataList = this._jqObj.find(".tfp-dataset-list");
    let rowDiv = dataList.find(".tfp-dataset-row").eq(index);
    let row = {};
    let checked = false;
    if(this.dataModel.showCheckbox && rowDiv.find(".tfp-dataset-checkbox").get(0).checked) {
      checked = true;
      row.checked = true;
    }
    if(onlyGetChecked && !checked) return {
      row: null,
      isCheckOk: true
    };
    for(var i=0;i<this.dataModel.columns.length;i++) {
      let col = this.dataModel.columns[i];
      let index = i;
      if(this.dataModel.showCheckbox) index++;
      let val = null;
      let colDiv = rowDiv.children("div").eq(index);
      if(col.type=="text"||col.type=="password"||col.type=="number") {
        val = colDiv.find("input").val();
      } else if(col.type=="select") {
        val = colDiv.find(col.type).val();
      } else if(col.type=="switch") {
        val = false;
        if(colDiv.find(".switch").attr("value")=="true") val = true;
      }
      if(val=="") {
        if(col.required && checkRequired) {
          let colName = col.id;
          if(col.name) colName = col.name;
          this._tfp.showMsg(colName+"不能为空！");
          if(col.type=="text" || col.type=="select" || col.type=="password" || col.type=="number") {
            colDiv.find(col.type).focus();
          }
          return {
            row: null,
            isCheckOk: false
          };
        } else {
          if(col.type=="text" && autoFormat && col.dataType!="text") {
            if(col.dataType=="int") {
              val = 0;
            } else {
              val = 0.00;
            }
          }
        }
      } else {
        if(col.type=="text" && autoFormat && col.dataType!="text") {
          if(col.dataType=="int") {
            val = parseInt(val);
          } else {
            val = parseFloat(val);
          }
        }
        row[col.id] = val;
      }
    }
    return {
      row: row,
      isCheckOk: true
    };
  }

  getRows(options, cb) {
    let checkRequired = false;
    let onlyGetChecked = false;
    if(options) {
      if(options.checkRequired) checkRequired = true;
      if(options.onlyGetChecked) onlyGetChecked = true;
    }
    if(onlyGetChecked && !this.dataModel.showCheckbox) return [];
    let that = this;
    let rows = [];
    let isCheckOk = true; 
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-row").each(function(index) {
      let ret = that.getRow(index, options);
      if(!ret.isCheckOk) {
        isCheckOk = false;
        return false;
      }
      if(ret.row) rows.push(ret.row);
    });
    if(!isCheckOk) return;
    if(cb) {
      cb(rows);
    } else {
      return rows;
    }
  }

  /**
   * 求指定列的合计值
   * @param  {[type]} colName [description]
   * @return {[type]}         [description]
   */
  sum(colId) {
    let ret = 0;
    let colIndex = 0;
    let dataType = "text";
    for(var i=0;i<this.columns.length;i++) {
      let col = this.columns[i];
      if(col.id==colId) {
        colIndex = i;
        if(this.dataModel.showCheckbox) colIndex++;
        if(col.dataType) dataType = col.dataType;
        break;
      }
    }
    let that = this;
    let dataList = this._jqObj.find(".tfp-dataset-list");
    dataList.find(".tfp-dataset-row").each(function(index) {
      let cellVal = $(this).children().eq(colIndex).find("input").val().trim().replaceAll(",", "");
      if(cellVal!="") {
        if(dataType=="int") {
          if(isInt(cellVal)) ret += parseInt(cellVal);
        } else if(!isNaN(cellVal)) {
          ret += parseFloat(cellVal);
        }
      }
    });
    if(dataType=="money") {
      ret = this._tfp.formatMoney(ret);
    }
    return ret;
  }

  initRuntime() {
    let that = this;
    $(".tfp-dataset-button-add").click(function() {
      that.addNewRow();
    });

    $(".tfp-dataset-button-add-from-dialog").click(function() {
      if(isNull(that.dataModel.addFromDialogPath)) {
        that._tfp.showMsg("请设置弹窗页面路径！");
        return;
      }
      let width = "640px";
      let height = "480px";
      if(that.dataModel.addFromDialogWidth) width = that.dataModel.addFromDialogWidth+"";
      if(width.indexOf("px")<0) width += "px";
      if(that.dataModel.addFromDialogHeight) height = that.dataModel.addFromDialogHeight+"";
      if(height.indexOf("px")<0) height += "px";
      that._tfp.openDialog(that.dataModel.addFromDialogButtonText, 
        that.dataModel.addFromDialogPath, width, height, null, function(ret) {
          if(ret) {
            if(Array.isArray(ret)) {
              for(let i=0;i<ret.length;i++) {
                that.addNewRow(ret[i]);
              }
            } else {
              that.addNewRow(ret);
            }
          }
        });
    });

    //设置计算列关联的列，以便当关联列的数据发生变化时，自动执行计算列的值
    if(this.dataModel.columns) {
      //存在关联计算的列
      this.calcCols = {};
      for(var i=0;i<this.dataModel.columns.length;i++) {
        let col = this.dataModel.columns[i];
        //如果是计算列
        if(col.formula) {
          let arr = col.formula.match(/\{[\w]+\}/g);
          if(arr.length>0) {
            for(var j=0;j<arr.length;j++) {
              for(var k=0;k<this.dataModel.columns.length;k++) {
                let colR = this.dataModel.columns[k];
                //如果当前列与计算列有关联，则标示为计算关联列
                if(("{"+colR.id+"}")==arr[j]) {
                  if(!this.calcCols[colR.id]) {
                    this.calcCols[colR.id] = [];
                  }
                  if(!this.calcCols[colR.id].contains(col.id)) 
                    this.calcCols[colR.id].push(col.id);
                }
              }
            }
          }
        }
      }
    }
  }
}