
function TFPUIDesigner() {
	var that = this;

	this.curSelectedCptId = null;  //当前选中的组件，默认为当前页面
	this.selectedCpts = [];  //选中的组件列表
	this.curCptNodeId = null;   //当前选中的组件节点编号
	this.curOptionBarIndex = {
		LeftBar: 0,
		RightBar: 0
	};
	this.pageFrameWin = null;
	this.curBorderStyleEl = null;
	this.curCursorStyleEl = null;
	this.Components = {};

	this.getCurCpt = function() {
		if(this.selectedCpts.length>0 || !this.curSelectedCptId) return null;
		return tfp.components[this.curSelectedCptId];
	}

	this.getToolBarWidth = function() {
		let width = 0;
		$("#uiToolBarContainer").find(".toolbar-col").each(function() {
			if($(this).is(":visible")) width += $(this).outerWidth();
		});
		return width;
	}

	this.toolBarScrollLeft = function() {
		let toolBar = $("#uiToolBar");
		let scrollLeft = toolBar.get(0).scrollLeft;
		if(scrollLeft==0) return;
		scrollLeft -= 30;
		if(scrollLeft<0) scrollLeft = 0;
		toolBar.get(0).scrollLeft = scrollLeft;
	}

	this.toolBarScrollRight = function() {
		let toolBar = $("#uiToolBar");
		let toolBarContainerWidth = this.getToolBarWidth();
		let toolBarWidth = toolBar.width();
		if(toolBarContainerWidth<=toolBarWidth) return;
		let scrollLeft = toolBar.get(0).scrollLeft;
		scrollLeft += 30;
		if(scrollLeft>(toolBarContainerWidth-toolBarWidth)) 
			scrollLeft = toolBarContainerWidth-toolBarWidth;
		toolBar.get(0).scrollLeft = scrollLeft;
	}

	this.toggleToolBarCol = function(type, text) {
		var el = $('#styleSetting_'+type+'_ex');
		el.toggle();
		var uiToolBarContainer = $("#uiToolBarContainer");
		if(el.is(':visible')) {
			$("#styleSetting_"+type+"_more").find("img").attr("src", "images/arrow_left_white.png");
			$("#styleSetting_"+type+"_more").attr("title", "隐藏更多"+text+"设置");
			uiToolBarContainer.css("width", uiToolBarContainer.width()+el.outerWidth());
		} else {
			$("#styleSetting_"+type+"_more").find("img").attr("src", "images/arrow_right_white.png");
			$("#styleSetting_"+type+"_more").attr("title", "显示更多"+text+"设置");
			uiToolBarContainer.css("width", uiToolBarContainer.width()-el.outerWidth());
		}
		this.onResize();
	}

	this.showWidthType = function() {
		tfpDesigner.showPopMenu({
			width: "120px", 
			showIcon: true,
			items: [{
				value: "width",
				text: "宽度",
				icon: "images/width.png"
			},{
				value: "max-width",
				text: "最大宽度",
				icon: "images/max_width.png"
			},{
				value: "min-width",
				text: "最小宽度",
				icon: "images/min_width.png"
			}], 
			value: $("[data-type='width-type']").attr("data-value")
		}, function(val, text) {
			$("[data-type='width-type']").find("img").eq(0).attr("src", 
				"images/"+(val.replace("-", "_"))+".png");
			$("[data-type='width-type']").attr("data-value", val);
			$("input[style-setting-id=width]").val("");
			$("select[style-setting-id=width]").val("px");
			if(that.selectedCpts.length>0) return;
			let cpt = tfp.components[that.curSelectedCptId];
			if(!cpt) return;
			let width = cpt.css(val);
			if(width) {
				width += "";
				$("input[style-setting-id=width]").val(width.replace("px", ""));
				if(width.indexOf("%")>0) $("select[style-setting-id=width]").val("%");
			}
		});
	}

	this.showHeightType = function() {
		tfpDesigner.showPopMenu({
			width: "120px", 
			showIcon: true,
			items: [{
				value: "height",
				text: "高度",
				icon: "images/height.png"
			},{
				value: "max-height",
				text: "最大高度",
				icon: "images/max_height.png"
			},{
				value: "min-height",
				text: "最小高度",
				icon: "images/min_height.png"
			}], 
			value: $("[data-type='height-type']").attr("data-value")
		}, function(val, text) {
			$("[data-type='height-type']").find("img").eq(0).attr("src", 
				"images/"+(val.replace("-", "_"))+".png");
			$("[data-type='height-type']").attr("data-value", val);
			$("input[style-setting-id=height]").val("");
			$("select[style-setting-id=height]").val("px");
			if(that.selectedCpts.length>0) return;
			let cpt = that.getCurCpt();
			if(!cpt) return;
			let height = cpt.css(val);
			if(height) {
				height += "";
				if(height.indexOf("%")>0) $("select[style-setting-id=height]").val("%");
				$("input[style-setting-id=height]").val(height.replace("px", "").replace("%", ""));
			}
		});
	}

	this.showFloatType = function() {
		tfpDesigner.showPopMenu({
			width: "130px", 
			showIcon: true,
			items: [{
				value: "none",
				text: "不浮动",
				icon: "images/float_none.png"
			},{
				value: "left",
				text: "向左浮动",
				icon: "images/float_left.png"
			},{
				value: "right",
				text: "向右浮动",
				icon: "images/float_right.png"
			}], 
			value: $("[style-setting-id='float']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='float']").attr("style-setting-value", val);
			$("[style-setting-id='float']").find("img").eq(0).attr("src", "images/float_"+val+".png");
			that.setSelectedCptStyle("float", val=="none" ? "" : val);
			if(val!="none") {
				that.setSelectedCptStyle("position", "");
				that.setSelectedCptStyle("z-index", "");
				that.setSelectedCptStyle("top", "");
				that.setSelectedCptStyle("bottom", "");
				that.setSelectedCptStyle("left", "");
				that.setSelectedCptStyle("bottom", "");
				that.setSelectedCptStyle("display", "");
				$("input[style-setting-id=top]").val("");
				$("input[style-setting-id=left]").val("");
			}
		});
	}

	this.showDisplayType = function() {
		let _display = "";
		let cpt = this.getCurCpt();
		if(cpt && cpt.css("display")) _display = cpt.css("display");
		tfpDesigner.showPopMenu({
			width: "140px", 
			items: [{
				value: "",
				text: "默认"
			},{
				value: "none",
				text: "不显示"
			},{
				value: "inline",
				text: "显示为内联元素"
			},{
				value: "block",
				text: "显示为块级元素"
			},{
				value: "inline-block",
				text: "显示为行内块元素"
			},{
				value: "list-item",
				text: "显示为列表元素"
			}], 
			value: _display
		}, function(val, text) {
			if(val!="" && val!="none") {
				that.setSelectedCptStyle("position", "");
				that.setSelectedCptStyle("top", "");
				that.setSelectedCptStyle("bottom", "");
				that.setSelectedCptStyle("left", "");
				that.setSelectedCptStyle("right", "");
				that.setSelectedCptStyle("float", "");
			}
			that.setSelectedCptStyle("display", val);
		});
	}

	this.showOverflowType = function() {
		let valDefault = "visible";
		let cpt = this.getCurCpt();
		if(cpt && cpt.css("overflow")) valDefault = cpt.css("overflow");
		tfpDesigner.showPopMenu({
			width: "140px", 
			items: [{
				value: "visible",
				text: "不裁剪溢出内容"
			},{
				value: "hidden",
				text: "裁剪溢出内容"
			},{
				value: "scroll",
				text: "始终显示滚动条"
			},{
				value: "auto",
				text: "溢出时显示滚动条"
			}], 
			value: valDefault
		}, function(val, text) {
			that.setSelectedCptStyle("overflow", val);
		});
	}

	this.showFontType = function() {
		var val = "";
		if(event.srcElement.tagName=="div") {
			val = $(event.srcElement).attr("data-value");
		} else {
			val = $(event.srcElement).parent().attr("data-value");
		}
		tfpDesigner.showPopMenu({
			width: "182px", 
			height: "320px",
			value: val,
			items: [{
				value: "",
				text: "默认字体"
			},{
				value: "Microsoft YaHei",
				text: "微软雅黑"
			},{
				value: "宋体",
				text: "宋体"
			},{
				value: "黑体",
				text: "黑体"
			},{
				value: "仿宋",
				text: "仿宋"
			},{
				value: "楷体",
				text: "楷体"
			},{
				value: "隶书",
				text: "隶书"
			},{
				value: "幼圆",
				text: "幼圆"
			},{
				value: "Arial, Helvetica, sans-serif",
				text: "Arial"
			},{
				value: "'Arial Black', Gadget, sans-serif",
				text: "Arial Black"
			},{
				value: "'Arial Narrow', sans-serif",
				text: "Arial Narrow"
			},{
				value: "Verdana, Geneva, sans-serif",
				text: "Verdana"
			},{
				value: "Georgia, serif",
				text: "Georgia"
			},{
				value: "'Times New Roman', Times, serif",
				text: "Times New Roman"
			},{
				value: "'Trebuchet MS', Helvetica, sans-serif",
				text: "Trebuchet MS"
			},{
				value: "'Courier New', Courier, monospace",
				text: "Courier New"
			},{
				value: "Impact, Charcoal, sans-serif",
				text: "Impact"
			},{
				value: "'Comic Sans MS', cursive",
				text: "Comic Sans MS"
			},{
				value: "Tahoma, Geneva, sans-serif",
				text: "Tahoma"
			},{
				value: "Courier, monospace",
				text: "Courier"
			},{
				value: "'Lucida Sans Unicode', 'Lucida Grande', sans-serif",
				text: "Lucida Sans Unicode"
			},{
				value: "'Lucida Console', Monaco, monospace",
				text: "Lucida Console"
			},{
				value: "Garamond, serif",
				text: "Garamond"
			},{
				value: "'MS Sans Serif', Geneva, sans-serif",
				text: "MS Sans Serif"
			},{
				value: "'MS Serif', 'New York', sans-serif",
				text: "MS Serif"
			},{
				value: "'Palatino Linotype', 'Book Antiqua', Palatino, serif",
				text: "Palatino Linotype"
			},{
				value: "Symbol, sans-serif",
				text: "Symbol"
			},{
				value: "'Bookman Old Style', serif",
				text: "Bookman Old Style"
			}]
		}, function(val, text) {
			var el = $("[style-setting-id='font-family']");
			el.attr("style-setting-value", val);
			el.find("input").val(text);
			that.setSelectedCptStyle("font-family", val);
		});
	}

	this.showTextDecorationType = function() {
		tfpDesigner.showPopMenu({
			width: "110px", 
			showIcon: true,
			items: [{
				value: "",
				text: "无修饰"
			},{
				value: "underline",
				text: "下划线",
				icon: "images/underline.png"
			},{
				value: "overline",
				text: "上划线",
				icon: "images/overline.png"
			},{
				value: "line-through",
				text: "删除线",
				icon: "images/line_through.png"
			}], 
			value: $("[style-setting-id='text-decoration']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='text-decoration']").attr("style-setting-value", val);
			if(val=="") {
				$("[style-setting-id='text-decoration']").find("img").eq(0).attr("src", "images/text_decoration.png");
			} else {
			  $("[style-setting-id='text-decoration']").find("img").eq(0).attr("src", "images/"+val.replace("-", "_")+".png");
		  }
			that.setSelectedCptStyle("text-decoration", val);
		});
	}

	this.showTextWrapType = function() {
		tfpDesigner.showPopMenu({
			width: "130px", 
			showIcon: false,
			items: [{
				value: "",
				text: "默认"
			},{
				value: "pre",
				text: "保留空白"
			},{
				value: "nowrap",
				text: "不换行"
			},{
				value: "pre-wrap",
				text: "保留空白并换行"
			},{
				value: "pre-line",
				text: "合并空白并换行"
			}], 
			value: $("[style-setting-id='white-space']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='white-space']").attr("style-setting-value", val);
			that.setSelectedCptStyle("white-space", val);
			that.setSelectedCptStyle("text-overflow", "");
			$("[style-setting-id='text-overflow']").removeClass("tool-button-selected");
		});
	}

	this.showTextTransformType = function() {
		tfpDesigner.showPopMenu({
			width: "130px", 
			showIcon: true,
			items: [{
				value: "",
				text: "无转换"
			},{
				value: "capitalize",
				text: "首字母大写",
				icon: "images/capitalize.png"
			},{
				value: "uppercase",
				text: "全部大写",
				icon: "images/uppercase.png"
			},{
				value: "lowercase",
				text: "全部小写",
				icon: "images/lowercase.png"
			}], 
			value: $("[style-setting-id='text-transform']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='text-transform']").attr("style-setting-value", val);
			if(val=="") {
				$("[style-setting-id='text-transform']").find("img").eq(0).attr("src", "images/text_transform.png");
			} else {
			  $("[style-setting-id='text-transform']").find("img").eq(0).attr("src", "images/"+val.replace("-", "_")+".png");
		  }
			that.setSelectedCptStyle("text-transform", val);
		});
	}

	this.showPositionSetting = function() {
		var srcEl = event.srcElement;
		if(srcEl.tagName!="DIV") srcEl = $(srcEl).parent().get(0);
		var divSetting = $("#positionStyleSetting");
		divSetting.css("top", ($(srcEl).offset().top+$(srcEl).height()+3)+"px");
		divSetting.css("left", $(srcEl).offset().left+"px");
		divSetting.find("select").val("");
		divSetting.find("input").val("");
		let cpt = this.getCurCpt();
		if(cpt && cpt.dataModel.styles) {
			if(cpt.css("position")) divSetting.find("select").val(cpt.css("position"));
			if(cpt.css("z-index")) divSetting.find("input[data-type='z-index']").val(cpt.css("z-index"));
			let top = cpt.css("top");
			if(top) divSetting.find("input[data-type=top]").val(top.replace("px", ""));
			let bottom = cpt.css("bottom");
			if(bottom) divSetting.find("input[data-type=bottom]").val(bottom.replace("px", ""));
			let left = cpt.css("left");
			if(left) divSetting.find("input[data-type=left]").val(left.replace("px", ""));
			let right = cpt.css("right");
			if(right) divSetting.find("input[data-type=right]").val(right.replace("px", ""));
		}
		$("#maskDiv").show();
		divSetting.show();
	}

	this.setPosition = function(pos) {
		let posDiv = $("#positionStyleSetting");
		posDiv.find("input[data-type!='z-index']").val("0");
		if(posDiv.find("select").val()=="") posDiv.find("select").val("absolute");
		if(posDiv.find("input[data-type='z-index']").val()=="")
		  posDiv.find("input[data-type='z-index']").val("1");
		if(pos=="top") {
			posDiv.find("input[data-type=bottom]").val("");
		} else if(pos=="bottom") {
			posDiv.find("input[data-type=top]").val("");
		} else if(pos=="left") {
			posDiv.find("input[data-type=right]").val("");
		} else if(pos=="right") {
			posDiv.find("input[data-type=left]").val("");
		}
	}

	this.positionTypeOnChange = function(slt) {
		let posDiv = $("#positionStyleSetting");
		if($(slt).val()=="") {
			posDiv.find("input").val("");
		} else {
			if(posDiv.find("input[data-type='z-index']").val()=="") 
				posDiv.find("input[data-type='z-index']").val("1");
			if(posDiv.find("input[data-type=top]").val()==""
				&& posDiv.find("input[data-type=left]").val()==""
				&& posDiv.find("input[data-type=bottom]").val()==""
				&& posDiv.find("input[data-type=right]").val()=="") {
				posDiv.find("input[data-type=top]").val("0");
				posDiv.find("input[data-type=left]").val("0");
			}
		}
	}

	this.confirmPositionStyleSetting = function() {
		let posDiv = $("#positionStyleSetting");
		let posType = posDiv.find("select").val();
		if(posType=="") {
			this.setSelectedCptStyle("position", "");
			this.setSelectedCptStyle("z-index", "");
			this.setSelectedCptStyle("top", "");
			this.setSelectedCptStyle("bottom", "");
			this.setSelectedCptStyle("left", "");
			this.setSelectedCptStyle("right", "");
			$("input[style-setting-id=top]").val("");
			$("input[style-setting-id=left]").val("");
		} else {
			this.setSelectedCptStyle("display", "");
			this.setSelectedCptStyle("position", posType);
			var zIndex = posDiv.find("input[data-type='z-index']").val();
			if(zIndex=="") zIndex = 1;
			this.setSelectedCptStyle("z-index", parseInt(zIndex));
			var top = posDiv.find("input[data-type=top]").val();
			if(top!="") top += "px";
			this.setSelectedCptStyle("top", top);
			$("input[style-setting-id=top]").val(top.replace("px", ""));
			var bottom = posDiv.find("input[data-type=bottom]").val();
			if(bottom!="") bottom += "px";
			this.setSelectedCptStyle("bottom", bottom);
			var left = posDiv.find("input[data-type=left]").val();
			if(left!="") left += "px";
			this.setSelectedCptStyle("left", left);
			$("input[style-setting-id=left]").val(left.replace("px", ""));
			var right = posDiv.find("input[data-type=right]").val();
			if(right!="") right += "px";
			this.setSelectedCptStyle("right", right);
			if(top!="" && bottom!="") {
				this.setSelectedCptStyle("height", "");
				this.setSelectedCptStyle("max-height", "");
				this.setSelectedCptStyle("min-height", "");
			  $("input[style-setting-id=height]").val("");
			  $("select[style-setting-id=height]").val("px");
			}
			if(left!="" && right!="") {
				this.setSelectedCptStyle("width", "");
				this.setSelectedCptStyle("max-width", "");
				this.setSelectedCptStyle("min-width", "");
			  $("input[style-setting-id=width]").val("");
			  $("select[style-setting-id=width]").val("px");
			}
		}
		this.setSelectedCptStyle("float", "");
		$("[style-setting-id='float']").attr("style-setting-value", "none");
		$("[style-setting-id='float']").find("img").eq(0).attr("src", "images/float_none.png");
		this.cancelPositionStyleSetting();
	}

	this.cancelPositionStyleSetting = function() {
		var divSetting = $("#positionStyleSetting");
		divSetting.hide();
		$("#maskDiv").hide();
		divSetting.find("select").val("");
		divSetting.find("input").val("");
	}

	this.clearBorderSetting = function() {
		var divSetting = $("#borderStyleSetting");
		divSetting.find("input").val("");
		divSetting.find(".border-style").attr("style-setting-value", "solid");
		divSetting.find(".border-style").find("div").css("border-top", "2px solid #cccccc");
		divSetting.find(".color-picker").attr("style-setting-value", "#000000");
		divSetting.find(".color-picker").css("background-color", "#000000");
	}

	this.setBorderStyleSetting = function(divSetting, cpt, borderType) {
		let borderStyle = borderType=="all" ? cpt.css("border") : cpt.css("border-"+borderType);
		if(!borderStyle) return;
		let arr = borderStyle.trim().split(" ");
		if(arr.length!=3) return;
		divSetting.find("input[data-type='border-width-"+borderType+"']").val(arr[0].replace("px", ""));
		divSetting.find("[data-type='border-style-"+borderType+"']").attr("style-setting-value", arr[1]);
		divSetting.find("[data-type='border-style-"+borderType+"']").find("div").css("border-top", "2px "+arr[1]+" #cccccc");
		divSetting.find("[data-type='border-color-"+borderType+"']").attr("style-setting-value", arr[2]);
		divSetting.find("[data-type='border-color-"+borderType+"']").css("background-color", arr[2]);
	}

	this.showBorderSetting = function() {
		var srcEl = event.srcElement;
		if(srcEl.tagName!="DIV") srcEl = $(srcEl).parent().get(0);
		var divSetting = $("#borderStyleSetting");
		//divSetting.css("top", ($(srcEl).offset().top+$(srcEl).height()+3)+"px");
		divSetting.css("top", "95px");
		divSetting.css("left", $(srcEl).offset().left+"px");
		//divSetting.css("left", ($(srcEl).offset().left-divSetting.width()+16)+"px");
		this.clearBorderSetting();
		let cpt = this.getCurCpt();
		if(cpt) {
			if(cpt.css("border")) {
				this.setBorderStyleSetting(divSetting, cpt, "all");
			} else {
				this.setBorderStyleSetting(divSetting, cpt, "top");
				this.setBorderStyleSetting(divSetting, cpt, "bottom");
				this.setBorderStyleSetting(divSetting, cpt, "left");
				this.setBorderStyleSetting(divSetting, cpt, "right");
			}
			if(cpt.css("border-radius")) {
				let radius = cpt.css("border-radius");
				if(radius.indexOf(" ")>0) {
					let radiusArr = radius.split(" ");
					for(let i=0;i<radiusArr.length && i<4; i++) {
						divSetting.find("input[data-type='border-radius']").eq(i).val(radiusArr[i].replace("px", ""));
					}
				} else {
					divSetting.find("input[data-type='border-radius']").val(radius.replace("px", ""));
				}
			}
		}
		$("#maskDiv").show();
		divSetting.show();
	}

	this.setCptBorderStyle = function(divSetting, cpt, borderType) {
		let borderWidth = divSetting.find("input[data-type='border-width-"+borderType+"']").val().trim();
		if(borderWidth=="") return;
		borderWidth = parseInt(borderWidth);
		if(borderWidth<0) return;
		borderWidth = borderWidth+"px";
		let borderStyle = divSetting.find("[data-type='border-style-"+borderType+"']").attr("style-setting-value");
		let borderColor = divSetting.find("[data-type='border-color-"+borderType+"']").attr("style-setting-value");
		if(borderType=="all") {
		  cpt.css("border", borderWidth+" "+borderStyle+" "+borderColor);
	  } else {
	  	cpt.css("border-"+borderType, borderWidth+" "+borderStyle+" "+borderColor);
	  }
	}

	this.getBorderStyleSetting = function(divSetting, borderType) {
		let borderWidth = divSetting.find("input[data-type='border-width-"+borderType+"']").val().trim();
		if(borderWidth=="") return "";
		borderWidth = parseInt(borderWidth);
		if(borderWidth<0) return "";
		borderWidth = borderWidth+"px";
		let borderStyle = divSetting.find("[data-type='border-style-"+borderType+"']").attr("style-setting-value");
		let borderColor = divSetting.find("[data-type='border-color-"+borderType+"']").attr("style-setting-value");
		return borderWidth+" "+borderStyle+" "+borderColor;
	}

	this.confirmBorderStyleSetting = function() {
		var divSetting = $("#borderStyleSetting");
		if(divSetting.find("input[data-type='border-width-all']").val().trim()!="") {
			this.setSelectedCptStyle("border-top", "");
			this.setSelectedCptStyle("border-bottom", "");
			this.setSelectedCptStyle("border-left", "");
			this.setSelectedCptStyle("border-right", "");
			this.setSelectedCptStyle("border", this.getBorderStyleSetting(divSetting, "all"));
		} else {
			this.setSelectedCptStyle("border", "");
			this.setSelectedCptStyle("border-top", this.getBorderStyleSetting(divSetting, "top"));
			this.setSelectedCptStyle("border-bottom", this.getBorderStyleSetting(divSetting, "bottom"));
			this.setSelectedCptStyle("border-left", this.getBorderStyleSetting(divSetting, "left"));
			this.setSelectedCptStyle("border-right", this.getBorderStyleSetting(divSetting, "right"));
		}
		let arrRadius = [];
		let haveRadius = false;
		divSetting.find("input[data-type='border-radius']").each(function() {
			if($(this).val().trim()!="") {
				let radius = parseInt($(this).val().trim());
				if(radius>0) {
				  arrRadius.push(radius+"px");
				  haveRadius = true;
			  } else {
			  	arrRadius.push("0");
			  }
			} else {
				arrRadius.push("0");
			}
		});
		if(haveRadius) {
			this.setSelectedCptStyle("border-radius", arrRadius[0]+" "+arrRadius[1]+" "+arrRadius[2]+" "+arrRadius[3]);
		} else {
			this.setSelectedCptStyle("border-radius", "");
		}
		this.cancelBorderStyleSetting();
	}

	this.cancelBorderStyleSetting = function() {
		var divSetting = $("#borderStyleSetting");
		divSetting.hide();
		$("#maskDiv").hide();
		divSetting.find("input").val("");
	}

	this.showMarginSetting = function(type) {
		var srcEl = event.srcElement;
		if(srcEl.tagName!="DIV") srcEl = $(srcEl).parent().get(0);
		var divSetting = $("#marginStyleSetting");
		divSetting.attr("data-type", type);
		divSetting.css("top", ($(srcEl).offset().top+$(srcEl).height()+3)+"px");
		divSetting.css("left", $(srcEl).offset().left+"px");
    divSetting.find("input").val("");

		let cpt = this.getCurCpt();
		if(cpt) {
			if(cpt.css(type)) divSetting.find("input[data-type=all]").val(cpt.css(type).replace("px", ""));
			if(cpt.css(type+"-top")) divSetting.find("input[data-type=top]").val(cpt.css(type+"-top").replace("px", ""));
			if(cpt.css(type+"-bottom")) divSetting.find("input[data-type=bottom]").val(cpt.css(type+"-bottom").replace("px", ""));
			if(cpt.css(type+"-left")) divSetting.find("input[data-type=left]").val(cpt.css(type+"-left").replace("px", ""));
			if(cpt.css(type+"-right")) divSetting.find("input[data-type=right]").val(cpt.css(type+"-right").replace("px", ""));
		}
		
		$("#maskDiv").show();
		divSetting.show();
	}

	this.confirmMarginStyleSetting = function() {
		let divSetting = $("#marginStyleSetting");
		let marginType = divSetting.attr("data-type");
		let allMargin = divSetting.find("input[data-type=all]").val().trim();
		if(allMargin!="") {
			this.setSelectedCptStyle(marginType+"-top", "");
			this.setSelectedCptStyle(marginType+"-bottom", "");
			this.setSelectedCptStyle(marginType+"-left", "");
			this.setSelectedCptStyle(marginType+"-right", "");
			this.setSelectedCptStyle(marginType, allMargin+"px");
		} else {
			var topMargin = divSetting.find("input[data-type=top]").val().trim();
			var bottomMargin = divSetting.find("input[data-type=bottom]").val().trim();
			var leftMargin = divSetting.find("input[data-type=left]").val().trim();
			var rightMargin = divSetting.find("input[data-type=right]").val().trim();
			this.setSelectedCptStyle(marginType, "");
			this.setSelectedCptStyle(marginType+"-top", topMargin=="" ? "" : topMargin+"px");
			this.setSelectedCptStyle(marginType+"-bottom", bottomMargin=="" ? "" : bottomMargin+"px");
			this.setSelectedCptStyle(marginType+"-left", leftMargin=="" ? "" : leftMargin+"px");
			this.setSelectedCptStyle(marginType+"-right", rightMargin=="" ? "" : rightMargin+"px");
		}
		this.cancelMarginStyleSetting();
	}

	this.cancelMarginStyleSetting = function() {
		var divSetting = $("#marginStyleSetting");
		divSetting.hide();
		$("#maskDiv").hide();
		divSetting.attr("data-type", "");
		divSetting.find("input").val("");
	}

	this.showShadowStyleSetting = function(type) {
		var srcEl = event.srcElement;
		if(srcEl.tagName!="DIV") srcEl = $(srcEl).parent().get(0);
		var divSetting = $("#shadowStyleSetting");
		divSetting.attr("data-type", type);
		//divSetting.css("top", ($(srcEl).offset().top+$(srcEl).height()+3)+"px");
		divSetting.css("top", "95px");
		if(type=="border") {
			divSetting.css("left", $(srcEl).offset().left+"px");
		} else {
		  divSetting.css("left", ($(srcEl).offset().left-divSetting.width()+16)+"px");
	  }
			
		divSetting.find(".color-picker").css("background-color", "#000000");
		divSetting.find(".color-picker").attr("style-setting-value", "#000000");
	  divSetting.find("input[data-type='h-shadow']").val("5");
	  divSetting.find("input[data-type='v-shadow']").val("5");
	  divSetting.find("input[data-type='blur']").val("3");
	  let cpt = this.getCurCpt();
		if(cpt) {
			let shadowArr = [];
		  if(type=="border") {
				if(cpt.css("box-shadow")) {
					shadowArr = cpt.css("box-shadow").trim().split(" ");
				}
			} else {
			  if(cpt.css("text-shadow")) {
					shadowArr = cpt.css("text-shadow").trim().split(" ");
				}
		  }
			if(shadowArr.length==4) {
				divSetting.find("input[data-type='h-shadow']").val(shadowArr[0].replace("px", ""));
				divSetting.find("input[data-type='v-shadow']").val(shadowArr[1].replace("px", ""));
				divSetting.find("input[data-type='blur']").val(shadowArr[2].replace("px", ""));
				divSetting.find(".color-picker").css("background-color", shadowArr[3]);
	      divSetting.find(".color-picker").attr("style-setting-value", shadowArr[3]);
			}
		}
		$("#maskDiv").show();
		divSetting.show();
	}

	this.confirmShadowStyleSetting = function() {
		let divSetting = $("#shadowStyleSetting");
		let shadowColor = divSetting.find(".color-picker").attr("style-setting-value").trim();
		if(shadowColor=="") shadowColor = "#000000";
		let hShadow = divSetting.find("input[data-type='h-shadow']").val().trim();
		let vShadow = divSetting.find("input[data-type='v-shadow']").val().trim();
		let blurShadow = divSetting.find("input[data-type='blur']").val().trim();
		let shadowType = divSetting.attr("data-type");
		if(shadowType=="border") {
			if(hShadow!="" && vShadow!="" && blurShadow!="") {
			  this.setSelectedCptStyle("box-shadow", hShadow+"px "+vShadow+"px "+blurShadow+"px "+shadowColor);
			} else {
				this.setSelectedCptStyle("box-shadow", "");
			}
	  } else {
	  	if(hShadow!="" && vShadow!="" && blurShadow!="") {
			  this.setSelectedCptStyle("text-shadow", hShadow+"px "+vShadow+"px "+blurShadow+"px "+shadowColor);
			} else {
				this.setSelectedCptStyle("text-shadow", "");
			}
	  }
		this.cancelShadowStyleSetting();
	}

	this.cancelShadowStyleSetting = function() {
		var divSetting = $("#shadowStyleSetting");
		divSetting.hide();
		$("#maskDiv").hide();
	}

	this.clearShadowStyleSetting = function() {
		var divSetting = $("#shadowStyleSetting");
		divSetting.find(".color-picker").attr("style-setting-value", "#000000");
		divSetting.find(".color-picker").css("background-color", "#000000");
		divSetting.find("input").val("");
	}

	this.showBackgroundClipType = function() {
		tfpDesigner.showPopMenu({
			width: "170px", 
			items: [{
				value: "",
				text: "默认"
			},{
				value: "border-box",
				text: "背景被裁剪到边框盒"
			},{
				value: "padding-box",
				text: "背景被裁剪到内边距框"
			},{
				value: "content-box",
				text: "背景被裁剪到内容框"
			}],
			value: $("[style-setting-id='background-clip']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='background-clip']").attr("style-setting-value", val);
			that.setSelectedCptStyle("background-clip", val);
			console.log(that.getCurCpt());
		});
	}

	this.showBackgroundOriginType = function() {
		tfpDesigner.showPopMenu({
			width: "100px", 
			items: [{
				value: "",
				text: "默认"
			},{
				value: "border-box",
				text: "边框盒"
			},{
				value: "padding-box",
				text: "内边距框"
			},{
				value: "content-box",
				text: "内容框"
			}],
			value: $("[style-setting-id='background-origin']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='background-origin']").attr("style-setting-value", val);
			that.setSelectedCptStyle("background-origin", val);
		});
	}

	this.showBackgroundRepeatType = function() {
		tfpDesigner.showPopMenu({
			width: "170px", 
			items: [{
				value: "",
				text: "默认"
			},{
				value: "no-repeat",
				text: "不重复"
			},{
				value: "repeat-x",
				text: "水平方向重复"
			},{
				value: "repeat-y",
				text: "垂直方向重复"
			},{
				value: "repeat",
				text: "垂直和水平方向都重复"
			}],
			value: $("[style-setting-id='background-repeat']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='background-repeat']").attr("style-setting-value", val);
			that.setSelectedCptStyle("background-repeat", val);
		});
	}

	this.showBackgroundFixedType = function() {
		tfpDesigner.showPopMenu({
			width: "90px", 
			items: [{
				value: "",
				text: "不固定"
			},{
				value: "fixed",
				text: "固定"
			}],
			value: $("[style-setting-id='background-attachment']").attr("style-setting-value")
		}, function(val, text) {
			$("[style-setting-id='background-attachment']").attr("style-setting-value", val);
			that.setSelectedCptStyle("background-attachment", val);
		});
	}

	this.closeBoderStyleType = function() {
		$("#borderStyleList").hide();
		document.removeEventListener("click", this.closeBoderStyleType);
		this.curBorderStyleEl = null;
	}

	this.showBoderStyleType = function() {
		this.curBorderStyleEl = $(event.srcElement);
		if(!this.curBorderStyleEl.hasClass("border-style")) this.curBorderStyleEl = this.curBorderStyleEl.parent();
		this.curBorderStyleEl.css("border", "1px solid #0099ff");
		var borderStyleList = $("#borderStyleList");
		borderStyleList.css("top", (this.curBorderStyleEl.offset().top+this.curBorderStyleEl.height()+3)+"px");
		borderStyleList.css("left", this.curBorderStyleEl.offset().left+"px");
		borderStyleList.show();
		document.addEventListener("click", this.closeBoderStyleType);
		event.stopPropagation();
	}

	this.closeCursorStyleType = function() {
		$("#cursorStyleList").hide();
		$("#maskDiv").hide();
		document.removeEventListener("click", this.closeCursorStyleType);
	}

	this.showCursorStyleType = function() {
		var srcEl = $(event.srcElement);
		if(event.srcElement.tagName!="DIV") srcEl = srcEl.parent();
		this.curCursorStyleEl = srcEl;
		var cursorStyleList = $("#cursorStyleList");
		cursorStyleList.css("top", (srcEl.offset().top+srcEl.height()+3)+"px");
		cursorStyleList.css("left", (srcEl.offset().left+1)+"px");
		cursorStyleList.show();
		$("#maskDiv").show();
		document.addEventListener("click", this.closeCursorStyleType);
		event.stopPropagation();
	}

	this.onResize = function() {
		let toolBar = $("#uiToolBar");
		let toolBarWidth = toolBar.width();
		let toolBarContainerWidth = this.getToolBarWidth();
		let isVisible = $("#uiToolBarScrollLeft").is(":visible");
		if(toolBarContainerWidth<=toolBarWidth) {
			if(isVisible) {
				$(".ui-toolbar-scroll").hide();
				toolBar.css("left", "166px");
				toolBar.css("right", "0");
			}
		} else {
		  if(!isVisible) {
				toolBar.css("left", "184px");
				toolBar.css("right", "18px");
				$(".ui-toolbar-scroll").show();
			}
		}
		$("#uiToolBar").get(0).scrollLeft = 0;
	}

	this.createCptLib = function(ComponentCategorys) {
  	//组件分类设置
    for (var i = 0; i < ComponentCategorys.length; i++) {
			var category = ComponentCategorys[i];
			var divCptLib = $("#uiDesignerLeftBar").find(".option-page").eq(0);
			divCptLib.append("<div id=\"cptCategory_" + category.id + "\" class=\"component-category\">"
				+ "<img src=\"../taskbuilder-renderer/images/arrow/down.png\" />"
				+ "<label style=\"\">" + category.name + "</label></div>");
			divCptLib.append("<div id=\"cptCategory_" + category.id
				+ "_items\" class=\"component-category-items\"></div>");
			for (var j = 0; j < category.components.length; j++) {
				let cptInfo = category.components[j];
				that.Components[cptInfo.name] = cptInfo;
				//非独立组件不用显示，例如选项页，只能用于选项卡组件
				if(cptInfo.dependent) continue;
				$("#cptCategory_" + category.id + "_items").append("<div id=\"compoent_"
					+ cptInfo.name + "\" class=\"compoent\"><div class=\"compoent-icon\">"
					+ "<img src=\"../tfp/src/components/" + cptInfo.name.toLowerCase() 
					+ "/images/icon-light.png\" draggable=\"false\" /></div>"
					+ "<div class=\"compoent-name\">" + cptInfo.comment + "</div></div>");
			}
		}

		$(".component-category").click(function () {
			var cid = $(this).attr("id");
			var cimg = $(this).find("img").get(0);
			if ($(cimg).attr("src") == "../taskbuilder-renderer/images/arrow/down.png") {
				$(cimg).attr("src", "../taskbuilder-renderer/images/arrow/right.png");
				$("#" + cid + "_items").hide("fast");
			} else {
				$(cimg).attr("src", "../taskbuilder-renderer/images/arrow/down.png");
				$("#" + cid + "_items").show("fast");
			}
		});

		$(".compoent").mousedown(function () {
			var e = window.event;
			tfpDesigner.mouseInfo.downX = e.clientX;
			tfpDesigner.mouseInfo.downY = e.clientY;
			tfpDesigner.mouseInfo.dragType = "CreateComponent";
			let cptType = $(this).attr("id").replace("compoent_", "");
			tfpDesigner.mouseInfo.cptType = cptType;
			tfpDesigner.mouseInfo.isDrag = true;
			$("#compoentDragging").find("img").attr("src", $(this).find("img").attr("src"));
			let cptTypeInfo = tfp.type(cptType);
			$("#compoentDragging").find("label").text(cptTypeInfo.name);
		});
	}

	/**
	 * 点击选项卡时显示对应的选项页
	 * @param  {[type]} divId     [description]
	 * @param  {[type]} optionBar [description]
	 * @return {[type]}           [description]
	 */
	this.optionBarOnClick = function (divId, optionBar) {
		var barIndex = $(optionBar).index();
		if (this.curOptionBarIndex[divId] == barIndex) return;
		$("#uiDesigner" + divId).find(".option-bar").children().removeClass("selected-option");
		$("#uiDesigner" + divId).find(".option-bar").children().css("color", "#aaaaaa");
		this.curOptionBarIndex[divId] = barIndex;
		$(optionBar).addClass("selected-option");
		$(optionBar).css("color", "#ffffff");
		$("#uiDesigner" + divId).find(".option-page").hide();
		$("#uiDesigner" + divId).find(".option-page").eq(barIndex).show();
	}

	/**
	 * 添加组件树节点
	 * @param {[type]} cpt       [description]
	 */
	this.addCptTreeNode = function (cpt) {
		var marginLeft = 5;
		for (var i = 0; i < cpt.level; i++) {
			marginLeft += 10;
		}

		let parentEl;
		if(cpt.type=="Page") {
			parentEl = $("#uiDesignerLeftBar").find(".option-page").eq(1);
		} else {
			parentEl = $("#cptTreeNodeChilds_"+cpt.parent.id);
		}

		var html = "<div id=\"cptTreeNode_" + cpt.id + "\" class=\"cpt-tree-node\" "
			+ "style=\"margin-left: " + marginLeft + "px;\">";
		if (cpt.isContainer || cpt.containerEl) {
			html += "<img src=\"../taskbuilder-renderer/images/arrow/down.png\" style=\"vertical-align:text-top;"
				+ "margin-top:2px\" /><label>";
			html += cpt.id;
			html += "</label></div>";
			html += "<div id=\"cptTreeNodeChilds_" + cpt.id + "\" class=\"cpt-tree-node-childs\"></div>";
			parentEl.append(html);
		} else {
			html += "&nbsp;&nbsp;·&nbsp;" + cpt.id + "</div>";
			parentEl.append(html);
		}

		var node = $("#cptTreeNode_" + cpt.id);
		node.find("img").click(function () {
			var e = arguments[0];
			e.stopPropagation();

			var cptId = $(this).parent().attr("id").replace("cptTreeNode_", "");
			$("#cptTreeNodeChilds_" + cptId).toggle();
			if ($("#cptTreeNodeChilds_" + cptId).is(":visible")) {
				$(this).attr("src", "../taskbuilder-renderer/images/arrow/down.png");
			} else {
				$(this).attr("src", "../taskbuilder-renderer/images/arrow/right.png");
			}
		});
		node.click(function () {
			var cptId = $(this).attr("id").replace("cptTreeNode_", "");
			that.cptOnClick(window.event, cptId);
		});
	}

	/**
	   * 选中指定id的组件
	   * @param  {[type]} cptId [description]
	   */
	this.selectCpt = function(cptId) {
		if (this.curSelectedCptId == cptId) return;
		if (this.curSelectedCptId) this.unSelectCpt(this.curSelectedCptId);
		if (this.selectedCpts.length == 0) this.curSelectedCptId = cptId;

		var cpt = tfp.components[cptId];
		if (!cpt) return;

		this.selectCptNode(cptId);
		this.selectCptEl(cpt);

		$("#uiDesignerCptPath").empty();

		if (this.curSelectedCptId) {
			this.setCptSettingInfo(cpt);
			$("#uiDesignerCenter").css("right", "201px");
			$("#uiDesignerRightBar").css("width", "200px");
			$("#uiDesignerRightBar").show();
			$("#uiDesignerCptPath").append("<div style=\"background-color:#0099FF; "
				+"border:0; height:22px; line-height:22px;\">"+cptId+"</div>");
			let parent = cpt.parent;
			while(parent) {
				$("#uiDesignerCptPath").prepend("<div>"+parent.id+"</div>");
				parent = parent.parent;
			}
			$("#uiDesignerCptPath").find("div").click(function() {
				that.selectCpt($(this).text());
			});
		} else {
			$("#uiDesignerCenter").css("right", "0");
			$("#uiDesignerRightBar").hide();
		}
	}

	this.unSelectCpt = function (cptId) {
		var cptOld = tfp.components[cptId];
		if(!cptOld) return;
		if ((cptOld.isContainer || cptOld.dataModel.components) 
			&& cptOld.type!="Page" && !cptOld.isInvisible) {
			if (!cptOld.styles || (!cptOld.styles["border"] && !cptOld.styles["border-width"])) {
				cptOld._jqObj.css("outline", "#CCCCCC dashed 1px");
			} else {
				cptOld._jqObj.css("outline", "0");
			}
		} else if (cptOld.type != "Page") {
			cptOld._jqObj.css("outline", "0");
		}
		$("#cptTreeNode_" + cptId).css("background-color", "");
		if (this.curSelectedCptId == cptId) this.curSelectedCptId = null;
		if (this.selectedCpts.includes(cptId)) this.selectedCpts.remove(cptId);
	};

	/**
	   * 选中组件列表中当前组件对应的节点
	   * @param  {[type]} cptId [description]
	   */
	this.selectCptNode = function (cptId) {
		if (this.selectedCpts.length == 0) {
			if (this.curCptNodeId == cptId) return;
			if (this.curCptNodeId) $(".cpt-tree-node").css("background-color", "");
			this.curCptNodeId = cptId;
		} else {
			this.curCptNodeId = null;
		}
		$("#cptTreeNode_" + cptId).css("background-color", "#0099FF");
	};

	/**
	   * 选中组件对应的html元素
	   * @param  {[type]} cpt [description]
	   */
	this.selectCptEl = function (cpt) {
		if (cpt.type != "Page") {
			cpt._jqObj.css("outline", "2px solid #0000ff");
		}
		if (cpt.type == "Page" || cpt.isInvisible || this.selectedCpts.length > 0) {
			//
		} else if (this.curSelectedCptId == cpt.id) {
			//let w = cpt._jqObj.outerWidth();
			//let h = cpt._jqObj.outerHeight();
		}
	};

	/**
	 * 重置组件设置栏，包括属性设置、样式设置和事件设置
	 * @param {[type]} cpt [description]
	 */
	this.setCptSettingInfo = function (cpt) {
		this.setCptStyleList(cpt);
		this.setCptAttrList(cpt);
		this.setCptEventList(cpt);
	};

	this.cptOnClick = function (e, cptId) {
		e.stopPropagation();
		if (tfpDesigner.mouseInfo.isDrag) {
			tfpDesigner.mouseInfo.isDrag = false;
			return;
		}

		let cpt = tfp.components[cptId];
		if (!cpt) return;
		if(cpt) cpt._jqObj.css("cursor", "auto");

		//如果按住了ctrl或shift键，则表示要多选
		if (e.ctrlKey || e.shiftKey) {
			//如果目前仅选中了一个组件
			if (this.curSelectedCptId) {
				//如果点击的是当前选中的组件，则不处理
				if (this.curSelectedCptId == cptId) return;
				this.selectedCpts = [];
				//如果当前选中的不是页面组件，则先将该组件加入选中的组件列表
				if (this.curSelectedCptId != tfp.curPage.id) {
					//如果当前选中的组件和当前点击的组件的父组件不一样，则不能多选
					//也就是说只能同时选中同一个父组件的多个子组件
					let cptCur = tfp.components[this.curSelectedCptId];
					if (cptCur.parent.id != cpt.parent.id) return;
					//非可视组件不能和可视组件一起多选
					if (cptCur.isInvisible != cpt.isInvisible) return;
					this.selectedCpts.push(this.curSelectedCptId);
					//再将当前点击的组件加入选中的组件列表
					this.selectedCpts.push(cptId);
				}
				//清空当前选中的组件ID变量
				this.curSelectedCptId = null;
				//选中点击的组件
				this.selectCpt(cptId);
			} else {
				//如果当前未选中任何组件，则选中该组件
				if (this.selectedCpts.length == 0) {
					this.selectCpt(cptId);
				}
				//如果已经选中该组件，则需要取消对该组件的选中
				else if (this.selectedCpts.includes(cptId)) {
					this.unSelectCpt(cptId);
					//如果选中组件列表一个组件也没有了，则选中页面组件
					if (this.selectedCpts.length == 0) {
						this.selectCpt(tfp.curPage.id);
					}
					//如果选中组件列表只剩一个组件，则清空列表，并设置当前选中组件为该组件
					else if (this.selectedCpts.length == 1) {
						let cptIdTmp = this.selectedCpts[0];
						this.selectedCpts = [];
						this.curSelectedCptId = null;
						this.selectCpt(cptIdTmp);
					}
				}
				//否则，如果该组件不是页面组件，将该组件加入选中组件列表，并选中
				else if (cptId != tfp.curPage.id) {
					//如果当前点击的组件和已选中的组件的父组件不一样，则不能多选
					//也就是说只能同时选中同一个父组件的多个子组件
					let cptTmp = tfp.components[this.selectedCpts[0]];
					if (cptTmp.parent.id != cpt.parent.id) return;
					//非可视组件不能和可视组件一起多选
					if (cptTmp.isInvisible != cpt.isInvisible) return;
					this.selectedCpts.push(cptId);
					this.selectCpt(cptId);
				}
			}
		} else {  //如果没有按Ctrl键，则同时只能选中一个组件
			//如果已经选中了多个组件，则需要取消对这些组件的选中
			while (this.selectedCpts.length > 0) {
				this.unSelectCpt(this.selectedCpts[0]);
			}
			//选中点击的组件
			this.selectCpt(cptId);
		}
	}

	this.cptOnMouseDown = function (cpt, e) {
		//禁止事件冒泡，以免移动父组件
		e.stopPropagation();
		if (this.selectedCpts.includes(cpt.id)) {
			tfpDesigner.mouseInfo.offset = [];
			for (var i = 0; i < this.selectedCpts.length; i++) {
				var cptTmp = tfp.components[this.selectedCpts[i]];
				if (cptTmp && cptTmp.styles && cptTmp.styles["top"] && cptTmp.styles["left"]
					&& !cptTmp.styles["right"] && !cptTmp.styles["bottom"]) {
					tfpDesigner.mouseInfo.offset.push({
						top: parseInt(cptTmp.styles["top"].replace("px", "")),
						left: parseInt(cptTmp.styles["left"].replace("px", ""))
					});
				} else {
					tfpDesigner.mouseInfo.offset.push({});
				}
			}
		} else {
			//if(this.curSelectedCptId!=cpt.id) this.selectCpt(cpt.id);
			//let cpt = tfp.components[cpt.id];
			if (cpt && cpt.styles && cpt.styles["top"] && cpt.styles["left"]
				&& !cpt.styles["right"] && !cpt.styles["bottom"]) {
				tfpDesigner.mouseInfo.offset = [{
					top: parseInt(cpt.styles["top"].replace("px", "")),
					left: parseInt(cpt.styles["left"].replace("px", ""))
				}];
			} else {  //没有纵坐标和横坐标的组件不能拖拽
				if (cpt.isContainer) {
					tfpDesigner.mouseInfo.dragType = "SelectComponent";
				} else {
					return;
				}
			}
		}
		tfpDesigner.mouseInfo.downX = e.clientX;
		tfpDesigner.mouseInfo.downY = e.clientY;
		if (!tfpDesigner.mouseInfo.dragType) tfpDesigner.mouseInfo.dragType = "MoveComponent";
		tfpDesigner.mouseInfo.cptId = cpt.id;
		tfpDesigner.mouseInfo.isDrag = false;
		cpt._jqObj.css("cursor", "move");
	}

	this.cptOnMouseOver = function (cpt, e) {
		e.stopPropagation();

		if (!tfpDesigner.mouseInfo.isDrag) return;

		var dragCptClass = tfp.type(tfpDesigner.mouseInfo.cptType);
		if (!dragCptClass) return;
		if (dragCptClass.isInvisible) return;  //不可视组件不能放在其他组件上

		if (tfp.curPage.positionType == "float") {
			/*if (cpt.isContainer) {
				if ($("#tempCptDiv").length > 0) {
					if ($("#tempCptDiv").attr("parent-cpt-id") == cpt.id) {
						return;
					} else {
						$("#tempCptDiv").remove();
					}
				}
				let containerEl = cpt.getContainerEl();
				$(containerEl).append("<div id=\"tempCptDiv\" parent-cpt-id=\"" + cpt.id + "\"></div>");
			} else {
				if ($("#tempCptDiv").length > 0) {
					if ($("#tempCptDiv").attr("before-cpt-id") == cpt.id) {
						return;
					} else {
						$("#tempCptDiv").remove();
					}
				}
				$("<div id=\"tempCptDiv\" before-cpt-id=\"" + cpt.id + "\"></div>").insertAfter(cpt._jqObj);
			}*/
		}
	}

	this.dragCpt = function (e, cptId, offset) {
		if ((!offset.top && offset.top!=0) || (!offset.left && offset.left!=0)) return;
		let cpt = tfp.components[cptId];
		if (!cpt) return;
		if (cpt._jqObj.length == 0) return;
		let parentEl = cpt._jqObj.parent();
		let x = offset.left + (e.clientX - tfpDesigner.mouseInfo.downX);
		//if((x+cpt._jqObj.outerWidth(true))>parentEl.width()) x = parentEl.width() - cpt._jqObj.outerWidth(true);
		if (x < 0) x = 0;
		let y = offset.top + (e.clientY - tfpDesigner.mouseInfo.downY);
		//if((y+cpt._jqObj.outerHeight(true)+2)>parentEl.height()) y = parentEl.height() - cpt._jqObj.outerHeight(true)-2;
		if (y < 0) y = 0;
		cpt._jqObj.css("left", x + "px");
		cpt._jqObj.css("top", y + "px");
		if (!cpt.styles) cpt.styles = {};
		cpt.styles["left"] = x + "px";
		cpt.styles["top"] = y + "px";
		if (this.selectedCpts.length == 0) {
			$("input[style-setting-id=left]").val(x + "");
			$("input[style-setting-id=top]").val(y + "");
		}
	}

	/***************************************** 样式设置 ******************************************/

	/**
	 * 重置组件样式设置列表
	 * @return {[type]} [description]
	 */
	this.resetCptStyleList = function () {
		let uiToolBarContainer = $("#uiToolBarContainer");
		uiToolBarContainer.children().hide();
		uiToolBarContainer.find("input").val("");
		uiToolBarContainer.find("select").val("");
		uiToolBarContainer.find(".tool-button").removeClass("tool-button-selected");
		uiToolBarContainer.find(".toolbar-col-more").find("img").attr("src", "images/arrow_right_white.png");
		
		$("[data-type='width-type']").attr("data-value", "width");
		$("[data-type='height-type']").attr("data-value", "height");
		$("[data-type='width-type']").find("img").eq(0).attr("src", "images/width.png");
		$("[data-type='height-type']").find("img").eq(0).attr("src", "images/height.png");
		$("select[style-setting-id=width]").val("px");
		$("select[style-setting-id=height]").val("px");
		
		$("[style-setting-id='float']").attr("style-setting-value", "none");
		$("[style-setting-id='float']").find("img").eq(0).attr("src", "images/float_none.png");
    
		$("#styleSetting_font").find(".color-picker").css("background-color", "#000000").attr("style-setting-value", "#000000");
		uiToolBarContainer.find(".font-family-list").attr("style-setting-value", "");
		$("[style-setting-id='text-decoration']").attr("style-setting-value", "");
		$("[style-setting-id='text-decoration']").find("img").eq(0).attr("src", "images/text_decoration.png");
		$("[style-setting-id='text-transform']").attr("style-setting-value", "");
		$("[style-setting-id='text-transform']").find("img").eq(0).attr("src", "images/text_transform.png");
		$("[style-setting-id='white-space']").attr("style-setting-value", "");

    $("#styleSetting_background").find(".color-picker").css("background-color", "#FFFFFF").attr("style-setting-value", "#FFFFFF");
		$("#styleSetting_background").find(".tool-button-ex").attr("style-setting-value", "");

		$("#cursorStyle").find("img").get(0).src = "images/cursor_default.png";
	}

	/**
	 * 设置组件样式列表
	 * @param {[type]} cpt [description]
	 */
	this.setCptStyleList = function (cpt) {
		this.resetCptStyleList();

		//如果是非可视组件，则不需要设置样式
		if (cpt.isInvisible) return;

		if (cpt.styles) {
			for (styleName in cpt.styles) {
				styleName = styleName.toLowerCase();
				var styleVal = cpt.styles[styleName];
				if(!styleVal) continue;
				styleVal = (styleVal+"").trim();
				if(styleVal=="") continue;
				styleVal = styleVal.replace("  ", " ");
				var styleSettingEl = $("[style-setting-id=" + styleName + "]");
				if(styleName=="float") {
					styleSettingEl.attr("style-setting-value", styleVal);
		      styleSettingEl.find("img").eq(0).attr("src", "images/float_"+styleVal.toLowerCase()+".png");
				} else if(styleName=="text-decoration" || styleName=="text-transform") {
					styleSettingEl.attr("style-setting-value", styleVal);
		      styleSettingEl.find("img").eq(0).attr("src", 
		      	"images/"+styleVal.toLowerCase().replace("-", "_")+".png");
				} else {
					if(styleName=="width" || styleName=="height") {
						if (styleVal.indexOf("px") > 0) {
							styleSettingEl.eq(0).val(styleVal.replace("px", ""));
							styleSettingEl.eq(1).val("px");
						} else if (styleVal.indexOf("%") > 0) {
							styleSettingEl.eq(0).val(styleVal.replace("%", ""));
							styleSettingEl.eq(1).val("%");
						}
					} else if(["top", "left", "font-size", "line-height", "letter-spacing", "word-spacing"].includes(styleName)) {
						styleSettingEl.val(styleVal.toLowerCase().replace("px", ""));
					} else if(styleName=="color" || styleName=="background-color") {
						styleSettingEl.css("background-color", styleVal);
						styleSettingEl.attr("style-setting-value", styleVal);
					} else if(styleName=="text-align") {
						if(styleVal=="left") {
							styleSettingEl.eq(0).addClass("tool-button-selected");
						} else if(styleVal=="center") {
							styleSettingEl.eq(1).addClass("tool-button-selected");
						} else if(styleVal=="right") {
							styleSettingEl.eq(2).addClass("tool-button-selected");
						} else if(styleVal=="justify") {
							styleSettingEl.eq(3).addClass("tool-button-selected");
						}
					} else if((styleName=="font-weight" || styleName=="font-style" 
						|| styleName=="text-overflow")
						&& styleVal==styleSettingEl.attr("style-setting-value")) {
						styleSettingEl.addClass("tool-button-selected");
					} else if(styleName=="font-family") {
						styleSettingEl.attr("style-setting-value", styleVal);
						styleSettingEl.find("input").val(styleVal);
					} else if(styleName=="white-space" || styleName=="background-clip" 
						|| styleName=="background-origin" || styleName=="background-repeat"
						|| styleName=="background-attachment") {
						styleSettingEl.attr("style-setting-value", styleVal);
					} else if(styleName=="background-image") {
						styleSettingEl.val(styleVal);
					} else if(styleName=="background-position") {
						if(styleVal.indexOf(" ")<0) {
						  styleSettingEl.eq(0).val(styleVal);
					  } else {
					  	let arrVal = styleVal.split(" ");
						  styleSettingEl.eq(0).val(arrVal[0]);
						  styleSettingEl.eq(1).val(arrVal[1]);
					  }
					} else if(styleName=="background-size") {
						let arrVal = styleVal.split(" ");
						if(arrVal.length==2) {
							styleSettingEl.eq(0).val(arrVal[0].replace("px", ""));
							styleSettingEl.eq(1).val(arrVal[1].replace("px", ""));
						}
					} else if(styleName=="opacity") {
						styleSettingEl.val(parseFloat(styleVal)*100);
					} else if(styleName=="cursor") {
						styleSettingEl.find("img").eq(0).attr("src", "images/cursor_"+styleVal+".png");
					}
				}
			}
		}

		if (!cpt.metadata.styles) return;
		for (var i = 0; i < cpt.metadata.styles.length; i++) {
			let styleType = cpt.metadata.styles[i];
			if(styleType=="border") styleType = "margin";
			if($("#styleSetting_" + styleType).length>0) {
				$("#styleSetting_" + styleType).show();
				$("#styleSetting_" + styleType+"_more").show();
				$(".style_setting_split_" + styleType).show();
			}
		}
		this.onResize();
	}

	/**
	 * 设置当前组件的CSS样式
	 * @param {[type]} styleName  [description]
	 * @param {[type]} styleVal [description]
	 */
	this.setCurCptStyle = function (styleName, styleVal) {
		var cpt = tfp.components[this.curSelectedCptId];
		if(!cpt) return;
		cpt.css(styleName, styleVal);
	}

	/**
	 * 设置组件的CSS样式，如果不是组件元数据中定义的样式，则忽略
	 * @param {[type]} cptId     [description]
	 * @param {[type]} styleName [description]
	 * @param {[type]} styleVal  [description]
	 */
	this.setCptStyle = function(cptId, styleName, styleVal) {
		let cpt = tfp.components[cptId];
		if(!cpt) return;
		let metadata = cpt.metadata;
		if(!metadata.styles) return;
		//大小
		if(["width", "max-width", "min-width", "height", "max-height", "min-height"].includes(styleName)) {
			if(!metadata.styles.includes("size")) return;
			cpt.css(styleName, styleVal);
	  } else
		//定位
		if(["position", "z-index", "top", "left", "bottom", "right", "float"].includes(styleName)) {
			if(!metadata.styles.includes("position")) return;
			cpt.css(styleName, styleVal);
	  } else
		//边距
		if(["margin", "margin-left", "margin-right", "margin-top", "margin-bottom", 
			"padding", "padding-left", "padding-right", "padding-top", "padding-bottom"].includes(styleName)) {
			if(!metadata.styles.includes("margin")) return;
			cpt.css(styleName, styleVal);
	  } else
		//边框
		if(["border", "border-left", "border-right", "border-top", "border-bottom", 
			"border-radius", "box-shadow"].includes(styleName)) {
			if(!metadata.styles.includes("border")) return;
		  cpt.css(styleName, styleVal);
		} else
		//文字
		if(["color", "text-align", "font-weight", "font-style", "text-decoration", "font-family", 
			"font-size", "line-height", "letter-spacing", "word-spacing", "text-shadow", 
			"text-transform", "white-space", "text-wrap", "text-overflow"].includes(styleName)) {
			if(!metadata.styles.includes("font")) return;
		  cpt.css(styleName, styleVal);
		} else
		//背景
		if(["background-color", "background-clip", "background-origin", "background-repeat", 
			"background-attachment", "background-image", "background-position", "background-size"].includes(styleName)) {
			if(!metadata.styles.includes("background")) return;
		  cpt.css(styleName, styleVal);
		} else
		//其他
		if(["display", "overflow", "opacity", "cursor"].includes(styleName)) {
			if(!metadata.styles.includes("other")) return;
		  cpt.css(styleName, styleVal);
		}
	}

	/**
	 * 设置选中的组件的CSS样式
	 * @param {[type]} styleName [description]
	 * @param {[type]} styleVal  [description]
	 */
	this.setSelectedCptStyle = function(styleName, styleVal) {
		if(this.selectedCpts.length>0) {
			for(let i=0;i<this.selectedCpts.length;i++) {
				this.setCptStyle(this.selectedCpts[i], styleName, styleVal);
			}
		} else {
			this.setCptStyle(this.curSelectedCptId, styleName, styleVal);
		}
	}

	/**
   * 当组件的样式发生变化时
   * @param  {[type]} styleEl [description]
   * @return {[type]}         [description]
   */
	this.cptStyleOnChange = function (styleEl) {
		//如果是图片按钮
		if (styleEl.hasClass("tool-button")) {
			var styleName = styleEl.attr("style-setting-id");
			var styleVal = styleEl.attr("style-setting-value");
			if(styleName=="text-align" || styleName=="text-transform") {
				styleEl.parent().find("[style-setting-id='"+styleName+"']").removeClass("tool-button-selected");
				this.setSelectedCptStyle(styleName, styleVal);
			  styleEl.addClass("tool-button-selected");
			} else if(styleName=="font-weight" || styleName=="font-style") {
				if(styleEl.hasClass("tool-button-selected")) {
					this.setSelectedCptStyle(styleName, "");
					styleEl.removeClass("tool-button-selected");
			  } else {
			    this.setSelectedCptStyle(styleName, styleEl.attr("style-setting-value"));
					styleEl.addClass("tool-button-selected");
			  }
			} else if(styleName == "text-overflow") {
				if(styleEl.hasClass("tool-button-selected")) {
			    this.setSelectedCptStyle("text-overflow", "");
					this.setSelectedCptStyle("overflow", "");
			    $("[style-setting-id='overflow']").attr("style-setting-value", "");
			    this.setSelectedCptStyle("white-space", "");
			    $("[style-setting-id='white-space']").attr("style-setting-value", "");
					styleEl.removeClass("tool-button-selected");
			  } else {
			    this.setSelectedCptStyle("text-overflow", "ellipsis");
			    this.setSelectedCptStyle("overflow", "hidden");
			    $("[style-setting-id='overflow']").attr("style-setting-value", "hidden");
			    this.setSelectedCptStyle("white-space", "nowrap");
			    $("[style-setting-id='white-space']").attr("style-setting-value", "nowrap");
					styleEl.addClass("tool-button-selected");
			  }
			}
		} else {
			var styleName = styleEl.attr("style-setting-id");
			var styleVal = "";
			var styleSettingEls = $("[style-setting-id=" + styleName + "]");
			if (styleName == "width" || styleName == "height") {
				styleName = $("[data-type='"+styleName+"-type']").attr("data-value");
				//组件大小设置需要组合输入框和下拉列表两个组件
				if (styleSettingEls.eq(0).val().trim() != "") {
					styleVal = styleSettingEls.eq(0).val().trim() + '' + styleSettingEls.eq(1).val();
				}
			} else {
				styleVal = (styleEl.val()+"").trim();
				if (styleName == "opacity") {
					styleVal = parseInt(styleVal) / 100;
				} else if (["left", "top", "font-size", "line-height", "letter-spacing", "word-spacing"].includes(styleName)
					&& styleVal.indexOf("px") < 0 && styleVal.indexOf("%") < 0
					&& styleVal.indexOf("em") < 0 && styleVal.indexOf("rem") < 0
					&& styleVal.indexOf("cm") < 0 && styleVal != "0") {
					if(styleVal!="") styleVal += "px";
				} else if(styleName=="background-position") {
					if(styleSettingEls.eq(0).val() != "" && styleSettingEls.eq(1).val() != "") {
						styleVal = styleSettingEls.eq(0).val() + " " + styleSettingEls.eq(1).val();
					} else if(styleSettingEls.eq(0).val() != "") {
						styleVal = styleSettingEls.eq(0).val() + " center";
					} else if(styleSettingEls.eq(1).val() != "") {
						styleVal = "center "+styleSettingEls.eq(1).val();
					}
				} else if(styleName=="background-size") {
					let width = styleSettingEls.eq(0).val().trim();
					if(width!="" && width.indexOf("px")<0 && width.indexOf("%")<0) width += "px";
					let height = styleSettingEls.eq(1).val().trim();
					if(height!="" && height.indexOf("px")<0 && height.indexOf("%")<0) height += "px";
					if(width!= "" && height != "") {
						styleVal = width + " " + height;
					} else if(width != "") {
						styleVal = width + " auto";
					} else if(height != "") {
						styleVal = "auto "+height;
					}
				}
			}
			this.setSelectedCptStyle(styleName, styleVal);
		}
	}

	/***************************************** 属性设置 ******************************************/

	/**
	 * 设置组件属性列表
	 * @param {[type]} cpt     [description]
	 */
	this.setCptAttrList = function (cpt) {
		var cptTypeInfo = tfp.type(cpt.type);
		if (!cptTypeInfo) {
			alert('不支持组件类型：' + cpt.type);
			return;
		}
		var divCptAttrs = $("#uiDesignerRightBar").find(".option-page").eq(0);
		divCptAttrs.html("");
		var cptAttrGroupBase = {
			name: "baseInfo",
			comment: "基本信息",
			items: [{
				name: "id",
				comment: "组件编号",
				type: "String"
			},{
				name: "type",
				comment: "组件类型",
				type: "String",
				readonly: true
			}]
		};
		if (!cpt.isInvisible) {
			cptAttrGroupBase.items.push({
				name: "class",
				comment: "样式类",
				type: "String"
			});
			cptAttrGroupBase.items.push({
				name: "style",
				comment: "自定义样式",
				type: "String"
			});
		}
		this.addCptAttrSettingGroup(cpt, cptAttrGroupBase);

		if (cptTypeInfo.attrs) {
			var attrOtherGroup = null;
			for (var i = 0; i < cptTypeInfo.attrs.length; i++) {
				var attr = cptTypeInfo.attrs[i];
				if (attr.type.toLowerCase() == "group" || attr.items) {
					this.addCptAttrSettingGroup(cpt, attr);
				} else {
					if(!attrOtherGroup) {
						attrOtherGroup = {
							name: "other",
							comment: "其他",
							items: []
						};
					}
					attrOtherGroup.items.push(attr);
				}
			}
			if(attrOtherGroup) {
				this.addCptAttrSettingGroup(cpt, attrOtherGroup);
			}
		}
	};

	/**
	   * 添加组件属性设置分组栏
	   * @param {[type]} cpt  [description]
	   * @param {[type]} attr [description]
	   */
	this.addCptAttrSettingGroup = function (cpt, attr) {
		var groupId = "cptAttrGroup_" + cpt.id + "_" + attr.name;
		var groupName = attr.comment;
		if (!groupName) groupName = attr.name;
		var divCptAttrs = $("#uiDesignerRightBar").find(".option-page").eq(0);
		let attrStyle = "";
		if (attr.hidden) {
			let hiddenAttr = false;
			if (typeof (attr.hidden) == "string") {
				if (attr.hidden.indexOf("{") >= 0 && attr.hidden.indexOf("}") >= 0) {
					try {
						if (eval("(" + tfp.replaceDataField(cpt.dataModel, attr.hidden) + ")")) {
							hiddenAttr = true;
						}
					} catch (e) {
						console.log(e);
					}
				} else if (attr.hidden.trim() == "true") {
					hiddenAttr = true;
				}
			} else {
				hiddenAttr = true;
			}
			if (hiddenAttr) attrStyle += " style=\"display:none;\"";
		}
		divCptAttrs.append("<div id=\"" + groupId + "\" class=\"cpt-attr-group\" "+attrStyle+">"
			+ "<img src=\"../taskbuilder-renderer/images/arrow/down.png\" style=\"margin-top:2px;\" />"
			+ "<label style=\"color:#ffffff;\">" + groupName + "</label></div>");
		divCptAttrs.append("<div id=\"" + groupId + "_items\" "
			+ "class=\"cpt-attr-group-items\" "+attrStyle+"></div>");
		if (attr.items) {
			for (var i = 0; i < attr.items.length; i++) {
				var item = attr.items[i];
				if (attr.isStyle) item.isStyle = true;
				this.addCptAttrSettingRow(cpt, item, groupId);
			}
		}
		$("#" + groupId).click(function () {
			var _groupId = $(this).attr("id");
			if ($("#" + _groupId + "_items").is(":visible")) {
				$("#" + _groupId).find("img").attr("src", "../taskbuilder-renderer/images/arrow/right.png");
				$("#" + _groupId + "_items").hide();
			} else {
				$("#" + _groupId).find("img").attr("src", "../taskbuilder-renderer/images/arrow/down.png");
				$("#" + _groupId + "_items").show();
			}
		});
	};

	/**
	   * 添加组件属性设置行
	   * @param {[type]} cpt     [description]
	   * @param {[type]} attr    [description]
	   * @param {[type]} groupId [description]
	   */
	this.addCptAttrSettingRow = function (cpt, attr, groupId) {
		var attrVal = cpt[attr.name];
    var divCptAttrs = $("#uiDesignerRightBar").find(".option-page").eq(0);
		var parent = divCptAttrs;
		var prefix = "";
		if (groupId) parent = $("#" + groupId + "_items");

		var attrHtml = "<div class=\"cpt-attr\" attr-name=\"" + attr.name + "\"";
		let attrStyle = "";
		if (attr.hidden) {
			let hiddenAttr = false;
			if (typeof (attr.hidden) == "string") {
				if (attr.hidden.indexOf("{") >= 0 && attr.hidden.indexOf("}") >= 0) {
					try {
						if (eval("(" + tfp.replaceDataField(cpt.dataModel, attr.hidden) + ")")) {
							hiddenAttr = true;
						}
					} catch (e) {
						console.log(e);
					}
				} else if (attr.hidden.trim() == "true") {
					hiddenAttr = true;
				}
			} else {
				hiddenAttr = true;
			}
			if (hiddenAttr) attrStyle += "display:none;";
		}
		let attrType = attr.type.toLowerCase();
		if(attrType=="switch") attrStyle += "height:30px;";
		if(attrStyle!="") attrHtml += " style=\""+attrStyle+"\"";
		attrHtml += "><div class=\"cpt-attr-name\"";
		if(attrType=="switch") attrHtml += " style=\"float:left;\"";
		let attrName = attr.name;
		if(attr.comment) attrName = attr.comment;
		attrHtml += ">" + attrName + "</div>";
		if (attrType == "select") {
			attrHtml += "<div class=\"cpt-attr-val\">";
			if (attr.readonly) {
				attrHtml += "<input type=\"text\" style=\"background-color:#333333;\" readonly";
				if (attrVal && attr.options) {
					for (var j = 0; j < attr.options.length; j++) {
						if (attrVal == attr.options[j].value) {
							attrHtml += " value=\"" + attr.options[j].text + "\"";
							break;
						}
					}
				}
				attrHtml += " />";
			} else {
				attrHtml += "<select style=\"background-color:#222222;\" >";
				if (attr.options) {
					attrHtml += "<option value=\"\"></option>";
					for (var j = 0; j < attr.options.length; j++) {
						attrHtml += "<option value=\"" + attr.options[j].value + "\"";
						if (attrVal == attr.options[j].value) attrHtml += " selected";
						attrHtml += ">" + attr.options[j].text + "</option>";
					}
				}
				attrHtml += "</select>";
			}
			attrHtml += "</div>";
		} else if (attrType == "service") {
			attrHtml += "<div class=\"cpt-attr-val\">";
			attrHtml += "<select style=\"background-color:#222222;\" >";
			attrHtml += "<option value=\"\"></option>";
			var isInvisibleCpts = $("#uiDesignerInvisibleCpts").find("[id]");
			for (var i = 0; i < isInvisibleCpts.length; i++) {
				var cptService = tfp.components[isInvisibleCpts.eq(i).attr("id")];
				if (cptService.type == "Service") {
					attrHtml += "<option value=\"" + cptService.id + "\"";
					if (attrVal == cptService.id) attrHtml += " selected";
					attrHtml += ">" + cptService.id + "</option>";
				}
			}
			attrHtml += "</select>";
			attrHtml += "</div>";
		} else if (attrType == "switch") {
			attrHtml += "<div class=\"switch\"><div";
			if (attrVal) attrHtml += " style=\"float: right; background-color:#0099ff;\"";
			attrHtml += "></div></div>";
		} else if (attrType == "dataset") {
			attrHtml += "<div class=\"cpt-attr-dataset\"><label>(数据集)</label><label>...</label></div>";
		} else if (attrType == "formula") {
			attrHtml += "<div class=\"cpt-attr-formula\"><label>(表达式)</label><label>...</label></div>";
		} else {
			attrHtml += "<div class=\"cpt-attr-val\">";
			attrHtml += "<input type=\"";
			if (attrType == "int") {
				attrHtml += "number";
			} else {
				attrHtml += "text";
			}
			attrHtml += "\"";
			if (attrVal != null && attrVal != undefined) attrHtml += " value=\"" + attrVal + "\"";
			if (attr.readonly || attrType == "servicepicker") {
				attrHtml += " style=\"background-color:#333333;\" readonly";
			} else {
				attrHtml += " style=\"background-color:#222222;\"";
			}
			attrHtml += " />";
			attrHtml += "</div>";
		}
		attrHtml += "</div>";
		parent.append(attrHtml);

		var attrValueEl;

		if (attrType == "pathpicker") {
			attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find("input");
			attrValueEl.click(function () {
				that.showPathPicker(attr);
			});
			return;
		} else if (attrType == "servicepicker") {
			attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find("input");
			attrValueEl.click(function () {
				that.showServicePicker(attr);
			});
			return;
		} else if(attr.name=="class") {
			attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find("input");
			attrValueEl.dblclick(function() {
				that.setCptStyleClass(this);
			});
			return;
		}

		if (!attr.readonly) {
			if (attrType == "select" || attrType == "service") {
				attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find("select");
			} else if (attrType == "switch") {
				attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find(".switch");
				attrValueEl.click(function () {
					var _attrName = $(this).parent().attr("attr-name");
					if ($(this).find("div").css("float") == "left") {
						$(this).find("div").css("float", "right");
						$(this).find("div").css("background-color", "#0099ff");
						that.setCurCptAttr(_attrName, true);
					} else {
						$(this).find("div").css("float", "left");
						$(this).find("div").css("background-color", "#999999");
						that.setCurCptAttr(_attrName, false);
					}
				});
			} else if (attrType == "dataset") {
				attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find(".cpt-attr-dataset");
				attrValueEl.click(function () {
					let isPro = false;
					if(attr.isPro) isPro = true;
					that.showAttrDataSet(attr, isPro);
				});
			} else if (attrType == "formula") {
				attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find(".cpt-attr-formula");
				attrValueEl.click(function () {
					that.showAttrFormula(attr);
				});
			} else {
				attrValueEl = divCptAttrs.find("[attr-name=" + attr.name + "]").find("input");
			}
			if (attrValueEl && (attrType != "switch" && attrType != "dataset")) {
				attrValueEl.change(function () {
					var _attrName = $(this).parent().parent().attr("attr-name");
					var _attrVal = $(this).val();
					//如果是后台服务类属性，要设置与服务组件的关系，以便在请求服务后给组件绑定数据
					if (attrType == "service") {
						//如果原来该属性有值，需要先跟原服务解绑
						if (cpt[_attrName]) {
							let oldService = tfp.components[cpt[_attrName]];
							if (oldService && oldService.dataModel.bindComponents) {
								oldService.dataModel.bindComponents.remove(cpt.id);
							}
						}
						//绑定新的服务
						if (_attrVal) {
							let newService = tfp.components[_attrVal];
							if (!newService.dataModel.bindComponents) newService.dataModel.bindComponents = [];
							if (newService) {
								newService.dataModel.bindComponents.push(cpt.id);
							}
						}
					}
					that.setCurCptAttr(_attrName, _attrVal);
				});
			}
		}
	};

	this.showAttrSettingRow = function(attrName) {
		$("[attr-name='" + attrName + "']").show();
	}

	this.hideAttrSettingRow = function(attrName) {
		$("[attr-name='" + attrName + "']").hide();
	}

	/**
	 * 设置当前组件的属性设置
	 * @param {[type]} attrName [description]
	 * @param {[type]} val    [description]
	 */
	this.setCurCptAttrSettingVal = function (attrName, val) {
		var cpt = tfp.components[this.curSelectedCptId];
		if (!cpt) return;
		var attr = tfp.attrType(cpt.metadata, attrName);
		if (!attr) return;
		var attrSettingEl = $("[attr-name='" + attrName + "']");
		let attrType = attr.type.toLowerCase();
		if (attrType == "select") {
			if (attr.readonly) {
				attrSettingEl.find("input").val(val);
			} else {
				attrSettingEl.find("select").val(val);
			}
		} else if (attrType == "switch") {
			if (val) {
				attrSettingEl.find(".switch").find("div").css("float", "right");
				attrSettingEl.find(".switch").find("div").css("background-color", "#0099ff");
			} else {
				attrSettingEl.find(".switch").find("div").css("float", "left");
				attrSettingEl.find(".switch").find("div").css("background-color", "#999999");
			}
		} else if (attrType == "dataset") {
			//
		} else {
			attrSettingEl.find("input").val(val);
		}
	};

	/**
	 * 设置当前组件的属性
	 * @param {[type]} attr [description]
	 * @param {[type]} val  [description]
	 */
	this.setCurCptAttr = function (attrName, val) {
		var cpt = tfp.components[this.curSelectedCptId];
		if (!cpt) return;
		if (cpt._jqObj.length==0) return;

		if (attrName == "id" && cpt.id != val) {
			if (tfp.components[val]) {
				alert("ID为" + val + "的组件已存在！");
				$("[attr-name='id']").find("input").focus();
				return;
			}
			this.curSelectedCptId = val;
			$("#cptTreeNode_" + cpt.id).attr("id", "cptTreeNode_" + val);
			$("#cptTreeNodeChilds_" + cpt.id).attr("id", "cptTreeNodeChilds_" + val);
			if (cpt.dataModel.components) {
				$("#cptTreeNode_" + val).find("label").text(val);
			} else {
				$("#cptTreeNode_" + val).html("&nbsp;&nbsp;·&nbsp;" + val);
			}
		  if (cpt.isInvisible) {
	    	$("#"+cpt.id).find("label").text(val);
	    	$("#"+cpt.id).attr("id", val);
	    }
			/*if(cpt.type=="Text" || cpt.type=="TextArea") {
				cpt.placeholder = "请输入"+cpt.id;
				cpt._jqObj.attr("placeholder", cpt.placeholder);
			}*/
	    cpt.id = val;
		}

		//设置对话框设计时属性
		if (cpt.type == "Page" && cpt.pagetype == "dialog") {
			if (attrName == "width") {
				if (val.indexOf("px") < 0) val += "px";
				//$(".tfp-dialog-header").css(attrName, val);
				//$(".tfp-dialog-content").css(attrName, val);
			} else if (attrName == "height") {
				val = parseInt((val + "").replace("px", ""));
				//$(".tfp-dialog-content").css(attrName, (val - 33) + "px");
				val = val + "px";
			} else if (attrName == "title") {
				//$(".tfp-dialog-title").html(val);
			}
		}

		if(attrName=="class" || attrName=="style") {
			cpt[attrName] = val;
			return;
		}

		if(cpt.attrTypes) {
			for(var i=0;i<cpt.attrTypes.length;i++) {
				let attr = cpt.attrTypes[i];
				if(attr.name==attrName) {
					cpt[attrName] = val;
					break;
				}
			}
		}
	}

	/**
	 * 显示数据集设置控件
	 * @param  {[type]} attrName [description]
	 * @return {[type]}        [description]
	 */
	this.showAttrDataSet = function (attr, isPro) {
		var cpt = tfp.components[this.curSelectedCptId];
		if (!cpt) return;
		var args = {
			dataset: attr,
			val: cpt[attr.name]
		};
		if (cpt.type == "Switch") {
			args.val = [];
			for (var i = 0; i < cpt[attr.name].length; i++) {
				args.val.push({ value: cpt[attr.name][i] });
			}
		}

		if (args.dataset && args.dataset.columns) {
			let haveEventSetting = false;
			for (var i = 0; i < args.dataset.columns.length; i++) {
				let col = args.dataset.columns[i];
				if (col.type.toLowerCase() == "event") {
					haveEventSetting = true;
					break;
				}
			}
			if (haveEventSetting) {
		    args.clientType = tfp.curPage.client;
		    args.components = [];
		    args.metadatas = {};
		    for (let cptId in tfp.components) {
		      let cptTmp = tfp.components[cptId];
		      if(cptTmp.type=="Page") continue;
		      args.components.push({ id: cptId, type: cptTmp.type });
		      if(!args.metadatas[cptTmp.type]) args.metadatas[cptTmp.type] = tfp.type(cptTmp.type);
		    }
		    if (tfp.curPage.dataModel.jsFuncs) {
		      args.funcs = [];
		      for (var i = 0; i < tfp.curPage.dataModel.jsFuncs.length; i++) {
		        let func = tfp.curPage.dataModel.jsFuncs[i];
		        args.funcs.push({
		          name: func.name,
		          comment: func.comment,
		          args: func.args
		        });
		      }
		    }
			}
		}

		let dialogWidth = "480px";
		let dialogHeight = "360px";
		if(attr.width) {
			dialogWidth = attr.width+"";
			dialogWidth = dialogWidth.replace("%", "");
			if(dialogWidth.indexOf("px")<0) dialogWidth += "px";
		}
		if(attr.height) {
			dialogHeight = attr.height+"";
			dialogHeight = dialogHeight.replace("%", "");
			if(dialogHeight.indexOf("px")<0) dialogHeight += "px";
		}
		
		let settingPagePath = "taskbuilder-tfp-designer/DataSetSetting";
		if(isPro) settingPagePath += "Pro";
		settingPagePath += ".html";

		openDialog("设置数据集", settingPagePath, dialogWidth, dialogHeight,
			JSON.stringify(args), function (ret) {
				if (cpt.type == "Select" || cpt.type == "Radio" || cpt.type == "CheckBox") {
					cpt.options = ret;
				} else if (cpt.type == "Switch") {
					if (ret.length != 2) {
						alert("开关组件必须设置两个可选值");
						return;
					}
					let switchVal = [];
					for (var i = 0; i < ret.length; i++) {
						switchVal.push(ret[i].value);
					}
					cpt[attr.name] = switchVal;
				} else {
					cpt[attr.name] = ret;
				}
				that.curSelectedCptId = null;
				that.selectCpt(cpt.id);
			});
	};

  /**
	 * 显示计算表达式设计器
	 * @param  {[type]} attrName [description]
	 * @return {[type]}        [description]
	 */
	this.showAttrFormula = function (attr) {
		var cpt = tfp.components[this.curSelectedCptId];
		if (!cpt) return;
		var args = {
			val: cpt[attr.name]
		};
		args.components = [];
    args.metadatas = {};
    for (let cptId in tfp.components) {
      let cptTmp = tfp.components[cptId];
      if(cptTmp.isFormInput || cptTmp.type=="DataSet") 
      	args.components.push({ id: cptId, type: cptTmp.type });
      //if(!args.metadatas[cptTmp.type]) args.metadatas[cptTmp.type] = tfp.type(cptTmp.type);
    }
    if (tfp.curPage.dataModel.jsFuncs) {
      args.funcs = [];
      for (var i = 0; i < tfp.curPage.dataModel.jsFuncs.length; i++) {
        let func = tfp.curPage.dataModel.jsFuncs[i];
        args.funcs.push({
          name: func.name,
          comment: func.comment,
          args: func.args
        });
      }
    }

		openDialog("设置计算表达式", "taskbuilder-tfp-designer/FormulaSetting.html", 
			"900px", "540px", JSON.stringify(args), function (ret) {
				if(!ret || ret.trim()=="") {
					cpt[attr.name] = null;
				} else {
				  cpt[attr.name] = ret;
			  }
			});
	};

	/**
	 * 显示路径选择器
	 * @param  {[type]} attr [description]
	 * @return {[type]}      [description]
	 */
	this.showPathPicker = function (attr) {
		var cpt = tfp.components[that.curSelectedCptId];
		if (!cpt) return;
		var filePath = "";
		if (cpt[attr.name]) filePath = cpt[attr.name];

		let args = {
			path: filePath,
			fileTypes: attr.fileTypes
		};

		openDialog("选择文件路径", "taskbuilder-tfp-designer/PathPicker.html", "480px", "480px",
		  JSON.stringify(args), function (ret) {
			let filePath = ret;
			if (ret.startsWith("/web/")) filePath = ret.substr(5);
			$(".cpt-attr[attr-name=" + attr.name + "]").find("input").val(filePath);
			cpt[attr.name] = filePath;
		});
	}

	/**
	 * 显示服务选择器
	 * @param  {[type]} attr [description]
	 * @return {[type]}      [description]
	 */
	this.showServicePicker = function (attr) {
		var cpt = tfp.components[that.curSelectedCptId];
		if (!cpt) return;
		var servicePath = "";
		if (cpt[attr.name]) servicePath = cpt[attr.name];

		let args = {
			path: servicePath,
			fileTypes: ["service"]
		};

		openDialog("选择服务路径", "taskbuilder-tfp-designer/PathPicker.html", "480px", "480px",
		  JSON.stringify(args), function (ret) {
			let servicePath = ret;
			if (ret.startsWith("/app/")) servicePath = ret.substr(5);
			$(".cpt-attr[attr-name=" + attr.name + "]").find("input").val(servicePath);
			cpt[attr.name] = servicePath;
		});
	}

	this.setCptStyleClass = function (ipt) {
		var args = {
			cssClass: $(ipt).val(),
			styleSheets: []
		};

		if (tfp.curPage.styleSheets) {
			for (var i = 0; i < tfp.curPage.styleSheets.length; i++) {
				let styleSheet = tfp.curPage.styleSheets[i];
				if (styleSheet.id.startsWith(".")) {
					args.styleSheets.push(styleSheet.id.substr(1));
				}
			}
		}

		openDialog("设置数据集", "taskbuilder-tfp-designer/setCssClass.html", "340px", "360px",
			JSON.stringify(args), function (cssClass) {
				$(ipt).val(cssClass);
				that.setCurCptAttr("class", cssClass)
			});
	}

	/***************************************** 事件设置 ******************************************/

	/**
	 * 设置组件事件列表
	 * @param {[type]} cpt     [description]
	 */
	this.setCptEventList = function (cpt) {
		var divCptEvents = $("#uiDesignerRightBar").find(".option-page").eq(1);
		divCptEvents.html("");
		var cptTypeInfo = tfp.type(cpt.type);
		if (!cptTypeInfo) return;
		if (cptTypeInfo.events) {
			for (var i = 0; i < cptTypeInfo.events.length; i++) {
				var eventInfo = cptTypeInfo.events[i];
				var eventName = "";
				var eventComment = "";
				if (typeof eventInfo === 'string') {
					eventName = eventInfo;
					eventComment = eventInfo;
				} else {
					eventName = eventInfo.name;
					eventComment = eventInfo.comment;
				}
				var eventVal = "";
				if (cpt.dataModel[eventName]) eventVal = cpt.dataModel[eventName];
				var eventHtml = "";
				eventHtml = "<div class=\"cpt-event\"><div class=\"cpt-event-name\">" 
				  + eventComment + "</div><div class=\"cpt-event-val\">";
				eventHtml += "<input type=\"text\"\" id=\"iptEvent_" + eventName + "\"";
				if (eventVal) eventHtml += " value=\"" + eventVal + "\"";
				eventHtml += " /></div></div>";
				divCptEvents.append(eventHtml);
			}
			$(".cpt-event").find("input").each(function () {
				let eventEl = $(this);
				eventEl.blur(function () {
					let eventName = $(this).attr("id").replace("iptEvent_", "");
					let eventVal = eventEl.val();
					if(!eventVal) {
						delete cpt.dataModel[eventName];
					} else {
					  cpt.dataModel[eventName] = eventVal;
				  }
				});
				eventEl.dblclick(function () {
					let eventName = $(this).attr("id").replace("iptEvent_", "");
					let funcName = that.curSelectedCptId+"_"+eventName;
					if($(this).val().trim()!="") {
						funcName = $(this).val().trim();
						if(funcName.indexOf("(")>0) funcName = funcName.substr(0, funcName.indexOf("("));
					}
					console.log(funcName);

					let curCpt = tfp.components[that.curSelectedCptId];

					if(tfp.curPage.dataModel.jsFuncs) {
			      for(var i=0;i<tfp.curPage.dataModel.jsFuncs.length;i++) {
			        let funcTmp = tfp.curPage.dataModel.jsFuncs[i];
			        if(funcTmp.name==funcName) {
			        	tfpDesigner.showDesigner("JS");
			        	jsEditor.selectFunc(funcTmp);
			        	if($(this).val().trim()=="" || $(this).val().indexOf("(")<0) {
			        		curCpt.dataModel[eventName] = funcName;
			        		let funcStr = funcName+"(";
			        		if(funcTmp.args) {
			        			for(let j=0;j<funcTmp.args.length;j++) {
			        				if(j>0) funcStr += ", ";
			        				funcStr += funcTmp.args[j].name;
			        			}
			        		}
			        		funcStr += ")";
			        		$(this).val(funcStr);
			        	}
			          return;
			        }
			      }
			    }

			    //如果设置的不是页面函数，则不执行后续操作
			    if($(this).val().trim()!="") return;

			    let funcNew = {
			    	name: funcName,
		        comment: "",
		        editType: "code",
			    	args: []
			    };

			    let metadata = tfp.type(curCpt.type);
			    let eventInfo = null;
				  for (var j = 0; j < metadata.events.length; j++) {
					  if(metadata.events[j].name==eventName) {
					  	eventInfo = metadata.events[j];
					  	break;
					  }
					}
					if(!eventInfo) return;

					if(eventInfo.comment) funcNew.comment = eventInfo.comment;
					if(eventInfo.args) funcNew.args = eventInfo.args;

			    if(!tfp.curPage.dataModel.jsFuncs) tfp.curPage.dataModel.jsFuncs = [];
			    tfp.curPage.dataModel.jsFuncs.push(funcNew);
			    curCpt.dataModel[eventName] = funcName;
			    let funcStr = funcName+"(";
      		if(funcNew.args) {
      			for(let j=0;j<funcNew.args.length;j++) {
      				if(j>0) funcStr += ", ";
      				funcStr += funcNew.args[j].name;
      			}
      		}
      		funcStr += ")";
      		$(this).val(funcStr);

		      if(jsEditor.isInit) jsEditor.addFunc(funcNew);
		      tfpDesigner.showDesigner("JS");
			    jsEditor.selectFunc(funcNew);
				});
			});
		}
	}

	/***************************************** 复制粘贴组件 ****************************************/

	this.copyCpts = function () {
		if (this.curSelectedCptId) {
			let curCpt = tfp.components[this.curSelectedCptId];
			if(curCpt.type=="Page") return;
			this.clipboard = [JSON.parse(JSON.stringify(curCpt.dataModel))];
		} else if (this.selectedCpts.length > 0) {
			this.clipboard = [];
			for (var i = 0; i < this.selectedCpts.length; i++) {
				let cpt = tfp.components[this.selectedCpts[i]];
				this.clipboard.push(JSON.parse(JSON.stringify(cpt.dataModel)));
			}
		}
	}

	this.cutCpts = function () {
		if (this.curSelectedCptId) {
			let curCpt = tfp.components[this.curSelectedCptId];
			if(curCpt.type=="Page") return;
			this.clipboard = [JSON.parse(JSON.stringify(curCpt.dataModel))];
			this.delCpt(this.curSelectedCptId);
			this.selectCpt(tfp.curPage.id);
		} else if (this.selectedCpts.length > 0) {
			this.clipboard = [];
			for (var i = 0; i < this.selectedCpts.length; i++) {
				let cpt = tfp.components[this.selectedCpts[i]];
				this.clipboard.push(JSON.parse(JSON.stringify(cpt.dataModel)));
			}
			this.delCpts();
		}
	}

	this.cloneCpt = function (cdm) {
		var parentCpt = tfp.curPage;
		if (this.curSelectedCptId)
			parentCpt = tfp.components[this.curSelectedCptId];
		if(!parentCpt || !parentCpt.isContainer) return;
		delete cdm["id"];
		if (!cdm.styles) cdm.styles = {};
		if(tfp.curPage.positionType=="absolute") {
			cdm.styles["position"] = "absolute";
			var left = 100;
			var top = 100;
			if (cdm.styles["left"]) left = parseInt(cdm.styles["left"].replace("px", "")) + 20;
			if (cdm.styles["top"]) top = parseInt(cdm.styles["top"].replace("px", "")) + 20;
			cdm.styles["left"] = left + "px";
			cdm.styles["top"] = top + "px";
			
			let maxZIndex = 0;
			if (parentCpt.components) {
				for (var i = 0; i < parentCpt.components.length; i++) {
					let cptBrother = tfp.get(parentCpt.components[i].id);
					if(!cptBrother) continue;
					if (cptBrother.css("z-index") && parseInt(cptBrother.css("z-index")) > maxZIndex) {
						maxZIndex = parseInt(cptBrother.css("z-index"));
					}
				}
			}
			cdm.styles["z-index"] = maxZIndex + 1;
			
			delete cdm.styles["float"];
			//delete cdm.styles["bottom"];
			//delete cdm.styles["right"];
		}
		return tfp.render(cdm, parentCpt);
	}

	this.pasteCpts = function () {
		if (!this.clipboard || this.clipboard.length == 0) return;
		if (this.clipboard.length == 1) {
			let cdm = this.clipboard[0];
			let cptNew = this.cloneCpt(cdm);
			if(cptNew) this.selectCpt(cptNew.id);
		} else {
			for (var i = 0; i < this.clipboard.length; i++) {
				let cdm = this.clipboard[i];
				this.cloneCpt(cdm);
			}
		}
	}

	/**
	 * 删除选中的组件
	 */
	this.delCpts = function () {
		if (this.curSelectedCptId) {
			if (this.curSelectedCptId == tfp.curPage.id) return;
			//var elFocus = $(document.activeElement);
			//if(elFocus.is("body") || elFocus.attr("id")==(that.curSelectedCptId+"")) {
			this.delCpt(this.curSelectedCptId);
			//}
		} else if (this.selectedCpts.length > 0) {
			for (var i = 0; i < this.selectedCpts.length; i++) {
				this.delCpt(this.selectedCpts[i]);
			}
			this.selectedCpts = [];
		}
		this.curSelectedCptId = null;
		this.selectCpt(tfp.curPage.id);
	}

	this.delChildCpts = function (cpt) {
		if (cpt.components) {
			for (var i = 0; i < cpt.components.length; i++) {
				let child = cpt.components[i];
				this.delChildCpts(child);
				delete tfp.components[child.id];
				child = null;
			}
			cpt.components = null;
		}
	}

	this.delCpt = function (cptId) {
		
		let cpt = tfp.components[cptId];
		if(!cpt) return;
		cpt._jqObj.remove();
		if (cpt.isInvisible) {
			if ($("#uiDesignerInvisibleCpts").find(".invisible-cpt").length == 0) {
				$("#uiDesignerFrame").css("bottom", "0");
				$("#uiDesignerInvisibleCpts").hide();
			}
		}

		$("#cptNode_" + cptId).remove();
		$("#cptNodeChilds_" + cptId).remove();

		//删除父组件的关联
		if (cpt.parent) {
			if (cpt.parent.components) {
				var cptIndex = -1;
				for (var i = 0; i < cpt.parent.components.length; i++) {
					var cptTmp = cpt.parent.components[i];
					if (cptTmp.id == cptId) {
						cptIndex = i;
						break;
					}
				}
				if (cptIndex >= 0) cpt.parent.components.splice(cptIndex, 1);
			}
		}

		//删除子组件
		this.delChildCpts(cpt);
		//删除自己
		delete tfp.components[cpt.id];
		cpt = null;
	}

	/****************************** 移动组件 **********************************/
	
	this.moveSelectedCpt = function (direction) {
		if (this.curSelectedCptId) {
			if (this.curSelectedCptId == tfp.curPage.id) return;
			this.moveCpt(this.curSelectedCptId, direction);
		} else if (this.selectedCpts.length > 0) {
			for (var i = 0; i < this.selectedCpts.length; i++) {
				this.moveCpt(this.selectedCpts[i], direction);
			}
		}
	};

	this.moveCpt = function (cptId, direction) {
		let cpt = tfp.components[cptId];
		//如果不是绝对定位或相对定位，则不能修改组件位置
		if (!cpt || !cpt.styles || !cpt.styles["position"]) return;

		let cptEl = cpt._jqObj;
		if (cptEl.length == 0) return;
		let parentEl = $(cpt.parent.containerEl);
		if (direction == "up") {
			let y = parseInt(cpt.styles["top"].replace("px"));
			if (y <= 0) return;
			cptEl.css("top", (y - 1) + "px");
			cpt.styles["top"] = (y - 1) + "px";
			if (this.curSelectedCptId) {
				$("input[style-setting-id=top]").val(y - 1);
			}
		} else if (direction == "down") {
			let y = parseInt(cpt.styles["top"].replace("px"));
			if ((parentEl.innerHeight() - cptEl.outerHeight(true) - y) <= 0) return;
			cptEl.css("top", (y + 1) + "px");
			cpt.styles["top"] = (y + 1) + "px";
			if (this.curSelectedCptId) {
				$("input[style-setting-id=top]").val(y + 1);
			}
		} else if (direction == "left") {
			let x = parseInt(cpt.styles["left"].replace("px"));
			if (x <= 0) return;
			cptEl.css("left", (x - 1) + "px");
			cpt.styles["left"] = (x - 1) + "px";
			if (this.curSelectedCptId) {
				$("input[style-setting-id=left]").val(x - 1);
			}
		} else if (direction == "right") {
			let x = parseInt(cpt.styles["left"].replace("px"));
			if ((parentEl.innerWidth() - cptEl.outerWidth(true) - x) <= 0) return;
			cptEl.css("left", (x + 1) + "px");
			cpt.styles["left"] = (x + 1) + "px";
			if (this.curSelectedCptId) {
				$("input[style-setting-id=left]").val(x + 1);
			}
		}
	};

	/**
	 * 添加不可视组件
	 * @param {[type]} cpt [description]
	 */
	this.addInvisibleComponent = function(cpt) {
		$("#uiDesignerInvisibleCpts").append("<div id='" + cpt.id + "' "
			+ "class='invisible-cpt'>"
			+ "<img src='../tfp/src/components/" + cpt.type.toLowerCase() + "/images/icon-light.png' />"
			+ "<label>" + cpt.id + "</label></div>");
		$("#uiDesignerFrame").css("bottom", "42px");
		$("#uiDesignerInvisibleCpts").show();
		cpt._jqObj = $("#"+cpt.id);
	};

	/****************************** 初始化 ************************************/

	/**
	 * 初始化UI设计器
	 */
	this.init = function(tfpSrc) {
		this.onResize();

    $("#borderStyleList").children("div").click(function() {
    	if(!that.curBorderStyleEl) return;
    	that.curBorderStyleEl.find("div").css("border-top", $(this).find("div").css("border-top"));
    	that.curBorderStyleEl.attr("style-setting-value", $(this).attr("border-style"));
    	that.curBorderStyleEl.css("border", "1px solid #999999");
    });

    $("#borderStyleSetting").find(".color-picker").click(function() {
    	colorPicker.show($(this));
    });

    $("#shadowStyleSetting").find(".color-picker").click(function() {
    	colorPicker.show($(this));
    });

    $("#styleSetting_font").find(".color-picker").click(function() {
    	colorPicker.show($(this), function(color) {
    		that.setSelectedCptStyle("color", color);
    	});
    });

    $("#styleSetting_background").find(".color-picker").click(function() {
    	colorPicker.show($(this), function(color) {
    		that.setSelectedCptStyle("background-color", color);
    	});
    });

    $("#cursorStyleList").children("div").click(function() {
    	if(!that.curCursorStyleEl) return;
    	that.curCursorStyleEl.attr("style-setting-value", $(this).attr("cursor-style"));
    	that.curCursorStyleEl.find("img").eq(0).attr("src", $(this).find("img").attr("src"));
    	that.setSelectedCptStyle("cursor", $(this).attr("cursor-style"));
    });

    //如果是输入框或下拉列表，则监听值发生改变事件
		$("#uiToolBarContainer").find("input").change(function () {  
			that.cptStyleOnChange($(this));
		});
		$("#uiToolBarContainer").find("select").change(function () {  
			that.cptStyleOnChange($(this));
		});

		$("#styleSetting_font").find(".tool-button").click(function() {
			that.cptStyleOnChange($(this));
		});

		$("#styleSetting_font_ex").find(".tool-button").click(function() {
			that.cptStyleOnChange($(this));
		});

		//设置左侧面板选项卡切换操作
		$("#uiDesignerLeftBar").find(".option-bar").children().click(function () {
			that.optionBarOnClick("LeftBar", this);
		});

		//设置右侧面板选项卡切换操作
		$("#uiDesignerRightBar").find(".option-bar").children().click(function () {
			that.optionBarOnClick("RightBar", this);
		});

		let divDesignerFrame = $("#uiDesignerFrame");
		let uiDesignerPageTitle = $("#uiDesignerPageTitle");
		let divDesignerPageContent = $("#uiDesignerPageContent");
		let designerFrame = divDesignerPageContent.find("iframe");
		if(tfpSrc.client=="phone") {
			$("#uiDesignerCenter").css("background-color", "#fff");
			$("#uiDesignerCenter").css("overflow", "auto");
			let left = Math.round(($("#uiDesignerCenter").width() - 433)/2);
			if(left<0) left = 0;
			divDesignerFrame.css("top", "10px");
			divDesignerFrame.css("left", left+"px");
			divDesignerFrame.css("margin-bottom", "20px");
			divDesignerFrame.css("width", "433px");
			divDesignerFrame.css("height", "865px");
			divDesignerFrame.css("background-image", "url(images/phone_bg.png)");
			uiDesignerPageTitle.css("top", "70px");
			uiDesignerPageTitle.css("left", "59px");
			uiDesignerPageTitle.css("width", "315px");
			uiDesignerPageTitle.css("overflow", "hidden");
			uiDesignerPageTitle.css("font-size", "16px");
			uiDesignerPageTitle.css("text-align", "center");
			uiDesignerPageTitle.css("color", "#333333");
			uiDesignerPageTitle.html(tfpSrc.title);
			uiDesignerPageTitle.show();
			divDesignerPageContent.css("top", "112px");
			divDesignerPageContent.css("left", "29px");
			divDesignerPageContent.css("height", "660px");
			divDesignerPageContent.css("width", "373px");
			divDesignerPageContent.css("overflow", "auto");
			divDesignerPageContent.css("background-color", "#FFFFFF");
			divDesignerPageContent.css("border-bottom", "1px solid #cccccc");
		} else if(tfpSrc.pageType=="dialog") {
			divDesignerFrame.css("top", "10px");
			divDesignerFrame.css("left", "10px");
			divDesignerFrame.css("right", "");
			divDesignerFrame.css("bottom", "");
			divDesignerFrame.css("width", tfpSrc.width);
			divDesignerFrame.css("height", (parseInt(tfpSrc.height.replace("px", "")))+"px");

			divDesignerPageContent.css("top", "30px");
			divDesignerPageContent.css("overflow", "auto");
			
			uiDesignerPageTitle.html("&nbsp;&nbsp;"+tfpSrc.title);
			//uiDesignerPageTitle.css("width", tfpSrc.width);
			if(tfpSrc.bgColorMode=="dark") {
			  uiDesignerPageTitle.css("background-color", "#444");
			  uiDesignerPageTitle.css("color", "#fff");
			  divDesignerFrame.css("border", "1px solid #666");
			} else {
			  uiDesignerPageTitle.css("background-color", "#EEE");
			  uiDesignerPageTitle.css("color", "#333333");
			  divDesignerFrame.css("border", "1px solid #CCC");
			}
			uiDesignerPageTitle.show();
		} else {
			divDesignerFrame.css("background-color", "#222222");
			//designerFrame.css("height", divDesignerFrame.height()+"px");
		}
		designerFrame.load(function() {
			that.pageFrameWin = this.contentWindow;
			window.tfp = that.pageFrameWin.tfp;
			that.pageFrameWin.initPage(tfpSrc);
		});
		designerFrame.attr("src", "page.html");
	}
}

var uiDesigner = new TFPUIDesigner();
