/*
* KisFlow.js
* Copyright(C) 2011 guiping ling <pingerlin@163.com>
* Site http://www.felinsoft.cn/
* Create: 2011-12-10
*  Description: workflow designer for web
*/

var EventUtile =
{
	addEvent : function(element, type, handler){
		if(element.addEventListener)
			element.addEventListener(type, handler, false);
		else if(element.attachEvent)
			element.attachEvent('on'+type, handler);
		else
			element['on'+type] = handler();	
	},
	
	delEvent : function(element, type, handler){
	if(element.removeEventListener)
			element.removeEventListener(type, handler, false);
		else if(element.detachEvent)
			element.detachEvent('on'+type, handler);
		else
			element['on'+type] = null;		
	}
};

var KisFlow = 
{
	//画笔类型
	BRUSH_SELECT:0, 
	//BRUSH_TEXT  :1, 
	BRUSH_STATE :1,
	BRUSH_ACTION:2,
	BRUSH_REDO:3,
	BRUSH_SAVE:4,
	BRUSH_NEW:5,
	BRUSH_DEL:6,
	
	//对象类型
	OBJECT_STATE : 1,
	OBJECT_ACTION: 2,
	OBJECT_MARK  : 3,
	OBJECT_PLACE : 4,
	OBJECT_TEXT  : 5,
	
	//状态对象宽度
	OBJ_STATE_WIDTH  : 80,
	//状态对象高度
	OBJ_STATE_HEIGHT : 40,
	
	STATE_SELECT 	: 0, //流程状态_对象选择状态
	STATE_ADD_STATE : 1, //流程状态_增加对象状态
	STATE_ADD_ACTION: 2, //流程状态_增加动作状态
	STATE_CHARTING_ACTION: 3,//流程状态_描绘动作状态
	STATE_MOVING_STATE : 4, //流程状态_移动对象状态
	
	shape_group : "<v:group style='position:relative;' coordsize='0,0' />",
	shape_img : "<v:image style='position:relative;' />",
	shape_rect : "<v:Rect style='position:relative;' />",
	shape_roundrect : "<v:RoundRect style='position:relative;' oncontextmenu='setMenu(this, 1);'  />",
	shape_polyline : "<v:PolyLine style='position:absolute;' Points='0,0' filled='false' cursor:crosshair' oncontextmenu='setMenu(this, 2);'  />",
	shape_text : "<v:TextBox style='position:relative;font-size:9pt;' />",
	
	flow_id : 0,
	flow_name : '',
	state_set:[], //状态集合
	action_set:[],//动作集合
	mark_set:[], //标记集合
	state_id : 0,
	action_id : 0,
	mark_id : 0,
	
	left : 0, 
	top : 0, 
	width : 0, 
	height : 0,
	flow_state:0,
	flag_focus:1,
	flag_move:1,
	flag_charting:0,	
	current_brush:0,
	focus_object:null,
	
	_init : function(l,t,w,h)
	{
		try{
			this.left = l;
			this.top =t;
			this.width = w;
			this.height = h;
			this.corder_x = w;
			this.corder_y = h;
			
			this.group_str = "<table border=0 cellspacing=0 cellpadding=0 width='"+this.width+"' height='"+this.height+"' bgcolor='#000000'>";
			this.group_str += "<tr>";
			this.group_str += "<td bgcolor='#ffffff'>";
			this.group_str += "<v:group ID='flow_group' style='position:absolute; left:"+this.left+"; top:"+this.top+"; width:"+this.width+";height:"+this.height+";' coordsize='"+this.corder_x+","+this.corder_y+"' />";
			this.group_str += "</td>";
			this.group_str += "</tr>";
			this.group_str += "</table>";
			$('#span_flow_chart').html(this.group_str);
			
			this.canvas = new KisCanvas('flow_canvas', this.shape_rect,0, 0, this.width, this.height);
			this.canvas.addEvent('mousedown', KisFlow.mousedown);
			$('#flow_group').append(this.canvas._instance);
			
			this.toolbar = new KisToolbar('flow_toolbar', this.shape_group, this.width, 0, 40, 190);
			$('#flow_group').append(this.toolbar._instance);
		}catch(error){
			alert('_int():'+error.message);
		}
	},
	
	_clear : function()
	{
		this.flow_id = 0;
		this.flow_name = '';
		this.state_set=[];
		this.action_set=[];
		this.mark_set=[];
		this.state_id = 0;
		this.action_id = 0;
		this.mark_id = 0;
		this.group_str = "<table border=0 cellspacing=0 cellpadding=0 width='"+this.width+"' height='"+this.height+"' bgcolor='#000000'>";
		this.group_str += "<tr>";
		this.group_str += "<td bgcolor='#ffffff'>";
		this.group_str += "<v:group ID='flow_group' style='position:absolute; left:"+this.left+"; top:"+this.top+"; width:"+this.width+";height:"+this.height+";' coordsize='"+this.corder_x+","+this.corder_y+"' />";
		this.group_str += "</td>";
		this.group_str += "</tr>";
		this.group_str += "</table>";
		$('#span_flow_chart').html(this.group_str);
			
		this.canvas = new KisCanvas('flow_canvas', this.shape_rect,0, 0, this.width, this.height);
		this.canvas.addEvent('mousedown', KisFlow.mousedown);
		$('#flow_group').append(this.canvas._instance);
			
		this.toolbar = new KisToolbar('flow_toolbar', this.shape_group, this.width, 0, 40, 190);
		$('#flow_group').append(this.toolbar._instance);	
	},
	
	_load : function(flow_data)
	{
		var obj = eval( "(" + flow_data + ")" );
		$("#flow_chart_title").html(obj.flow_name);
		this.flow_id=obj.flow_id;
		this.flow_name=obj.flow_name;
		
		for(var i=0; i<obj.status.length; i++)
			this._loadStatus(obj.status[i]);
		for(var i=0; i<obj.actions.length; i++)
			this._loadAction(obj.actions[i]);
	},
	
	_loadStatus : function(json_status)
	{
		try
		{
			this.state_id = json_status.chart_state_id.substring(6);
			this.state_id++;
			
			var l = parseInt(json_status.coord_left);
			var t = parseInt(json_status.coord_top);			
			var state = new KisState(json_status.chart_state_id, KisFlow.shape_roundrect, l, t, KisFlow.OBJ_STATE_WIDTH, KisFlow.OBJ_STATE_HEIGHT);
			state.setDBID(json_status.status_id)
			state.setStateType(json_status.state_type);
			state.setText(json_status.state_name);
			state.setTitle(json_status.state_title);
			
			state.setCursor('move');
			state.addEvent('mouseover', KisFlow.overObject);
			state.addEvent('mousedown', KisFlow.mousedown);
			
			this.addNode(state);
			
		}catch(error){alert('_loadStatus():'+error.message);}
	},
	
	_loadAction : function(json_action)
	{
		try{
			this.action_id = json_action.chart_action_id.substring(7);
			this.action_id++;
			
			var l = parseInt(json_action.coord_left);			
			var t = parseInt(json_action.coord_top);
			var action = new KisAction(json_action.chart_action_id, KisFlow.shape_polyline, l, t, 0, 0);
			action.appendChildStr("<v:stroke dashstyle='Sold' EndArrow='Classic'/>");
			action._instance.style.position='absolute';
			action.setCursor('hand');
			action.addEvent('mousedown', KisFlow.mousedown);
			
			this.addNode(action);
			action.setDBID(json_action.action_id)
			action.setText(json_action.action_name);
			action.setTitle(json_action.action_title);
			action.setPointsValue(json_action.points);
			
			//点集合
			action.Points = [];
			
			//var pts =action.getPoints().split(",");
			//for(var i=0; i<pts.length; i+=2)
			//	action.Points.push(new KisPoint(pts[i], pts[i+1]))
			var pts =json_action.points.split(" ");
			for(var i=0; i<pts.length; i++)
			{
				var pt = pts[i].split(",");
				action.Points.push( new KisPoint( parseInt(pt[0]), parseInt(pt[1]) ) );
			}			
			//action.setTextInset();
			
			//关联状态
			action.begin_state = this.findState(json_action.src_status);
			action.end_state = this.findState(json_action.dst_status);
			
			//反向加入状态
			action.begin_state.begin_actions.push(action);
			action.end_state.end_actions.push(action);			
		}catch(error){alert('_loadAction():'+error.message);}
	},
	
	_save : function(flow_name)
	{
		if(flow_name != undefined && flow_name == 0) return;
		this.flow_name = flow_name;
		
		var json = "{";
		json += "\"flow_id\":"+this.flow_id;
		json += ",\"flow_name\":\""+this.flow_name+"\"";
		json += ",\"states\":"+this.getStateJson();
		json += ",\"actions\":"+this.getActionJson();
		json += "}";
		
		$.ajax({
			type: "POST",
			url: "control/doaction.php",
			dataType: "text",
			data: { 
				action:"cfg_flow",
				job:"add",
				flow_id:this.flow_id,
				json_str:json
			},
			timeout: 1000,
			complete: function(){},
			success: function(data)
			{
				if(data!=0) this.flow_id = data;
				alert("保存成功");
				KisFlow.selectBrush(KisFlow.BRUSH_SELECT);
			}
		});
	},
	
	getStateJson : function()
	{
		var json = "[";
		
		for(var i=0; i<this.state_set.length; i++)
		{
			if(i>0) json += ",";
			json += this.state_set[i].toJson();	
		}
		json += "]";
		
		return json;
	},
	
	getActionJson : function()
	{
		var json = "[";
		
		for(var i=0; i<this.action_set.length; i++)
		{
			if(i>0) json += ",";
			json += this.action_set[i].toJson();	
		}
		json += "]";
		
		return json; 
	},
	
	//克隆Action
	cloneAction : function(action)
	{
		var begin_x = action.begin_state.getCenterX();
		var begin_y = action.begin_state.getCenterY();
		var end_x = action.end_state.getCenterX();
		var end_y = action.end_state.getCenterY();
		
		var clone_action = new KisAction('action_'+this.action_id++, KisFlow.shape_polyline, begin_x, begin_y, 0, 0);
		clone_action.appendChildStr("<v:stroke dashstyle='ShortDash' />");
		clone_action._instance.style.position='absolute';
		
		for(var i=0; i<action.Points.length; i++)
		{
			var pt = new KisPoint(action.Points[i].x, action.Points[i].y)
			clone_action.Points[i] = pt; 
		}
		clone_action.Points[0] = new KisPoint(0, 0);
		clone_action.Points[clone_action.Points.length-1] = new KisPoint(end_x-begin_x, end_y-begin_y);
		clone_action.setPointsValue(clone_action.getPointStr());
		return clone_action
	},
	
	//选择工具按钮
	selectBrush : function(brush)
	{
		if(brush == this.current_brush || brush>KisFlow.BRUSH_DEL) return;
		this.toolbar.focus_bt.setTop(25*brush+2);
		
		this.current_brush = brush; 
		switch(brush)
		{
			case KisFlow.BRUSH_SELECT:
				this.flow_state = KisFlow.STATE_SELECT;
				this.canvas.setCursor('auto');
			break;
			//case KisFlow.BRUSH_TEXT:
			//	this.flow_state = KisFlow.STATE_SELECT;
			//	this.canvas.setCursor('text');
			//break;
			case KisFlow.BRUSH_STATE:
				this.flow_state = KisFlow.STATE_ADD_STATE;
				this.canvas.setCursor('crosshair');
			break;
			case KisFlow.BRUSH_ACTION:
				this.flow_state = KisFlow.STATE_ADD_ACTION;
				this.canvas.setCursor('crosshair');
			break;
			case KisFlow.BRUSH_REDO:				
				if(this.flow_id != 0)
					LoadFlow(this.flow_id);
				else
					this._clear();
				this.selectBrush(KisFlow.BRUSH_SELECT);
			break;
			case KisFlow.BRUSH_SAVE:
				this.flow_state = KisFlow.STATE_SELECT;
				this.canvas.setCursor('auto');
				var flow_name = OpenDialogRet("dialog/dialog.php?dlg=dlg_saveflow&flow_id="+KisFlow.flow_id+"&flow_name="+KisFlow.flow_name, 300, 120);
				this._save(flow_name);
			break;
			case KisFlow.BRUSH_NEW:
				this._clear();
				$('#flow_chart_title').html('创建新流程');
				this.selectBrush(KisFlow.BRUSH_SELECT);	
			break;
			case KisFlow.BRUSH_DEL:
				DelFlow(KisFlow.flow_id, KisFlow.flow_name);				
				this.selectBrush(KisFlow.BRUSH_NEW);	
			break;
		}
	},
	
	//增加节点
	addNode : function(kis_obj)
	{ 
		$('#flow_group').append(kis_obj._instance);
		if(kis_obj.getType()==KisFlow.OBJECT_STATE)
			this.state_set.push(kis_obj);
		else if(kis_obj.getType()==KisFlow.OBJECT_ACTION)
			this.action_set.push(kis_obj);
		else if(kis_obj.getType()==KisFlow.OBJECT_MARK)
			this.mark_set.push(kis_obj);
	},
	
	//删除节点
	delNode : function(kis_obj)
	{
		if(kis_obj.getType()==KisFlow.OBJECT_STATE)
		{
			var tmp_set = [];
			var index=0;
			var i=0;
			for(;i<this.state_set.length; i++)
			{
				if(this.state_set[i].id == kis_obj.id)
				{
					this.state_set[i].clearAction();
					continue;
				}
				tmp_set[index++] = this.state_set[i];
			}
			this.state_set = tmp_set;
		}//del state_set
		else if(kis_obj.getType()==KisFlow.OBJECT_ACTION)
		{
			var tmp_set = [];
			var index=0;
			var i=0;
			for(;i<this.action_set.length; i++)
			{
				if(this.action_set[i].id == kis_obj.id)
				{
					this.action_set[i].delMarker();
					continue;
				}
				tmp_set[index++] = this.action_set[i];
			}
			this.action_set = tmp_set;
			kis_obj.distachState();
		}
		else if(kis_obj.getType()==KisFlow.OBJECT_MARK)
		{
			var tmp_set = [];
			var index=0;
			var i=0;
			for(;i<this.mark_set.length; i++)
			{
				if(this.mark_set[i].id == kis_obj.id)
					continue;
				tmp_set[index++] = this.mark_set[i];
			}
			this.mark_set = tmp_set;
		}
		
		document.getElementById('flow_group').removeChild(kis_obj._instance);
	},
	
	//聚焦节点
	focusNode : function(kis_obj)
	{
		if(KisFlow.focus_object)
		{
			KisFlow.focus_object.setStrokeColor('#000000');
			KisFlow.focus_object.delMarker();
		}
		kis_obj.setStrokeColor('red');
		KisFlow.focus_object = kis_obj;
		kis_obj.delMarker();
		kis_obj.addMarker();
	},
	
	findState : function(id)
	{
		var i=0;
		for(i=0;i<this.state_set.length; i++)
		{
			if(this.state_set[i].id == id)
				return	this.state_set[i];
		}
		return null;
	},
	
	findMark : function(id)
	{
		var i=0;
		for(; i<this.mark_set.length; i++)
		{
			if(this.mark_set[i].id == id)
				return this.mark_set[i];
		}
		return null;
	},
	
	findAction : function(id)
	{
		var i=0;
		for(i=0;i<this.action_set.length; i++)
		{
			if(this.action_set[i].id == id)
				return	this.action_set[i];
		}
		return null;
	},
	
	//移动节点	
	moveNode : function(kis_obj)
	{
		var move_object = kis_obj._instance;
		var current_x = event.clientX;
		var current_y = event.clientY;	
	 	
		document.onmousemove = function(){
			try{
				var newX = event.clientX;
				var newY = event.clientY;
			 	var distanceX = parseInt(newX - current_x);
				var distanceY = parseInt(newY - current_y);
			  
				var newLeft = parseInt(move_object.style.left) + distanceX;
				var newTop = parseInt(move_object.style.top) + distanceY;
				
				if(newLeft<0) newLeft=0;
				if( (newLeft + parseInt(move_object.style.width)) > KisFlow.width ) newLeft=(KisFlow.width-parseInt(move_object.style.width));
				
				if(newTop<0) newTop=0;
				if( (newTop + parseInt(move_object.style.height)) > KisFlow.height ) newTop=(KisFlow.height-parseInt(move_object.style.height));
				
				current_x = newX;
				current_y = newY;
			  
				move_object.style.left = newLeft;
				move_object.style.top = newTop;	
				
				if(kis_obj.getType()==KisFlow.OBJECT_STATE || kis_obj.getType()==KisFlow.OBJECT_MARK)
					kis_obj.moveActions(distanceX, distanceY);
				else if(kis_obj.getType()==KisFlow.OBJECT_PLACE)
				{
					kis_obj.updatePoint(newLeft,newTop,distanceX, distanceY);					
					if(kis_obj.isAddPoint())
					{
						KisFlow.addNode(kis_obj.dst_action);
						kis_obj.isAdd = true;						
					}
				}
			}catch(error){alert('moveNode():'+error.message);}
		};
			
		document.onmouseup = function(){
			try{
			document.onmousemove = '';
			document.onmouseup = '';
			
			if(kis_obj.getType()==KisFlow.OBJECT_STATE || kis_obj.getType()==KisFlow.OBJECT_MARK)
				kis_obj.mergeActionPoint();
			else if(kis_obj.getType()==KisFlow.OBJECT_PLACE)
			{
				if(kis_obj.isAdd)
				{
					if(kis_obj.isFlushAction())
					{
						kis_obj.src_action.Points = kis_obj.dst_action.Points;
						
						//生成实际的动作连接线
						var _count = kis_obj.src_action.Points.length;			
						//1 取与开始状态相交的点
						var point = kis_obj.src_action.Points[1];
						var cross_1 = kis_obj.src_action.begin_state.getCossPoint(point.x, point.y);
						kis_obj.src_action.Points[0] = cross_1;						
						//2 取与结束状态相交的点
						point = kis_obj.src_action.Points[_count-2];
						var end_x = kis_obj.src_action.Points[_count-1].x;
						var end_y = kis_obj.src_action.Points[_count-1].y;						
						var cross_2 = kis_obj.src_action.end_state.getCossPoint( (point.x-end_x), (point.y-end_y));
						cross_2.x += end_x;
						cross_2.y += end_y;
						kis_obj.src_action.Points[_count-1] = cross_2;
						//3 设置实际值						
						kis_obj.src_action.setPointsValue(kis_obj.src_action.getPointStr());
						
						kis_obj.src_action.setTextInset()
						
						KisFlow.focusNode(kis_obj.src_action);
					}
					KisFlow.delNode(kis_obj.dst_action);
				}
				kis_obj = null;
			}
			}catch(error){alert("moveNode():onmouseup:"+error.message);}
		};
	},
		
	overObject : function()
	{
		try{
		if(KisFlow.current_brush == KisFlow.BRUSH_ACTION && event.srcElement.style.cursor != 'crosshair')
			event.srcElement.style.cursor = 'crosshair';
		else if(KisFlow.current_brush != KisFlow.BRUSH_ACTION && event.srcElement.style.cursor == 'crosshair')
			event.srcElement.style.cursor = 'move';
		}catch(error){alert('overObject():'+error.message);}
	},
	
	collision : function(x,y)
	{
		try{
			var index = this.state_set.length-1;
			var i=0;
			for(i=0;i<this.state_set.length; i++)
			{
				var state_obj = this.state_set[index]; 
				if(state_obj.includePoint(x,y))
					return state_obj;
				
				index--;
			}
		}catch(error)
		{alert(error.message);}
		
		return null;
	},
	
	//判断点是否超出画布
	outsideCanvas : function(x,y)
	{
		if(x<0 || x>parseInt(this.canvas.getWidth())) return true;
		if(y<0 || y>parseInt(this.canvas.getHeight())) return true;
		return false;
	},
	
	//选择对象
	selectObject : function()
	{
		try{
			var obj_instance = event.srcElement;
			if(obj_instance == this.canvas._instance)
				return;
			
			var obj = this.findState(obj_instance.id);
			if(!obj)
				obj = this.findAction(obj_instance.id);
			if(!obj)
				obj = this.findMark(obj_instance.id);
				
			if(obj.getType()!=KisFlow.OBJECT_MARK)
				this.focusNode(obj);
			
			if(obj.getType() == KisFlow.OBJECT_STATE || obj.getType() == KisFlow.OBJECT_MARK)
				this.moveNode(obj);
			else if(obj.getType() == KisFlow.OBJECT_ACTION)
			{
				var virtual_action = this.cloneAction(obj);				
				var offset_x = parseInt(event.clientX) - parseInt(KisFlow.left);
  				var offset_y = parseInt(event.clientY) - parseInt(KisFlow.top);
				var index = virtual_action.insertPoint(offset_x, offset_y);
				if(index != 0)
				{
					var place_obj = new KisPlace(obj, virtual_action, index, offset_x, offset_y);
					this.moveNode(place_obj);
				}				
				else
					virtual_action = null;
			}
		}catch(error){alert('selectObject():'+error.message);}
	},
	
	//增加状态对象
	addState : function()
	{
		try
		{
			var l = parseInt(event.offsetX)-KisFlow.OBJ_STATE_WIDTH/2;
			if(l<0) l=0;
			if( (l+KisFlow.OBJ_STATE_WIDTH) > parseInt(this.canvas.getWidth()) ) l = parseInt(this.canvas.getWidth())-KisFlow.OBJ_STATE_WIDTH;
			
			var t = parseInt(event.offsetY)-KisFlow.OBJ_STATE_HEIGHT/2;
			if(t<0) t=0;
			if( (t+KisFlow.OBJ_STATE_HEIGHT) > parseInt(this.canvas.getHeight()) ) t = parseInt(this.canvas.getHeight())-KisFlow.OBJ_STATE_HEIGHT;
		
			var state_node = new KisState('state_'+KisFlow.state_id++, KisFlow.shape_roundrect, l, t, KisFlow.OBJ_STATE_WIDTH, KisFlow.OBJ_STATE_HEIGHT);
			state_node.setCursor('move');
			state_node.addEvent('mouseover', KisFlow.overObject);
			state_node.addEvent('mousedown', KisFlow.mousedown);
			
			this.addNode(state_node);
			this.focusNode(state_node);
		}catch(error){alert('addState():'+error.message);}
		
		this.selectBrush(KisFlow.BRUSH_SELECT);	
	},
	
	//增加动作对象
	addAction : function()
	{
		if(KisFlow.flow_state != KisFlow.STATE_ADD_ACTION)
			return;
		try{
			KisFlow.flow_state = KisFlow.STATE_CHARTING_ACTION;
			
			var src_element = event.srcElement;
			var state_obj = this.findState(src_element.id);
			
			if(!state_obj)
				return;
				
			var x = state_obj.getCenterX();
			var y = state_obj.getCenterY();
			
			var action_node = new KisAction('action_'+this.action_id++, KisFlow.shape_polyline, x, y, 0, 0);
			action_node.appendChildStr("<v:stroke dashstyle='Dot' />");
			action_node.setCursor('crosshair');
			action_node._instance.style.position='absolute';
			action_node._instance.StrokeColor = 'red';
			action_node.addEvent('mousedown', KisFlow.mousedown);
			
			this.addNode(action_node);
			this.focusNode(action_node);
			
			document.onmousemove = function()
			{
				var offset_x = parseInt(event.clientX) - parseInt(KisFlow.left);
  				var offset_y = parseInt(event.clientY) - parseInt(KisFlow.top);
  				var end_x = offset_x-x;
  				var end_y = offset_y-y;
				action_node.updateEndPoint(end_x, end_y);
			};
			
			document.onmouseup = function()
			{
				var offset_x = parseInt(event.clientX) - parseInt(KisFlow.left);
				var offset_y = parseInt(event.clientY) - parseInt(KisFlow.top);
				var end_x = offset_x-x;
				var end_y = offset_y-y;
  			
				//判断动作是否与状态碰撞
				var state_collision = KisFlow.collision(offset_x, offset_y);
				if(!state_collision)
				{
					if(KisFlow.outsideCanvas(offset_x, offset_y)) //点在画布之外
					{
						KisFlow.delNode(action_node);
						KisFlow.selectBrush(KisFlow.BRUSH_SELECT);
						document.onmouseup = '';
						document.onmousemove = '';
					}
					else
						action_node.addPoint(end_x, end_y);
				}
				else
				{					
					end_x = state_collision.getCenterX() - x;
					end_y = state_collision.getCenterY() - y;
					action_node.addPoint(end_x, end_y);
					
					//生成实际的动作连接线
					var _count = action_node.Points.length;			
					//1 取与开始状态相交的点
					var point = action_node.Points[1];
					var cross_1 = state_obj.getCossPoint(point.x, point.y);
					action_node.Points[0] = cross_1;					
					//2 取与结束状态相交的点
					point = action_node.Points[_count-2];
					var cross_2 = state_collision.getCossPoint( (point.x-end_x), (point.y-end_y));
					cross_2.x += end_x;
					cross_2.y += end_y;
					action_node.Points[_count-1] = cross_2;
					//3 设置实际值
					action_node.setPointsValue(action_node.getPointStr());
					
					//设置动作线的样式					
					action_node._instance.style.cursor = 'hand';
					action_node._instance.children[1].EndArrow='Classic';
					action_node._instance.children[1].dashstyle='Sold';
					//action_node.setTitle('新加动作')
					//action_node.setText('动作');
										
					//加入动作->对象关联关系
					state_obj.begin_actions.push(action_node);
					state_collision.end_actions.push(action_node);
					action_node.begin_state = state_obj; 
					action_node.end_state = state_collision;
					
					//校正关联自己的动作
					if(action_node.isSameState() && action_node.Points.length==3)
						action_node.setDefault();
					
					action_node.setTextInset();
					KisFlow.selectBrush(KisFlow.BRUSH_SELECT);
					KisFlow.focusNode(action_node);
					document.onmousemove = '';
					document.onmouseup = '';
				}
			};
		}catch(error){alert("addAction():"+error.message);}
	},
	
	mousedown : function()
	{
		if(appState.contextMenu != null) removeMenu();
	
		if(event.button==1)
		{
			switch(KisFlow.flow_state)
			{
				case KisFlow.STATE_SELECT: 	//流程状态_对象选择状态
					KisFlow.selectObject();
				break;
				case KisFlow.STATE_ADD_STATE: //流程状态_增加对象状态
					KisFlow.addState();
				break;
				case KisFlow.STATE_ADD_ACTION://流程状态_增加动作状态
					KisFlow.addAction();
				break;
				case KisFlow.STATE_CHARTING_ACTION://流程状态_描绘动作状态
				case KisFlow.STATE_MOVING_STATE: //流程状态_移动对象状态
				break;
			}
		}
		else if(event.button==2)
		{
			//setStateMenu();
		}
	} //mousedown
};  

var KisPoint = function(x, y)
{
	this.x = x;
	this.y = y;
	this.toStr = function()
	{
		return this.x + "," + this.y;
	};
}

var KisObject = function(id, shape_str, l, t, w, h)
{
	this.id = id;
	this.db_id = 0;
	this._type=0;
	this._text_node = '';
	this._instance = document.createElement(shape_str);
	this._instance.id = id;
	this._instance.style.left = l;
	this._instance.style.top = t;
	this._instance.style.width = w;
	this._instance.style.height = h;
	
	this.addEvent = function(ev_type, handler){EventUtile.addEvent(this._instance, ev_type, handler);};
	this.delEvent = function(ev_type, handler){EventUtile.delEvent(this._instance, ev_type, handler);};
	
	this.appendChild = function(obj){ this._instance.appendChild(obj._instance);};
	this.appendChildStr = function(str){ this._instance.appendChild(document.createElement(str));};
	this.addMarker = function(){};
	this.delMarker = function(){};
	
	this.setID = function(id){this.id = id; this._instance.id = id;};
	this.getID = function(){return this.id;};
	
	this.setDBID = function(id){ this.db_id = id; };
	this.getDBID = function(){ return this.db_id; };
	
	this.setType = function(node_type){this._type=node_type;};
	this.getType = function(){return this._type;};
	
	this.setTitle = function(title) { this._instance.title = title; };
	this.getTitle = function(){return this._instance.title;};
	
	this.setText = function(txt) {this._instance.innerText = txt;};
	this.getText = function(){return this._instance.innerText};
	
	this.setStrokeColor = function(color){this._instance.StrokeColor=color;};
	this.getStrokeColor = function(){return this._instance.StrokeColor;};
	
	this.setCursor = function(cursor){this._instance.style.cursor = cursor;};
	this.getCursor = function(){return this._instance.style.cursor};
	
	this.setImg = function(img_src)	{this._instance.src = img_src;};
	this.getImg = function(){return this._instance.src;};
	
	this.setPoints = function(Points) {this._instance.Points=Points;};
	this.setPointsValue = function(Points) {this._instance.Points.value=Points;};
	this.getPoints = function(){return this._instance.Points.value;};
	
	this.setTop = function(t){this._instance.style.top=t;};
	this.getTop = function(){return this._instance.style.top;};
	this.setLeft = function(l){this._instance.style.left=l;};
	this.getLeft = function(){return this._instance.style.left;};
	
	this.getWidth = function(){return this._instance.style.width;};
	this.getHeight = function(){return this._instance.style.height;};	
	this.getCenterX = function(){	return (parseInt(this.getLeft()) + parseInt(this.getWidth())/2);}
	this.getCenterY = function(){	return (parseInt(this.getTop()) + parseInt(this.getHeight())/2);}
	
	//判断点是否在状态框内
	this.includePoint=function(x,y)
	{
		var min_x = parseInt(this.getLeft());
		var min_y = parseInt(this.getTop());
		var max_x = min_x + parseInt(this.getWidth());
		var max_y = min_y + parseInt(this.getHeight());
		if(x>=min_x&&x<=max_x&&y>=min_y&&y<=max_y) return true;
		return false;
	};
	
	//计算两点之间的斜率
	this.calcSlope = function(pt_0, pt_1)
	{
		if((pt_1.x-pt_0.x)==0) return 37320539;
		var slope = Math.abs( (pt_1.y-pt_0.y)/(pt_1.x-pt_0.x) );
		return (slope>37320539 ? 37320539 : slope);
	};
	
	//获取JSON对象
	this.toJson = function(){return "";};
};

var KisCanvas = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape,l,t, w, h);
};

var KisButton = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape, l, t, w, h);
};	

var KisToolbar = function(id, shape, l, t, w, h)
{ 
	KisObject.call(this, id, shape,l, t, w, h);
	this._instance.coordsize = "'" + w + "," + h + "'";
	
	var bar = new KisButton('flow_bar', KisFlow.shape_rect, 0, 0, w, h);
	this.appendChild(bar);

	//添加选中按钮
	this.focus_bt = new KisButton('', KisFlow.shape_rect, 5, 2, 30, 26);
	this.focus_bt.appendChildStr("<v:fill opacity='.1' color='red' />");
	this.appendChild(this.focus_bt);
		
	this.clickButton = function()
	{
		try{
		var brush = 0;
		switch(event.srcElement.id)
		{
			case "bt_select":
			brush = KisFlow.BRUSH_SELECT;
			break;
			//case "bt_text":
			//brush = KisFlow.BRUSH_TEXT;
			//break;	
			case "bt_state":
			brush = KisFlow.BRUSH_STATE;
			break;	
			case "bt_action":
			brush = KisFlow.BRUSH_ACTION;
			break;
			case "bt_redo":
			brush = KisFlow.BRUSH_REDO;	
			break;
			case "bt_save":
			brush = KisFlow.BRUSH_SAVE;
			break;
			case "bt_new":
			brush = KisFlow.BRUSH_NEW;	
			break;
			case "bt_del":
			brush = KisFlow.BRUSH_DEL;			
			break;
		}
		KisFlow.selectBrush(brush);
		}catch(error){alert(error.message);}
	};
	
	//添加按钮
	var _h = 5;
	var bt = new KisButton('bt_select', KisFlow.shape_img, 10, _h, 20, 20);
	bt.setImg('imgs/select.jpg');
	bt.setTitle('选择');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
		
	//_h += 25;
	//var bt = new KisButton('bt_text', KisFlow.shape_text, 10, _h, 20, 20);
	//bt.setTitle('文字输入');
	//bt.setText('ABC');
	//bt.setCursor('hand');
	//bt.addEvent('click', this.clickButton);
	//this.appendChild(bt);
	
	_h += 25;
	var bt = new KisButton('bt_state', KisFlow.shape_roundrect, 10, _h, 20, 16);
	bt.setTitle('状态');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
	
	_h +=25;
	var bt = new KisButton('bt_action', KisFlow.shape_polyline, 10, _h, 20, 16);
	bt.setPoints('0,16 0,0 20,0');
	bt.setTitle(' 动作 ');
	bt.setCursor('hand');
	bt.appendChildStr("<v:stroke EndArrow='Classic' />");
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
	
	_h += 25;
	var bt = new KisButton('bt_redo', KisFlow.shape_img, 8, _h, 22, 22 );
	bt.setImg('imgs/undo_16.gif');
	bt.setTitle(' 重置 ');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
	
	_h += 25;
	var bt = new KisButton('bt_save', KisFlow.shape_img, 8, _h, 22, 22 );
	bt.setImg('imgs/save.jpg');
	bt.setTitle(' 保存 ');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
	
	_h += 25;
	var bt = new KisButton('bt_new', KisFlow.shape_img, 8, _h, 22, 22 );
	bt.setImg('imgs/newflow.gif');
	bt.setTitle(' 创建新流程 ');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);
	
	_h += 25;
	var bt = new KisButton('bt_del', KisFlow.shape_img, 8, _h, 22, 22 );
	bt.setImg('imgs/b_drop.png');
	bt.setTitle(' 删除 ');
	bt.setCursor('hand');
	bt.addEvent('click', this.clickButton);
	this.appendChild(bt);	
};

var KisText = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape, l, t, w, h);
	this.setType(KisFlow.OBJECT_TEXT);
	
	this.setInset = function(inset)
	{
		this._instance.inset=inset;
	};
};

var KisState = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape, l, t, w, h);
	//this.setTitle('新加状态');
	this.appendChildStr("<v:fill opacity='0.6' color='#FFFF8E' />");
	this.setType(KisFlow.OBJECT_STATE);
	this.begin_actions = [];
	this.end_actions = [];
	this.state_type = 2; //默认是处理状态
	
	this._text_node = new KisText(0, KisFlow.shape_text, 10, 5, 0, 0);
	//this._text_node.setText('状态');			
	this.appendChild(this._text_node);
	
	//获取JSON对象
	this.toJson = function()
	{
		var json = "{";
		json += "\"db_id\":" + this.getDBID();
		json += ",\"state_id\":\"" + this.getID() +"\"";
		json += ",\"state_type\":" + this.state_type;
		json += ",\"state_name\":\"" + this.getText() + "\"";
		json += ",\"state_title\":\"" + this.getTitle() + "\"";
		json += ",\"coord_left\":" + parseInt(this.getLeft());
		json += ",\"coord_top\":" + parseInt(this.getTop());
		json += "}";
		//alert(json);
		return json;
	};
	
	this.setStateType = function(type)
	{
		if(type < 0 || type > 6) return;
		this.state_type = type;
	};
	
	this.getStateType = function()
	{
		return this.state_type;	
	};
	
	this.setText = function(txt)
	{
		this._text_node.setText(txt);
		this._text_node.setInset('5pt,5pt,0pt,0pt');
	};
	
	this.getText = function()
	{
		return this._text_node.getText();
	};
	
	//获取中心到pt的直线与边的交叉点
	this.getCossPoint=function(pt_x, pt_y)
	{
		var cross_x = 0, cross_y = 0;
			
		var w = parseInt(this.getWidth());
		var h = parseInt(this.getHeight());
			
		if(Math.abs(pt_x)<=(w/2) && Math.abs(pt_y)<=(h/2)) 
			return new KisPoint(cross_x, cross_y);;
			
		var x=w/2; 
		var y=h/2;
		if(pt_x>=0)
		{
			if(pt_y<0)
				y *= -1;
		}
		
		if(pt_x<0)
		{
			x *= -1;
			if(pt_y<0)
				y *= -1;
		}
			
		if( Math.abs(pt_y/pt_x) <= Math.abs(y/x)) //与竖边相交
		{
			cross_x = x;
			cross_y = parseInt((pt_y/pt_x) * cross_x * 100 ) * 0.01;
		}
		else //与横边相交
		{
			cross_y = y;
			cross_x = parseInt((pt_x/pt_y) * cross_y*100) * 0.01;
		}
			
		return new KisPoint(cross_x, cross_y);
	};
	
	this.mergeActionPoint = function()
	{
		var i=0;
		for(i=0;i<this.begin_actions.length; i++)
			this.begin_actions[i].mergePoint(0);
		
		for(i=0;i<this.end_actions.length; i++)	
				this.end_actions[i].mergePoint(1);
	};
	
	this.moveBeginAction = function(_action, x, y)
	{
		var x_0 = _action.begin_state.getCenterX();
		var y_0 = _action.begin_state.getCenterY();
		_action.setLeft(x_0);
		_action.setTop(y_0);
		
		if(_action.isSameState()) return;
		
		//所有点减去移动距离
		var i=0;
		for(i=1; i<_action.Points.length-1; i++)
		{
			_action.Points[i].x -= x;
			_action.Points[i].y -= y;
		}
			
		var _count = _action.Points.length;
		_action.Points[0] = this.getCossPoint(_action.Points[1].x, _action.Points[1].y);
			
		var point = _action.Points[_count-2];
		var end_x = _action.end_state.getCenterX() - this.getCenterX();
		var end_y = _action.end_state.getCenterY() - this.getCenterY();
			
		var cross_point = _action.end_state.getCossPoint( (point.x-end_x), (point.y-end_y));
		cross_point.x += end_x;
		cross_point.y += end_y;
		_action.Points[_count-1] = cross_point;
		
		_action.setPointsValue(_action.getPointStr());
	};
	
	this.moveEndAction = function(_action, x, y)
	{
		if(_action.isSameState()) return;
		
		var _count = _action.Points.length;		
		var point = _action.Points[_count-2];
		var end_x = this.getCenterX()-_action.begin_state.getCenterX();
		var end_y = this.getCenterY()-_action.begin_state.getCenterY();
		var cross_point = _action.end_state.getCossPoint( (point.x-end_x), (point.y-end_y));
		cross_point.x += end_x;
		cross_point.y += end_y;
		_action.Points[_count-1] = cross_point;
		
		if(_count == 2)
		{
			var cross_point = _action.begin_state.getCossPoint( end_x, end_y);
			_action.Points[0] = cross_point;	
		}
				
		_action.setPointsValue(_action.getPointStr());
	};
	
	this.moveActions=function(x,y)
	{
		try
		{
			var i=0;
			for(i=0;i<this.begin_actions.length; i++)
			{
				this.moveBeginAction(this.begin_actions[i], x,y);
				this.begin_actions[i].setTextInset();
			}
			
			for(i=0;i<this.end_actions.length; i++)
			{
				this.moveEndAction(this.end_actions[i], x,y);
				this.end_actions[i].setTextInset();
			}
		}catch(error){alert("moveActions():"+error.message);}
	};
	
	this.clearAction = function()
	{
		for(var i=0;i<this.begin_actions.length; i++)
		{
			this.begin_actions[i].end_state.distachEndAction(this.begin_actions[i].getID());
			KisFlow.delNode(this.begin_actions[i]);
		}
		for(var i=0;i<this.end_actions.length; i++)
		{
			this.end_actions[i].begin_state.distachBeginAction(this.end_actions[i].getID());
			KisFlow.delNode(this.end_actions[i]);
		}
	};
	
	this.distachBeginAction = function(id)
	{
		var tmp = [];
		var index=0;
		for(var i=0;i<this.begin_actions.length; i++)
		{
			if(this.begin_actions[i].getID() == id)
				continue;
			tmp[index++] = this.begin_actions[i];
		}
		this.begin_actions=tmp;
	};
	
	this.distachEndAction = function(id)
	{
		var tmp = [];
		var index=0;
		for(var i=0;i<this.end_actions.length; i++)
		{
			if(this.end_actions[i].getID() == id)
				continue;
			tmp[index++] = this.end_actions[i];
		}
		this.end_actions=tmp;	
	};
};

var KisAction = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape, l, t, w, h);
	this.setType(KisFlow.OBJECT_ACTION);
	this.begin_state='';
	this.end_state='';
	this.Points = [];
	this.Markers = [];
	this.Points.push(new KisPoint(0,0));
	
	this._text_node = new KisText(0, KisFlow.shape_text, 0, 0, 0, 0);
	this.appendChild(this._text_node);
	
	this.toJson = function()
	{
		var json = "{";
		json += "\"db_id\":"+this.getDBID();
		json += ",\"action_id\":\""+this.getID()+"\"";
		json += ",\"action_name\":\""+this.getText()+"\"";
		json += ",\"action_title\":\""+this.getTitle()+"\"";
		json += ",\"src_state\":\""+this.begin_state.getID()+"\"";
		json += ",\"dst_state\":\""+this.end_state.getID()+"\"";
		json += ",\"points\":\""+this.getPointStr()+"\"";
		json += ",\"coord_left\":"+parseInt(this.getLeft());
		json += ",\"coord_top\":"+parseInt(this.getTop());
		json += "}";
		
		return json;
	};
	
	this.setText = function(txt)
	{
		this._text_node.setText(txt);	
	};
	
	this.getText = function()
	{
		return this._text_node.getText();
	};
	
	this.setTextInset = function()
	{
		var i=parseInt(this.Points.length/2);
		var j=i-1;
		
		var x = parseInt(Math.abs((this.Points[i].x + this.Points[j].x)/2 - this.Points[0].x));
		var y = parseInt(Math.abs((this.Points[i].y + this.Points[j].y)/2 - this.Points[0].y));
		//var x = parseInt((this.Points[i].x + this.Points[j].x)/2 );
		//var y = parseInt((this.Points[i].y + this.Points[j].y)/2 );
			
		if(Math.abs(x)<20) x=-20;
		if(Math.abs(y)<20) y=-20;
		
		var inset = x+"px,"+y+"px,5px,5px";
		if(this.Points[i].y < this.Points[0].y )
			inset = x+"px,5px 5px,"+y+"px";
		this._text_node.setInset(inset);
	};
	
	this.distachState = function()
	{
		try{
		this.begin_state.distachBeginAction(this.id);
		this.end_state.distachEndAction(this.id);
		}catch(error){alert(error.message);}
	}
	
	this.setDefault = function()
	{
		var w = parseInt(this.begin_state.getWidth());
		var h = parseInt(this.begin_state.getHeight());
		this.Points[0]=new KisPoint(0,h/2);
		this.Points[1]=new KisPoint(0,h);
		this.Points[2]=new KisPoint(w,h);
		this.Points[3]=new KisPoint(w,0);
		this.Points[4]=new KisPoint(w/2,0);	
		this.setPointsValue(this.getPointStr());
	};
	
	this.addMarker = function()
	{
		try{
		var i = 0;
		for(i=0; i<this.Points.length; i++)
		{
			var x = parseInt(this.getLeft())+this.Points[i].x-2;
			var y = parseInt(this.getTop())+this.Points[i].y-2;
			var mark_node = new KisMark('mark_'+KisFlow.mark_id++, KisFlow.shape_rect, x, y, 4, 4);
			mark_node.action = this;
			mark_node.index = i;
			this.Markers.push(mark_node);
			
			if(i>0 && i<(this.Points.length-1))
				mark_node.addEvent('mousedown', KisFlow.mousedown);
			
			KisFlow.addNode(mark_node);
		}
		}catch(error){alert(error.message);}
	};
	
	this.delMarker = function()
	{
		var i=0;
		for(;i<this.Markers.length; i++)
			KisFlow.delNode(this.Markers[i]);
		this.Markers = [];
		KisFlow.mark_set=[];
	};
	
	this.isSameState = function()
	{
		return this.begin_state.getID() == this.end_state.getID();
	};
	
	this.getPointStr = function()
	{
		var str = "";
		var i=0;
		for(i=0;i<this.Points.length; i++)
		{
			if(i>0) str += " ";
			str += this.Points[i].toStr();
		}
		return str;
	};
	
	this.addPoint = function(x, y)
	{
		this.Points.push(new KisPoint(x,y));
		var str = this.getPointStr();		
		this.setPointsValue(str);
	};
	
	this.updateEndPoint = function(x,y)
	{	
		var str = this.getPointStr();
		str += " "+x+","+y;
		this.setPointsValue(str);
	};
	
	this.flushPoint = function(index, x, y)
	{
		this.Points[index].x += x;
		this.Points[index].y += y;
		this.setPointsValue(this.getPointStr());
	};
	
	this.removePoint = function(index)
	{
		var i=0;
		var n = 0;
		var tmp = [];
		for(i=0; i<this.Points.length; i++)
		{
			if(i==index) continue;
			tmp[n] = this.Points[i];
			n++;
		}
		this.Points = tmp;
		
		if(this.isSameState() && this.Points.length<=3)
			this.setDefault();
	};
	
	this.insertPoint = function(x, y)
	{
		try{
			var index = this.getInsertIndex(x, y);
			if(index == 0) return null;
			
			var px = x-parseInt(this.getLeft());
			var py = y-parseInt(this.getTop());	
			var node = new KisPoint(px, py);
			
			var i=0;
			for(i=this.Points.length;i>index;i--)
				this.Points[i] = this.Points[i-1];
			this.Points[index] = node;
			this.setPointsValue(this.getPointStr());
		}catch(error){alert('insert node:'+error.message);}
		return index;
	};
	
	//获取插入点的索引位置
	this.getInsertIndex = function(x, y)
	{
		var px = x-parseInt(this.getLeft());
		var py = y-parseInt(this.getTop());
		var i=0, index=0;
			
		for(;i<(this.Points.length-1);i++)
		{	
			if(this.Points[i].x==px && this.Points[i].y==py)
				break;
				
			var minus_x0 = px-this.Points[i].x;
			var minus_y0 = py-this.Points[i].y;				
			var minus_x1 = this.Points[i+1].x - this.Points[i].x;
			var minus_y1 = this.Points[i+1].y - this.Points[i].y;
					
			if(Math.round((minus_y0/minus_x0)*1000) != Math.round((minus_y0/minus_x0)*1000)) continue;
			if( Math.abs(minus_x1)<Math.abs(minus_x0) ) continue;
			if( Math.abs(minus_y1)<Math.abs(minus_y0) ) continue;
				
			index = i+1;
			break;
		}
		
		return index;
	};
	
	//判断3点是否在同一条线:夹角<3度
	this.isLine = function(begin, middle, end)
	{
		return (Math.abs(this.calcSlope(begin, middle) - this.calcSlope(begin,end)) < 0.04);
	};
	
	//合并中间点
	this.mergePoint = function(flag)
	{
		var _count = this.Points.length;
		if(_count<3) return;
		
		try{
			var begin = 0;
			var middle = 1;
			var end = 2;
			if(flag==1)
			{
				begin = _count-3;
				middle = _count-2;
				end = _count-1;
			}
			
			if(this.isLine(this.Points[begin], this.Points[middle], this.Points[end]))
			{
				this.removePoint(middle);
				this.setPointsValue(this.getPointStr());
			}
		}catch(error){alert("mergePoint():"+error.message);}
	};
};

var KisMark = function(id, shape, l, t, w, h)
{
	KisObject.call(this, id, shape, l, t, w, h);
	this.appendChildStr("<v:fill opacity='1' color='#000000' />");
	this.setType(KisFlow.OBJECT_MARK);
	this.action='';
	this.index = 0;
	
	this.moveActions = function(x, y)
	{
		this.action.flushPoint(this.index, x, y);
	};
	
	this.mergeActionPoint = function()
	{	
		var begin = this.action.Points[this.index-1];
		var middle = this.action.Points[this.index];
		var end = this.action.Points[this.index+1];
		try{
		if(this.action.isLine(begin, middle, end))
		{
			this.action.removePoint(this.index);
			this.action.setPointsValue(this.action.getPointStr());
			this.action.delMarker();
			this.action.addMarker();
		}}catch(error){alert("mergeActionPoint():"+error.message);}
	};
};

var KisPlace = function(src_action, dst_action, move_index, x, y)
{
	KisObject.call(this, 'place_0', KisFlow.shape_rect, x, y, 0, 0);
	
	this.setType(KisFlow.OBJECT_PLACE);
	this.src_action	= src_action;
	this.dst_action	= dst_action;
	this.index = move_index;
	this.isAdd = false;
	
	//判断是否可以增加转折点
	this.isAddPoint=function()
	{
		if(this.isAdd) return false;
		var point_0 = this.dst_action.Points[this.index-1];
		var point_1 = this.dst_action.Points[this.index];
		var point_2 = this.dst_action.Points[this.index+1];
		var slope = Math.abs( this.calcSlope(point_0,point_1)-this.calcSlope(point_0,point_2) );
		return slope>=0.02; //夹角大于3度
	};
	
	//判断是否更新Action
	this.isFlushAction = function()
	{
		if(!this.isAdd)	return false;
		var point_0 = this.dst_action.Points[this.index-1];
		var point_1 = this.dst_action.Points[this.index];
		var point_2 = this.dst_action.Points[this.index+1];
		var slope = Math.abs( this.calcSlope(point_0,point_1)-this.calcSlope(point_0,point_2) );
		return slope>=0.04; //夹角大于4度
	};
	
	//更新移动点
	this.updatePoint = function(newLeft,newTop, x, y)
	{
		this.setLeft(newLeft);
		this.setTop(newTop);
		this.dst_action.Points[this.index].x += x;
		this.dst_action.Points[this.index].y += y;
		this.dst_action.setPointsValue(this.dst_action.getPointStr());
	};
};
