public void decrementEPage() {
   ePage = ePage - 1;
   for (int i = 0; i < attrib.size(); i++) {
     ObjAttribute obj = attrib.get(i);
     if (obj.getPage() == ePage + 1) obj.setPage(ePage);
   }
 }
 public void decrementSPage() {
   sPage = sPage - 1;
   myPage = sPage;
   for (int i = 0; i < attrib.size(); i++) {
     ObjAttribute obj = attrib.get(i);
     if (obj.getPage() == sPage + 1) obj.setPage(sPage);
   }
 }
  @Override
  public void save(BufferedWriter writer) throws IOException {

    writer.write("## START STATE TRANSITION OBJECT\n");
    writer.write("<transition>\n");

    writer.write(i(1) + "<attributes>\n");
    for (int i = 0; i < attrib.size(); i++) {
      ObjAttribute obj = attrib.get(i);
      obj.save(writer, 1);
    }
    writer.write(i(1) + "</attributes>\n");

    writer.write(
        i(1) + "<startState>\n" + i(1) + startState.getName() + "\n" + i(1) + "</startState>\n");
    writer.write(i(1) + "<endState>\n" + i(1) + endState.getName() + "\n" + i(1) + "</endState>\n");
    writer.write(i(1) + "<startPtX>\n" + i(1) + startPt.getX() + "\n" + i(1) + "</startPtX>\n");
    writer.write(i(1) + "<startPtY>\n" + i(1) + startPt.getY() + "\n" + i(1) + "</startPtY>\n");
    writer.write(i(1) + "<endPtX>\n" + i(1) + endPt.getX() + "\n" + i(1) + "</endPtX>\n");
    writer.write(i(1) + "<endPtY>\n" + i(1) + endPt.getY() + "\n" + i(1) + "</endPtY>\n");
    writer.write(
        i(1) + "<startCtrlPtX>\n" + i(1) + startCtrlPt.getX() + "\n" + i(1) + "</startCtrlPtX>\n");
    writer.write(
        i(1) + "<startCtrlPtY>\n" + i(1) + startCtrlPt.getY() + "\n" + i(1) + "</startCtrlPtY>\n");
    writer.write(
        i(1) + "<endCtrlPtY>\n" + i(1) + endCtrlPt.getX() + "\n" + i(1) + "</endCtrlPtY>\n");
    writer.write(
        i(1) + "<endCtrlPtY>\n" + i(1) + endCtrlPt.getY() + "\n" + i(1) + "</endCtrlPtY>\n");
    writer.write(
        i(1)
            + "<startStateIndex>\n"
            + i(1)
            + startStateIndex
            + "\n"
            + i(1)
            + "</startStateIndex>\n");
    writer.write(
        i(1) + "<endStateIndex>\n" + i(1) + endStateIndex + "\n" + i(1) + "</endStateIndex>\n");
    writer.write(i(1) + "<page>\n" + i(1) + myPage + "\n" + i(1) + "</page>\n");
    writer.write(i(1) + "<color>\n" + i(1) + color.getRGB() + "\n" + i(1) + "</color>\n");
    writer.write(i(1) + "<pageSX>\n" + i(1) + pageS.getX() + "\n" + i(1) + "</pageSX>\n");
    writer.write(i(1) + "<pageSY>\n" + i(1) + pageS.getY() + "\n" + i(1) + "</pageSY>\n");
    writer.write(i(1) + "<pageSCX>\n" + i(1) + pageSC.getX() + "\n" + i(1) + "</pageSCX>\n");
    writer.write(i(1) + "<pageSCY>\n" + i(1) + pageSC.getY() + "\n" + i(1) + "</pageSCY>\n");
    writer.write(i(1) + "<pageEX>\n" + i(1) + pageE.getX() + "\n" + i(1) + "</pageEX>\n");
    writer.write(i(1) + "<pageEY>\n" + i(1) + pageE.getY() + "\n" + i(1) + "</pageEY>\n");
    writer.write(i(1) + "<pageECX>\n" + i(1) + pageEC.getX() + "\n" + i(1) + "</pageECX>\n");
    writer.write(i(1) + "<pageECY>\n" + i(1) + pageEC.getY() + "\n" + i(1) + "</pageECY>\n");
    writer.write(i(1) + "<stub>\n" + i(1) + stub + "\n" + i(1) + "</stub>\n");

    writer.write("</transition>\n");
    writer.write("## END STATE TRANSITION OBJECT\n");
  }
 @Override
 public void updateObjPages(int page) {
   if (startState.getPage() == endState.getPage()) {
     if (attrib != null) {
       for (int i = 0; i < attrib.size(); i++) {
         ObjAttribute obj = attrib.get(i);
         obj.setPage(page);
       }
     }
     myPage = sPage = ePage = page;
     // updateObj();
   } else updateObj();
 }
 @Override
 public void setPage(int i) {
   if (selectStatus == SelectOptions.TXT) {
     if (attrib != null) {
       for (int j = 0; j < attrib.size(); j++) {
         ObjAttribute s = attrib.get(j);
         if (s.getSelectStatus() != 0) {
           s.setPage(i);
           break;
         }
       }
     }
   } else {
     super.setPage(i);
   }
 }
  @Override
  public void updateObj() {
    int oldS = sPage;
    int oldE = ePage;

    sPage = startState.getPage();
    myPage = sPage;
    ePage = endState.getPage();

    if (oldS != sPage && oldS != oldE) {
      for (int i = 0; i < attrib.size(); i++) {
        ObjAttribute obj = attrib.get(i);
        if (obj.getPage() == oldS) obj.setPage(sPage);
      }
    }
    if (oldE != ePage && oldS != oldE) {
      for (int i = 0; i < attrib.size(); i++) {
        ObjAttribute obj = attrib.get(i);
        if (obj.getPage() == oldE) obj.setPage(ePage);
      }
    }
    if (sPage != ePage && oldS == oldE) {
      for (int i = 0; i < attrib.size(); i++) {
        ObjAttribute obj = attrib.get(i);
        obj.setPage(sPage);
      }
    }

    if ((startState.getSelectStatus() != SelectOptions.TXT
            && startState.getSelectStatus() != SelectOptions.NONE)
        || (endState.getSelectStatus() != SelectOptions.TXT
            && endState.getSelectStatus() != SelectOptions.NONE)) {
      if (oldS != oldE && sPage == ePage) setEndPts();
      else moveEndPts();
      curve.setCurve(
          startPt.getX(),
          startPt.getY(),
          startCtrlPt.getX(),
          startCtrlPt.getY(),
          endCtrlPt.getX(),
          endCtrlPt.getY(),
          endPt.getX(),
          endPt.getY());
    }
  }
  @Override
  public boolean setSelectStatus(int x, int y) {

    selectStatus = SelectOptions.NONE;
    xTemp = x;
    yTemp = y;
    // check for text
    if (attrib != null) {
      for (int j = 0; j < attrib.size(); j++) {
        ObjAttribute s = attrib.get(j);
        s.unselect();
      }
      for (int i = 0; i < attrib.size(); i++) {
        ObjAttribute s = attrib.get(i);
        if (s.setSelectStatus(x, y)) {
          selectStatus = SelectOptions.TXT;
          break;
        }
      }
    }
    if (selectStatus != SelectOptions.TXT) {

      // check control points
      if (!stub) {
        if (startCtrlPt.getX() - x <= 3
            && startCtrlPt.getX() - x >= -3
            && startCtrlPt.getY() - y <= 3
            && startCtrlPt.getY() - y >= -3) selectStatus = SelectOptions.STARTCTRL;
        if (endCtrlPt.getX() - x <= 3
            && endCtrlPt.getX() - x >= -3
            && endCtrlPt.getY() - y <= 3
            && endCtrlPt.getY() - y >= -3) selectStatus = SelectOptions.ENDCTRL;
        if (endPt.getX() - x <= 3
            && endPt.getX() - x >= -3
            && endPt.getY() - y <= 3
            && endPt.getY() - y >= -3) selectStatus = SelectOptions.END;
        if (pageSC.getX() - x <= 3
            && pageSC.getX() - x >= -3
            && pageSC.getY() - y <= 3
            && pageSC.getY() - y >= -3) selectStatus = SelectOptions.PAGESC;
        if (pageEC.getX() - x <= 3
            && pageEC.getX() - x >= -3
            && pageEC.getY() - y <= 3
            && pageEC.getY() - y >= -3) selectStatus = SelectOptions.PAGEEC;
        if (pageE.getX() - x <= 3
            && pageE.getX() - x >= -3
            && pageE.getY() - y <= 3
            && pageE.getY() - y >= -3) selectStatus = SelectOptions.PAGEE;
        // check page connecter icon
        if (pageS.getX() - x <= 0
            && pageS.getX() - x >= -40
            && pageS.getY() - y <= 10
            && pageS.getY() - y >= -10) selectStatus = SelectOptions.PAGES;
        if (pageE.getX() - x <= 40
            && pageE.getX() - x >= 0
            && pageE.getY() - y <= 10
            && pageE.getY() - y >= -10) selectStatus = SelectOptions.PAGEE;
      }
      if (startPt.getX() - x <= 3
          && startPt.getX() - x >= -3
          && startPt.getY() - y <= 3
          && startPt.getY() - y >= -3) selectStatus = SelectOptions.START;
      if (pageS.getX() - x <= 3
          && pageS.getX() - x >= -3
          && pageS.getY() - y <= 3
          && pageS.getY() - y >= -3) selectStatus = SelectOptions.PAGES;

      // if not a control point, search around line
      if (selectStatus == SelectOptions.NONE) {
        /*
         * for(int i = -4; i < 5; i++)
         * {
         * for(int j = -4; j < 5; j++)
         * {
         * if(curve.contains(x+i,y+j))
         * {
         * selectStatus = 5;
         * break;
         * }
         * }
         * }
         */

        BasicStroke bs = new BasicStroke(10); // sets width of transition
        // "grab handle" lines
        if (!stub) {
          if (bs.createStrokedShape(curve).contains(new Point2D.Double(x, y)))
            selectStatus = SelectOptions.BR;
        } else {
          if (bs.createStrokedShape(new Line2D.Double(startPt, pageS))
              .contains(new Point2D.Double(x, y))) selectStatus = SelectOptions.BR;
        }
      }
    }
    if (selectStatus == SelectOptions.NONE) return false;
    else return true;
  }
  @Override
  public void adjustShapeOrPosition(int x, int y) {
    if (selectStatus == SelectOptions.START) {
      Point currPt = new Point(x, y);
      double temp;
      double max = 1000000;
      for (int i = 0; i < 36; i++) {
        temp = currPt.distanceSq(startBorderPts.get(i));
        if (temp < max) {
          startStateIndex = i;
          max = temp;
        }
      }
      startPt.setLocation(
          startBorderPts.get(startStateIndex).getX(), startBorderPts.get(startStateIndex).getY());

      if (stub) {
        angle = getAngle(startPt, startState.getRealCenter(myPage));
        pageS.setLocation(
            new Point(
                (int) (startPt.getX() + len * Math.cos(angle)),
                (int) (startPt.getY() - len * Math.sin(angle))));
      }
    }
    if (selectStatus == SelectOptions.STARTCTRL) startCtrlPt.setLocation(x, y);
    if (selectStatus == SelectOptions.ENDCTRL) endCtrlPt.setLocation(x, y);
    if (selectStatus == SelectOptions.END) {
      Point currPt = new Point(x, y);
      double temp;
      double max = 1000000;
      for (int i = 0; i < 36; i++) {
        temp = currPt.distanceSq(endBorderPts.get(i));
        if (temp < max) {
          endStateIndex = i;
          max = temp;
        }
      }
      endPt.setLocation(
          endBorderPts.get(endStateIndex).getX(), endBorderPts.get(endStateIndex).getY());
    }
    if (selectStatus == SelectOptions.PAGES) {
      pageS.setLocation(pageS.getX() + x - xTemp, pageS.getY() + y - yTemp);
      xTemp = x;
      yTemp = y;
      if (stub) {
        angle = getAngle(pageS, startState.getRealCenter(myPage));
        int index = 36 - (int) Math.round((angle / (Math.PI * 2)) * 36);
        if (index > 35) index -= 36;

        startStateIndex = index;
        startPt = startBorderPts.get(index);
        len = (int) startPt.distance(pageS);
      }
    }
    if (selectStatus == SelectOptions.PAGESC) pageSC.setLocation(x, y);
    if (selectStatus == SelectOptions.PAGEEC) pageEC.setLocation(x, y);
    if (selectStatus == SelectOptions.PAGEE) {
      pageE.setLocation(pageE.getX() + x - xTemp, pageE.getY() + y - yTemp);
      xTemp = x;
      yTemp = y;
    }

    if (selectStatus == SelectOptions.TXT) {
      if (attrib != null) {
        for (int i = 0; i < attrib.size(); i++) {
          ObjAttribute s = attrib.get(i);
          if (s.getSelectStatus() != 0) {
            s.adjustShapeOrPosition(x, y);
            break;
          }
        }
      }
    }

    if (startState.getPage() == endState.getPage())
      curve.setCurve(
          startPt.getX(),
          startPt.getY(),
          startCtrlPt.getX(),
          startCtrlPt.getY(),
          endCtrlPt.getX(),
          endCtrlPt.getY(),
          endPt.getX(),
          endPt.getY());

    if (selectStatus != SelectOptions.ALL) modified = true;
  }