text: /**
   * @author GJ
   */
  var connections = [];
  var nodes=[];
  var r=null;
  var _dragger = function () {
  	this.ox = this.attr("x");
  	this.oy = this.attr("y");
  };
  var _move = function (dx, dy) {
  	var att = {x: this.ox + dx, y: this.oy + dy};
  	this.attr(att);
  	if(this.type == "rect"){
  		var w=this.attr("width");
  		var h=this.attr("height");
  		att = {x: this.ox + dx + w/2, y: this.oy + dy + h/2};
  		this.text.attr(att);
  	}else{
  		var w=this.rect.attr("width");
  		var h=this.rect.attr("height");
  		att = {x: this.ox + dx - w/2, y: this.oy + dy -h/2};
  		this.rect.attr(att);		
  	}
  	for (var i = connections.length; i--;) {
  		r.connection(connections[i]);
  	}
  	r.safari();
  };
  
  Raphael.fn.connection = function (obj1, obj2) {
  	var line=null;
      if (obj1.line && obj1.from && obj1.to) {
          line = obj1;
          obj1 = line.from;
          obj2 = line.to;
      }
      var bb1 = obj1.getBBox(),bb2 = obj2.getBBox();
      var x1=bb1.x+bb1.width/2;
      var y1=bb1.y+bb1.height/2;
      var x2=bb2.x+bb2.width/2;
      var y2=bb2.y+bb2.height/2;
      var newPath=["M"];
      var path="M "+x1+","+y1+" L "+x2+","+y2;
      var objPath=this.elementPath(obj1);
      var dot=Raphael.pathIntersection(path,objPath);
      newPath.push(dot[0].x);
      newPath.push(dot[0].y);
      objPath=this.elementPath(obj2);
      dot=Raphael.pathIntersection(path,objPath);
      newPath.push(dot[0].x);
      newPath.push(dot[0].y);
      if (line && line.line) {
          line.bg && line.bg.attr({path: newPath});
          line.line.attr({path: newPath});
      } else {
      	var newLine= this.path(newPath).attr({stroke: "#2B547E", fill: "none","arrow-end":"block-wide-long","stroke-width":1.5});
      	newLine.toBack();
      	return {
      		line:newLine,
      		from: obj1,
      		to: obj2
      	};
      }
  };
  Raphael.fn.elementPath = function(element) {
  	var p1 = element.attr("x");
  	var p2 = element.attr("y");
  	var p3 = element.attr("x")+element.attr("width");
  	var p4 = element.attr("y");
  	var p5 = element.attr("x")+element.attr("width");
  	var p6 = element.attr("y")+element.attr("height");
  	var p7 = element.attr("x");
  	var p8 = element.attr("y")+element.attr("height");
  	return "M "+p1+" "+p2+" L "+p3+" "+p4+" L "+p5+" "+p6+" L "+p7+"  "+p8+" L "+p1+"  "+p2+"";
  };
  
  var ReteNode=function(node,r){
  	this.id=node["id"];
  	var x=node["x"];
  	var y=node["y"];
  	var w=node["width"];
  	var h=node["height"];
  	var corner=node["roundCorner"];
  	this.rect=r.rect(x, y, w, h, corner);
  	var label=node["label"];
  	var title=node["title"];
  	var text=r.text(x+w/2,y+h/2,label);
  	text.drag(_move, _dragger);
  	text.attr({fill: "blue", "title": title,cursor: "move"});
  	this.rect.text=text;
  	text.rect=this.rect;
  	var color = node["color"];
  	this.rect.attr({fill: color, stroke: color, "stroke-width": 2, "title": title, cursor: "move"});
  	this.rect.drag(_move, _dragger);
  	nodes.push(this);
  	var children=node["children"];
  	if(!children){
  		return;
  	}
  	for(var i=0;i<children.length;i++){
  		var childNode=children[i];
  		new ReteNode(childNode,r);
  	}
  };
  ReteNode.prototype.getRect=function(){
  	return this.rect;
  };
  ReteNode.prototype.getId=function(){
  	return this.id;
  };
  var _drawReteTree=function(container,filelist){
  	var url = "urule?action=loadrete";
  	$.ajax({
  		cache : false,
  		url : url,
  		type : "POST",
  		data : {
  			files : filelist
  		},
  		error : function(req, error) {
  			alert("规则树加载失败!");
  		},
  		success : function(data) {
  			var width=data["width"];
  			var height=data["height"];
  			var winWidth=$(window).height();
  			var winHeight=$(window).width();
  			if(winWidth>width){
  				width=winWidth;
  			}
  			if(winHeight>height){
  				height=winHeight;
  			}
  			r = Raphael(container, width, height);
  			new ReteNode(data["rootNode"],r);
  			var edges=data["edges"];
  			if(!edges){
  				return;
  			}
  			for(var i=0;i<edges.length;i++){
  				var edge=edges[i];
  				var fromId=edge["from"];
  				var toId=edge["to"];
  				var fromNode=_findNode(fromId);
  				var toNode=_findNode(toId);
  				connections.push(r.connection(fromNode.getRect(),toNode.getRect()));
  			}
  		}
  	});
  };
  var _findNode=function(id){
  	for(var i=0;i<nodes.length;i++){
  		var node=nodes[i];
  		if(node.getId()==id){
  			return node;
  		}
  	}
  	throw "Node ["+id+"] not found.";
  };