import PaintElement from "./PaintElement";
import Resources from "../utility/Resources";
import Point from "../utility/Point";
import Polygon from "../utility/Polygon";
import StringUtil from "../utility/StringUtil";

class Relation extends PaintElement {
  constructor(diagram) {
    super(diagram);

    this.state = "";

    this.i = 0;

    this.startnodeid = "";

    this.endnodeid = null;

    this.ispassed = false;

    this.isreturn = false; // 是否是返回路径
    /**
     * 线路显示条件, 在(FlowDiagram.getNextNode)中使用
     */
    this.condition = "";

    this.formlist = "";

    this.filtercondition = "";

    this.editMode = "";

    this.processDescription = "";

    this.action = "";

    this.pointstack = "";

    this._endpoint = null;

    this._startnode = null;

    this._endnode = null;

    this._mousepoint = null;

    this._movepoint = null; // 拖拉时鼠标的移动点

    this.breakpoint = null; // 按下鼠标时的点

    this.relationName = null;

    this.vector = [];

    this.changevector = -1; // 当鼠标按下时恰好是流程线原有折点时的折点位置

    this.currentselect = false;

    this.initstart = true; // 由于该流程图用xml文件保存，所以当装载流程图时要构造保存流程线的折点位置的vector

    this.validateScript = "";

    this.contentmenu1 = null;

    this.nameText = "";

    this.txtH = 20;

    this.changeFlowCc = false;
    this.changeFlowOperator = false;
    this.disableFlowNode = false;
    this.newRelation = false;

		this.radius = 3;

    this.delVector = false; // 是否有删除折点

    this.delIndex = ''; // 删除折点的下标
  }

  getClassName() {
    return "cn.myapps.runtime.workflow.element.Relation";
  }

  paint(graphics) {
    let g = graphics;

    let old = this.color; // 保存当前颜色
		let hasMergPoint = false;

    const startPoint = this.getStartPoint();
    const endPoint = this.getEndPoint();

    if (this.initstart) {
      // 如果流程图是第一次画，则要从原有xml文件中读取折点的坐标
      this.initVector(this.pointstack); // pointstack是与xml文件打交道的用于存储流程线的折点坐标的public
      // String型变量
    }
    this.drawSelfCycle(startPoint, endPoint); // 画自循环线
    this.initstart = false;
    if (startPoint != null && endPoint != null) {
      this.mergPoint(); // 合并折点
      let d2 = 0,
        h2 = 0;
      let d3 = 0,
        h3 = 0;
      if (this.ispassed) {
        this.color = PaintElement.DEF_PASSCOLOR;
      } else if (this.currentselect) {
        this.color = PaintElement.DEF_SELECTEDCOLOR;
        this.currentselect = false;
      } else if (this._owner.isCurrentToEdit(this)) {
        this.color = PaintElement.DEF_CURREDITCOLOR;
      } else {
        this.color = PaintElement.DEF_COLOR;
      }
      if (this.vector.length < 2) {
        d2 = 0;
        h2 = 0;
      } else {
        let node = this.getEndnode();

        d2 = node.width;
        h2 = node.height;
        let startNode = this.getStartnode();

        d3 = startNode.width;
        h3 = startNode.height;
      }

      g.setColor(this.color);

      let sPoint = null;

      sPoint = this.getArrowhead(new Point(endPoint.x, endPoint.y), new Point(startPoint.x, startPoint.y), d3, h3); // 得到流程线箭头的坐标

      let ePoint = null;

      ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2); // 得到流程线箭头的坐标

      if (this.vector.length < 3) {
        // 鼠标从开始结点拖拉到结尾结点的过程中，鼠标当前移动点作为暂时的尾结点

        if (this._movepoint != null) {
          sPoint = this.getArrowhead(new Point(this._movepoint.x, this._movepoint.y), new Point(startPoint.x, startPoint.y), d3, h3);
          g.drawLine(sPoint.x, sPoint.y, this._movepoint.x, this._movepoint.y);

          startPoint.x = this._movepoint.x;
          startPoint.y = this._movepoint.y;

          ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2);
          g.drawLine(this._movepoint.x, this._movepoint.y, ePoint.x, ePoint.y);
          this._movepoint = null;
        } else {
          g.drawLine(sPoint.x, sPoint.y, ePoint.x, ePoint.y);
        }
      } else {
        if (this._movepoint != null) {
          // 画流程线折点时拖拉鼠标的情况(检查点击的是不是原来的折点)
          let whichLine = this.getWhichLine(this.getBreakpoint());
          for (let j = 0; j < this.vector.length - 1; j++) {
            let obj1 = this.vector[j];
            let obj2 = this.vector[j + 1];

            startPoint.x = obj1.x;
            startPoint.y = obj1.y;

            if (j == 0) {
              obj1 = this.getStartPoint();
            }
            if (j == this.vector.length - 2) {
              ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2);
              obj2 = ePoint;
            }
            if (j == whichLine) {
              g.drawLine(obj1.x, obj1.y, this._movepoint.x, this._movepoint.y);
              startPoint.x = this._movepoint.x;
              startPoint.y = this._movepoint.y;
              if (j == this.vector.length - 2) {
                sPoint = this.getArrowhead(new Point(endPoint.x, endPoint.y), new Point(startPoint.x, startPoint.y), d3, h3);
                obj1 = sPoint;

                ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2);
                obj2 = ePoint;
              }
              g.drawLine(this._movepoint.x, this._movepoint.y, obj2.x, obj2.y);
            } else {
              g.drawLine(obj1.x, obj1.y, obj2.x, obj2.y);
            }
          }
          this._movepoint = null;
        } else {
          // 鼠标释放点设为新折点
          for (let k = 0; k < this.vector.length - 1; k++) {
						// 需要生成锚点
						hasMergPoint = true;
            let obj3 = this.vector[k];
            let obj4 = this.vector[k + 1];
            startPoint.x = obj3.x;
            startPoint.y = obj3.y;
            if (k == 0) {
							hasMergPoint = false;
              obj3 = this.getStartPoint();
              obj3 = this.getArrowhead(new Point(obj4.x, obj4.y), new Point(obj3.x, obj3.y), d3, h3);
              // obj3 = sPoint;
            }
            if (k == this.vector.length - 2) {
              ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2);
              obj4 = ePoint;
            }
            g.drawLine(obj3.x, obj3.y, obj4.x, obj4.y);
						if(hasMergPoint){
							g.save();
							g.drawArc(obj3.x,obj3.y, this.radius, '#F0F0F0', '#000000');
							g.restore();
						}
          }
        }
      }
      ePoint = this.getArrowhead(new Point(startPoint.x, startPoint.y), new Point(endPoint.x, endPoint.y), d2, h2);

      this.drawArrow(g, endPoint.x, endPoint.y, startPoint.x, startPoint.y, ePoint); // 画箭头

      g.setColor(Resources.COLOR.black);

      this.drawRelationText(g, endPoint.x, endPoint.y, startPoint.x, startPoint.y); // 画“名称”
    }
    this.color = old; // 恢复当前颜色
    this.setPointStack(this.vector); // 把vector里的折点坐标存储在pointstack里，跟xml文件打交道
  }

  drawRelationText(g, x1, y1, x2, y2) {
    let mx, my;
    if (this.name != null) {
      mx = (x2 + x1) / 2;
      my = (y2 + y1) / 2;

      let rx = mx - 10;
      let ry = my + Resources.FONT_METRICS.height; // 比线段中间位低

      g.setColor(Resources.COLOR.blue);

      g.drawString(StringUtil.dencodeHTML(this.name), rx, ry);

      g.setColor(Resources.COLOR.black);
    }
  }

  drawArrow(g, x1, y1, x2, y2, arrowhead) {
    let hx, hy;
    let sina, cosa;
    sina = Math.abs(Math.sqrt((y2 - y1) * (y2 - y1)) / Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
    cosa = Math.abs(Math.sqrt((x2 - x1) * (x2 - x1)) / Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
    // 第一象限
    let arrowstart1 = new Point();
    let arrowstart2 = new Point();
    if (x2 < arrowhead.x && y2 < arrowhead.y) {
      // 求箭头线的开始点，有两个，分别在流程线的两侧
      arrowstart1.x = arrowhead.x + (Relation.ARROW_WIDTH * sina - Relation.ARROW_LONG * cosa);
      arrowstart1.y = arrowhead.y - (Relation.ARROW_LONG * sina + Relation.ARROW_WIDTH * cosa);
      arrowstart2.x = arrowhead.x - (Relation.ARROW_LONG * cosa + Relation.ARROW_WIDTH * sina);
      arrowstart2.y = arrowhead.y + (Relation.ARROW_WIDTH * cosa - Relation.ARROW_LONG * sina);
    } else if (x2 == arrowhead.x && y2 < arrowhead.y) {
      arrowstart1.x = arrowhead.x + Relation.ARROW_WIDTH;
      arrowstart1.y = arrowhead.y - Relation.ARROW_LONG;
      arrowstart2.x = arrowhead.x - Relation.ARROW_WIDTH;
      arrowstart2.y = arrowhead.y - Relation.ARROW_LONG;
    } else if (x2 > arrowhead.x && y2 < arrowhead.y) {
      arrowstart1.x = arrowhead.x + (Relation.ARROW_LONG * cosa + Relation.ARROW_WIDTH * sina);
      arrowstart1.y = arrowhead.y + (Relation.ARROW_WIDTH * cosa - Relation.ARROW_LONG * sina);
      arrowstart2.x = arrowhead.x + (Relation.ARROW_LONG * cosa - Relation.ARROW_WIDTH * sina);
      arrowstart2.y = arrowhead.y - (Relation.ARROW_LONG * sina + Relation.ARROW_WIDTH * cosa);
    } else if (x2 > arrowhead.x && y2 == arrowhead.y) {
      arrowstart1.x = arrowhead.x + Relation.ARROW_LONG;
      arrowstart1.y = arrowhead.y + Relation.ARROW_WIDTH;
      arrowstart2.x = arrowhead.x + Relation.ARROW_LONG;
      arrowstart2.y = arrowhead.y - Relation.ARROW_WIDTH;
    } else if (x2 > arrowhead.x && y2 > arrowhead.y) {
      arrowstart1.x = arrowhead.x + (Relation.ARROW_LONG * cosa - Relation.ARROW_WIDTH * sina);
      arrowstart1.y = arrowhead.y + (Relation.ARROW_LONG * sina + Relation.ARROW_WIDTH * cosa);
      arrowstart2.x = arrowhead.x + (Relation.ARROW_LONG * cosa + Relation.ARROW_WIDTH * sina);
      arrowstart2.y = arrowhead.y + (Relation.ARROW_LONG * sina - Relation.ARROW_WIDTH * cosa);
    } else if (x2 == arrowhead.x && y2 > arrowhead.y) {
      arrowstart1.x = arrowhead.x - Relation.ARROW_WIDTH;
      arrowstart1.y = arrowhead.y + Relation.ARROW_LONG;
      arrowstart2.x = arrowhead.x + Relation.ARROW_WIDTH;
      arrowstart2.y = arrowhead.y + Relation.ARROW_LONG;
    } else if (x2 < arrowhead.x && y2 > arrowhead.y) {
      arrowstart1.x = arrowhead.x - (Relation.ARROW_LONG * cosa + Relation.ARROW_WIDTH * sina);
      arrowstart1.y = arrowhead.y + (Relation.ARROW_LONG * sina - Relation.ARROW_WIDTH * cosa);
      arrowstart2.x = arrowhead.x + (Relation.ARROW_WIDTH * sina - Relation.ARROW_LONG * cosa);
      arrowstart2.y = arrowhead.y + (Relation.ARROW_LONG * sina + Relation.ARROW_WIDTH * cosa);
    } else {
      arrowstart1.x = arrowhead.x - Relation.ARROW_LONG;
      arrowstart1.y = arrowhead.y - Relation.ARROW_WIDTH;
      arrowstart2.x = arrowhead.x - Relation.ARROW_LONG;
      arrowstart2.y = arrowhead.y + Relation.ARROW_WIDTH;
    }
    hx = arrowhead.x;

    hy = arrowhead.y;
    // g.setColor(Color.red);
    let arrow = new Polygon();
    arrow.addPoint(hx, hy);
    arrow.addPoint(arrowstart1.x, arrowstart1.y);
    arrow.addPoint(arrowstart2.x, arrowstart2.y);
    g.fillPolygon(arrow);
  }

	/**
	 * 合并折点
	 */
  mergPoint() {
    // 重置有没有合并到折点
    // this.delVector = false
    if (this.vector.length >= 3) {
      while (true) {
        // 把相邻的两个距离小于10的折点合并为一个点
        if (this.vector.length >= 3) {
          let distance = -1;
          let m = 0;
          let size = this.vector.length - 1;
          for (m = 0; m < size; m++) {
            let obj1 = this.vector[m];
            let obj2 = this.vector[m + 1];
            if (m == 0) {
              obj1 = this.getStartPoint();
            }
            if (m == this.vector.lenght - 2) {
              obj2 = this.getEndPoint();
            }

            distance = this.getDistance(obj1, obj2);

            if (distance <= 10) {
              // 若两点相邻且距离小于10，则删去其中一个点
              if (m == this.vector.length - 2) {
								// 从数组中移除
                this.vector = this.removeElementAt(this.vector, m);
								this.delVector = true;
              } else {
                this.vector = this.removeElementAt(this.vector, m+1);
								this.delVector = true;
              }
              break;
            }
          }
          if (m == size) {
            break;
          }
        } else {
          break;
        }
      }
      while (true) {
        // 把相邻的两条夹角小于5度的直线合并为一条直线
        if (this.vector.length >= 3) {
          let remove = false;
          let n = 0;
          let size = this.vector.length - 2;
          for (n = 0; n < size; n++) {
            let obj1 = this.vector[n];
            let obj2 = this.vector[n + 1];
            let obj3 = this.vector[n + 2];
            if (n == 0) {
              obj1 = this.getStartPoint();
            }
            if (n == this.vector.length - 3) {
              obj3 = this.getEndPoint();
            }

            remove = this.lineTolineAngle(obj1, obj2, obj3); // 判断两线夹角是否小于5度
            if (remove) {
              this.vector = [...this.vector.slice(0, n), ...this.vector.slice(n + 1)];
							this.delVector = true;
							console.log('夹角小于5',this.vector)
              break;
            }
          }
          if (n == size) {
            break;
          }
        } else {
          break;
        }
      }
    }
  }

	isRealtion(){
		let arr = []
		for(let o = 0; o < this._owner._elems.length ; o++){
			if(this._owner._elems[o] instanceof Relation){
				arr.push(this._owner._elems[o])
			}
		}
		return arr
	}

	/**
	 * 从元素组中删除
	 * @param {*} array 
	 * @param {*} element 
	 * @returns 
	 */
	removeElementAt(array, index) {
		let arr = []
    for (let i = 0; i < array.length; i++) {
      if(i == index){
				continue;
			}else{
				arr.push(array[i])
			}
    }
		return arr
  }
	/**
	 * 画自循环的圆
	 * @param {*} startPoint 
	 * @param {*} endPoint 
	 */
  drawSelfCycle(startPoint, endPoint) {
    // 如果开始坐标与结束坐标点重合，则生成自连接线
    if (!this.getCurrentselect() && this.getStartnode() == this.getEndnode()) {
      if (startPoint != null) {
        this.vector = [];
        this.vector.push(startPoint);
        let point = new Point(startPoint.x + 30, startPoint.y);
        this.vector.push(point);
        point = new Point(point.x, point.y - 50);
        this.vector.push(point);
        point = new Point(point.x - 30, point.y);
        this.vector.push(point);
        this.vector.push(endPoint);
      }
    }
  }

  /**
   * Access method for the Startnode property.
   *
   * @return the current value of the Startnode property
   * @roseuid 3E0A6E1B0318
   */
  getChangevector() {
    return this.changevector;
  }

  setChangevector(change) {
    this.changevector = change;
  }

  setPointStack(vector) {
    let strTemp = "";
    if (this.vector != null) {
      for (let i = 0; i < this.vector.length; i++) {
        let point = this.vector[i];
        strTemp = strTemp + point.x + ";" + point.y;
        if (i < this.vector.length - 1) {
          strTemp = strTemp + ";"; // 例如： "123；234；456；444"形式
        }
      }
    }
    this.pointstack = strTemp;
  }

  /**
   * 把pointstack里的x,y坐标转换成vector里的Point对象
   *
   * @param pointstack
   */
  initVector(pointstack) {
    let str = "";
    str = pointstack;
    let length = 0;
    if (str == null || str == "") {
    } else {
      let x = 0;
      let y = 0;
      let position = 0;
      length = str.length;
      let strTemp = "";
      while (true) {
        try {
          position = str.indexOf(";");
          if (position <= 0) {
            break;
          }
          strTemp = str.substring(0, position);
          x = parseInt(strTemp);
          str = str.substring(position + 1, str.length);
          position = str.indexOf(";");
          if (position <= 0) {
            strTemp = str;
            y = parseInt(strTemp);
            this.vector.push(new Point(x, y));
            break;
          }
          strTemp = str.substring(0, position);
          y = parseInt(strTemp);
          this.vector.push(new Point(x, y));
          str = str.substring(position + 1, str.length);
        } catch (e) {}
      }
    }
  }

  setCurrentselect(curSelect) {
    this.currentselect = curSelect;
  }

  getCurrentselect() {
    return this.currentselect;
  }

  getBreakpoint() {
    return this.breakpoint;
  }

  setBreakpoint(point) {
    this.breakpoint = point;
  }

  setProps(newProps) {
		Object.assign(this, newProps);
	}

  /**
   * 得到箭头坐标
   *
   * @param p1
   * @param p2
   * @param d2
   * @param h2
   * @return
   */
  getArrowhead(p1, p2, d2, h2) {
    let k = Math.abs((p2.y - p1.y) / (p2.x - p1.x));
    let k2 = h2 / d2;
    let arrowhead = new Point();
    if (p2.y > p1.y && p2.x > p1.x) {
      if (k2 >= k) {
        arrowhead.x = p2.x - d2 / 2;
        arrowhead.y = p2.y - (k * d2) / 2;
      } else {
        arrowhead.x = p2.x - h2 / 2 / k;
        arrowhead.y = p2.y - h2 / 2;
      }
    } else if (p2.y == p1.y && p2.x > p1.x) {
      arrowhead.x = p2.x - d2 / 2;
      arrowhead.y = p2.y;
    } else if (p2.y < p1.y && p2.x > p1.x) {
      if (k2 >= k) {
        arrowhead.y = p2.y + (d2 / 2) * k;
        arrowhead.x = p2.x - d2 / 2;
      } else {
        arrowhead.x = p2.x - h2 / 2 / k;
        arrowhead.y = p2.y + h2 / 2;
      }
    } else if (p2.y < p1.y && p2.x == p1.x) {
      arrowhead.x = p2.x;
      arrowhead.y = p2.y + h2 / 2;
    } else if (p2.y < p1.y && p2.x < p1.x) {
      if (k2 >= k) {
        arrowhead.x = p2.x + d2 / 2;
        arrowhead.y = p2.y + (k * d2) / 2;
      } else {
        arrowhead.x = p2.x + h2 / 2 / k;
        arrowhead.y = p2.y + h2 / 2;
      }
    } else if (p2.y == p1.y && p2.x < p1.x) {
      arrowhead.x = p2.x + d2 / 2;
      arrowhead.y = p2.y;
    } else if (p2.y > p1.y && p2.x < p1.x) {
      if (k2 >= k) {
        arrowhead.x = p2.x + d2 / 2;
        arrowhead.y = p2.y - (d2 * k) / 2;
      } else {
        arrowhead.x = p2.x + h2 / 2 / k;
        arrowhead.y = p2.y - h2 / 2;
      }
    } else {
      arrowhead.x = p2.x;
      arrowhead.y = p2.y - h2 / 2;
    }

    return arrowhead;
  }

  getVector() {
    return this.vector;
  }

  addVector(obj) {
    console.log("Relation.addVector.1->", this.vector, obj);
    if (this.vector.lenght < 2) {
      this.vector.addElement(obj);
    } else {
      // 把新折点插入vector
      let i = this.getWhichLine(this.getBreakpoint());
      this.vector = [...this.vector.slice(0, i + 1), obj, ...this.vector.slice(i + 1)];
    }
    console.log("Relation.addVector.2->", this.vector);
    this.mergPoint();
    console.log("Relation.addVector.3->", this.vector);
  }
  addChangeVector(obj, i) {
    // 把新折点插入vector
    this.vector = [...this.vector.slice(0, i + 1), obj, ...this.vector.slice(i + 1)];
    this.mergPoint();
    console.log("Relation.addVector.3->", this.vector);
  }

  /**
   * 检查点到点的距离是否小于一个给定常数
   *
   * @param point
   * @return
   */
  checkDistance(point) {
    let x = point.x;
    let y = point.y;
    let lx = 0;
    let ly = 0;
    let hx = 0;
    let hy = 0;
    let i = this.getWhichLine(this.getBreakpoint());
    if (i >= 0) {
      let obj1 = this.vector[i];
      let obj2 = this.vector[i + 1];
      if (i == 0) {
        obj1 = this.getStartPoint();
      }
      if (i == this.vector.length - 2) {
        obj2 = this.getEndPoint();
      }

			if(obj1 && obj2){
				if (obj1.x == obj2.x) {
					// selected = Math.abs(x - obj1.x) < 5
					// && ((y > obj1.y && y < obj2.y) || (y > obj2.y && y <
					// obj1.y));
					return Math.abs(obj1.y - obj2.y) < 15;
				} else {
				}
	
				if (obj1.x < obj2.x) {
					lx = obj1.x;
					hx = obj2.x;
				} else {
					hx = obj1.x;
					lx = obj2.x;
				}
				if (obj1.y < obj2.y) {
					ly = obj1.y;
					hy = obj2.y;
				} else {
					hy = obj1.y;
					ly = obj2.y;
				}
				let k = (obj2.y - obj1.y) / (obj2.x - obj1.x);
	
				let z = obj1.y - k * obj1.x;
				let py = k * x + z;
				let px = (y - z) / k;
				if (k > 1 || k < -1) {
					if (ly <= y && y <= hy && x - px >= -15 && x - px <= 15) {
						return true;
					} else {
					}
				} else {
					if (lx <= x && x <= hx && y - py >= -15 && y - py <= 15) {
						return true;
					} else {
					}
				}
			}
      
    }
    return false;
  }

  changeVector(vector, point) {
    let pos = this.getChangevector();
    if (pos != -1) {
      console.log('vector', this.vector)
			// 在原有的折点中查找然后修改折点的值
      this.delIndex = ''
      for (let j = 0; j < vector.length; j++) {
				// 判断选择的是哪个折点
				if (Math.abs(vector[j].x - point.x) < 50 && Math.abs(vector[j].y - point.y) < 50) {
          this.delIndex = j;
          break;
				}
			}
      // for (let j = 0; j < vector.length; j++) {
			// 	// 判断选择的是哪个折点
			// 	if (Math.abs(vector[j].x - point.x) < 50 && Math.abs(vector[j].y - point.y) < 50) {
			// 		vector[j].x = point.x;
			// 		vector[j].y = point.y;
			// 	}
			// }
      vector.map(item =>{
        if (Math.abs(item.x - point.x) < 50 && Math.abs(item.y - point.y) < 50) {
          item.x = point.x;
          item.y = point.y;
        }
      })
			console.log('vector', vector, this.delIndex)
    }
  }

	/**
   * yx 检查是否按下原来的折点
   */
	checkPressBreakPoint(vectors, x, y) {
    let press = false;
    for (let i = 0; i < vectors.length; i++) {
      if (Math.abs(vectors[i].x - x) < 5 && Math.abs(vectors[i].y - y) < 5) {
        // 按下的是折点位置
        press = true;
        break;
      }
    }
    return press
  }

  /**
   * 检查新折点应该插入哪条折线之间
   *
   * @param point
   * @return
   */
  getWhichLine(point) {
    if (point == null) {
      return -1;
    } else {
    }
    let x = point.x;
    let y = point.y;
    let lx = 0;
    let ly = 0;
    let hx = 0;
    let hy = 0;
    let i = 0;
    if (this.endnodeid != null && !this.getStartnode().isSelected(x, y) && !this.getEndnode().isSelected(x, y)) {
      for (i = 0; i < this.vector.length - 1; i++) {
        let obj1 = this.vector[i];
        let obj2 = this.vector[i + 1];
        if (i == 0) {
          obj1 = this.getStartPoint();
        }
        if (i == this.vector.length - 2) {
          obj2 = this.getEndPoint();
        }

        if (obj1.x == obj2.x) {
          break;
        } else {
          if (obj1.x < obj2.x) {
            lx = obj1.x;
            hx = obj2.x;
          } else {
            hx = obj1.x;
            lx = obj2.x;
          }
          if (obj1.y < obj2.y) {
            ly = obj1.y;
            hy = obj2.y;
          } else {
            hy = obj1.y;
            ly = obj2.y;
          }
          let k = (obj2.y - obj1.y) / (obj2.x - obj1.x);
          let z = obj1.y - k * obj1.x;
          let py = k * x + z;
          let px = (y - z) / k;
          if (k > 1 || k < -1) {
            if (ly <= y && y <= hy && x - px >= -5 && x - px <= 5) {
              break;
            } else {
            }
          } else {
            if (lx <= x && x <= hx && y - py >= -5 && y - py <= 5) {
              break;
            } else {
            }
          }
        }
      }
    }
    return i;
  }

  /**
   * 返回开始结点
   *
   * @return
   */
  getStartnode() {
    if (this.startnodeid != null && this.startnodeid.trim().length > 0) {
      if (this._startnode == null) {
        let sn = this._owner.getElementByID(this.startnodeid);
        this._startnode = sn;
      }

      return this._startnode;
    }
    return null;
  }

  /**
   * Sets the value of the Startnode property.
   *
   * @param aStartnode
   *            the new value of the Startnode property@param nd
   * @roseuid 3E0A6E1B0322
   */

  setStartnode(nd) {
    this.startnodeid = nd.id;
  }

  /**
   * Access method for the Endnode property.
   *
   * @return the current value of the Endnode property
   * @roseuid 3E0A6E1B0336
   */
  getEndnode() {
    if (this.endnodeid != null && this.endnodeid.trim().length > 0) {
      if (this._endnode == null) {
        let en = this._owner.getElementByID(this.endnodeid);
        this._endnode = en;
      }

      return this._endnode;
    }
    return null;
  }

  /**
   * Sets the value of the Endnode property.
   *
   * @param aEndnode
   *            the new value of the Endnode property@param nd
   * @roseuid 3E0A6E1B034A
   */
  setEndnode(nd) {
    this.endnodeid = nd.id;
  }

  /**
   * @param x
   * @param y
   * @roseuid 3E0A6E1B035E
   */
  moveTo(x, y) {
    if (this._mousepoint == null) {
      this._mousepoint = new Point(x, y);
    } else {
      this._mousepoint.move(x, y);
    }
    if (this._startpoint == null) {
      this._startpoint = this._mousepoint;
    }

    if (this._endpoint == null) {
      this._endpoint = this._mousepoint;
    }
  }

  /**
   * @param x
   * @param y
   * @return boolean
   * @roseuid 3E0A6E1B037C
   */
  isSelected(x, y) {
    let selected = false;
    let lx = 0;
    let ly = 0;
    let hx = 0;
    let hy = 0;

    let startNode = this.getStartnode();
    let endNode = this.getEndnode();

    if (this.endnodeid != null && startNode != null && endNode != null && !startNode.isSelected(x, y) && !endNode.isSelected(x, y)) {
      for (let i = 0; i < this.vector.length - 1; i++) {
        let obj1 = this.vector[i];
        let obj2 = this.vector[i + 1];
        if (i == 0) {
          obj1 = this.getStartPoint();
        }
        if (i == this.vector.length - 2) {
          obj2 = this.getEndPoint();
        }

        if (obj1.x == obj2.x) {
          selected = Math.abs(x - obj1.x) < 5 && ((y > obj1.y && y < obj2.y) || (y > obj2.y && y < obj1.y));
          break;
        } else {
          if (obj1.x < obj2.x) {
            lx = obj1.x;
            hx = obj2.x;
          } else {
            hx = obj1.x;
            lx = obj2.x;
          }
          if (obj1.y < obj2.y) {
            ly = obj1.y;
            hy = obj2.y;
          } else {
            hy = obj1.y;
            ly = obj2.y;
          }
          let k = (obj2.y - obj1.y) / (obj2.x - obj1.x);
          let z = obj1.y - k * obj1.x;

          // 斜率大于1时比较x方向的差距,否则比较y方向的差距

          let py = k * x + z;
          let px = (y - z) / k;
          if (k > 1 || k < -1) {
            if (ly <= y && y <= hy && x - px >= -5 && x - px <= 5) {
              selected = true;
              break;
            } else {
              selected = false;
            }
          } else {
            if (lx <= x && x <= hx && y - py >= -5 && y - py <= 5) {
              selected = true;
              break;
            } else {
              selected = false;
            }
          }
        }
      }
    }
    if (selected) {
      if (this._owner.get_statues() == 0x00000001) {
      } else {
        this._owner.canvas.style.cursor = "pointer";
      }
    } else {
      if (this._owner.get_statues() == 0x00000001) {
      } else {
        this._owner.canvas.style.cursor = "initial";
      }
    }

    return selected;
  }

	/**
	 * yx 获取对应的属性值
	 */
	getProp(prop) {
		return this[prop];
	}

  /**
   * @return java.awt.Rectangle
   * @roseuid 3E0A6E1B039A
   */
  getRepaintRect() {
    let rct = new Rectangle();
    return rct;
  }

  /**
   * 检查新折点与哪个原有折点距离最近
   *
   * @param point
   * @return
   */
  checkWhichpoint(point) {
    let d = 0;
    let i = 0;
    let position = -1;
    for (i = 0; i < this.vector.length; i++) {
      let obj = this.vector[i];
      d = Math.abs(Math.sqrt((point.y - obj.y) * (point.y - obj.y) + (point.x - obj.x) * (point.x - obj.x)));
      if (d <= 10) {
        position = i;
        this.changevector = i;
        break;
      }
    }

    return position;
  }

  /**
   * 得到点到点之间的距离
   *
   * @param point1
   * @param point2
   * @return
   */
  getDistance(point1, point2) {
    let d = -1;
    d = Math.abs(Math.sqrt((point2.y - point1.y) * (point2.y - point1.y) + (point2.x - point1.x) * (point2.x - point1.x)));
    return d;
  }

  /**
   * 检查线与线的夹角是否小于一个给定值
   *
   * @param point1
   * @param point2
   * @param point3
   * @return
   */
  lineTolineAngle(point1, point2, point3) {
    let k1 = 0;
    let k2 = 0;
    let a = 0;
    if (point2.x == point1.x && point3.x == point2.x) {
      return true;
    } else if (point2.x == point1.x) {
      k1 = 0;
      k2 = (point3.y - point2.y) / (point3.x - point2.x);
      a = Math.abs((k2 - k1) / (1 + k1 * k2));
      if (a >= Math.tan((85 / 180) * Math.PI)) {
        return true;
      } else {
      }
    } else {
      if (point3.x == point2.x) {
        k2 = 0;
        k1 = (point2.y - point1.y) / (point2.x - point1.x);
        a = Math.abs((k2 - k1) / (1 + k1 * k2));
        if (a >= Math.tan((85 / 180) * Math.PI)) {
          return true;
        } else {
        }
      } else {
        k1 = (point2.y - point1.y) / (point2.x - point1.x);
        k2 = (point3.y - point2.y) / (point3.x - point2.x);
        a = Math.abs((k2 - k1) / (1 + k1 * k2));
        if (a <= Math.tan((5 / 180) * Math.PI)) {
          return true;
        } else {
        }
      }
    }
    return false;
  }

  /**
   * @return java.awt.Point
   * @roseuid 3E0A6E1B03B8
   */
  getMovepoint() {
    return this._movepoint;
  }

  setMovepoint(p) {
    this._movepoint = p;
  }

  /**
   * 返回开始结点的坐标
   *
   * @return
   */
  getStartPoint() {
    let nd = this.getStartnode();
    if (nd != null) {
      let p = new Point(nd.x + nd.width / 2, nd.y + nd.height / 2);

      this._startpoint = p;
      return p;
    }
    return this._startpoint;
  }

  /**
   * 返回结束结点的坐标
   *
   * @return java.awt.Point
   * @roseuid 3E0A6E1B03CC
   */
  getEndPoint() {
    let nd = this.getEndnode();
    if (nd != null) {
      let p = new Point(nd.x + nd.width / 2, nd.y + nd.height / 2);

      this._endpoint = p;
      return p;
    } else {
      return this._endpoint;
    }
  }

  removeSubElement(id) {
    return false;
  }

  removeAllSubElement() {}

  //拼装XML
  toXML() {
    var str = "<cn.myapps.runtime.workflow.element.Relation>\n";

    str += "<state>" + this.replaceCharacter(this.state) + "</state>\n";
    str += "<startnodeid>" + this.replaceCharacter(this.startnodeid) + "</startnodeid>\n";
    str += "<endnodeid>" + this.replaceCharacter(this.endnodeid) + "</endnodeid>\n";
    str += "<ispassed>" + this.ispassed + "</ispassed>\n";
    str += "<isreturn>" + this.isreturn + "</isreturn>\n";
    str += "<condition>" + this.replaceCharacter(this.condition) + "</condition>\n";
    str += "<filtercondition>" + this.replaceCharacter(this.filtercondition) + "</filtercondition>\n";
    str += "<editMode>" + this.replaceCharacter(this.editMode) + "</editMode>\n";
    str += "<processDescription>" + this.replaceCharacter(this.processDescription) + "</processDescription>\n";
    str += "<formlist>" + this.formlist + "</formlist>\n";
    str += "<action>" + this.replaceCharacter(this.action) + "</action>\n";
    str += "<pointstack>" + this.replaceCharacter(this.pointstack) + "</pointstack>\n";
    str += "<validateScript><![CDATA[" + this.replaceXML(this.validateScript) + "]]></validateScript>\n";
    str += super.toXML();

    str += "</cn.myapps.runtime.workflow.element.Relation>\n";

    return str;
  }
}

Relation.ARROW_LONG = 14;
Relation.ARROW_WIDTH = 4;
Relation.EDITMODE_VIEW = "00"; // 流程条件视图编辑模式
Relation.EDITMODE_CODE = "01"; // 流程条件代码编辑模式
Relation.PAI = 3.1415926525;

export default Relation;
