/* 未能缩小。正在返回未缩小的内容。
(720,9): run-time error CSS1031: Expected selector, found '='
(720,9): run-time error CSS1025: Expected comma or open brace, found '='
(720,13): run-time error CSS1019: Unexpected token, found ';'
(721,19): run-time error CSS1031: Expected selector, found '='
(721,19): run-time error CSS1025: Expected comma or open brace, found '='
(721,23): run-time error CSS1019: Unexpected token, found ';'
(723,16): run-time error CSS1031: Expected selector, found '='
(723,16): run-time error CSS1025: Expected comma or open brace, found '='
(793,26): run-time error CSS1031: Expected selector, found '='
(793,26): run-time error CSS1025: Expected comma or open brace, found '='
(856,32): run-time error CSS1031: Expected selector, found '='
(856,32): run-time error CSS1025: Expected comma or open brace, found '='
(962,19): run-time error CSS1031: Expected selector, found '='
(962,19): run-time error CSS1025: Expected comma or open brace, found '='
(982,14): run-time error CSS1031: Expected selector, found '='
(982,14): run-time error CSS1025: Expected comma or open brace, found '='
(1000,20): run-time error CSS1031: Expected selector, found '='
(1000,20): run-time error CSS1025: Expected comma or open brace, found '='
(2863,14): run-time error CSS1031: Expected selector, found '='
(2863,14): run-time error CSS1025: Expected comma or open brace, found '='
(2933,20): run-time error CSS1031: Expected selector, found '='
(2933,20): run-time error CSS1025: Expected comma or open brace, found '='
(4627,14): run-time error CSS1031: Expected selector, found '='
(4627,14): run-time error CSS1025: Expected comma or open brace, found '='
(4643,20): run-time error CSS1031: Expected selector, found '='
(4643,20): run-time error CSS1025: Expected comma or open brace, found '='
(8456,3): run-time error CSS1019: Unexpected token, found ','
(8458,15): run-time error CSS1030: Expected identifier, found ' '
(8458,25): run-time error CSS1031: Expected selector, found '('
(8458,25): run-time error CSS1025: Expected comma or open brace, found '('
(8496,3): run-time error CSS1019: Unexpected token, found '('
(8496,4): run-time error CSS1019: Unexpected token, found ')'
(8496,5): run-time error CSS1019: Unexpected token, found ','
(8498,15): run-time error CSS1030: Expected identifier, found ' '
(8498,25): run-time error CSS1031: Expected selector, found '('
(8498,25): run-time error CSS1025: Expected comma or open brace, found '('
(8522,3): run-time error CSS1019: Unexpected token, found ','
(8524,14): run-time error CSS1030: Expected identifier, found ' '
(8524,24): run-time error CSS1031: Expected selector, found '('
(8524,24): run-time error CSS1025: Expected comma or open brace, found '('
(8555,3): run-time error CSS1019: Unexpected token, found ','
(8557,13): run-time error CSS1030: Expected identifier, found ' '
(8557,23): run-time error CSS1031: Expected selector, found '('
(8557,23): run-time error CSS1025: Expected comma or open brace, found '('
(8566,3): run-time error CSS1019: Unexpected token, found ','
(8568,10): run-time error CSS1030: Expected identifier, found ' '
(8568,20): run-time error CSS1031: Expected selector, found '('
(8568,20): run-time error CSS1025: Expected comma or open brace, found '('
(8640,1): run-time error CSS1019: Unexpected token, found '}'
(8641,12): run-time error CSS1031: Expected selector, found '='
(8641,12): run-time error CSS1025: Expected comma or open brace, found '='
(8648,18): run-time error CSS1031: Expected selector, found '='
(8648,18): run-time error CSS1025: Expected comma or open brace, found '='
(8860,11): run-time error CSS1031: Expected selector, found '='
(8860,11): run-time error CSS1025: Expected comma or open brace, found '='
 */
/***
Boby
***/
body {
  background-color: #4276a4;
}


.menu-header{
  background:  url(../../img/hiadmin.png) repeat !important;
  border-bottom: 1px #244c6f solid !important;
  height: 45px;
}


/*** 
Page Header
***/
/* Header search bar, toggler button & top menu */
.page-header.navbar {
  background-color: #2d5f8b;
  border-bottom: 1px #486c8c solid;
  /* Top notification menu/bar */
  /* Header seaech box */
  /* Toggler button for sidebar expand/collapse and responsive sidebar menu */
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle:hover {
  background-color: #3774aa;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle > i {
  color: #4e85b6;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle .badge.badge-default {
  background-color: #d64635;
  color: white;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown.open .dropdown-toggle {
  background-color: #3774aa;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle {
  background-color: #28547c;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle .username {
  color: #9ca5c7;
}
.page-header.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle > i {
  color: #9ca5c7;
}
.page-header.navbar .search-form {
  background: #28547c;
}
.page-header.navbar .search-form:hover {
  background: #3774aa;
}
.page-header.navbar .search-form .input-group .form-control {
  color: #83aac8;
}
.page-header.navbar .search-form .input-group .form-control::-moz-placeholder {
  color: #7fa8c6;
  opacity: 1;
}
.page-header.navbar .search-form .input-group .form-control:-ms-input-placeholder {
  color: #7fa8c6;
}
.page-header.navbar .search-form .input-group .form-control::-webkit-input-placeholder {
  color: #7fa8c6;
}
.page-header.navbar .search-form .input-group .input-group-btn .btn.submit {
  background: url(../../img/header_search_icon_blue.png) center center no-repeat !important;
}
.page-header.navbar .search-form.open {
  background: #3774aa;
}
.page-header.navbar .menu-toggler {
  background-image: url(../../img/sidebar_toggler_icon_blue.png);
  border-bottom: #335c7f 1px solid;
}

/* Default Horizontal Menu */
.page-header.navbar {
  /* Horizontal mega menu */
}
.page-header.navbar .hor-menu .navbar-nav {
  /* Mega menu content */
  /* Classic menu */
}
.page-header.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu {
  box-shadow: 5px 5px rgba(55, 116, 170, 0.2);
}
.page-header.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu {
  border-right: 1px solid #3d81bd;
}
.page-header.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li > h3 {
  color: #acb4d0;
}
.page-header.navbar .hor-menu .navbar-nav > li > a {
  color: #9ca5c7;
}
.page-header.navbar .hor-menu .navbar-nav > li.open > a,
.page-header.navbar .hor-menu .navbar-nav > li > a:hover,
.page-header.navbar .hor-menu .navbar-nav > li > a:focus {
  color: #9ca5c7;
  background: #3774aa;
}
.page-header.navbar .hor-menu .navbar-nav > li.active > a,
.page-header.navbar .hor-menu .navbar-nav > li.active > a:hover, .page-header.navbar .hor-menu .navbar-nav > li.current > a,
.page-header.navbar .hor-menu .navbar-nav > li.current > a:hover {
  color: white;
  background: #d64635;
}
.page-header.navbar .hor-menu .navbar-nav > li.active .selected, .page-header.navbar .hor-menu .navbar-nav > li.current .selected {
  border-top: 6px solid #d64635;
}
.page-header.navbar .hor-menu .navbar-nav > li .dropdown-menu {
  box-shadow: 5px 5px rgba(55, 116, 170, 0.2);
  background: #3774aa;
}
.page-header.navbar .hor-menu .navbar-nav > li .dropdown-menu li > a {
  color: #9ca5c7;
}
.page-header.navbar .hor-menu .navbar-nav > li .dropdown-menu li > a:hover {
  color: white;
  background: #d64635;
}

/* Light Horizontal Menu */
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav {
  /* Mega menu */
  /* Classic menu */
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu {
  box-shadow: 5px 5px rgba(91, 91, 91, 0.2);
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu {
  border-right: 1px solid #eeeeee;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li h3 {
  color: #666666;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li a {
  color: #777777;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu:last-child {
  border-right: 0;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li > a {
  color: #9ca5c7;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li > a:hover, .page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li > a:focus {
  color: #9ca5c7;
  background: #3774aa;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a {
  color: #777777;
  background: #fefefe;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a:hover, .page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a:focus {
  color: #777777;
  background: #fefefe;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"] {
  color: #777777;
  background: #fefefe;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"]:hover, .page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"]:focus {
  color: #777777;
  background: #fefefe;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.active > a,
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.active > a:hover, .page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.current > a,
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.current > a:hover {
  color: white;
  background: #d64635;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.active .selected, .page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li.current .selected {
  border-top: 6px solid #d64635;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu {
  box-shadow: 5px 5px rgba(91, 91, 91, 0.2);
  background: #fefefe;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu li > a {
  color: #777777;
}
.page-header.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu li > a:hover {
  color: #777777;
  background: #f0f0f0;
}

/* Page sidebar */
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover,
.page-sidebar {
  background-color: #4276a4;
  /* Sidebar search */
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu,
.page-sidebar .page-sidebar-menu {
  /* 1st level links */
  /* All links */
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a,
.page-sidebar .page-sidebar-menu > li > a {
  border-top: 1px solid #487ead;
  color: #c9dff5;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a > i,
.page-sidebar .page-sidebar-menu > li > a > i {
  color: #8eb8de;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a > i[class^="icon-"],
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a > i[class*="icon-"],
.page-sidebar .page-sidebar-menu > li > a > i[class^="icon-"],
.page-sidebar .page-sidebar-menu > li > a > i[class*="icon-"] {
  color: #c9ddef;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu > li > a > .arrow:before,
.page-sidebar .page-sidebar-menu > li > a > .arrow.open:before {
  color: #8eb8de;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li:hover > a, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.open > a,
.page-sidebar .page-sidebar-menu > li:hover > a,
.page-sidebar .page-sidebar-menu > li.open > a {
  background: #497fae;
  color: #c9dff5;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li:hover > a > i, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.open > a > i,
.page-sidebar .page-sidebar-menu > li:hover > a > i,
.page-sidebar .page-sidebar-menu > li.open > a > i {
  color: #d2e6f9;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li:hover > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li:hover > a > .arrow.open:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.open > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.open > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu > li:hover > a > .arrow:before,
.page-sidebar .page-sidebar-menu > li:hover > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu > li.open > a > .arrow:before,
.page-sidebar .page-sidebar-menu > li.open > a > .arrow.open:before {
  color: #d2e6f9;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a,
.page-sidebar .page-sidebar-menu > li.active > a,
.page-sidebar .page-sidebar-menu > li.active.open > a {
  background: #d64635;
  border-top-color: transparent;
  color: white;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a:hover, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a:hover,
.page-sidebar .page-sidebar-menu > li.active > a:hover,
.page-sidebar .page-sidebar-menu > li.active.open > a:hover {
  background: #d64635;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a > i, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a > i,
.page-sidebar .page-sidebar-menu > li.active > a > i,
.page-sidebar .page-sidebar-menu > li.active.open > a > i {
  color: white;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a > .arrow.open:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu > li.active > a > .arrow:before,
.page-sidebar .page-sidebar-menu > li.active > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu > li.active.open > a > .arrow:before,
.page-sidebar .page-sidebar-menu > li.active.open > a > .arrow.open:before {
  color: white;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a > .selected, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a > .selected,
.page-sidebar .page-sidebar-menu > li.active > a > .selected,
.page-sidebar .page-sidebar-menu > li.active.open > a > .selected {
  background-image: url("../../img/sidebar-menu-arrow.png");
}
.page-sidebar-reversed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active > a > .selected, .page-sidebar-reversed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open > a > .selected, .page-sidebar-reversed
.page-sidebar .page-sidebar-menu > li.active > a > .selected, .page-sidebar-reversed
.page-sidebar .page-sidebar-menu > li.active.open > a > .selected {
  background-image: url("../../img/sidebar-menu-arrow-reverse.png");
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active + li > a,
.page-sidebar .page-sidebar-menu > li.active + li > a {
  border-top-color: transparent;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li.active.open + li > a,
.page-sidebar .page-sidebar-menu > li.active.open + li > a {
  border-top-color: #487ead;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu > li:last-child > a,
.page-sidebar .page-sidebar-menu > li:last-child > a {
  border-bottom: 1px solid transparent !important;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu li > a > .arrow:before,
.page-sidebar .page-sidebar-menu li > a > .arrow.open:before {
  color: #8eb8de;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li:hover > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li:hover > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu li:hover > a > .arrow:before,
.page-sidebar .page-sidebar-menu li:hover > a > .arrow.open:before {
  color: #d2e6f9;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li.active > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu li.active > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu li.active > a > .arrow:before,
.page-sidebar .page-sidebar-menu li.active > a > .arrow.open:before {
  color: white;
}
.page-sidebar-closed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu:hover .sub-menu, .page-sidebar-closed
.page-sidebar .page-sidebar-menu:hover .sub-menu {
  background-color: #4276a4;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a,
.page-sidebar .page-sidebar-menu .sub-menu > li > a {
  color: #c9dff5;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a > i,
.page-sidebar .page-sidebar-menu .sub-menu > li > a > i {
  color: #8eb8de;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a > i[class^="icon-"],
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a > i[class*="icon-"],
.page-sidebar .page-sidebar-menu .sub-menu > li > a > i[class^="icon-"],
.page-sidebar .page-sidebar-menu .sub-menu > li > a > i[class*="icon-"] {
  color: #c9ddef;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu .sub-menu > li > a > .arrow:before,
.page-sidebar .page-sidebar-menu .sub-menu > li > a > .arrow.open:before {
  color: #8eb8de;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li:hover > a, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.open > a, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.active > a,
.page-sidebar .page-sidebar-menu .sub-menu > li:hover > a,
.page-sidebar .page-sidebar-menu .sub-menu > li.open > a,
.page-sidebar .page-sidebar-menu .sub-menu > li.active > a {
  background: #497fae !important;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li:hover > a > i, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.open > a > i, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.active > a > i,
.page-sidebar .page-sidebar-menu .sub-menu > li:hover > a > i,
.page-sidebar .page-sidebar-menu .sub-menu > li.open > a > i,
.page-sidebar .page-sidebar-menu .sub-menu > li.active > a > i {
  color: #d2e6f9;
  color: #ddeaf5;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li:hover > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li:hover > a > .arrow.open:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.open > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.open > a > .arrow.open:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.active > a > .arrow:before, .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .page-sidebar-menu .sub-menu > li.active > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu .sub-menu > li:hover > a > .arrow:before,
.page-sidebar .page-sidebar-menu .sub-menu > li:hover > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu .sub-menu > li.open > a > .arrow:before,
.page-sidebar .page-sidebar-menu .sub-menu > li.open > a > .arrow.open:before,
.page-sidebar .page-sidebar-menu .sub-menu > li.active > a > .arrow:before,
.page-sidebar .page-sidebar-menu .sub-menu > li.active > a > .arrow.open:before {
  color: #d2e6f9;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-toggler,
.page-sidebar .sidebar-toggler {
    line-height: 30px;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group,
.page-sidebar .sidebar-search .input-group {
  border-bottom: 1px solid #4f86b6;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group .form-control,
.page-sidebar .sidebar-search .input-group .form-control {
  background-color: #4276a4;
  color: #6897c0;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group .form-control::-moz-placeholder,
.page-sidebar .sidebar-search .input-group .form-control::-moz-placeholder {
  color: #6897c0;
  opacity: 1;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group .form-control:-ms-input-placeholder,
.page-sidebar .sidebar-search .input-group .form-control:-ms-input-placeholder {
  color: #6897c0;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group .form-control::-webkit-input-placeholder,
.page-sidebar .sidebar-search .input-group .form-control::-webkit-input-placeholder {
  color: #6897c0;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search .input-group .input-group-btn .btn,
.page-sidebar .sidebar-search .input-group .input-group-btn .btn {
  background-image: url(../../img/sidebar_search_icon_blue.png) !important;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-bordered .input-group,
.page-sidebar .sidebar-search.sidebar-search-bordered .input-group {
  border: 1px solid #4f86b6;
}
.page-sidebar-closed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.open .input-group, .page-sidebar-closed
.page-sidebar .sidebar-search.open .input-group {
  background-color: #4276a4;
}
.page-sidebar-closed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.open .remove, .page-sidebar-closed
.page-sidebar .sidebar-search.open .remove {
  background-image: url("../../img/sidebar_search_close_icon_blue.png");
}
.page-sidebar-closed .page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-solid .input-group, .page-sidebar-closed
.page-sidebar .sidebar-search.sidebar-search-solid .input-group {
  background: none;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-solid .input-group,
.page-sidebar .sidebar-search.sidebar-search-solid .input-group {
  border: 1px solid #3b6992;
  background: #3b6992;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-solid .input-group .form-control,
.page-sidebar .sidebar-search.sidebar-search-solid .input-group .form-control {
  background: #3b6992;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-solid.open .input-group,
.page-sidebar .sidebar-search.sidebar-search-solid.open .input-group {
  border: 1px solid #4276a4;
  background: #4276a4;
}
.page-sidebar-closed.page-sidebar-fixed .page-sidebar:hover .sidebar-search.sidebar-search-solid.open .input-group .form-control,
.page-sidebar .sidebar-search.sidebar-search-solid.open .input-group .form-control {
  background: #4276a4;
}

/***
Footer 
***/
.page-footer .page-footer-inner {
  color:#FFF;
}
.page-footer .page-footer-tools .go-top {
  background-color: #5188b9;
}
.page-footer .page-footer-tools .go-top:hover {
  opacity: 0.7;
  filter: alpha(opacity=70);
}
.page-footer .page-footer-tools .go-top i {
  color: #a4c1db;
}
.page-footer-fixed .page-footer {
  background-color: #38648b;
}

@media (min-width: 992px) {
  /* 992px */
  /* Fixed Sidebar */
  .page-sidebar-fixed:not(.page-footer-fixed) .page-content {
    border-bottom: 0;
  }
  .page-sidebar-fixed:not(.page-footer-fixed) .page-footer {
    background-color: #fff;
  }
  .page-sidebar-fixed:not(.page-footer-fixed) .page-footer .page-footer-inner {
    color: #333;
  }
  .page-sidebar-fixed:not(.page-footer-fixed) .page-footer .page-footer-tools .go-top {
    background-color: #7B838A;
  }
  .page-sidebar-fixed:not(.page-footer-fixed) .page-footer .page-footer-tools .go-top i {
    color: #ddd;
  }

  .page-boxed {
    background-color: #3e6e99 !important;
    /* Page container */
    /* Page sidebar */
    /* Page footer */
  }
  .page-boxed .page-container {
    background-color: #4276a4;
    border-left: 1px solid #487ead;
    border-bottom: 1px solid #487ead;
  }
  .page-boxed.page-sidebar-reversed .page-container {
    border-left: 0;
    border-right: 1px solid #487ead;
  }
  .page-boxed.page-sidebar-fixed .page-container {
    border-left: 0;
    border-bottom: 0;
  }
  .page-boxed.page-sidebar-reversed.page-sidebar-fixed .page-container {
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
  }
  .page-boxed.page-sidebar-fixed .page-sidebar {
    border-left: 1px solid #487ead;
  }
  .page-boxed.page-sidebar-reversed.page-sidebar-fixed .page-sidebar {
    border-right: 1px solid #487ead;
    border-left: 0;
  }
  .page-boxed.page-sidebar-fixed.page-footer-fixed .page-footer {
    background-color: #3e6e99 !important;
  }
  .page-boxed.page-sidebar-fixed.page-footer-fixed .page-footer .page-footer-inner {
    color: #c9dae9;
  }
}
@media (max-width: 991px) {
  /* 991px */
  /* Page sidebar */
  .page-sidebar {
    background-color: #38648b;
  }
  .page-sidebar .page-sidebar-menu > li > a {
    border-top: 1px solid #4276a4;
  }
  .page-sidebar .page-sidebar-menu > li:hover > a, .page-sidebar .page-sidebar-menu > li.open > a {
    background: #335c80;
  }
  .page-sidebar .page-sidebar-menu > li:last-child > a {
    border-bottom: 0 !important;
  }
  .page-sidebar .page-sidebar-menu > li .sub-menu {
    background-color: #38648b !important;
  }
  .page-sidebar .page-sidebar-menu .sidebar-search input {
    background-color: #38648b !important;
  }
}


.page-button-color {
    color: white;
    background-color: #578ebe;
}
.page-button-color.btn:hover, .page-button-color.btn:focus, .page-button-color.btn:active, .page-button-color.btn.active {
  color: white;
  background-color: #427aaa;
}

.page-box-title {
    color: #4b77be !important;
}




/*** 
page-content-menu
***/
/* Header search bar, toggler button & top menu */
.page-content-menu.navbar {
width: 100%;
padding: 0 20px 0 20px;
margin: 0;
border: 0px;
padding: 0px;
padding-left: 35px;
box-shadow: none;
min-height: 36px;
filter: none;
min-height: 36px;
}
.page-content-menu.navbar {
  background-color: #28557c;
  /* Top notification menu/bar */
  /* Header seaech box */
  /* Toggler button for sidebar expand/collapse and responsive sidebar menu */
}
.navbar-nav>li>a {
padding-top:8px;
padding-bottom: 8px;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle:hover {
  background-color: #3774aa;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle > i {
  color: #4e85b6;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown .dropdown-toggle .badge.badge-default {
  background-color: #d64635;
  color: white;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown.open .dropdown-toggle {
  background-color: #3774aa;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle {
  background-color: #28547c;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle .username {
  color: #9ca5c7;
}
.page-content-menu.navbar .top-menu .navbar-nav > li.dropdown-user .dropdown-toggle > i {
  color: #9ca5c7;
}
.page-content-menu.navbar .search-form {
  background: #28547c;
}
.page-content-menu.navbar .search-form:hover {
  background: #3774aa;
}
.page-content-menu.navbar .search-form .input-group .form-control {
  color: #83aac8;
}
.page-content-menu.navbar .search-form .input-group .form-control::-moz-placeholder {
  color: #7fa8c6;
  opacity: 1;
}
.page-content-menu.navbar .search-form .input-group .form-control:-ms-input-placeholder {
  color: #7fa8c6;
}
.page-content-menu.navbar .search-form .input-group .form-control::-webkit-input-placeholder {
  color: #7fa8c6;
}
.page-content-menu.navbar .search-form .input-group .input-group-btn .btn.submit {
  background: url(../../img/header_search_icon_blue.png) center center no-repeat !important;
}
.page-content-menu.navbar .search-form.open {
  background: #3774aa;
}
.page-content-menu.navbar .menu-toggler {
  background-image: url(../../img/sidebar_toggler_icon_blue.png);
  border-bottom: #335c7f 1px solid;
}

/* Default Horizontal Menu */
.page-content-menu.navbar {
  /* Horizontal mega menu */
}
.page-content-menu.navbar .hor-menu .navbar-nav {
  /* Mega menu content */
  /* Classic menu */
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu {
  box-shadow: 5px 5px rgba(55, 116, 170, 0.2);
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu {
  border-right: 1px solid #3d81bd;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li > h3 {
  color: #acb4d0;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li > a {
  color: #9ca5c7;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.open > a,
.page-content-menu.navbar .hor-menu .navbar-nav > li > a:hover,
.page-content-menu.navbar .hor-menu .navbar-nav > li > a:focus {
  color: #9ca5c7;
  background: #3774aa;
    font-size: 12px;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.active > a,
.page-content-menu.navbar .hor-menu .navbar-nav > li.active > a:hover, .page-content-menu.navbar .hor-menu .navbar-nav > li.current > a,
.page-content-menu.navbar .hor-menu .navbar-nav > li.current > a:hover {
  color: white;
  background: #d64635;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li.active .selected, .page-content-menu.navbar .hor-menu .navbar-nav > li.current .selected {
  border-top: 6px solid #d64635;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li .dropdown-menu {
  box-shadow: 5px 5px rgba(55, 116, 170, 0.2);
  background: #3774aa;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li .dropdown-menu li > a {
  color: #9ca5c7;
}
.page-content-menu.navbar .hor-menu .navbar-nav > li .dropdown-menu li > a:hover {
  color: white;
  background: #d64635;
}

/* Light Horizontal Menu */
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav {
  /* Mega menu */
  /* Classic menu */
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu {
  box-shadow: 1px 1px rgba(91, 91, 91, 0.2);
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu {
  border-right: 1px solid #eeeeee;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li h3 {
  color: #666666;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu li a {
  color: #777777;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.mega-menu-dropdown > .dropdown-menu .mega-menu-content .mega-menu-submenu:last-child {
  border-right: 0;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li > a {
  color: #9ca5c7;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li > a:hover, .page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li > a:focus {
  color: #9ca5c7;
  background: #3774aa;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a {
  color: #777777;
  background: #fefefe;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a:hover, .page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a:focus {
  color: #777777;
  background: #fefefe;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"] {
  color: #777777;
  background: #fefefe;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"]:hover, .page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.open > a[data-hover="dropdown"]:focus {
  color: #777777;
  background: #fefefe;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.active > a,
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.active > a:hover, .page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.current > a,
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.current > a:hover {
  color: white;
  background: #d64635;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.active .selected, .page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li.current .selected {
  border-top: 6px solid #d64635;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu {
  box-shadow: 5px 5px rgba(91, 91, 91, 0.2);
  background: #fefefe;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu li > a {
  color: #777777;
}
.page-content-menu.navbar .hor-menu.hor-menu-light .navbar-nav > li .dropdown-menu li > a:hover {
  color: #777777;
  background: #f0f0f0;
}

.navbar .nav > li:hover .dropdown-menu {
	display: block;
}
var com = {};
com.workflowGraph = {};

var PathGlobal = com.workflowGraph.PathGlobal = {
	
	pointTypeLeftUp : 1,
	pointTypeUp : 2,
	pointTypeUpRight : 3,
	pointTypeLeft : 4,
	pointTypeRight :5,
	pointTypeLeftDown : 6,
	pointTypeDown : 7,
	pointTypeDownRight : 8,
	
	lineDefIndex : 10,
	lineDefStep : 2,
	modeDefIndex : 10,
	modeDefStep : 2,
	
	modeInc : 3,
	pauseTime : 10,
	modeHeigh : 0,
	copyModeDec : 10,
	rightMenu : false,
	isPixel : true,
	isAutoLineType : false,
	maxEvent : 17,
	minHeight : 32,
	minWidth : 32,
	selectColor : 'C5E7F6',
	clearBoderColor : 'blue',
	defaultColor : 'green',
	defaultMaxMag : 0.5,
	defaultMinMag : 2,
	lineColor : 'black',
	lineCheckColor : 'red',
	strokeweight : 1.8,
	dragPointDec : 3,
	switchType : false,
    //unicode编码
	newGraph : '\u65b0\u5efa\u56fe\u5c42',
	modeCreate : '\u521b\u5efa\u6a21\u5143',
	lineCreate : '\u521b\u5efa\u7ebf\u5143',
	modeMove : '\u79fb\u52a8\u6a21\u5143',
	lineMove : '\u79fb\u52a8\u7ebf\u5143',
	modeDragPoint : '\u7f29\u653e\u6a21\u5143',
	updateMode : '\u7f16\u8f91\u6a21\u5143',
	updateLine : '\u7f16\u8f91\u7ebf\u5143',
	copyMode : '\u62f7\u8d1d\u6a21\u5143',
	removeMode : '\u5220\u9664\u6a21\u5143',
	remodeLine : '\u5220\u9664\u7ebf\u5143',
	baseClear : '\u9009\u62e9\u6a21\u5143',
	toMerge : '\u7ec4\u5408\u6a21\u5143',
	toSeparate : '\u89e3\u7ec4\u6a21\u5143',
	clearContext : '\u6e05\u9664\u533a\u57df',
	contextDivDrag : '\u79fb\u52a8\u533a\u57df',
	toLeft : '\u5de6\u5bf9\u9f50',
	toRight : '\u53f3\u5bf9\u9f50',
	toMiddleWidth : '\u5782\u76f4\u5c45\u4e2d',
	toTop : '\u9876\u5bf9\u9f50',
	toMiddleHeight : '\u6c34\u5e73\u5c45\u4e2d',
	toBottom : '\u5e95\u5bf9\u9f50',
	buildLineAndMode : '\u7ed1\u5b9a\u7ebf\u5143',
	removeLineAndMode : '\u79fb\u9664\u7ed1\u5b9a',
	modeCutter : '\u526a\u5207\u6a21\u5143',
	modeDuplicate : '\u590d\u5236\u6a21\u578b',
	eventName : '\u89e6\u53d1\u4e8b\u4ef6',
	lineProTitle : '\u7ebf\u5c5e\u6027\u8bbe\u7f6e',
	modeProTitle : '\u7f16\u8f91\u6a21\u5143',
	editProp : '\u7f16\u8f91\u5c5e\u6027'
	
}
 	
var UndoRedoEventFactory = com.workflowGraph.UndoRedoEventFactory = function (hisMessageDiv) {
	
	var self = this;
	
	self.hisMessageDiv = hisMessageDiv;
	self.stack = [];
	self.index = 0;
	
	self.redo = function() {
		
		stopEvent = true;
		
		var fn = self.stack[self.index];

		if (fn) {
			fn.redo();
			this.index++;
		}
		
		var endLength = self.stack.length;
		
		if (this.index > endLength) {
			this.index = endLength;
		}
		
		self.history();
	
	}
	
	self.undo = function() {
		
		stopEvent = true;
		
		var fn = self.stack[self.index - 1];
		
		if (fn) {
			fn.undo();
			self.index--;
		}
		
		if (this.index < 1) {
			self.index = 1;
		}
		
		self.history();
	
	}
	
	self.addEvent = function(undoRedoEvent) {
		
		self.stack.splice(self.index, (self.stack.length - self.index++), undoRedoEvent);
		
		if (self.stack.length > PathGlobal.maxEvent) {
			self.stack.splice(0, 1);
			this.index = PathGlobal.maxEvent;
		}
		
		self.history();
		
	}
	
}

UndoRedoEventFactory.prototype = {
	
	init : function () {
	
		var newGraph = new com.workflowGraph.UndoRedoEvent(function () {}, PathGlobal.newGraph);
		newGraph.setRedo(function() {});

	}, 
	
	onHistory : function (historyDiv, indexDiv) {
	
		var self = this;
	
		historyDiv.onclick = function () {
			
			var global = com.workflowGraph.Global;
			
			global.lineTool.clear();
			global.modeTool.clear();
			
			stopEvent = true;
		
			if (indexDiv > self.index) {

				for (var i = self.index; i <= indexDiv - 1; i++) {
			
					var fn = self.stack[i];
				
					if (fn && fn.redo) {
						fn.redo();
					}
			
				}
		
			} else if (indexDiv < self.index) {
			
				for (var i = self.index; i >= indexDiv; i--) {
			
					var fn = self.stack[i];
				
					if (fn && fn.undo) {
						fn.undo();
					}
			
				}
			
			}
		
			self.index = indexDiv;
			self.history();
	
		}
	
	},
	
	history : function () {
	
		var history = $id(this.hisMessageDiv);
	
		if (!history) {
			return;
		}
	
		var self = this;
		history.innerHTML = "";
	
		var stackLength = self.stack.length,
		doc = document,
		tempFragment = doc.createDocumentFragment();
	
		for (var i = 0; i < stackLength; i++) {
		
			var div = doc.createElement("div");
			div.style.cssText = "position:relative;text-align:center;border-bottom:1px dotted #cccccc; width:112px;height:20px;line-height:20px;";
			div.innerHTML = self.stack[i].name;
		 
			var indexDiv = i + 1;
			self.onHistory(div, indexDiv);
		 
			if ((self.index) == indexDiv) {
				div.style.backgroundColor = PathGlobal.selectColor;
			}
		 
			tempFragment.appendChild(div);

		}
	
		history.appendChild(tempFragment);
	
	}, 
	
	clear : function () {
	
		var self = this;
	
		delete self.stack;
	
		self.stack = [];
		self.index = 0;
		
		self.history();
	
	}

}

var UndoRedoEvent = com.workflowGraph.UndoRedoEvent = function (undoFn, name) {
	
	var self = this;
	
	self.name = name ? name : PathGlobal.eventName;
	self.undo = undoFn;
	self.redo;
	
	com.workflowGraph.Global.undoRedoEventFactory.addEvent(self);
	
	self.setUndo = function (undoFn) {
		self.undo = undoFn;
	}
	
	self.setRedo = function (redoFn) {
		self.redo = redoFn;
	}
	
}

var BaseTool = com.workflowGraph.BaseTool = function (pathBody, width, height) {
	
	var self = this;
	
	self.pathBody = pathBody;
	self.checkColor = "#00ff00";
	self.areaDiv = document.createElement("div");
	self.initEndDiv(width, height);
	self.initPathBody(self.pathBody);
	self.contextMoveAbale = false;
	self.contextMoveAttempt = false;
	self.contextMap = new Map();
	self.tempContextId = null;
	
	self.checkBrowser();
	
}

BaseTool.prototype = {
	
	initScaling : function (multiple) {
	
		var self = this,
				global = com.workflowGraph.Global,
				tempSmallTool = global.smallTool,
				tempLineTool = global.lineTool;
	
		self.forEach(self.contextMap, function (contextId) {
		
			var context = $id(contextId),
			contextStyle = context.style;
		
			contextStyle.top = 0 + "px";
			contextStyle.left = 0 + "px";
		
			var contextWidth = 0,
					contextHeight = 0,
					contextInfo = self.contextMap.get(contextId),
					modeMaps = contextInfo.contextModeMap,
					lineMaps = contextInfo.contextLineMap;
					
			self.forEach(lineMaps, function (lineId) {
				
					var line = $id(lineId),
			    path = tempLineTool.getPath(line),
					paths = tempLineTool.getPathArray(path),
					pathLength = paths.length;
					
					for (var i = pathLength; i--;) {
						
						var isTop = (i % 2 == 1);
						
						if (isTop && (parseInt(contextStyle.top) > paths[i] || parseInt(contextStyle.top) == 0)) {
							contextStyle.top = paths[i] - 2 + "px";
						}
			
						if (!isTop && (parseInt(contextStyle.left) > paths[i] || parseInt(contextStyle.left) == 0)) {
							contextStyle.left = paths[i] - 2 + "px";
						}
						
						if (isTop && (parseInt(contextHeight) < parseInt(paths[i]))) {
							contextHeight = paths[i];
						}
						
						if (!isTop && (parseInt(contextWidth) < parseInt(paths[i]))) {
							contextWidth = paths[i];
						}
						
					}
					
			});
		
			self.forEach(modeMaps, function (modeId) {
			
				var mode = $id(modeId),
				modeStyle = mode.style,
			
				modeTop = parseInt(modeStyle.top),
				modeLeft = parseInt(modeStyle.left),
				modeWidth = parseInt(mode.offsetWidth),
				modeHeight = parseInt(mode.offsetHeight),
			
				contextTop = parseInt(contextStyle.top),
				contextLeft = parseInt(contextStyle.left);
			
				if (contextTop > modeTop || contextTop == 0) {
					contextStyle.top = modeTop + "px";
				}
			
				if (contextLeft > modeLeft || contextLeft == 0) {
					contextStyle.left = modeLeft + "px";
				}
			
				if (contextWidth < modeWidth + modeLeft) {
					contextWidth = modeWidth + modeLeft;
				}
			
				if (contextHeight < modeHeight + modeTop) {
					contextHeight = modeHeight + modeTop;
				}
			
			});
			
			

			contextStyle.width = contextWidth - parseInt(contextStyle.left) + "px";
			contextStyle.height = contextHeight - parseInt(contextStyle.top) + "px";
		
		});
	
	}, 

	getOptionMap : function (tempContextId) {
	
		var self = this,
		map = null;

		if (tempContextId) {
			map = self.contextMap.get(tempContextId).contextModeMap;
		} else {
			
			
			var global = com.workflowGraph.Global;
			
			map = new Map();
			map.putAll(global.modeMap);
		
			var tempBaseTool = global.baseTool;
		
			tempBaseTool.forEach(tempBaseTool.contextMap, function (contextId) {
				
				var sonContextModeMap = tempBaseTool.contextMap.get(contextId).contextModeMap,
				sonContextDiv = $id(contextId),
				isGroups = sonContextDiv.getAttribute("groups");
				
				tempBaseTool.forEach(sonContextModeMap, function (modeId) {
				
					if (isGroups == "true" || isGroups) {
						map.remove(modeId);
					}
					
				});
				
			});
		
		}
	
		return map;

	},

	toLeft : function () {
	
		var self = this,
		map = self.getOptionMap(self.tempContextId),
		
		left = -1;
	
		self.forEach(map, function (modeId) {
			
			var mode = $id(modeId),
			modeLeft = parseInt(mode.style.left);
		
			if (left > modeLeft || left == -1) {
				left = modeLeft;
			}
		
		});
		
		var global = com.workflowGraph.Global,
	
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldLeftMap = new Map(),
		afterLeftMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			oldLeftMap.put(modeId, parseInt(modeStyle.left));
		
			modeStyle.left = left + "px";
		
			afterLeftMap.put(modeId, parseInt(modeStyle.left));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = oldLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toLeft);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = afterLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	},
	
	toMiddleWidth : function () {
	
		var self = this,
		map = self.getOptionMap(self.tempContextId),
		middleWidthArray = [],
		i = 0;
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId);
			middleWidthArray[i++] = parseInt(mode.style.left) + parseInt(parseInt(mode.offsetWidth) / 2);
		
		});
	
		middleWidthArray = middleWidthArray.sort(function (n1, n2) { 
			return n1 - n2
		});
	
		var middleNumber = parseInt(middleWidthArray.length / 2),
		middleLeft = middleWidthArray[middleNumber],
	
		global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldLeftMap = new Map(),
		afterLeftMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			oldLeftMap.put(modeId, parseInt(modeStyle.left));
		
			var decLeft = parseInt(parseInt(modeStyle.left) + parseInt(parseInt(mode.offsetWidth) / 2) - middleLeft);
			modeStyle.left = parseInt(parseInt(modeStyle.left) - decLeft) + "px";
		
			afterLeftMap.put(modeId, parseInt(modeStyle.left));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = oldLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toMiddleWidth);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = afterLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	},
	
	toRight : function () {
	
		var self = this,
		map = self.getOptionMap(self.tempContextId),
	
		right = -1;
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeRight = parseInt(mode.style.left) + parseInt(mode.offsetWidth);
		
			if (right < modeRight) {
				right = modeRight;
			}
		
		});
		
		var global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldLeftMap = new Map(),
		afterLeftMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			oldLeftMap.put(modeId, parseInt(modeStyle.left));
		
			var modeRight = parseInt(modeStyle.left) + parseInt(mode.offsetWidth);
			modeStyle.left = (right - modeRight) + parseInt(modeStyle.left) + "px";
		
			afterLeftMap.put(modeId, parseInt(modeStyle.left));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = oldLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toRight);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.left = afterLeftMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	}, 

	toTop : function () {
	
		var self = this,
		map = self.getOptionMap(self.tempContextId),
		top = -1;
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeTop = parseInt(mode.style.top);
		
			if (top > modeTop || top == -1) {
				top = modeTop;
			}
		
		});
		
		var global = com.workflowGraph.Global,
	
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldTopMap = new Map(),
		afterTopMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			oldTopMap.put(modeId, parseInt(modeStyle.top));
		
			modeStyle.top = top + "px";
		
			afterTopMap.put(modeId, parseInt(modeStyle.top));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = oldTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toTop);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = afterTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	},

	toMiddleHeight : function () {
	
		var self = this,
		map = self.getOptionMap(self.tempContextId),
		middleHeightArray = [],
		i = 0;
	
		this.forEach(map, function (modeId) {
		
			var mode = $id(modeId);
			middleHeightArray[i++] = parseInt(mode.style.top) + parseInt(parseInt(mode.offsetHeight) / 2);
		
		});
	
		middleHeightArray = middleHeightArray.sort(function (n1, n2) { 
			return n1 - n2
		});
	
		var middleNumber = parseInt(middleHeightArray.length / 2),
		middleTop = middleHeightArray[middleNumber],
		
		global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldTopMap = new Map(),
		afterTopMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style,
		
			decTop = parseInt(parseInt(modeStyle.top) + parseInt(parseInt(mode.offsetHeight) / 2) - middleTop);
		
			oldTopMap.put(modeId, parseInt(modeStyle.top));
		
			modeStyle.top = parseInt(parseInt(modeStyle.top) - decTop) + "px";
		
			afterTopMap.put(modeId, parseInt(modeStyle.top));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = oldTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toMiddleHeight);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = afterTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	},

	toBottom : function () {
	
		var self = this,
		
		map = self.getOptionMap(self.tempContextId),
		bottom = -1;

		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeBottom = parseInt(mode.style.top) + parseInt(mode.offsetHeight);
		
			if (bottom < modeBottom) {
				bottom = modeBottom
			}
		
		});
		
		var global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempSmallTool = global.smallTool,
	
		oldTopMap = new Map(),
		afterTopMap = new Map();
	
		self.forEach(map, function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style,
		
			modeBottom = parseInt(modeStyle.top) + parseInt(mode.offsetHeight);
		
			oldTopMap.put(modeId, parseInt(modeStyle.top));
		
			modeStyle.top = (bottom - modeBottom) + parseInt(modeStyle.top) + "px";
		
			afterTopMap.put(modeId, parseInt(modeStyle.top));
		
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
		
			tempSmallTool.drawMode(mode);
		
		});
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = oldTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
				
		}, PathGlobal.toBottom);
	
		undoRedoEvent.setRedo(function () {
		
			self.forEach(map, function (modeId) {
		
				var mode = $id(modeId);
		
				mode.style.top = afterTopMap.get(modeId) + "px";
		
				tempModeTool.showPointer(mode);
				tempModeTool.changeBaseModeAndLine(mode, true);
		
				tempSmallTool.drawMode(mode);
		
			});
		
		});
	
	}, 

	sumLeftTop : function (body, sumLeft, sumTop) {
	
		if (!sumLeft) {
			sumLeft = body.offsetLeft;
		}
	
		if (!sumTop) {
			sumTop = body.offsetTop;
		}
	
		var parent = body.offsetParent;
					
		if (parent) {
						
			sumLeft += parent.offsetLeft;
			sumTop += parent.offsetTop; 
						
			return this.sumLeftTop(parent, sumLeft, sumTop);
					
		} else {
			return [sumLeft, sumTop];
		}
	
	},
	
	changStyle : function (div) {
	
		PathGlobal.isPixel = !PathGlobal.isPixel;
		div.innerHTML = PathGlobal.isPixel ? "Pixel" : "Grid";
	
	},

	showMenu : function (event, contextId) {
		this.tempContextId = contextId;
	
		event = event || window.event;
	
		if (!event.pageX) {
			event.pageX = event.clientX;
		} 
		
		if (!event.pageY) {
			event.pageY = event.clientY;
		}
   	
  	var tx = event.pageX,
		ty = event.pageY,
		
		global = com.workflowGraph.Global,
		
		tempPathBody = global.lineTool.pathBody,
		leftTops = global.baseTool.sumLeftTop(tempPathBody);
   			
		tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
		ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
	
		var isPixel = $id("isPixel"),
		isPixelStyle = isPixel.style;
	
		if (contextId) {
			isPixelStyle.visibility = "hidden";
		} else {
			isPixelStyle.visibility = "visible";
		}
	
		var pathBodyRightMenu = $id("pathBodyRightMenu");
		pathBodyRightMenuStyle = pathBodyRightMenu.style;

		pathBodyRightMenuStyle.top = ty + "px";
		pathBodyRightMenuStyle.left = tx + "px";
		pathBodyRightMenuStyle.visibility = "visible";
		var bodyMenu_zIndex = com.workflowGraph.Global.modeTool.getNextIndex();

	    //node_div的zIndex是60
		if (bodyMenu_zIndex < 60)
		    bodyMenu_zIndex = 61;
		pathBodyRightMenuStyle.zIndex = bodyMenu_zIndex;
					
	},

	toSeparate : function () {
	
		var self = this,
		contextArray = [],
		i = 0;
	
		self.forEach(self.contextMap, function(contextId) {
			
			var contextDiv = $id(contextId);
		
			if (contextDiv.style.borderColor == PathGlobal.defaultColor) {
				contextArray[i++] = contextDiv;
				contextDiv.setAttribute("groups", false);
			}
		
		});
		
		var global = com.workflowGraph.Global;
		
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			var contextLength = contextArray.length,
			tempBaseTool = global.baseTool;
		
			for (var i = contextLength; i--;) {
		
				var contextDiv = contextArray[i];
				contextDiv.setAttribute("groups", true);
			
			}
		
		}, PathGlobal.toSeparate);
	
		undoRedoEvent.setRedo(function () {
		
			var contextLength = contextArray.length,
			tempBaseTool = global.baseTool;
		
			for (var i = contextLength; i--;) {
			
				var contextDiv = contextArray[i];
				contextDiv.setAttribute("groups", true);
			
			}
		
		});
	
		self.clearContext();
	
	},

	checkBrowser : function () {

		var ua = navigator.userAgent.toLowerCase();

		check = function(r){
			return r.test(ua);
		}
	
		var self = this;
	
		self.isOpera = check(/opera/);
		self.isIE = !self.isOpera && check(/msie/);
		self.isIE7 = self.isIE && check(/msie 7/);
		self.isIE8 = self.isIE && check(/msie 8/);
		self.isIE6 = self.isIE && !self.isIE7 && !self.isIE8;
		self.isChrome = check(/chrome/);
		self.isWebKit = check(/webkit/);
		self.isSafari = !self.isChrome && check(/safari/);
		self.isSafari2 = self.isSafari && check(/applewebkit\/4/);
		self.isSafari3 = self.isSafari && check(/version\/3/);
		self.isSafari4 = self.isSafari && check(/version\/4/);
		self.isGecko = !self.isWebKit && check(/gecko/);
		self.isGecko2 = self.isGecko && check(/rv:1\.8/);
		self.isGecko3 = self.isGecko && check(/rv:1\.9/);
	
	},
	
	getBrowserName : function () {
	
		var self = this;
	
		if (self.isIE) {
		
			if (self.isIE8) {
				return "IE8";
			} else if (self.isIE7) {
				return "IE7";
			} else if (self.isIE6) {
				return "IE6";
			} else {
				return "IE";
			}
		
		}
	
		if (self.isChrome) {
			return "CHROME";
		} else if (self.isWebKit) {
			return "WEBKIT";
		} else if (self.isOpera) {
			return "OPERA";
		} else if (self.isGecko) {
			return "GECKO";
		} else if (self.isGecko2) {
			return "GECKO2";
		} else if (self.isGecko3) {
			return "GECKO3";
		}
	
		if (self.isSafari) {
			return "SAFARI";
		} else if (self.isSafari2) {
			return "SAFARI2";
		} else if (self.isSafari3) {
			return "SAFARI3";
		} else if (self.isSafari4) {
			return "SAFARI4";
		}
	
	},

	printView : function () {
	
		var viewHTML = window.open('view.html', '', '');
		
		if (this.isChrome || this.isGecko) {
		
			var viewHTMLBuffer = [],
			i = 0;
	
			viewHTMLBuffer[i++] = '<html>';
			viewHTMLBuffer[i++] = '<head>';
			viewHTMLBuffer[i++] = '<link href="/Content/layout/css/flowPath.css" type="text/css" rel="stylesheet" />';
			viewHTMLBuffer[i++] = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
			viewHTMLBuffer[i++] = '<title></title>';
			viewHTMLBuffer[i++] = '</head>';
			viewHTMLBuffer[i++] = '<body>';
			viewHTMLBuffer[i++] = document.getElementById("contextBody").innerHTML;
			viewHTMLBuffer[i++] = '</body></html>';
		
			viewHTML.document.write(viewHTMLBuffer.join(""));
		
		}
	
		viewHTML.document.close();

	},

	toMerge : function () {
	
		var self = this,
		contextArray = [],
		i = 0;
	
		self.forEach(self.contextMap, function(contextId) {
		
			var contextDiv = $id(contextId);
		
			if (contextDiv.style.borderColor ==  PathGlobal.defaultColor) {
			
				contextArray[i++] = contextDiv;
				contextDiv.setAttribute("groups", true);
			
				contextDiv.oncontextmenu = function () {
					return false;
				}
			
			}
		
		});
		
		var global = com.workflowGraph.Global;
		
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			var contextLength = contextArray.length,
			tempBaseTool = global.baseTool;
		
			for (var i = contextLength; i--;) {
		
				var contextDiv = contextArray[i];
			
				contextDiv.setAttribute("groups", false);
				contextDiv.oncontextmenu = function (event) {
			
					PathGlobal.rightMenu = true;
					tempBaseTool.showMenu(event, this.id);
			
					return false;
		
				}
			
			}
		
		}, PathGlobal.toMerge);
	
		undoRedoEvent.setRedo(function () {
		
			var contextLength = contextArray.length,
			tempBaseTool = global.baseTool;
		
			for (var i = contextLength; i--;) {
			
				var contextDiv = contextArray[i];
			
				contextDiv.setAttribute("groups", true);
				contextDiv.oncontextmenu = function (event) {
					return false;
				}
			
			}
		
		});
	
	},
	
	forEach : function (maps, fn) {

		var mapKeys = maps.getKeys(),
  	    mapKeysLength = mapKeys.length;

		for (var i = mapKeysLength; i--;) {
		
			if (fn) {
				fn(mapKeys[i]);
			}
			
		}

	},
	
	removeAll : function () {
	
		var self = this,
		tempBaseTool = com.workflowGraph.Global.baseTool;
	
		self.forEach(self.contextMap, function(contextId) {
		
			var contextDiv = $id(contextId);
			
			tempBaseTool.contextMap.remove(contextId);
			tempBaseTool.pathBody.removeChild(contextDiv);

		});
	
	},
	
	clearContext : function () {
	
		var self = this;
	
		self.tempContextId = null;
	
		var contextArray = [],
		contextMap = [],
		i = 0,
	
		tempBaseTool = com.workflowGraph.Global.baseTool;
	
		self.forEach(self.contextMap, function(contextId) {
		
			var contextDiv = $id(contextId),
			contextDivStyle = contextDiv.style;
		
			contextDivStyle.borderColor = PathGlobal.clearBoderColor;
			contextDivStyle.filter = "alpha(opacity=10)";
			contextDivStyle.opacity = "0.1";
		
			var groups = contextDiv.getAttribute("groups");

			if (groups == "false" || !groups) {
			
				contextArray[i] = contextDiv;
				contextMap[i++] = tempBaseTool.contextMap.get(contextId);
			
				tempBaseTool.contextMap.remove(contextId);
				tempBaseTool.pathBody.removeChild(contextDiv);
		
			}
		
		});
	
		if (contextArray.length > 0) {
		
			var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
				var contextLength = contextArray.length;
		
				for (var i = contextLength; i--;) {
			
					var contextDiv = contextArray[i];
			
					tempBaseTool.contextMap.put(contextDiv.id, contextMap[i]);
					tempBaseTool.pathBody.appendChild(contextDiv);
			
				}
				
			}, PathGlobal.clearContext);
	
			undoRedoEvent.setRedo(function () {
		
				var contextLength = contextArray.length;
		
				for (var i = contextLength; i--;) {
			
					var contextDiv = contextArray[i];
				
					if (contextDiv && contextDiv.id && $id(contextDiv.id)) {
					
						tempBaseTool.contextMap.remove(contextDiv.id);
						tempBaseTool.pathBody.removeChild(contextDiv);
				
					}
			
				}
		
			});
		
		}

	},
	
	clear : function () {
	
		PathGlobal.rightMenu = false;
	
		var pathBodyRightMenu = $id("pathBodyRightMenu");
		pathBodyRightMenu.style.visibility = "hidden";
	
		var isPixel = $id("isPixel");
		isPixel.style.visibility = "hidden";
	
		var self = this,
		areaDivStyle = self.areaDiv.style,
	
		top = parseInt(areaDivStyle.top),
		left = parseInt(areaDivStyle.left),
		width = parseInt(areaDivStyle.width),
		height = parseInt(areaDivStyle.height);
	
		if (areaDivStyle.visibility != "visible") {
			return;
		}
	
		var contextDiv = document.createElement("div"),
		contextDivStyle = contextDiv.style;
	
		contextDivStyle.position = "absolute";
		contextDivStyle.fontSize = "0px";
		contextDivStyle.borderWidth = "1px";
		contextDivStyle.borderStyle = "solid";
		contextDivStyle.borderColor = PathGlobal.defaultColor;
		contextDivStyle.visibility = "visible";
		contextDivStyle.top = 0 + "px";
		contextDivStyle.left = 0 + "px";
		contextDivStyle.width = 0 + "px";
		contextDivStyle.height = 0 + "px";
		contextDivStyle.backgroundColor = PathGlobal.selectColor;
		contextDivStyle.filter = "alpha(opacity=20)";
		contextDivStyle.opacity = "0.2";
		
		var global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempLineTool = global.lineTool,
		contextDivId = tempModeTool.getNextIndex();
		
		contextDivStyle.zIndex = contextDivId;

		contextDiv.setAttribute("id", "contextDiv" + contextDivId);
	
		var contextModeMap = new Map(),
				contextLineMap = new Map(),
	
				contextWidth = 0,
				contextHeight = 0,
	
				tempBaseTool = com.workflowGraph.Global.baseTool;
		
		tempLineTool.clear();
		
		tempLineTool.forEach(function (lineId) {
			
			var line = $id(lineId),
			    path = tempLineTool.getPath(line),
					paths = tempLineTool.getPathArray(path),
					pathLength = paths.length,
					isHas = true,
					point1 = 0,
					point2 = 0;
					
					for (var i = pathLength; i--;) {
						
						var isTop = true;
						if (i % 2 == 1) {
							
							point1 = top;
							point2 = top + height;
							
 						
 						} else {
							
							point1 = left;
							point2 = left + width;
							isTop = false;
							
						}
						
						if (!(paths[i] >= point1 && paths[i] <= point2)) {
							
								isHas = false;	
								break;
						}
						
						if (isTop && (parseInt(contextDivStyle.top) > paths[i] || parseInt(contextDivStyle.top) == 0)) {
							contextDivStyle.top = paths[i] - 2 + "px";
						}
			
						if (!isTop && (parseInt(contextDivStyle.left) > paths[i] || parseInt(contextDivStyle.left) == 0)) {
							contextDivStyle.left = paths[i] - 2 + "px";
						}
						
						if (isTop && (parseInt(contextHeight) < parseInt(paths[i]))) {
							contextHeight = paths[i];
						}
						
						
						if (!isTop && (parseInt(contextWidth) < parseInt(paths[i]))) {
							contextWidth = paths[i];
						}
			
					}
					
					if (isHas) {
						
						var isAbleMode = true;
						
						tempBaseTool.forEach(tempBaseTool.contextMap, function (contextId) {
				
							var sonContextLineMap = global.baseTool.contextMap.get(contextId).contextLineMap, 
									sonContextDiv = $id(contextId),
									isGroups = sonContextDiv.getAttribute("groups");
				
									tempBaseTool.forEach(sonContextLineMap, function (lineId) {
					
										if (lineId == line.id && (isGroups == "true" || isGroups)) {
											isAbleMode = false;
										}
					
									});
				
						});
						
						stopEvent = true;
						
						if (isAbleMode) {
							
							tempLineTool.show(line);
							contextLineMap.put(lineId, line);
							
						}
						
					}
			
		});
	
		tempModeTool.forEach(function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style,
		
			imag = $id(modeId.replace("module", "backImg")),
			imagStyle = imag.style,
		
			modeTop = parseInt(modeStyle.top),
			modeLeft = parseInt(modeStyle.left),
		
			modeWidth = parseInt(imagStyle.width),
			modeHeight = parseInt(imagStyle.height),
		
			isAbleMode = true;
			
			tempBaseTool.forEach(tempBaseTool.contextMap, function (contextId) {
				
				var sonContextModeMap = global.baseTool.contextMap.get(contextId).contextModeMap,
						sonContextDiv = $id(contextId),
						isGroups = sonContextDiv.getAttribute("groups");
				
				tempBaseTool.forEach(sonContextModeMap, function (modeId) {
					
					if (modeId == mode.id && (isGroups == "true" || isGroups)) {
						isAbleMode = false;
					}
					
				});
				
			});
		
			if (isAbleMode && modeTop > top && modeLeft > left 
					&& modeLeft + modeWidth < left + width 
					&& modeTop + modeHeight < top + height) {
			
				if (parseInt(contextDivStyle.top) > modeTop || parseInt(contextDivStyle.top) == 0) {
					contextDivStyle.top = modeTop + "px";
				}
			
				if (parseInt(contextDivStyle.left) > modeLeft || parseInt(contextDivStyle.left) == 0) {
					contextDivStyle.left = modeLeft + "px";
				}
			
				if (contextWidth < modeWidth + modeLeft) {
					contextWidth = modeWidth + modeLeft;
				}
			
				if (contextHeight < modeHeight + modeTop) {
					contextHeight = modeHeight + modeTop;
				}
			
				stopEvent = true;
				global.modeTool.showPointer(mode);
				contextModeMap.put(mode.id, mode);
			
			} else {
				global.modeTool.hiddPointer(mode);
			}
		
		});
		
		self.clearContext();
		
		function contextEntry (modeMap, lineMap) {
			this.contextModeMap = modeMap;
			this.contextLineMap = lineMap;
		}

		if ((contextModeMap.size() + contextLineMap.size()) > 1) {
			
			self.pathBody.appendChild(contextDiv);
			
			var contextEntry = new contextEntry(contextModeMap, contextLineMap);
			
			self.contextMap.put(contextDiv.id, contextEntry);
		
			self.tempContextId = contextDiv.id;
		
			contextDivStyle.width = (contextWidth - parseInt(contextDivStyle.left)) + "px";
			contextDivStyle.height = (contextHeight - parseInt(contextDivStyle.top)) + "px";
		
			var tempBaseTool = global.baseTool;
		
			var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
				if (contextDiv && contextDiv.id && $id(contextDiv.id)) {
				
					tempBaseTool.pathBody.removeChild(contextDiv);		
					tempBaseTool.contextMap.remove(contextDiv.id);
			
				}
			
			}, PathGlobal.baseClear);
	
			undoRedoEvent.setRedo(function () {
				
				tempBaseTool.pathBody.appendChild(contextDiv);
				tempBaseTool.contextMap.put(contextDiv.id, contextEntry);
			
			});
		
			self.contextDivDrag(contextDiv, contextEntry);

		}
	
		areaDivStyle.top = 1 + "px";
		areaDivStyle.left = 1 + "px";
		areaDivStyle.width = 1 + "px";
		areaDivStyle.height = 1 + "px";
		areaDivStyle.visibility = "hidden";
	
	},
	
	contextDivDrag : function (contextDiv, contextEntry) {
	
		var contextDivStyle = contextDiv.style,
		global = com.workflowGraph.Global,
		tempSmallTool = global.smallTool,
		tempBaseTool = global.baseTool,
		tempModeTool = global.modeTool,
		tempLineTool = global.lineTool,
		contextModeMap = contextEntry.contextModeMap,
		contextLineMap = contextEntry.contextLineMap;
	
		contextDiv.onclick = function () {
			
			contextDivStyle.borderColor = PathGlobal.defaultColor;
			contextDivStyle.filter = "alpha(opacity=30)";
			contextDivStyle.opacity = "0.3";
			
			tempBaseTool.forEach(tempBaseTool.contextMap, function (contextId) {
				
				if (contextId != contextDiv.id) {
				
					var sonContextDiv = $id(contextId);
					var sonContextDivStyle = sonContextDiv.style;
				
					sonContextDivStyle.borderColor = PathGlobal.clearBoderColor;
					sonContextDivStyle.filter = "alpha(opacity=10)";
					sonContextDivStyle.opacity = "0.1";
				
				}
				
			});
			
		}
		
		contextDiv.oncontextmenu = function (event) {
			
			PathGlobal.rightMenu = true;
			tempBaseTool.showMenu(event, this.id);
			
			return false;
		
		}
		
		contextDiv.ondragstart = function () {
			return false;
		};
	
		contextDiv.onmousedown = function(event) {
			event = event || window.event;
			
			global.modeTool.clear();
			
			tempBaseTool.contextMoveAbale = true;
			contextDivStyle.borderColor = PathGlobal.defaultColor;
			contextDivStyle.filter = "alpha(opacity=20)";
			contextDivStyle.opacity = "0.2";
			contextDivStyle.visibility = "visible";
			
			tempBaseTool.forEach(tempBaseTool.contextMap, function (contextId) {
				
				if (contextId != contextDiv.id) {
				
					var sonContextDiv = $id(contextId),
					sonContextDivStyle = sonContextDiv.style;
					
					sonContextDivStyle.borderColor = PathGlobal.clearBoderColor;
					sonContextDivStyle.filter = "alpha(opacity=10)";
					sonContextDivStyle.opacity = "0.1";
				
				}
				
			});
			
			var oldTop = parseInt(contextDivStyle.top),
			oldLeft = parseInt(contextDivStyle.left);
		
			if (contextDiv.setCapture) {
				contextDiv.setCapture();
			} else if (window.captureEvents) {
				window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
		
			var x = event.layerX && event.layerX >= 0 ? event.layerX : event.offsetX,
			y = event.layerY && event.layerX >= 0 ? event.layerY : event.offsetY,
			
			oldTop = parseInt(contextDivStyle.top),
			oldLeft = parseInt(contextDivStyle.left),
			doc = document;
			
			doc.onmousemove = function (event) {
			
				tempBaseTool.contextMoveAttempt = true;
				
				event = event || window.event;
				
				if (!event.pageX) {
					event.pageX = event.clientX;
				} 
		
   			if (!event.pageY) {
   				event.pageY = event.clientY;
   			}
   		
   			var tx = event.pageX - x,
   			ty = event.pageY - y,
   			
   			global = com.workflowGraph.Global,
   			
   			tempPathBody = global.lineTool.pathBody,
   			leftTops = global.baseTool.sumLeftTop(tempPathBody);
   			
   			tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
				ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
			
				contextDivStyle.left = tx + "px";
    		contextDivStyle.top = ty + "px";

			};
		
			doc.onmouseup = function (event) {
			
				event = event || window.event;
				
				if (!event.pageX) {
					event.pageX = event.clientX;
				} 
		
   			if (!event.pageY) {
   				event.pageY = event.clientY;
   			}
				
				var tx = event.pageX - x,
   			ty = event.pageY - y,
   			
   			global = com.workflowGraph.Global,
   			
   			tempPathBody = global.lineTool.pathBody,
   			leftTops = global.baseTool.sumLeftTop(tempPathBody);
   			
   			tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
				ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
			
				if (contextDiv.releaseCapture) {
					contextDiv.releaseCapture();
				} else if (window.releaseEvents) {
					window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
				}
				
   			doc.onmousemove = null;
   			doc.onmouseup = null;
   			
   			if (tempBaseTool.contextMoveAttempt) {

   				var contextModeMapKeys = contextModeMap.getKeys(),
  						contextModeMapKeyLength = contextModeMapKeys.length,
  						contextLineMapKeys = contextLineMap.getKeys(),
  						contextLineMapKeyLength = contextLineMapKeys.length,
  						oldPathMap = new Map(),
							newPathMap = new Map();

  				for (var i = contextLineMapKeyLength; i--;) {
  					
  					var lineId = contextLineMapKeys[i];
  					line = $id(lineId),
  					newLineLeft = tx - oldLeft,
						newLineTop = ty - oldTop,
						path = tempLineTool.getPath(line),
						paths = tempLineTool.getPathArray(path),
						pathLength = paths.length,
						lineMode = global.lineMap.get(line.id),
						xBaseMode = lineMode.xBaseMode,
						wBaseMode = lineMode.wBaseMode;
						
						oldPathMap.put(lineId, path);
						
						for (var j = pathLength; j--;) {
							
							if (j % 2 == 1) {
								paths[j] = parseInt(paths[j]) + parseInt(newLineTop);
							} else {
								paths[j] = parseInt(paths[j]) + parseInt(newLineLeft);
							}
							
						}
						
						var newPath = tempLineTool.arrayToPath(paths);
						
						newPathMap.put(lineId, newPath);
			
						tempLineTool.setPath(line, newPath);
						tempLineTool.setDragPoint(line);
						
						if (wBaseMode && $id(wBaseMode.id) && !contextModeMap.containsKey(wBaseMode.id)) {
							tempLineTool.removeAllLineAndMode(line, $id(wBaseMode.id));
						}
						
						if (xBaseMode && $id(xBaseMode.id) && !contextModeMap.containsKey(xBaseMode.id)) {
							tempLineTool.removeAllLineAndMode(line, $id(xBaseMode.id));
						}
						
						tempSmallTool.drawLine(line);
						tempLineTool.clearLine(lineId);
  					
  				}
  				
  				function ModeTopLeft(valueTop, valueLeft) {
  					
  					var self = this;
  					
  					self.modeTop = valueTop;
  					self.modeLeft = valueLeft;
  					
  				}
  				
  				var oldModeTopLeftMap = new Map(),
					newModeTopLeftMap = new Map(); 
  			
					for (var i = contextModeMapKeyLength; i--;) {
		
						var mode = $id(contextModeMapKeys[i]),
						modeStyle = mode.style,
					
						newModeLeft = tx - oldLeft,
						newModeTop = ty - oldTop;
						
						oldModeTopLeftMap.put(mode.id, new ModeTopLeft(parseInt(modeStyle.top), parseInt(modeStyle.left)));
						
						modeStyle.left = parseInt(modeStyle.left) + newModeLeft + "px";
						modeStyle.top = parseInt(modeStyle.top) + newModeTop + "px";
						
						newModeTopLeftMap.put(mode.id, new ModeTopLeft(parseInt(modeStyle.top), parseInt(modeStyle.left)));
						
						tempModeTool.changeBaseModeAndLine(mode, true);
    				tempSmallTool.drawMode(mode);

					}
					
					var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
						
						contextDivStyle.top = oldTop + "px";
						contextDivStyle.left = oldLeft + "px";
  					
  					for (var i = contextModeMapKeyLength; i--;) {
		
							var mode = $id(contextModeMapKeys[i]),
							modeStyle = mode.style,
							modeTopLeft = oldModeTopLeftMap.get(mode.id);
							
							modeStyle.left = modeTopLeft.modeLeft + "px";
							modeStyle.top = modeTopLeft.modeTop + "px";
							
							tempModeTool.showPointer(mode);
							tempModeTool.changeBaseModeAndLine(mode, true);
							
    					tempSmallTool.drawMode(mode);

						}
						
						for (var i = contextLineMapKeyLength; i--;) {
							
							var lineId = contextLineMapKeys[i];
									line = $id(lineId),
									oldLine = oldPathMap.get(lineId);
									
							tempLineTool.setPath(line, oldLine);
							tempLineTool.show(line);
						
							tempSmallTool.drawLine(line);
							
						}
			
					}, PathGlobal.contextDivDrag);
					
					var afterTop = parseInt(contextDivStyle.top),
					afterLeft = parseInt(contextDivStyle.left);
					
					undoRedoEvent.setRedo(function () {

						contextDivStyle.top = afterTop + "px";
						contextDivStyle.left = afterLeft + "px";
						
						for (var i = contextModeMapKeyLength; i--;) {
		
							var mode = $id(contextModeMapKeys[i]),
							modeStyle = mode.style,
							modeTopLeft = newModeTopLeftMap.get(mode.id);
							
							modeStyle.left = modeTopLeft.modeLeft + "px";
							modeStyle.top = modeTopLeft.modeTop + "px";
							
							tempModeTool.showPointer(mode);
							tempModeTool.changeBaseModeAndLine(mode, true);
							
    					tempSmallTool.drawMode(mode);

						}
						
						for (var i = contextLineMapKeyLength; i--;) {
							
							var lineId = contextLineMapKeys[i];
									line = $id(lineId),
									newPath = newPathMap.get(lineId);
									
							tempLineTool.setPath(line, newPath);
							tempLineTool.show(line);
						
							tempSmallTool.drawLine(line);
							
						}
		
					});
				
				}
				
				tempBaseTool.contextMoveAttempt = false;
				tempBaseTool.contextMoveAbale = false;

			};
		
		}
	
	}, 
	
	initPathBody : function (pathBody) {
	
		var pathBody = $id(pathBody.id),
		self = this,
	
		areaDiv = self.areaDiv,
		areaDivStyle = areaDiv.style;
	
		areaDivStyle.position = "absolute";
		areaDivStyle.width = 1 + "px";
		areaDivStyle.height = 1 + "px";
		areaDivStyle.fontSize = "0px";
		areaDivStyle.borderWidth = "1px";
		areaDivStyle.borderStyle= "solid";
		areaDivStyle.visibility = "hidden";
		areaDivStyle.backgroundColor = PathGlobal.selectColor;
		areaDivStyle.filter = "alpha(opacity=30)";
		areaDivStyle.opacity = "0.3";

		pathBody.appendChild(areaDiv);
	
		pathBody.ondragstart = function () {
				return false;
		};
		
		var global = com.workflowGraph.Global;
		
		pathBody.onclick = function () {
			global.baseTool.clear();
		}
	
		pathBody.ondblclick = function () {
			global.baseTool.clear();
		}

		pathBody.onmousedown = function(event) {
		
			areaDivStyle.borderColor = global.baseTool.checkColor;
			event = event || window.event;
		
			if (!PathGlobal.rightMenu) {
				global.baseTool.clear();
			}
		
			var x = event.clientX ? event.clientX : event.offsetX,
			y = event.clientY ? event.clientY : event.offsetY,
			
			tempPathBody = global.lineTool.pathBody,
			leftTops = global.baseTool.sumLeftTop(tempPathBody);
		
			x = x - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
			y = y - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);

			areaDivStyle.left = x + "px";
			areaDivStyle.top = y + "px";
		
			if (global.modeTool.moveable == true || global.lineTool.moveable == true || global.baseTool.contextMoveAbale == true) {
			} else {
				areaDivStyle.visibility = "visible";
			}
		
			pathBody.onmousemove = function (event) {
			
				event = event || window.event;
			
   			var tx = event.clientX,
						ty = event.clientY,
   		
   			tempPathBody = global.lineTool.pathBody,
   			leftTops = global.baseTool.sumLeftTop(tempPathBody);
   		
   			tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
				ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
			
				var newTx = tx - x,
						newTy = ty - y;

				if (areaDiv && areaDivStyle.visibility == "visible") {
				
					if (tx >= x) {
						areaDivStyle.width = newTx + "px";
					} 
				
					if (ty >= y) {
						areaDivStyle.height = newTy + "px";
					}
				
					if (ty < y) {
						areaDivStyle.top = ty + "px";
						areaDivStyle.height = Math.abs(newTy) + "px";
					}
				
					if (tx < x) {
						areaDivStyle.left = tx + "px";
						areaDivStyle.width = Math.abs(newTx) + "px";
					}
				
				}

			};
		
			pathBody.onmouseup = function (event) {

				if (areaDiv && areaDivStyle.visibility == "visible" && !PathGlobal.rightMenu) {
					global.baseTool.clear();
				}
			
			};
		
		}
	
	},
	
	findBackImgSrc : function (baseMode) {
	
		for(var sonNode = baseMode.firstChild; sonNode != null; sonNode = sonNode.nextSibling) {
		
			if (sonNode.id && sonNode.id.indexOf("backGroundImg") >= 0) {
				return sonNode.src;
			}
					
		}
	
	},
	
	drag : function (baseMode, isLine, brokenType) {
	    
		var baseMode = baseMode,
		isLine = isLine,
		imgSrc = this.findBackImgSrc(baseMode),
		
		global = com.workflowGraph.Global;
	
		baseMode.ondragstart = function () {
			return false;
		};
	
		baseMode.onmousedown = function(event) {
		    
			event = event || window.event;
            var target = event.target || event.srcElement,
                name = target.name;
		
			var moveBaseModeImg = $id("moveBaseModeImg");
			moveBaseModeImg.src = imgSrc;

			var moveBaseMode = $id("moveBaseMode"),
			moveBaseModeStyle = moveBaseMode.style;
		
			moveBaseModeStyle.visibility = "visible";
		
			if (moveBaseMode.setCapture) {
				moveBaseMode.setCapture();
			} else if (window.captureEvents) {
				document.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
		
			var x = event.clientX ? event.clientX : event.offsetX,
					y = event.clientY ? event.clientY : event.offsetY;
		
			moveBaseModeStyle.left = x + "px";
			moveBaseModeStyle.top = y + "px";
		
			var doc = document;
		
			doc.onmousemove = function (event) {
			    event = event || window.event;
			    var tx = event.clientX,
   					ty = event.clientY;
			    moveBaseModeStyle.left = tx + "px";
    		    moveBaseModeStyle.top = ty + "px";
			};
		
			doc.onmouseup = function (event) {
			    event = event || window.event;

			    if (moveBaseMode.releaseCapture) {
			        moveBaseMode.releaseCapture();
			    } else if (window.releaseEvents) {
			        document.releaseEvents(Event.MOUSEMOVE | Event.MOUSEUP);
			    }

			    doc.onmousemove = null;
			    doc.onmouseup = null;

			    moveBaseModeStyle.visibility = "hidden";

			    if (!event.pageX) {
			        event.pageX = event.clientX;
			    }
			    if (!event.pageY) {
			        event.pageY = event.clientY;
			    }

			    var tx = event.pageX,
                    ty = event.pageY,
                    tempPathBody = global.lineTool.pathBody,
                    leftTops = global.baseTool.sumLeftTop(tempPathBody);

			    tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
			    ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);

			    var isCreate = tx >= 0 && ty >= 0;

			    if (isCreate) {
			        if (isLine) {
			            global.lineTool.create(tx, ty, brokenType);
			        } else {
			            global.modeTool.create(ty, tx, imgSrc, name);
			        }
			    }
			};
		
		}
	
	},
	
	initEndDiv : function (width, height) {
	
		var self = this;

		self.endDiv = document.createElement("div");
		var endDiv = self.endDiv,
				endDivStyle = endDiv.style;
	
		endDivStyle.left = width + "px";
		endDivStyle.top = height + "px";
		endDivStyle.width = "10px";
		endDivStyle.height = "10px";
		endDivStyle.fontSize = "10px";
		endDivStyle.position = "absolute";
	
		self.pathBody.appendChild(endDiv);
	
		var topCross = $id("topCross"),
		leftCross = $id("leftCross");
	
		topCross.style.width = width + "px";
		leftCross.style.height = height + "px";
	
	}, 

	isSVG : function () {
		return this.VGType() == "SVG";
	},
	
	VGType : function () {
		return window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML";
	},
	
	isVML : function () {
		return this.VGType() == "VML";
	}

}
var LineTool = com.workflowGraph.LineTool = function (pathBody) {
	
	var self = this;
	
	self.stepIndex = PathGlobal.lineDefStep;
	self.pathBody = pathBody;
	
	var global = com.workflowGraph.Global;
	
	self.tool = global.baseTool;
	self.moveable = false;
	self.isSVG = self.tool.isSVG();
	self.isVML = self.tool.isVML();
	
	self.pathBody.oncontextmenu = function (event) {
				
		if (!PathGlobal.rightMenu) {
		    //Line右键菜单
			PathGlobal.rightMenu = true;
			global.baseTool.showMenu(event);
		}
		return false;
	}
	
	self.baseLineIdIndex = PathGlobal.lineDefIndex;
	
	if (self.isSVG) {
		
		var doc = document;
		
		self.svgBody = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
		self.svgBody.setAttribute("id", "svgContext");
        self.svgBody.setAttribute("style", "position:absolute;z-index:0;");
        self.svgBody.setAttribute("height", this.pathBody.scrollHeight + "px");
		self.svgBody.setAttribute("width", this.pathBody.scrollWidth + "px");
		
		var marker = doc.createElementNS('http://www.w3.org/2000/svg', 'marker');
		marker.setAttribute("id", "arrow");
		marker.setAttribute("viewBox", "0 0 18 20");
		marker.setAttribute("refX", "0");
		marker.setAttribute("refY", "10");
		marker.setAttribute("markerUnits", "strokeWidth");
		marker.setAttribute("markerWidth", "3");
		marker.setAttribute("markerHeight", "10");
		marker.setAttribute("orient", "auto");
		
		var linePath = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
		linePath.setAttribute("d", "M 0 0 L 20 10 L 0 20 z");
		linePath.setAttribute("fill", PathGlobal.lineColor);
		linePath.setAttribute("stroke", PathGlobal.lineColor);
		
		marker.appendChild(linePath);
		
		self.svgBody.appendChild(marker);
		self.pathBody.appendChild(self.svgBody);
		
		self.pathBody.addEventListener("scroll", function() {
				global.smallTool.initSmallBody();
		}, false);
		
	} else if (self.isVML) {

		self.pathBody.attachEvent("onscroll", function() {
				global.smallTool.initSmallBody();
		});
		
	}
	
}

LineTool.prototype = {
	
	tempLine : null,
	
	removeAll : function () {
	
		var self = this;
	
		self.forEach(function (lineId) {
			self.removeNode(lineId);
		});
	
	},
	
	createRect : function (id) {
		
		var result,
				doc = document,
                text = null;
		
		if (this.isSVG) {
			//console.log("sss")
			var g = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
			g.setAttribute("style", "cursor: pointer;");
		
			var rect = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
			rect.setAttribute("stroke", "black");
			rect.setAttribute("id", id);
			rect.setAttribute("fill", "#00FF00");
			rect.setAttribute("shape-rendering", "crispEdges");
			rect.setAttribute("shapeRendering", "crispEdges");
			rect.setAttribute("stroke-width", "1");
			rect.setAttribute("strokeWidth", "1");
		
			rect.setAttribute("x", "100");
			rect.setAttribute("y", "100");
			rect.setAttribute("width", "7");
			rect.setAttribute("height", "7");
			rect.style.visibility = "hidden";

            if (id.indexOf("lineMiddle") > -1) {
                text = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
                text.setAttribute("x", "100");
                text.setAttribute("y", "100");
                text.innerHTML = "line";
                text.style.visibility = "hidden";
                text.setAttribute("id", id + "text");
               // g.appendChild(text);
            }
		
			g.appendChild(rect);

			result = g;

		} else if (this.isVML) {
		
			var rect = document.createElement("v:rect");
			rect.setAttribute("id", id);
			
			var rectStyle = rect.style;
            rectStyle.width = "7px";
            rectStyle.height = "7px";
            rectStyle.position = "absolute";
            rectStyle.left = "100px";
            rectStyle.top = "100px";
            rectStyle.cursor = "pointer";
            rectStyle.visibility = "hidden";

            rect.fillcolor = "#00FF00";
            rect.stroked = "black";

            result = rect;
			
		}
		
		return result; 
		
	},

	removeNode : function (lineId) {

		var self = this,
		line = $id(lineId);
		
		var dragBody = null;
		
		if (self.isVML && line) {
				
				dragBody = self.pathBody;
				
				dragBody.removeChild($id(lineId + 'lineHead'));
				dragBody.removeChild($id(lineId + 'lineMiddle'));
				dragBody.removeChild($id(lineId + 'lineEnd'));
			
		} else if (self.isSVG && line) {
				
				dragBody = self.svgBody;
				
				dragBody.removeChild($id(lineId + 'lineHead').parentNode);
				dragBody.removeChild($id(lineId + 'lineMiddle').parentNode);
				dragBody.removeChild($id(lineId + 'lineEnd').parentNode);
				
		}
		
		if (line) {
			
			dragBody.removeChild(line);
		
			var global = com.workflowGraph.Global;
			global.lineMap.remove(lineId);
	
			global.smallTool.removeLine(lineId);
		
		}
		
	},

	formatPath : function (path) {
	
		if (this.isVML) {
		
			path = path.replaceAll(",", " "),
			path = path.replaceAll("e", "z"),
			path = path.replaceAll("l", "L ");
		
		} else {
			
			path = path.replaceAll(",NaN NaN", ""),
			path = path.replaceAll(",undefined undefined", "");
			
		}
	
		return path;
	
	},
	
	getNextIndex : function () {
	
		var self = this;
		self.baseLineIdIndex += self.stepIndex;
	
		return self.baseLineIdIndex;

	},
	
	getActiveLine : function () {
	
		var activeLine;
	
		this.forEach(function (lineId) {
		
			var line = $id(lineId);
		
			if (com.workflowGraph.Global.lineTool.isActiveMode(line)) {
				activeMode = line;
			}
		
		});
	
		return activeLine;
	
	},
	
	isActiveLine : function (line) {
	
		var isActive,
		global = com.workflowGraph.Global;
		
		if (global.lineTool.isVML) {
			isActive = (line.getAttribute("strokecolor") == PathGlobal.lineCheckColor);
		} else if (global.lineTool.isSVG) {		
			isActive = (line.getAttribute("style").indexOf(PathGlobal.lineCheckColor) > 0);
		}

		return isActive;
	
	}, 
	
	forEach : function (fn) {
	
		var lineKeys = com.workflowGraph.Global.lineMap.getKeys(),
  	        lineKeysLength = lineKeys.length;
  	
		for (var i = lineKeysLength; i--;) {
		
			if (fn) {
				fn(lineKeys[i]);
			}
		
		}
	
	},

	createBaseLine : function (lineId, path, brokenType) {
	
		var self = this,
		line = null,
	    text = null,
		doc = document;
		var dragBody = null;
	
		if (self.isSVG) {
		
			line = doc.createElementNS('http://www.w3.org/2000/svg', "path");
			line.setAttribute("id", lineId);
			self.setPath(line, path);
			line.setAttribute("style", "cursor:pointer; fill:none; stroke:" + PathGlobal.lineColor + "; stroke-width:" + + PathGlobal.strokeweight);
			line.setAttribute("stroke", "purple");
			line.setAttribute("marker-end", 'url(#arrow)');
			line.setAttribute("brokenType", brokenType);

			dragBody = self.svgBody;
    
		} else if (self.isVML) {

			line = doc.createElement('<v:shape style="cursor:pointer;WIDTH:100;POSITION:absolute;HEIGHT:100" coordsize="100,100" filled="f" strokeweight="' + PathGlobal.strokeweight + 'px" strokecolor="' + PathGlobal.lineColor + '"></v:shape>'); 
		
			var stroke = doc.createElement("<v:stroke EndArrow='classic'/>");
			line.appendChild(stroke);
		
			line.setAttribute("id", lineId);
			line.setAttribute("brokenType", brokenType);
		
			self.setPath(line, path);
			
			dragBody = self.pathBody;
		
		}
		
		dragBody.appendChild(line);
			
		dragBody.appendChild(self.createRect(lineId + 'lineHead'));
		dragBody.appendChild(self.createRect(lineId + 'lineMiddle'));
		dragBody.appendChild(self.createRect(lineId + 'lineEnd'));
			
		self.drag(line);
	
		return line;
	
	},

    setTransPoint: function(startPoint, firstTurn, secondTurn, threshold) {

        var transitionf = new Point();
        var transitions = new Point();
        var array = new Array();

        if (startPoint.x == firstTurn.x && startPoint.y > firstTurn.y) {

            transitionf.x = firstTurn.x;
            transitionf.y = firstTurn.y + threshold;

            if (secondTurn.y == firstTurn.y && secondTurn.x < firstTurn.x) {
                transitions.x = firstTurn.x - threshold;
                transitions.y = firstTurn.y;

            } else if (secondTurn.y == firstTurn.y && secondTurn.x > firstTurn.x) {
                transitions.x = firstTurn.x + threshold;
                transitions.y = firstTurn.y;
            }

        } else if (startPoint.x == firstTurn.x && startPoint.y < firstTurn.y) {

            transitionf.x = firstTurn.x;
            transitionf.y = firstTurn.y - threshold;

            if (secondTurn.y == firstTurn.y && secondTurn.x < firstTurn.x) {
                transitions.x = firstTurn.x - threshold;
                transitions.y = firstTurn.y;

            } else if (secondTurn.y == firstTurn.y && secondTurn.x > firstTurn.x) {
                transitions.x = firstTurn.x + threshold;
                transitions.y = firstTurn.y;
            }

        } else if (startPoint.y == firstTurn.y && startPoint.x < firstTurn.x) {

            transitionf.x = firstTurn.x - threshold;
            transitionf.y = firstTurn.y;

            if (secondTurn.x == firstTurn.x && secondTurn.y < firstTurn.y) {
                transitions.y = firstTurn.y - threshold;
                transitions.x = firstTurn.x;

            } else if (secondTurn.x == firstTurn.x && secondTurn.y > firstTurn.y) {
                transitions.y = firstTurn.y + threshold;
                transitions.x = firstTurn.x;
            }

        } else if (startPoint.y == firstTurn.y && startPoint.x > firstTurn.x) {

            transitionf.x = firstTurn.x + threshold;
            transitionf.y = firstTurn.y;

            if (secondTurn.x == firstTurn.x && secondTurn.y < firstTurn.y) {
                transitions.y = firstTurn.y - threshold;
                transitions.x = firstTurn.x;
            } else if (secondTurn.x == firstTurn.x && secondTurn.y > firstTurn.y) {
                transitions.y = firstTurn.y + threshold;
                transitions.x = firstTurn.x;
            }

        }

        if (startPoint.y == firstTurn.y && startPoint.x == firstTurn.x) {
            transitionf.x = firstTurn.x;
            transitionf.y = firstTurn.y;
        }

        if (secondTurn.y == firstTurn.y && secondTurn.x == firstTurn.x) {
            transitions.x = secondTurn.x;
            transitions.y = secondTurn.y;
        }



        //console.log(secondTurn.y == firstTurn.y && secondTurn.x == firstTurn.x)
        array.push(transitionf);
        array.push(transitions);
        return array;

    },


    getPathString : function(pointArray) {

        var pathD = "";
        var pointArrayOne = this.setTransPoint(pointArray[0], pointArray[1], pointArray[2], 5);
        var pointArrayTwo = this.setTransPoint(pointArray[1], pointArray[2], pointArray[3], 5);

        if (pointArrayOne[0].empty() || pointArrayOne[1].empty()) {
            pointArrayOne[0].x = pointArray[1].x;
            pointArrayOne[0].y = pointArray[1].y;
            pointArrayOne[1].x = pointArray[1].x;
            pointArrayOne[1].y = pointArray[1].y;

        }

        if (pointArrayTwo[0].empty() || pointArrayTwo[1].empty()) {
            pointArrayTwo[0].x = pointArray[2].x;
            pointArrayTwo[0].y = pointArray[2].y;
            pointArrayTwo[1].x = pointArray[2].x;
            pointArrayTwo[1].y = pointArray[2].y;

        }

        pathD += "M" + pointArray[0].x + " " + pointArray[0].y + " ";
        pathD += "L" + pointArrayOne[0].x + " " + pointArrayOne[0].y + " ";
        pathD += "C" + pointArrayOne[0].x + " " + pointArrayOne[0].y + " "
            + pointArray[1].x + " " + pointArray[1].y + " " + + pointArrayOne[1].x + " " + pointArrayOne[1].y + " ";

        pathD += "L" + pointArrayTwo[0].x + " " + pointArrayTwo[0].y + " ";
        pathD += "C" + pointArrayTwo[0].x + " " + pointArrayTwo[0].y + " "
            + pointArray[2].x + " " + pointArray[2].y + " " + + pointArrayTwo[1].x + " " + pointArrayTwo[1].y + " ";
        pathD += "L" + pointArray[3].x + " " + pointArray[3].y;

        return pathD;
    },

    getPointArray : function(pathD) {

        var rs = "";
        var reArray = new Array();
        var pointArray = new Array();

        for (var i = 0; i < pathD.length; i++) {
            rs = rs + pathD.substr(i, 1).replace(",",' ');
        }

        var pathDArray = rs.split(" ");

        for (var i = 0; i < pathDArray.length; i++) {

            if (!isNaN(pathDArray[i]) && pathDArray[i] != "") {
                reArray.push(pathDArray[i]);
            }
            //pathDArray[i] = pathDArray[i].replace(/[^0-9]/ig, "");
        }

        for (var i = 0; i < reArray.length; i = i + 2) {

            var point = new Point();
            point.x = parseInt(reArray[i]);
            point.y = parseInt(reArray[i + 1]);
            pointArray.push(point);

        }

        return pointArray;

    },
	
	setPath : function (line, path, flag) {

		var self = this;
        var pathR = self.getPointArray(path)
        var newPath = "";

        if (self.isSVG) {
            path = path.replace("z", "");
        }

        if (pathR.length > 3) {
            newPath = self.getPathString(pathR);
            line.setAttribute("d", newPath);

            if (flag) {
                line.setAttribute("d", path);
                line.setAttribute("path", path);
            } else {
                line.setAttribute("path", newPath);

            }

        } else {
            if (path.indexOf("undefined") == -1) {
                line.setAttribute("d", path);
                line.setAttribute("path", path);
            }
        }

        line.setAttribute("name", path);
	
	},
	
	getMiddle : function (path, lineId, isPainting) {
		
		path = path.replace("M", "");
		path = path.replace("m", "");
		path = path.replace("z", "");
		
		var paths = path.split("L"),
	
		self = this,
		endStr = self.strTrim(paths[1]),
	
		end,
		middle,
		middlePoint;
		
		if (self.isSVG) {
			
			if (endStr.indexOf(",") > 0) {
			
				end = endStr.split(",");

				var begin = self.strTrim(end[0]).split(" "),
						end = self.strTrim(end[1]).split(" "),
			
						x1 = parseInt(begin[0]),
						y1 = parseInt(begin[1]),
			
						x2 = parseInt(end[0]),
						y2 = parseInt(end[1]);
				
				middlePoint = [x1, y1, x2, y2];
				middle = [parseInt(Math.abs(x1 + x2) / 2), parseInt(Math.abs(y2 + y1) / 2)];
			
			} else {
			
				var head = self.getLineHead(path),
						end = self.getLineEnd(path);
				
				middle = [parseInt(Math.abs(head[0] + end[0]) / 2), parseInt(Math.abs(head[1] + end[1]) / 2)];

			}
		
		} else if (self.isVML) {
			
			end = self.strTrim(endStr).split(" ");

			if (end.length > 2) {
				
				var x1 = parseInt(self.strTrim(end[0])),
						y1 = parseInt(self.strTrim(end[1])),
				
						x2 = parseInt(self.strTrim(end[2])),
						y2 = parseInt(self.strTrim(end[3]));
				
				middlePoint = [x1, y1, x2, y2];
				middle = [parseInt(Math.abs(x1 + x2) / 2), parseInt(Math.abs(y2 + y1) / 2)];
				
			} else {
			
				var head = self.getLineHead(path),
					  end = self.getLineEnd(path);
				
				middle = [parseInt(Math.abs(head[0] + end[0]) / 2), parseInt(Math.abs(head[1] + end[1]) / 2)];

			}
			
		}
		
		if (isPainting) {
			
			var rectMiddle = $id(lineId + "lineMiddle");
//                text = $id(lineId + "lineMiddletext");
					rectMiddleStyle = rectMiddle.style;

			rectMiddle.setAttribute("x", middle[0] - PathGlobal.dragPointDec);
			rectMiddle.setAttribute("y", middle[1] - PathGlobal.dragPointDec);

//            text.setAttribute("x", middle[0] * 0.99 - PathGlobal.dragPointDec);
//            text.setAttribute("y", middle[1] * 1.1 - PathGlobal.dragPointDec);

			if (self.isActiveLine($id(lineId))) {
				rectMiddleStyle.visibility = "";
               // text.style.visibility = "";
			}
			
			rectMiddleStyle.left = middle[0] - PathGlobal.dragPointDec + "px";
			rectMiddleStyle.top = middle[1] - PathGlobal.dragPointDec + "px";
			
		}
		
		return middlePoint;
		
	},
	
	getLineHead : function (path) {
	
		path = path.replace("M", "");
		path = path.replace("m", "");
		path = path.replace("z", "");
	
		var paths = path.split("L"),
	
		head = this.strTrim(paths[0]).split(" "),
	
		left = parseInt(head[0]),
		top = parseInt(head[1]);
	
		return [left, top];
	
	},
	
	getLineEnd : function (path) {
	
		path = path.replace("M", "");
		path = path.replace("m", "");
		path = path.replace("z", "");
		
		if (this.isSVG) {
			
			var paths = path.split("L"),
			self = this,
			endStr = self.strTrim(paths[1]),
			end;
	
			if (endStr.indexOf(",") > 0) {
				end = endStr.split(",");
				end = self.strTrim(end[end.length - 1]).split(" ");
			} else {
				end = endStr.split(" ");
				end = [end[end.length - 2], end[end.length - 1]];
			}
		} else {
			
			path = path.replace("L", " ");
			path = path.replace(",", " ");

			path = this.strTrim(path);

			var end = path.split(" ");
			end = [end[end.length - 2], end[end.length - 1]];

			return [parseInt(end[0]), parseInt(end[1])];
	
		}
		
		return [parseInt(end[0]), parseInt(end[1])];
	
	},
	
	brokenPath : function (path, brokenType) {
	
		var self = this,
	
		head = self.getLineHead(path),
		left = head[0],
		top = head[1],
	
		end = self.getLineEnd(path),
		endLeft = end[0],
		endTop = end[1];
	
		if (brokenType == 2) {
			path = self.brokenVertical(left, top, endLeft, endTop, path);
		} else if (brokenType == 3) {
			path = self.brokenCross(left, top, endLeft, endTop, path);
		}
	
		return path;
	
	},
	
	broken : function (left, top, endLeft, endTop, brokenType, path) {
	
		if (brokenType == 2) {
			path = this.brokenVertical(left, top, endLeft, endTop, path);
		} else if (brokenType == 3) {
			path = this.brokenCross(left, top, endLeft, endTop, path);
		}

		return path;
	
	},
	
	brokenVertical : function (left, top, endLeft, endTop, path) {
	
		var paths = this.getPathArray(path),
				pathLength = paths.length;
		
		if (PathGlobal.switchType || pathLength < 5) {
			
			var descTop = endTop - top,
	
			path = "M " + left + " " + top + " L " + 
			(left) + " " + (top + parseInt(descTop/2)) + 
			"," + (endLeft) + " " + (endTop - parseInt(descTop/2)) + 
			"," + endLeft + " " + endTop + " z";
			
		} else {
			
			paths[0] = left;
			paths[1] = top;
			paths[2] = left;
			
			paths[4] = endLeft;
			paths[5] = paths[3];
			paths[6] = endLeft;
			paths[7] = endTop;
			
			path = this.arrayToPath(paths);
		
		}
		
		return path;
	
	},
	
	brokenCross : function (left, top, endLeft, endTop, path) {
		
		var paths = this.getPathArray(path),
				pathLength = paths.length;
				
		if (PathGlobal.switchType || pathLength < 5) {
		
			var descLeft = endLeft - left,
	
			path = "M " + left + " " + top + " L " + 
			(left + parseInt(descLeft/2)) + " " + (top) + 
			"," + (left + parseInt(descLeft/2)) + " " + (endTop) + 
			"," + endLeft + " " + endTop + " z";
		
		} else {
			
			paths[0] = left;
			paths[1] = top;
			paths[3] = top;
			
			paths[4] = paths[2];
			paths[5] = endTop;
			paths[6] = endLeft;
			paths[7] = endTop;
			
			path = this.arrayToPath(paths);
			
		}
	
		return path;
	
	},
	
	getPathArray : function(path) {
		
		path = path.replace("M", ""),
		path = path.replace("m", ""),
		path = path.replace("z", ""),
		path = path.replace("L", ""),
		path = path.replace("  ", " "),
		path = path.replaceAll(",", " ");
		
		var paths = this.strTrim(path).split(" "),
				paths = paths.join(","),
				paths = paths.replaceAll(",,", ",");
		
		return this.strTrim(paths).split(",");
		
	},
	
	arrayToPath : function (paths) {
		return smallPath = "M " + paths[0] + " " + paths[1] + " " + " L " + paths[2] + " " + paths[3] + "," + paths[4] + " " + paths[5] + "," + paths[6] + " " + paths[7];
	},
	
	create : function (left, top, brokenType) {
	
		var self = this,
		idIndex = self.getNextIndex(),
	
		path = "M " + left + " " + top + " L " + (left + 100) + " " + top + " z";
	
		if (brokenType != 1) {
			path = "M " + left + " " + top + " L " + (left + 100) + " " + (top + 60) + " z";
			path = self.brokenPath(path, brokenType);
		}
	
		var line = self.createBaseLine("line" + idIndex, path, brokenType),
	
		lineMode = new BuildLine();
		lineMode.id = "line" + idIndex;
		
		var global = com.workflowGraph.Global;
	
		global.lineMap.put(lineMode.id, lineMode);
	
		var tempSmallTool = global.smallTool,
	
		undoRedoLineEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			var isExist = line && line.id && $id(line.id);
			
			var dragBody = null,
                lineId = line.getAttribute("id");
		
			if (self.isVML && isExist) {
				
				dragBody = self.pathBody;
				
				dragBody.removeChild($id(lineId + 'lineHead'));
				dragBody.removeChild($id(lineId + 'lineMiddle'));
				dragBody.removeChild($id(lineId + 'lineEnd'));
			
			} else if (self.isSVG && isExist) {
				
				dragBody = self.svgBody;
				
				dragBody.removeChild($id(lineId + 'lineHead').parentNode);
				dragBody.removeChild($id(lineId + 'lineMiddle').parentNode);
				dragBody.removeChild($id(lineId + 'lineEnd').parentNode);
				
			}
			
			if (isExist) {
				dragBody.removeChild(line);
			}
			
			global.lineMap.remove(lineMode.id);
		
			if (isExist) {
				tempSmallTool.removeLine(lineMode.id);
			}
		
		}, PathGlobal.lineCreate);
	
		undoRedoLineEvent.setRedo(function () {
			
			var dragBody = null,
					lineId = line.getAttribute("id");
			
			if (self.isVML) {
			
				line.setAttribute("filled", "f");
				line.setAttribute("strokeweight", PathGlobal.strokeweight + "px");
				line.setAttribute("strokecolor", PathGlobal.lineColor);
			
				dragBody = self.pathBody;
			
			} else if (self.isSVG) {
				dragBody = self.svgBody;
			}
			
			dragBody.appendChild(line);
			
			dragBody.appendChild(self.createRect(lineId + 'lineHead'));
			dragBody.appendChild(self.createRect(lineId + 'lineMiddle'));
			dragBody.appendChild(self.createRect(lineId + 'lineEnd'));
			
			self.drag(line);
		
			global.lineMap.put(line.id, lineMode);
			tempSmallTool.drawLine(line);
		
		});
		
	},


	getPath : function (line) {
	
		var self = this,
		pathStr = "";
  	
		if (self.isSVG) {
			pathStr = line.getAttribute("name");
  	    } else {
  		    pathStr = line.name + "";
 		}
 	 
 	 	pathStr = self.formatPath(pathStr);
  
  	return pathStr;
	
	},
	
	distancePoint : function (x, y, line) {
	
		var self = this,
	
		pathStr = this.getPath(line),
	
		head = self.getLineHead(pathStr),
		end = self.getLineEnd(pathStr),
	
		x1 = parseInt(head[0]),
		y1 = parseInt(head[1]),
		
		x2 = parseInt(end[0]),
		y2 = parseInt(end[1]),
	
		disPoint1 = Math.abs(Math.sqrt(Math.pow(x1 - x, 2) + Math.pow(y1 - y, 2))),
		disPoint2 = Math.abs(Math.sqrt(Math.pow(x2 - x, 2) + Math.pow(y2 - y, 2)));
	
		return disPoint1 <= disPoint2;
	
	},

	strTrim : function (text) {
	
		text = text.replace(/^\s+/, "");
		
		for (var i = text.length - 1; i >= 0; i--) {
		
			if (/\S/.test(text.charAt(i))) {
				text = text.substring(0, i + 1);
				break;
			}
		
		}
	
		return text;
		
	},
	
	initScaling : function (multiple) {
	
		var self = this,
		tempSmalTool = com.workflowGraph.Global.smallTool;
	
		self.forEach(function (lineId) {
		
			var line = $id(lineId),
			path = self.formatPath(self.getPath(line)),
			paths = self.getPathArray(path),
			pathLength = paths.length;
			
			for (var i = pathLength; i--;) {
				
				paths[i] = parseInt(paths[i] / multiple);
				
			}
			
			path = self.arrayToPath(paths);
			
			self.setPath(line, path);
			self.setDragPoint(line);

  		tempSmalTool.drawLine(line);
		
		});
	
	},
	
	getEndPoint : function (path) {
	
		var paths = path.split("L");
		paths[1] = this.strTrim(paths[1]);
	
		return paths[1].split(" ");
	
	},
	
	getHeadPoint : function (path) {
	
		var paths = path.split("L");
		paths[0] = this.strTrim(paths[0]);
	
		return paths[0].split(" ");
	
	},
	
	endPoint : function (x, y, path, brokenType) {

		var self = this,
		newPath;

		if (brokenType != 1) {
			
			var head = self.getLineHead(path);
			newPath = self.broken(parseInt(head[0]), parseInt(head[1]), x, y, brokenType, path);
		
		} else {
		
			var paths = path.split("L");
			paths[0] = this.strTrim(paths[0]);
		
			newPath = paths[0] + " L " + x + " " + y + " z";
		
		}
	
		return newPath;
	
	},
	
	headPoint : function (x, y, path, brokenType) {
	
		var self = this,
		newPath;
	
		if (brokenType != 1) {
		
			var end = self.getLineEnd(path);
			newPath = self.broken(x, y, parseInt(end[0]), parseInt(end[1]), brokenType, path);
			
		} else {
		
			var paths = path.split("L");
			paths[1] = this.strTrim(paths[1]);
		
			newPath = "M " + x + " " + y + " L " + paths[1];
		
		}
		
		return newPath;
		
	},
	
	vecMultiply : function (p1, p2, p3) {
		return (( p1.x - p3.x ) * ( p2.y - p3.y ) - ( p2.x - p3.x ) * ( p1.y - p3.y ));
	},

	poInTrigon : function (p1, p2, p3, p) {
	
		var self = this,
	
		re1 = self.vecMultiply(p1, p, p2),
		re2 = self.vecMultiply(p2, p, p3),   
		re3 = self.vecMultiply(p3, p, p1);   
		
		if (re1 * re2 * re3 == 0) {
			return false; 
		} 
		
		if ((re1 > 0 && re2 > 0 && re3 > 0 ) ||( re1 < 0 && re2 < 0 && re3 < 0 )) {
			return true; 
		}
		
		return false;
	
	}, 

	buildModeAndPoint : function (line, mode, x, y) {
	
		var w = mode.offsetWidth,
		h = mode.offsetHeight,
	
		point = new Point(),
		pointA = new Point();

		pointA.x = parseInt(mode.offsetLeft);
		pointA.y = parseInt(mode.offsetTop);
	
		var pointB = new Point();
		pointB.x = parseInt(mode.offsetLeft) + parseInt(w);
		pointB.y = parseInt(mode.offsetTop);
	
		var pointC = new Point();
		pointC.x = parseInt(mode.offsetLeft) + parseInt(w) / 2;
		pointC.y = parseInt(mode.offsetTop) + parseInt(h) / 2;
		
		var pointD = new Point();
		pointD.x = x;
		pointD.y = y;
	
		var self = this;
	
		if (self.poInTrigon(pointA, pointB, pointC, pointD)) {
	  	
			point.x = "0px";
			point.y = w / 2 + "px";
			point.index = PathGlobal.pointTypeUp;
	  	
		} 
		
		pointB.x = parseInt(mode.offsetLeft);
		pointB.y = parseInt(mode.offsetTop) + parseInt(h);

		if (self.poInTrigon(pointA, pointB, pointC, pointD)) {
	
			point.x = h / 2 + "px";
			point.y = "0px";
			point.index = PathGlobal.pointTypeLeft;
		
		} 
		
		pointA.x = parseInt(mode.offsetLeft) + parseInt(w);
		pointA.y = parseInt(mode.offsetTop) + parseInt(h);
		
		if (self.poInTrigon(pointA, pointB, pointC, pointD)) {
			
			point.x = h + "px";
			point.y = w/2 + "px";
			point.index = PathGlobal.pointTypeDown;
		
		}
		
		pointB.x = parseInt(mode.offsetLeft) + parseInt(w);
		pointB.y = parseInt(mode.offsetTop);
		
		if (self.poInTrigon(pointA, pointB, pointC, pointD)) {
			
			point.x = h / 2 + "px";
			point.y = w + "px";
			point.index = PathGlobal.pointTypeRight;
		
		}
		
		point.x = parseInt(mode.offsetTop) + parseInt(point.x);
		point.y = parseInt(mode.offsetLeft) + parseInt(point.y);
		
		return point;
	
	},
	
	buildLineAndMode : function (line, mode, x, y, isPoint1) {
	
		var self = this,
	
		point = self.buildModeAndPoint(line, mode, x, y),

		buildLine = new BuildLine();
		buildLine.index = point.index;
		buildLine.id = line.id;

		self.pathLine(point.y, point.x, line, isPoint1);
		
		self.setDragPoint(line);
		
		var global = com.workflowGraph.Global,
		
		baseMode = global.modeMap.get(mode.id);
		buildLine.type = isPoint1;
		baseMode.lineMap.put(buildLine.id + "-" + buildLine.type, buildLine);
		
		var lineMode = global.lineMap.get(line.id);

		if (isPoint1) {
			lineMode.xBaseMode = baseMode;
			lineMode.xIndex = point.index;
		} else {
			lineMode.wBaseMode = baseMode;
			lineMode.wIndex = point.index;
		}
		
		global.lineMap.put(line.id, lineMode);
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			if (isPoint1) {
				lineMode.xBaseMode = null;
			} else {
				lineMode.wBaseMode = null;
			}
	
			baseMode.lineMap.remove(buildLine.id + "-" + buildLine.type);
			self.setDragPoint(line);
	
		}, PathGlobal.buildLineAndMode);
	
		undoRedoEvent.setRedo(function () {
		
			if (isPoint1) {
				lineMode.xBaseMode = baseMode;
			} else {
				lineMode.wBaseMode = baseMode;
			}
	
			baseMode.lineMap.put(buildLine.id + "-" + buildLine.type, buildLine);
			self.setDragPoint(line);
	
		});
	
	},
	
	removeAllLineAndMode : function (line, mode) {
		this.removeBuildLineAndMode(line, mode, true);
		this.removeBuildLineAndMode(line, mode, false);
	},
	
	removeBuildLineAndMode : function (line, mode, isPoint1) {
		
		var global = com.workflowGraph.Global,
	
		baseMode = global.modeMap.get(mode.id),
  	    baseLineModeMap = baseMode.lineMap,
		key = line.id + "-" + isPoint1;
	
		if (baseLineModeMap.containsKey(key)) {
  		
  		var modeLineMap = baseMode.lineMap,
					oldMapEntry = modeLineMap.get(key),
					oldxBaseMode = null,
					oldwBaseMode = null;
					
			modeLineMap.remove(key);
			
  		var lineMode = global.lineMap.get(line.id);
  		
  		if (lineMode && lineMode.xBaseMode && lineMode.xBaseMode.id == mode.id) {
  			oldxBaseMode = lineMode.xBaseMode,
				lineMode.xBaseMode = null;
			} else if (lineMode && lineMode.wBaseMode && lineMode.wBaseMode.id == mode.id) {
  			lineMode.wBaseMode = null;
  			oldwBaseMode = lineMode.wBaseMode;
  		}
  		
  		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			 	modeLineMap.put(key, oldMapEntry);
			 	
			 	lineMode.xBaseMode = oldxBaseMode;
			 	lineMode.wBaseMode = oldwBaseMode;
	
			}, PathGlobal.removeLineAndMode);
	
			undoRedoEvent.setRedo(function () {
		
				 modeLineMap.remove(key);
				 
				 lineMode.xBaseMode = null;
				 lineMode.wBaseMode = null;
	
			});
  	
  	}
	
	},
	
	isMoveBaseMode : function (x, y, line, isPoint1) {
		
		var global = com.workflowGraph.Global,
		
		modeKeys = global.modeMap.getKeys(),
		modeKeysLength = modeKeys.length,
	
		tempModeTool = global.modeTool;
  
		for (var i = modeKeysLength; i--;) {
		
			var mode = $id(modeKeys[i]),
			modeStyle = mode.style,
		
			left = parseInt(modeStyle.left),
			xWidth = mode.offsetWidth + left,
  		
  		top = parseInt(modeStyle.top),
  		yHeight = mode.offsetHeight + top;
  	
			if (x > left && x < xWidth && y > top && y < yHeight) {
			
				tempModeTool.hiddPointer(mode);
				tempModeTool.flip(global.modeTool.getModeIndex(mode));
			
				break;
		
			} else {
				tempModeTool.hiddPointer(mode);
  		}
	
		}
	
	},

	isCoverBaseMode : function (x, y, line, isPoint1) {
		
		var global = com.workflowGraph.Global,
		
		modeKeys = global.modeMap.getKeys(),
		modeKeysLength = modeKeys.length,
		tempModeTool = global.modeTool,
	
		self = this,
	
		activeMode = global.modeTool.getActiveMode();
	
		if (activeMode) {
		
			tempModeTool.hiddPointer(activeMode);
			tempModeTool.flip(global.modeTool.getModeIndex(activeMode));
			
			self.buildLineAndMode(line, activeMode, x, y, isPoint1);
			
		}
  
		for (var i = modeKeysLength; i--;) {
			
			var mode = $id(modeKeys[i]),
			modeStyle = mode.style,
		
			left = parseInt(modeStyle.left),
			xWidth = mode.offsetWidth + left,
  		
  		top = parseInt(modeStyle.top),
  		yHeight = mode.offsetHeight + top;
	
			if (activeMode && activeMode.id == mode.id) {
				continue;
			} else {
				tempModeTool.hiddPointer(mode);
				self.removeBuildLineAndMode(line, mode, isPoint1);
  		}
	
		}
	
	},
	
	pathLine : function (x1, y1, line, isPoint1) {

		var self = this,
		oldPath = self.getPath(line),
		newPath,
		brokenType = line.getAttribute("brokenType");

        //console.log(isPoint1);
	
		if (isPoint1) {
			newPath = self.headPoint(parseInt(x1), parseInt(y1), oldPath, brokenType);
		} else {
			newPath = self.endPoint(parseInt(x1), parseInt(y1), oldPath, brokenType);
		}
	
		self.setPath(line, newPath);

		com.workflowGraph.Global.smallTool.drawLine(line);
  
	},
	
	clearLine : function (lineId) {
		
		var line = $id(lineId),
				global = com.workflowGraph.Global,
				tempLineTool = global.lineTool;
			
		if (tempLineTool.isVML) {
			line.setAttribute("strokecolor", PathGlobal.lineColor);
		} else if (global.lineTool.isSVG) {
			line.setAttribute("style", "cursor:pointer; fill:none; stroke:" + PathGlobal.lineColor + "; stroke-width:2");
		}
			
		var rectHead = $id(lineId + "lineHead"),
				rectEnd = $id(lineId + "lineEnd"),
				rectMiddle = $id(lineId + "lineMiddle");
			
				rectHead.style.visibility = "hidden";
				rectEnd.style.visibility = "hidden";
				rectMiddle.style.visibility = "hidden";
	
	},
	
	clear : function () {
		
		var global = com.workflowGraph.Global,
		tempLineTool = global.lineTool;
	
		this.forEach(function (lineId) {
			tempLineTool.clearLine(lineId);			
		});
		
		PathGlobal.rightMenu = false;
		
		var lineRightMenu = $id("lineRightMenu");
		lineRightMenu.style.visibility = "hidden";
		
		tempLineTool.tempLine = null;
		
		global.smallTool.clear();
		
	},
	
	setDragPoint : function (line) {
		
		var tempLineTool = com.workflowGraph.Global.lineTool,
				pathStr = tempLineTool.formatPath(tempLineTool.getPath(line)),
				lineId = line.getAttribute("id"),
					
				rectHead = $id(lineId + "lineHead"),
				rectEnd = $id(lineId + "lineEnd"),
				rectMiddle = $id(lineId + "lineMiddle"),
		 			
		 		head = tempLineTool.getLineHead(pathStr),
				end = tempLineTool.getLineEnd(pathStr),
				middle = tempLineTool.getMiddle(pathStr, lineId, true),
	
				headx1 = parseInt(head[0]),
				heady1 = parseInt(head[1]),
		
				endx2 = parseInt(end[0]),
				endy2 = parseInt(end[1]),
				
				lineStyle = line.style;
				
			rectHead.setAttribute("x", (endx2 - PathGlobal.dragPointDec));
			rectHead.setAttribute("y", (endy2 - PathGlobal.dragPointDec));
						
			var rectHeadStyle = rectHead.style;
			rectHeadStyle.left = (endx2 - PathGlobal.dragPointDec) + "px";
			rectHeadStyle.top = (endy2 - PathGlobal.dragPointDec) + "px";
			
			rectEnd.setAttribute("x", (headx1 - PathGlobal.dragPointDec));
			rectEnd.setAttribute("y", (heady1 - PathGlobal.dragPointDec));
			
			var rectEndStyle = rectEnd.style;
			rectEndStyle.left = (headx1 - PathGlobal.dragPointDec) + "px";
			rectEndStyle.top = (heady1 - PathGlobal.dragPointDec) + "px";
			
			rectHeadStyle.zIndex = 1;
			rectMiddle.style.zIndex = 1;
			rectEndStyle.zIndex = 1;
						
			if (tempLineTool.isActiveLine(line)) {

				rectHeadStyle.visibility = "";
				rectEndStyle.visibility = "";
			
			}
		
	},
	
	showProperty : function (event) {
		
		var line = this.tempLine,
				global = com.workflowGraph.Global,
				lineMap = global.lineMap,
				lineObj = lineMap.get(line.getAttribute("id")),
				prop = lineObj.prop,
				propDiv = $id("prop"),
				doc = document,
				tempClientTool = global.clientTool;

		propDiv.style.visibility = "";
		propDiv.innerHTML = "";
		
		propDiv.appendChild(tempClientTool.addProItem(prop));
		
		tempClientTool.showDialog(event, PathGlobal.lineProTitle, lineObj);

	},

    getProperty : function(event) {
        var line = this.tempLine,
            global = com.workflowGraph.Global,
            lineMap = global.lineMap,
            lineObj = lineMap.get(line.getAttribute("id")),
            prop = lineObj.prop,
            propDiv = $id("prop"),
            tempClientTool = global.clientTool;

        propDiv.style.visibility = "";
        propDiv.innerHTML = "";

        propDiv.appendChild(tempClientTool.addProSetting());
        tempClientTool.showSettingDialog(event, PathGlobal.lineProTitle, lineObj);

    },

    addInputItem : function() {

        var doc = document,
            self = this,
            div = doc.createElement("div"),
            input = doc.createElement("input"),
            button = doc.createElement("button"),
            attrs = doc.getElementById("attrs");

        button.innerHTML = "删除";
        button.onclick = self.delAttr

        div.appendChild(input);
        div.appendChild(button);

        attrs.appendChild(div);

    },

    delAttr : function(event) {

        event = event ? event : window.event;
        var obj = event.target || event.srcElement;
        var parent = obj.parentNode;
        parent.parentNode.removeChild(parent);

    },
	
	showMenu : function (event, line) {
	
		PathGlobal.rightMenu = true;
	
		var self = this;
	
		self.tempLine = line;
	
		event = event || window.event;
	
		if (!event.pageX) {
			event.pageX = event.clientX;
		} 
		
		if (!event.pageY) {
			event.pageY = event.clientY;
		}
   	
  	var tx = event.pageX,
				ty = event.pageY,
		
		global = com.workflowGraph.Global,
		
		tempPathBody = global.lineTool.pathBody,
  	leftTops = global.baseTool.sumLeftTop(tempPathBody);
  
		tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
		ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
				
		var lineRightMenu = $id("lineRightMenu"),
		lineRightMenuStyle = lineRightMenu.style;

		lineRightMenuStyle.top = ty + "px";
		lineRightMenuStyle.left = tx + "px";
		lineRightMenuStyle.visibility = "visible";
		lineRightMenuStyle.zIndex = self.getNextIndex();
	 
	},
	
	showId : function (lineId) {
		this.show($id(lineId));
	},
	
	show : function (line) {
		
		if (this.isVML) {
				line.setAttribute("strokecolor", PathGlobal.lineCheckColor);
		} else if (this.isSVG) {

				line.setAttribute("style", "cursor:pointer;fill:none; stroke:" + PathGlobal.lineCheckColor + "; stroke-width:" + PathGlobal.strokeweight);
		}
		
		this.setDragPoint(line);
		
	},
	
	drag : function (line) {
		
		var global = com.workflowGraph.Global,
				lineId = line.getAttribute("id"),
				rectHead = $id(lineId + "lineHead"),
				rectEnd = $id(lineId + "lineEnd"),
				rectMiddle = $id(lineId + "lineMiddle"),
				tempLineTool = global.lineTool,
				tempPathBody = tempLineTool.pathBody,
				self = this;
		
		global.smallTool.drawLine(line);
	
		line.ondragstart = function () {
			return false;
		};
		
		rectMiddle.oncontextmenu = rectEnd.oncontextmenu = rectHead.oncontextmenu = line.oncontextmenu = function (event) {
			
			tempLineTool.showMenu(event, line);
			return false;
				
		}
		
		rectEnd.onmousedown = rectHead.onmousedown = line.onmousedown = function (event) {
		
			event = event || window.event;
				
			global.modeTool.clear();
			global.lineTool.clear();

			tempLineTool.moveable = true;
		
			var tempSmallTool = global.smallTool,
			oldPath = tempLineTool.getPath(line),
		
			x = event.clientX ? event.clientX : event.offsetX,
			y = event.clientY ? event.clientY : event.offsetY,
			
			leftTops = global.baseTool.sumLeftTop(tempPathBody);
		
			x = x - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
			y = y - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
		
			if (!event.pageX) {
				event.pageX = event.clientX;
			} 
		
   		if (!event.pageY) {
   			event.pageY = event.clientY;
   		}
   	
   		var tx = event.clientX - x,
   				ty = event.clientY - y,
		
			isPoint1 = tempLineTool.distancePoint(x, y, line),
			doc = document;
			
			self.show(line);
		
			doc.onmousemove = function (event) {
			
				event = event || window.event;
			
				if (tempLineTool.moveable) {
			
					var x1 = event.clientX ? event.clientX : event.offsetX;
					var y1 = event.clientY ? event.clientY : event.offsetY;
				
					var leftTops = global.baseTool.sumLeftTop(tempPathBody);
			
					x1 = x1 - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
					y1 = y1 - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
			
					self.pathLine(x1, y1, line, isPoint1);
					self.setDragPoint(line);
				
				}

			}
		
			doc.onmouseup = function (event) {
				
				event = event || window.event;
			
				var x2 = event.clientX ? event.clientX : event.offsetX,
						y2 = event.clientY ? event.clientY : event.offsetY;
			
				var leftTops = global.baseTool.sumLeftTop(tempPathBody);
				x2 = x2 - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
				y2 = y2 - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
			
				tempLineTool.moveable = false;

   			doc.onmousemove = null;
   			doc.onmouseup = null;
   			
   			var newPath = tempLineTool.getPath(line);
   		
   			if (oldPath != newPath) {
   				
   				var oldHead = tempLineTool.getLineHead(oldPath),
							oldEnd = tempLineTool.getLineEnd(oldPath),
	
							oldHeadx1 = parseInt(oldHead[0]),
							oldHeady1 = parseInt(oldHead[1]),
		
							oldEndx2 = parseInt(oldEnd[0]),
							oldEndy2 = parseInt(oldEnd[1]),
							
							newHead = tempLineTool.getLineHead(newPath),
							newEnd = tempLineTool.getLineEnd(newPath),
	
							newHeadx1 = parseInt(newHead[0]),
							newHeady1 = parseInt(newHead[1]),
		
							newEndx2 = parseInt(newEnd[0]),
							newEndy2 = parseInt(newEnd[1]);
							
				if (oldHeadx1 !== newHeadx1 || oldHeady1 !== newHeady1 || oldEndx2 !== newEndx2 || oldEndy2 !== newEndy2) {
				    tempLineTool.isCoverBaseMode(x2, y2, line, isPoint1);
				}
   		
   				var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
  	
					global.lineTool.setPath(line, oldPath);
  					tempSmallTool.drawLine(line);
  					tempLineTool.setDragPoint(line);
					
				}, PathGlobal.lineMove);
			
   				undoRedoEvent.setRedo(function () {
			
  					global.lineTool.setPath(line, newPath);
  					tempSmallTool.drawLine(line);
  					tempLineTool.setDragPoint(line);
		
					});
				
				}
   		
			}
		
		}
		
		rectMiddle.onmousedown = function (event) {
			
			rectEnd.onmousedown(event);
			
			document.onmousemove = function (event) {
				
				event = event || window.event;
						
				if (tempLineTool.moveable) {
			
					var x1 = event.clientX ? event.clientX : event.offsetX;
					var y1 = event.clientY ? event.clientY : event.offsetY;
				
					var leftTops = global.baseTool.sumLeftTop(tempPathBody);
			
					x1 = x1 - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
					y1 = y1 - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
					
					var pathStr = tempLineTool.formatPath(tempLineTool.getPath(line));
					var	head = tempLineTool.getLineHead(pathStr),
							end = tempLineTool.getLineEnd(pathStr),
							rectMiddle = $id(lineId + "lineMiddle"),
							tempSmallTool = global.smallTool;
					
					tempSmallTool.drawLine(line);
										
					var brokenType = line.getAttribute("brokenType");
					self.changeBrokenType(line, x1, y1);
					
					if (brokenType == 3) {
						
						var dragPath = "M " + head[0] + " " + head[1] + " L " + x1 + " " + head[1] + "," + x1 + " " + end[1] + "," + end[0] + " " + end[1] + " z";
						
						tempLineTool.setPath(line, dragPath);
						rectMiddle.setAttribute("x", x1 - PathGlobal.dragPointDec);
						rectMiddle.style.left = x1 - PathGlobal.dragPointDec + "px";
						
					} else if (brokenType == 2) {
						
						var dragPath = "M " + head[0] + " " + head[1] + " L " + head[0] + " " + y1 + "," + end[0] + " " + y1 + "," + end[0] + " " + end[1] + " z";
						
						tempLineTool.setPath(line, dragPath);
						rectMiddle.setAttribute("y", y1 - PathGlobal.dragPointDec);
						rectMiddle.style.top = y1 - PathGlobal.dragPointDec + "px";
						
					}
						
					tempLineTool.setDragPoint(line);
					
				}
				
			}
			
		}
	
	},
		
	changeBrokenType : function (line, x1, y1) {
		
		var pathStr = this.getPath(line),
				brokenType = line.getAttribute("brokenType"),
				head = this.getLineHead(pathStr),
				end = this.getLineEnd(pathStr),
				
				xInArea = (
										parseInt(x1) > parseInt(head[0]) && parseInt(x1) < parseInt(end[0]) || 
										parseInt(x1) < parseInt(head[0]) && parseInt(x1) > parseInt(end[0])
									),
				yInArea = (
										parseInt(y1) > parseInt(head[1]) && parseInt(y1) < parseInt(end[1]) || 
										parseInt(y1) < parseInt(head[1]) && parseInt(y1) > parseInt(end[1])
									),
				xOutArea = (
									 	parseInt(x1) < parseInt(head[0]) && parseInt(x1) < parseInt(end[0]) || 
										parseInt(x1) > parseInt(head[0]) && parseInt(x1) > parseInt(end[0])
									 ) && yInArea,
				yOutArea = (
										parseInt(y1) < parseInt(head[1]) && parseInt(y1) < parseInt(end[1]) || 
										parseInt(y1) > parseInt(head[1]) && parseInt(y1) > parseInt(end[1])
									 ) && xInArea;
		
		if (xOutArea) {
			line.setAttribute("brokenType", 3);
		}	else if (yOutArea) {	
			line.setAttribute("brokenType", 2);
		}
		
	}
	
}
var ModeTool = com.workflowGraph.ModeTool = function (body) {
	
	var self = this;
	
	self.moveable = false;
	self.optionMode;
	self.baseModeIdIndex = PathGlobal.modeDefIndex;
	self.stepIndex = PathGlobal.modeDefStep;
	self.pathBody = body;
	self.tempMode;

    var global = com.workflowGraph.Global;
    self.tool = global.baseTool;
    //self.svgBody = global.lineTool(body);
}

ModeTool.prototype = {
	
	initScaling : function (multiple) {
	
		var self = this,
		tempSmallTool = com.workflowGraph.Global.smallTool;

		self.forEach(function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style,
			index = self.getModeIndex(mode),
			content = $id("content" + index),
			backImg = $id("backImg" + index),
		
			contentStyle = content.style,
			backImgStyle = backImg.style,
		
			newModeWidth = parseInt(parseInt(mode.offsetWidth) / multiple) + "px",
			newModeHeight = parseInt(parseInt(mode.offsetHeight) / multiple) + "px";
		
			modeStyle.top = parseInt(parseInt(modeStyle.top) / multiple) + "px";
			modeStyle.left = parseInt(parseInt(modeStyle.left) / multiple) + "px";
			
			contentStyle.width = newModeWidth; 
			contentStyle.height = newModeHeight;
		
			backImgStyle.width = newModeWidth;
			backImgStyle.height = newModeHeight;
		
			modeStyle.width = newModeWidth;
			modeStyle.height = newModeHeight;
		
			self.showPointer(mode);
		
			tempSmallTool.drawMode(mode);
		
		});
	
	},
	
	showMenu: function (event, mode) {

	    PathGlobal.rightMenu = true;

	    var self = this;

	    self.tempMode = mode.parentNode;

	    var nodeNameIndex = self.tempMode.id.replace("module", "");
	    var nodeMenuName = "rightMenu";
	    //*****************************************
	    var backImgSrc = $("#backImg" + nodeNameIndex).attr("src");
	    //开始{路由设置}
	    if (backImgSrc.indexOf("start.png") != -1) {
	        nodeMenuName = "rightMenuStart";
	    }
	    //条件 {路由设置，删除}
	    if (backImgSrc.indexOf("switch.png") != -1) {
	        nodeMenuName = "rightMenuCondition";
	    }
	    //审批 {节点动作，路由设置，审批人设置，删除}
	    if (backImgSrc.indexOf("aotoBusiness.png") != -1) {
	        nodeMenuName = "rightMenuApproval";
	    }
	    //动作  {节点动作，路由设置，删除}
	    if (backImgSrc.indexOf("message.png") != -1) {
	        nodeMenuName = "rightMenu";
	    }
	    //结束
	    if (backImgSrc.indexOf("end.png") != -1) {
	        nodeMenuName = "rightMenuEnd";
	    }
	    //*****************************************

	    event = event || window.event;

	    if (!event.pageX) {
	        event.pageX = event.clientX;
	    }

	    if (!event.pageY) {
	        event.pageY = event.clientY;
	    }

	    var tx = event.pageX,
            ty = event.pageY,

		global = com.workflowGraph.Global,

		tempPathBody = global.lineTool.pathBody,
  	    leftTops = global.baseTool.sumLeftTop(tempPathBody);

	    tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
	    ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);

	    //var rightMenu = $id("rightMenu"),
	    var rightMenu = $id(nodeMenuName),
		rightMenuStyle = rightMenu.style;
	    $id("rightMenuId").value = nodeMenuName;

	    rightMenuStyle.top = ty + "px";
	    rightMenuStyle.left = tx + "px";
	    rightMenuStyle.visibility = "visible";
	    var menu_zIndex = self.getNextIndex();
	    if (menu_zIndex < self.tempMode.style.zIndex)
	        menu_zIndex = self.tempMode.style.zIndex + 1;
	    rightMenuStyle.zIndex = menu_zIndex;
	},
	
	showProperty : function (event) {
	    //显示节点属性
		var global = com.workflowGraph.Global,
				modeMap = global.modeMap,
				modeObj = modeMap.get(this.tempMode.id),
				prop = modeObj.prop,
				doc = document,
				propDiv = $id("prop"),
				tempClientTool = global.clientTool;
		

	    //*****************************************
		var nodeNameIndex = modeObj.id.replace("module", "");
		
		var backImgSrc = $("#backImg" + nodeNameIndex).attr("src");
		alert(backImgSrc);
		var hashKey = new Object();
		var hashValue = new Object();
		    hashKey.key001 = "节点编码";
		    hashValue.key001 = "N001";
	    //*****************************************

		propDiv.style.visibility = "";
		propDiv.innerHTML = "";
		
		//a.appendChild(f.addProItem(hashKey, hashValue));
	    //propDiv.appendChild(tempClientTool.addProItem(prop));
		propDiv.appendChild(tempClientTool.addProItem(hashKey, hashValue));

		//f.showDialog(e, PathGlobal.modeProTitle, hashValue)
	    //tempClientTool.showDialog(event, PathGlobal.modeProTitle, modeObj);
		tempClientTool.showDialog(event, PathGlobal.modeProTitle, hashValue);
		
	},

    setProperty : function(event) {

        var global = com.workflowGraph.Global,
            modeMap = global.modeMap,
            modeObj = modeMap.get(this.tempMode.id),

            propDiv = $id("prop"),
            tempClientTool = global.clientTool;

        propDiv.style.visibility = "";
        propDiv.innerHTML = "";

        propDiv.appendChild(tempClientTool.addProSetting());
        tempClientTool.showSettingDialog(event, PathGlobal.lineProTitle, modeObj);

    },
	
	removeAll : function() {
	
		var self = this;
	
		self.forEach(function (modeId) {
			self.removeNode(modeId);
		});
	
	},
	
	removeNode : function (modeId) {
	
		var mode = $id(modeId);
	
		if (mode) {
			
			var global = com.workflowGraph.Global,
			pathBody = global.lineTool.pathBody;
			
			this.hiddPointer(mode);
		
			global.modeMap.remove(mode.id);
			global.smallTool.removeMode(mode.id);
			
			pathBody.removeChild(mode);
	
		}

	},
	
	cutter : function () {
	
		var self = this,
		tempModeId = self.tempMode.id,
		
		global = com.workflowGraph.Global,
		
		mode = global.modeMap.get(tempModeId),
		modeDiv = $id(tempModeId),
		pathBody = global.lineTool.pathBody;
	
		self.removeNode(tempModeId);
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
		
			global.modeMap.put(tempModeId, mode);
			
			pathBody.appendChild(modeDiv);
			self.showPointer(modeDiv);
			
			global.smallTool.drawMode(modeDiv);	
		
		}, PathGlobal.modeCutter);
	
		undoRedoEvent.setRedo(function () {
			self.removeNode(tempModeId);
		});

	},
	
	duplicate : function () {
		
		var global = com.workflowGraph.Global,
		
		pathBody = global.lineTool.pathBody,
		self = this,
	
		copyObj = global.modeTool.copy(self.tempMode),
		mode = global.modeMap.get(copyObj.id);
	
		global.modeTool.hiddPointer(self.tempMode);
		global.smallTool.drawMode(copyObj);
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			self.removeNode(copyObj.id);	
		}, PathGlobal.modeDuplicate);
	
		undoRedoEvent.setRedo(function () {
		
			global.modeMap.put(copyObj.id, mode);
			
			pathBody.appendChild(copyObj);
			self.showPointer(copyObj);
			
			global.smallTool.drawMode(copyObj);	
		
		});
			
	},
	
	del : function () {
	
	var self = this;
	self.cutter();
	self.tempMode = null;
			
	},
	
	getNextIndex : function () {
	
		var self = this;
		self.baseModeIdIndex += self.stepIndex;
		
		return self.baseModeIdIndex;
	
	}, 

	setClass : function (mode, className) {
	
		if (mode) {
			mode.setAttribute("class", className);
			mode.setAttribute("className", className);
		}
	
	},
	
	createBaseMode : function (top, left, imgSrc, modeIndex, backWidth, backHeight, name) {

		var self = this,
        global = com.workflowGraph.Global,
		doc = document,

		moduleDiv = doc.createElement("div"),
		titleDiv = doc.createElement("div"),
		contentDiv = doc.createElement("div"),
		backImg = doc.createElement("img");
	
		moduleDiv.appendChild(titleDiv);
		moduleDiv.appendChild(contentDiv);
		contentDiv.appendChild(backImg);
	
		var moduleDivStyle = moduleDiv.style;
		moduleDivStyle.top = top + "px";
		moduleDivStyle.left = left + "px";
		moduleDivStyle.zIndex = modeIndex;
	
		self.setClass(moduleDiv, "module");
		self.setClass(titleDiv, "title");
		self.setClass(contentDiv, "content");
	
		moduleDiv.id = "module" + modeIndex;
		titleDiv.id = "title" + modeIndex;
		contentDiv.id = "content" + modeIndex;
		backImg.id = "backImg" + modeIndex;
	
		backImg.style.width = backWidth;
		backImg.style.height = backHeight;
		backImg.src = imgSrc;
	
		var top_left = doc.createElement("div"),
		top_middle = doc.createElement("div"),
		top_right = doc.createElement("div"),
		middle_left = doc.createElement("div"),
		middle_right = doc.createElement("div"),
		bottom_left = doc.createElement("div"),
		bottom_middle = doc.createElement("div"),
		bottom_right = doc.createElement("div");
	
		self.setClass(top_left, "top_left");
		self.setClass(top_middle, "top_middle");
		self.setClass(top_right, "top_right");
		self.setClass(middle_left, "middle_left");
		self.setClass(middle_right, "middle_right");
		self.setClass(bottom_left, "bottom_left");
		self.setClass(bottom_middle, "bottom_middle");
		self.setClass(bottom_right, "bottom_right");
	
		top_left.id = "top_left" + modeIndex;
		top_middle.id = "top_middle" + modeIndex;
		top_right.id = "top_right" + modeIndex;
		middle_left.id = "middle_left" + modeIndex;
		middle_right.id = "middle_right" + modeIndex;
		bottom_left.id = "bottom_left" + modeIndex;
		bottom_middle.id = "bottom_middle" + modeIndex;
		bottom_right.id = "bottom_right" + modeIndex;
	
		moduleDiv.appendChild(top_left);
		moduleDiv.appendChild(top_middle);
		moduleDiv.appendChild(top_right);
		moduleDiv.appendChild(middle_left);
		moduleDiv.appendChild(middle_right);
		moduleDiv.appendChild(bottom_left);
		moduleDiv.appendChild(bottom_middle);
		moduleDiv.appendChild(bottom_right);
        var div = moduleDiv;
        //backImg.style.visibility = "hidden";

        if (global.baseTool.isSVG) {

            //self.svgMode(contentDiv, name, left, top, backWidth, parseInt(backHeight) * 0.6);
        }

		return div;
	
	},
	 
	create : function (top, left, imgSrc, name) {

		var self = this,
		modeIndex = self.getNextIndex(),
		doc = document,
	
		moduleDiv = self.createBaseMode(top, left, imgSrc, modeIndex, "105px", "60px", name);
		self.pathBody.appendChild(moduleDiv);
	
		var mode = new BaseMode();
		mode.id = moduleDiv.id;
		
		var global = com.workflowGraph.Global;
		
		global.modeMap.put(mode.id, mode);
	
		this.initEvent(modeIndex);
		global.smallTool.drawMode(moduleDiv);
	
		var tempModeTool = global.modeTool;
		tempModeTool.flip(modeIndex);
	
		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
			if ($id(moduleDiv.id)) {
				
				global.smallTool.removeMode(moduleDiv.id);
				tempModeTool.pathBody.removeChild(moduleDiv);
    		global.modeMap.remove(moduleDiv.id);
    	
    	}
			
		}, PathGlobal.modeCreate);
	
		undoRedoEvent.setRedo(function () {
		
			global.modeMap.put(mode.id, mode);
		
			tempModeTool.pathBody.appendChild(moduleDiv);
			tempModeTool.showPointer(moduleDiv);
			tempModeTool.changeBaseModeAndLine(moduleDiv, true);
		
			global.smallTool.drawMode(moduleDiv);
		
		});
	
	},
	
	initEvent : function (modeIndex) {
	
		var tempModeTool = com.workflowGraph.Global.modeTool;
  
		tempModeTool.drag($id("content" + modeIndex));
		tempModeTool.dragPoint($id("top_left" + modeIndex));
		tempModeTool.dragPoint($id("top_middle" + modeIndex));
		tempModeTool.dragPoint($id("top_right" + modeIndex));
		tempModeTool.dragPoint($id("middle_left" + modeIndex));
		tempModeTool.dragPoint($id("middle_right" + modeIndex));
		tempModeTool.dragPoint($id("bottom_left" + modeIndex));
		tempModeTool.dragPoint($id("bottom_middle" + modeIndex));
		tempModeTool.dragPoint($id("bottom_right" + modeIndex));
	
		$id("content" + modeIndex).onclick = function() {
			tempModeTool.showPointer($id("module" + modeIndex));
		}
				
	},
	
	clear : function () {
		
		var global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool;
	
		this.forEach(function (modeId) {
			tempModeTool.hiddPointer($id(modeId));
		});
	
		global.smallTool.clear();
		
	},

	toTop : function () {
	
		var tempModeTool = com.workflowGraph.Global.modeTool;
	
		this.forEach(function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			if (modeStyle.visibility == "visible") {
				modeStyle.zIndex = tempModeTool.getNextIndex();
			} else {

				if (modeStyle.zIndex < 1) {
					modeStyle.zIndex = 0;
				} else {
					modeStyle.zIndex = modeStyle.zIndex - 1;
				}
			
			}
		
		});
	
	},
	
	toBottom : function () {
	
		this.forEach(function (modeId) {
		
			var mode = $id(modeId),
			modeStyle = mode.style;
		
			if (modeStyle.visibility == "visible") {
				modeStyle.zIndex = 0;
			} else if (modeStyle.zIndex == 0) {
				modeStyle.zIndex = 1;
			}
		
		});

		stopEvent = true;
	
	},
	
	forEach : function (fn) {
	
		var modeKeys = com.workflowGraph.Global.modeMap.getKeys(),
		modeKeysLength = modeKeys.length;
  
		for (var i = modeKeysLength; i--;) {
		
			if (fn) {
				fn(modeKeys[i]);
			}
		
		}

		stopEvent = true;
	
	},
	
	hiddPointer : function(mode) {
		
		var idIndex = this.getModeIndex(mode);
	
		$id("module" + idIndex).style.visibility = "hidden";
		$id("top_left" + idIndex).style.visibility = "hidden";
		$id("top_middle" + idIndex).style.visibility = "hidden";
		$id("top_right" + idIndex).style.visibility = "hidden";
		$id("middle_left" + idIndex).style.visibility = "hidden";
		$id("middle_right" + idIndex).style.visibility = "hidden";
		$id("bottom_left" + idIndex).style.visibility = "hidden";
		$id("bottom_middle" + idIndex).style.visibility = "hidden";
		$id("bottom_right" + idIndex).style.visibility = "hidden";

	
	    //var rightMenu = $id("rightMenu");
		var rightMenuName = $id("rightMenuId").value;
		if (!rightMenuName) rightMenuName = "rightMenu";
		var rightMenu = $id(rightMenuName);

		rightMenu.style.visibility = "hidden";
	
		PathGlobal.rightMenu = false;
	
		var topCross = $id("topCross"),
		leftCross = $id("leftCross");
	
		topCross.style.visibility = "hidden";
		leftCross.style.visibility = "hidden";
	
		com.workflowGraph.Global.smallTool.clearMode($id("small" + mode.id));
	
	},
	
	getModeIndex : function(mode) {
	
		var subIndex;
	
		if (mode.className == "module") {
			subIndex = 6;
		} else if (mode.className == "content") {
			subIndex = 7;
		}
	
		return mode.id.substr(subIndex);

	},
	
	showPointer : function (mode) {
		this.showPointerId(this.getModeIndex(mode));
	},
	
	showPointerId : function (idIndex) {
	
		var smallObj = $id("small" + "module" + idIndex),
		global = com.workflowGraph.Global;
	
		if (smallObj) {
		
			var smallObjStyle = smallObj.style;
		
			smallObjStyle.borderWidth = "1px";
			smallObjStyle.borderColor = global.smallTool.checkColor;
			smallObjStyle.borderStyle= "solid";
	
		}
	
		var moduleDiv = $id("module" + idIndex);
		moduleDiv.style.visibility = "visible";
	
		var topLeftDiv = $id("top_left" + idIndex),
		topLeftDivStyle = topLeftDiv.style,

		sH = topLeftDiv.offsetHeight,
		sW = topLeftDiv.offsetWidth,
	
		mH = moduleDiv.offsetHeight,
		mW = moduleDiv.offsetWidth;
	
		$id("title" + idIndex).style.width = mW + "px";
	
		topLeftDivStyle.top = - sH/2 + "px";
		topLeftDivStyle.left = - sW/2 + "px";
		topLeftDivStyle.visibility = "visible";
	
		var topMiddleDivStyle = $id("top_middle" + idIndex).style;
		
		topMiddleDivStyle.top = - sH/2 + "px";
		topMiddleDivStyle.left = mW/2 -sW/2 + "px";
		topMiddleDivStyle.visibility = "visible";
	
		var topRightDivStyle = $id("top_right" + idIndex).style;
		
		topRightDivStyle.top = - sH/2 + "px";
		topRightDivStyle.left = mW -sW/2 + "px";
		topRightDivStyle.visibility = "visible";
	
		var middleLeftDivStyle = $id("middle_left" + idIndex).style;
		
		middleLeftDivStyle.top = mH/2 - sH/2 + "px";
		middleLeftDivStyle.left = -sW/2 + "px";
		middleLeftDivStyle.visibility = "visible";
	
		var middleRightDivStyle = $id("middle_right" + idIndex).style;

		middleRightDivStyle.top = mH/2 - sH/2 + "px";
		middleRightDivStyle.left = mW - sW/2 + "px";
		middleRightDivStyle.visibility = "visible";
	
		var bottomLeftDivStyle = $id("bottom_left" + idIndex).style;
	
		bottomLeftDivStyle.top = mH - sH/2 + "px";
		bottomLeftDivStyle.left = -sW/2 + "px";
		bottomLeftDivStyle.visibility = "visible";
	
		var bottomMiddleDivStyle = $id("bottom_middle" + idIndex).style;
	
		bottomMiddleDivStyle.top = mH - sH/2 + "px";
		bottomMiddleDivStyle.left = mW/2 -sW/2 + "px";
		bottomMiddleDivStyle.visibility = "visible";
	
		var bottomRightDivStyle = $id("bottom_right" + idIndex).style;
		
		bottomRightDivStyle.top = mH - sH/2 + "px";
		bottomRightDivStyle.left = mW -sW/2 + "px";
		bottomRightDivStyle.visibility = "visible";
	
		var imageStyle = $id("backImg" + idIndex).style;
	
		imageStyle.width = (mW - 2) + "px";
		imageStyle.height = (mH - 2)+ "px";
		imageStyle.top = "0px";
		imageStyle.left = "0px";
	
		global.controlTool.print(idIndex);
	
	},
	
	drag : function (mode) {
		var parentMode = mode.parentNode,
		parentModeStyle = parentMode.style,
		
		global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool,
		tempLineTool = global.lineTool;
	
		mode.ondragstart = function () {
			return false;
		};
	
		mode.onclick = function () {
			
			tempLineTool.clear();
			tempModeTool.clear();
			
			tempModeTool.showPointer(parentMode);
		
		}
	
		mode.ondblclick = function () {
			tempModeTool.hiddPointer(parentMode);
			tempModeTool.flip(global.modeTool.getModeIndex(parentMode));
		}
	
		mode.onmousemove = function () {
			
			if (tempLineTool.moveable) {
				tempModeTool.showPointerId(global.modeTool.getModeIndex(parentMode));
			}
		
		}
	
		mode.onmouseout = function () {
			
			if (tempLineTool.moveable) {
				tempModeTool.hiddPointer(parentMode);
			}
		
		}
	
		mode.oncontextmenu = function (event) {
					
			tempModeTool.showMenu(event, mode);
			return false;
				
		}
	
		mode.onmousedown = function(event) {
		
			tempLineTool.clear();
			tempModeTool.clear();
		
			tempModeTool.isModeCross(parentMode);
			tempModeTool.moveable = true;
		
			event = event || window.event;
		
			tempModeTool.showPointer(parentMode);
		
			if (parentMode.setCapture) {
				parentMode.setCapture();
			} else if (window.captureEvents) {
				window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
			
			var x = event.layerX && event.layerX >= 0 ? event.layerX : event.offsetX,
					y = event.layerX && event.layerY >= 0 ? event.layerY : event.offsetY;
		
			stopEvent = true;
		
			var doc = document,
		
			orgLeft = parseInt(parentMode.offsetLeft),
			orgTop = parseInt(parentMode.offsetTop);
		
			doc.onmousemove = function (event) {
			
				event = event || window.event;
			
				if (tempModeTool.moveable) {
				
					if (!event.pageX) {
						event.pageX = event.clientX;
					} 
		
   				if (!event.pageY) {
   					event.pageY = event.clientY;
   				}
   	
   				var tx = event.pageX - x,
   						ty = event.pageY - y,
   			
					tempPathBody = global.lineTool.pathBody,
   			
   				leftTops = global.baseTool.sumLeftTop(tempPathBody);
   			
   				tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
					ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
   		
					parentModeStyle.left = tx + "px";
    			parentModeStyle.top = ty + "px";
    		
    			tempModeTool.isModeCross(parentMode);
    			tempModeTool.changeBaseModeAndLine(parentMode, true);
    			tempModeTool.showPointer(parentMode);
    		
    			global.smallTool.drawMode(parentMode);
    		
				}

			};
		
			doc.onmouseup = function (event) {
			
				event = event || window.event;
			
				tempModeTool.moveable = false;
			
				if (parentMode.releaseCapture) {
					parentMode.releaseCapture();
				} else if (window.releaseEvents) {
					window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
				}

   			doc.onmousemove = null;
   			doc.onmouseup = null;
   		
   			var orgAfterLeft = parseInt(parentMode.offsetLeft),
				orgAfterTop = parseInt(parentMode.offsetTop);
			
				if (orgLeft != orgAfterLeft || orgTop != orgAfterTop) {
			
					var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
						parentMode.style.left = orgLeft + "px";
						parentMode.style.top = orgTop + "px";
			
						tempModeTool.showPointer(parentMode);
						tempModeTool.changeBaseModeAndLine(parentMode, true);
    		
    				global.smallTool.drawMode(parentMode);
			
					}, PathGlobal.modeMove);
   		
   				undoRedoEvent.setRedo(function () {
   			
   					parentModeStyle.left = orgAfterLeft + "px";
						parentModeStyle.top = orgAfterTop + "px";
				
						tempModeTool.showPointer(parentMode);
						tempModeTool.changeBaseModeAndLine(parentMode, true);
    		
    				global.smallTool.drawMode(parentMode);
    	
   				});
   		
   			}

			};
		
		}
	
	},
	
	findModeLine : function (mode, line) {
	
		var baseMode = com.workflowGraph.Global.modeMap.get(mode.id),
		baseLineModeMap = baseMode.lineMap,
		
		baseLineKey = baseLineModeMap.getKeys(),
		baseLineKeyLength = baseLineKey.length;
		
		for (var i = baseLineKeyLength; i--;) {
			
			var buildLine = baseLineModeMap.get(baseLineKey[i]);
			
			if (line.id == buildLine.id) {
				return buildLine;
			}
		
		}
	
		return null;

	},
	
	changeLineType : function (line, mode, buildLine) {
	
		var self = this,
	
		lineBase = com.workflowGraph.Global.lineMap.get(line.id),
		
		xBaseMode = lineBase.xBaseMode,
		wBaseMode = lineBase.wBaseMode,
		
		xMode,
		wMode;
		
		if (xBaseMode) {
			xMode = $id(xBaseMode.id);
		}
		
		if (wBaseMode) {
			wMode = $id(wBaseMode.id);
		}
	
		if (xBaseMode && xBaseMode.id == mode.id) {
		
			if (wMode && xMode) {

				var wBuildLine = self.findModeLine(wMode, line);
			
				if (wMode.offsetTop - (xMode.offsetTop + xMode.offsetHeight) > 0) {
						
					buildLine.index = PathGlobal.pointTypeDown;
					wBuildLine.index = PathGlobal.pointTypeUp;
						
				} else if (xMode.offsetTop - (wMode.offsetTop + wMode.offsetHeight) > 0) {
					
					buildLine.index = PathGlobal.pointTypeUp;
					wBuildLine.index = PathGlobal.pointTypeDown;
						
				} else if (xMode.offsetLeft - (wMode.offsetLeft + wMode.offsetWidth) > 0) {
						
					buildLine.index = PathGlobal.pointTypeLeft;
					wBuildLine.index = PathGlobal.pointTypeRight;
							
				} else if (wMode.offsetLeft - (xMode.offsetLeft + xMode.offsetWidth) > 0) {
						
					buildLine.index = PathGlobal.pointTypeRight;
					wBuildLine.index = PathGlobal.pointTypeLeft;
					
				}

				this.changeBaseModeAndLine(wMode, false);
					
			}
		}
		
		if (wBaseMode && wBaseMode.id == mode.id) {
			
			if (wMode && xMode) {
		
				var xBuildLine = self.findModeLine(xMode, line);
				
				if (xMode.offsetTop - (wMode.offsetTop + wMode.offsetHeight) > 0) {
					
					buildLine.index = PathGlobal.pointTypeDown;
					xBuildLine.index = PathGlobal.pointTypeUp;
				
				} else if (wMode.offsetTop - (xMode.offsetTop + xMode.offsetHeight) > 0) {
					
					buildLine.index = PathGlobal.pointTypeUp;
					xBuildLine.index = PathGlobal.pointTypeDown;
					
				} else if (wMode.offsetLeft - (xMode.offsetLeft + xMode.offsetWidth) > 0) {
					
					buildLine.index = PathGlobal.pointTypeLeft;
					xBuildLine.index = PathGlobal.pointTypeRight;
					
				} else if (xMode.offsetLeft - (wMode.offsetLeft + wMode.offsetWidth) > 0) {
					
					buildLine.index = PathGlobal.pointTypeRight;
					xBuildLine.index = PathGlobal.pointTypeLeft;
					
				}
			
				self.changeBaseModeAndLine(xMode, false);
					
			}
		}
		
		return buildLine;
	
	},
	
	changeBaseModeAndLine : function (mode, isChangeEnd) {
	
		var self = this,
	
		x = 0,
		y = 0,
		
		global = com.workflowGraph.Global,
		
		baseMode = global.modeMap.get(mode.id),
		baseLineModeMap = baseMode.lineMap,
		
		baseLineKey = baseLineModeMap.getKeys(),
		baseLineKeyLength = baseLineKey.length;
		
		for (var i = baseLineKeyLength; i--;) {
		
			var buildLine = baseLineModeMap.get(baseLineKey[i]),
			line = $id(buildLine.id);
		
			if (line) {
			
				if (isChangeEnd && PathGlobal.isAutoLineType) {
					self.changeLineType(line, mode, buildLine);
				}
			
				var w = mode.offsetWidth,
						h = mode.offsetHeight;
			
				if (buildLine.index == PathGlobal.pointTypeUp) {
						
					x = 0;
					y = w / 2;
					
				} else if (buildLine.index == PathGlobal.pointTypeLeft) {
						
					x = h / 2;
					y = 0;
					
				} else if (buildLine.index == PathGlobal.pointTypeDown) {
						
					x = h;
					y = w / 2;
						
				} else if (buildLine.index == PathGlobal.pointTypeRight) {
						
					x = h / 2;
					y = w;
					
				}
			
				x += parseInt(mode.offsetTop);
				y += parseInt(mode.offsetLeft);
				
				var tempLineTool = global.lineTool;
			
				tempLineTool.pathLine(y, x, line, buildLine.type);
				tempLineTool.setDragPoint(line);

			}
	
		}
		
	},
	
	dragPoint : function (point) {
		
		var global = com.workflowGraph.Global;
		
		point.onmousedown = function(event) {
		
			var parentMode = point.parentNode,
			parentModeStyle = parentMode.style,
		
			tempModeTool = global.modeTool;
		
			tempModeTool.isModeCross(parentMode);
			
			var idIndex = global.modeTool.getModeIndex(parentMode),
	
			contentImage = $id("backImg" + idIndex),
			contentImageStyle = contentImage.style,
			content = $id("content" + idIndex),
			contentStyle = content.style,

			dragType = point.className,
	
			oldTopBaseMode = parentMode.offsetTop,
			oldLeftBaseMode = parentMode.offsetLeft,
			oldWidthBaseMode = parentMode.offsetWidth,
			oldHeightBaseMode = parentMode.offsetHeight,
		
			undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
				parentModeStyle.left = oldLeftBaseMode + "px";
				parentModeStyle.top = oldTopBaseMode + "px";
				parentModeStyle.width = oldWidthBaseMode + "px";
				parentModeStyle.height = oldHeightBaseMode + "px";
			
				contentStyle.left = "0px";
				contentStyle.top = "0px";
				contentStyle.width = oldWidthBaseMode + "px";
				contentStyle.height = oldHeightBaseMode + "px";
			
				contentImageStyle.left = "0px";
				contentImageStyle.top = "0px";
				contentImageStyle.width = oldWidthBaseMode + "px";
				contentImageStyle.height = oldHeightBaseMode + "px";
			
				tempModeTool.showPointer(parentMode);
				tempModeTool.changeBaseModeAndLine(parentMode, true);
    		
    		global.smallTool.drawMode(parentMode);
			
			}, PathGlobal.modeDragPoint);
		
			global.modeTool.moveable = true;
		
			event = event || window.event;
		
			if (parentMode.setCapture) {
				parentMode.setCapture();
			} else if (window.captureEvents) {
				window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
			
			var x = event.layerX && event.layerX >= 0 ? event.layerX : event.offsetX,
					y = event.layerX && event.layerY >= 0 ? event.layerY : event.offsetY;
					
			stopEvent = true;
		
			var doc = document;
		
			doc.onmousemove = function(event) {
			
				event = event || window.event;
				
				if (global.modeTool.moveable) {
				
					if (!event.pageX) {
						event.pageX = event.clientX;
					} 
		
   				if (!event.pageY) {
   					event.pageY = event.clientY;
   				}
   	
   				var tx = event.pageX - x,
   						ty = event.pageY - y,
   			
   				tempPathBody = global.lineTool.pathBody,
   				leftTops = global.baseTool.sumLeftTop(tempPathBody);
   			
   				tx = tx - parseInt(leftTops[0]) + parseInt(tempPathBody.scrollLeft);
					ty = ty - parseInt(leftTops[1]) + parseInt(tempPathBody.scrollTop);
   			
   				var minWidth = PathGlobal.minWidth,
   						minHeight = PathGlobal.minHeight;
   							
   				if ("bottom_right" == dragType) {
   				
   					if ((parseInt(tx) - parseInt(parentMode.offsetLeft)) < minWidth) {
   					
							contentImageStyle.width = minWidth + "px";
							parentModeStyle.width = minWidth + "px";
							contentStyle.width = minWidth + "px";
						
						} else {
						
							contentImageStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
							parentModeStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
			  			contentStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
			 		 	}
			  
			 			if ((parseInt(ty) - parseInt(parentMode.offsetTop)) < minHeight) {
			 			
			  			contentImageStyle.height = minHeight + "px";
			  			parentModeStyle.height = minHeight + "px";
			  			contentStyle.height = minHeight + "px";
			  		
			  		} else {
			  		
							contentImageStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							parentModeStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							contentStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
						
						}
   				
   				} else if ("bottom_middle" == dragType) {
   				
   					if ((parseInt(ty) - parseInt(parentMode.offsetTop)) < minHeight) {
   					
							contentImageStyle.height = minHeight + "px";
							parentModeStyle.height = minHeight + "px";
							contentStyle.height = minHeight + "px";
						
						} else {
						
							contentImageStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							parentModeStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							contentStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
						
						}
   				
   				} else if ("bottom_left" == dragType) {
   			
   					if (parseInt(ty) - parseInt(parentMode.offsetTop) < minHeight) {
   					
							contentImageStyle.height = minHeight + "px";
							parentModeStyle.height = minHeight + "px";
							contentStyle.height = minHeight + "px";
						
						} else {
						
							contentImageStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							parentModeStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
							contentStyle.height = parseInt(ty) - parseInt(parentMode.offsetTop) + "px";
						
						}
					
						var newWidth = 0;
					
						if (parseInt(tx) > parseInt(oldLeftBaseMode)) {
						
							newWidth = parseInt(tx) - parseInt(oldLeftBaseMode);
							newWidth = parseInt(oldWidthBaseMode) - newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = parseInt(oldWidthBaseMode) - minWidth + parseInt(oldLeftBaseMode);
						
							}
				
						} else {
					
							newWidth = parseInt(oldLeftBaseMode) - parseInt(tx);
							newWidth = parseInt(oldWidthBaseMode) + newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = minWidth - parseInt(oldWidthBaseMode) + parseInt(oldLeftBaseMode);
						
							}
						}
				
						contentImageStyle.width = newWidth + "px";
						parentModeStyle.width = newWidth + "px";
						contentStyle.width = newWidth + "px";
					
						parentModeStyle.left = parseInt(tx) + "px";
   				
   				} else if ("middle_right" == dragType) {
   				
   					if (parseInt(tx) - parseInt(parentMode.offsetLeft) < minWidth) {
						
							contentImageStyle.width = minWidth + "px";
							parentModeStyle.width = minWidth + "px";
							contentStyle.width = minWidth + "px";
					
						} else {
						
							contentImageStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
							parentModeStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
							contentStyle.width = parseInt(tx) - parseInt(parentMode.offsetLeft) + "px";
					
						}
   				
   				} else if ("middle_left" == dragType) {
   				
   					var newWidth = 0;
				
						if (parseInt(tx) > parseInt(oldLeftBaseMode)) {
					
							newWidth = parseInt(tx) - parseInt(oldLeftBaseMode);
							newWidth = parseInt(oldWidthBaseMode) - newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = parseInt(oldWidthBaseMode) - minWidth + parseInt(oldLeftBaseMode);
						
							}
				
						} else {
					
							newWidth = parseInt(oldLeftBaseMode) - parseInt(tx);
							newWidth = parseInt(oldWidthBaseMode) + newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = minWidth - parseInt(oldWidthBaseMode) + parseInt(oldLeftBaseMode);
						
							}
						}
				
						contentImageStyle.width = newWidth + "px";
						parentModeStyle.width = newWidth + "px";
						contentStyle.width = newWidth + "px";
						parentModeStyle.left = parseInt(tx) + "px";
   				
   				} else if ("top_right" == dragType) {
   			
   					var newWidth = 0;
				
						if (parseInt(tx) > (parseInt(oldLeftBaseMode) + parseInt(oldWidthBaseMode))) {
					
							newWidth = parseInt(tx) - (parseInt(oldLeftBaseMode) + parseInt(oldWidthBaseMode));
							newWidth = parseInt(oldWidthBaseMode) + newWidth;
					
							if (newWidth <= minWidth) {
								newWidth = minWidth;
							}
				
						} else {
					
							newWidth = (parseInt(oldLeftBaseMode) + parseInt(oldWidthBaseMode)) - parseInt(tx);
							newWidth = parseInt(oldWidthBaseMode) - newWidth;
					
							if (newWidth <= minWidth) {
								newWidth = minWidth;
							}
					
						}
				
						contentImageStyle.width = newWidth + "px";
						parentModeStyle.width = newWidth + "px";
						contentStyle.width = newWidth + "px";
					
						var newHeight = 0;
				
						if (parseInt(ty) > parseInt(oldTopBaseMode)) {
					
							newHeight = parseInt(ty) - parseInt(oldTopBaseMode);
							newHeight = parseInt(oldHeightBaseMode) - parseInt(newHeight);
					
							if (newHeight <= minHeight) {
						
								newHeight = minHeight;
								ty = parseInt(oldHeightBaseMode) - minHeight + parseInt(oldTopBaseMode);
						
							}
				
						} else {
					
							newHeight = parseInt(oldTopBaseMode) - parseInt(ty);
							newHeight = parseInt(oldHeightBaseMode) + parseInt(newHeight);
					
							if (newHeight <= minHeight) {
						
								newHeight = minHeight;
								ty = minHeight - parseInt(oldHeightBaseMode) + parseInt(oldTopBaseMode);
							
							}
				
						}
				
						contentImageStyle.height = newHeight + "px";
						parentModeStyle.height = newHeight + "px";
						contentStyle.height = newHeight + "px";
						parentModeStyle.top = parseInt(ty) + "px";
   			
   				} else if ("top_middle" == dragType) {
   				
   					var newHeight = 0;
				
						if (parseInt(ty) > parseInt(oldTopBaseMode)) {
					
							newHeight = parseInt(ty) - parseInt(oldTopBaseMode);
							newHeight = parseInt(oldHeightBaseMode ) - parseInt(newHeight);
					
							if (newHeight <= minHeight) {
								newHeight = minHeight;
								ty = parseInt(oldHeightBaseMode) + parseInt(oldTopBaseMode) - minHeight;
							}
				
						} else {
					
							newHeight = parseInt(oldTopBaseMode) - parseInt(ty);
							newHeight = parseInt(oldHeightBaseMode) + parseInt(newHeight);
					
							if (newHeight <= minHeight) {
						
								newHeight = minHeight;
								ty = minHeight - parseInt(oldHeightBaseMode) + parseInt(oldTopBaseMode);
						
							}
				
						}
					
						contentImageStyle.height = newHeight + "px";
						contentStyle.height = newHeight + "px";
						parentModeStyle.height = newHeight + "px";
						parentModeStyle.top = parseInt(ty) + "px";
   				
   				} else if ("top_left" == dragType) {
   				
   					var newWidth = 0;
				
						if (parseInt(tx) > parseInt(oldLeftBaseMode)) {
					
							newWidth = parseInt(tx) - parseInt(oldLeftBaseMode);
							newWidth = parseInt(oldWidthBaseMode) - newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = parseInt(oldWidthBaseMode) - minWidth + parseInt(oldLeftBaseMode);
						
							}
				
						} else {
					
							newWidth = parseInt(oldLeftBaseMode) - parseInt(tx);
							newWidth = parseInt(oldWidthBaseMode) + newWidth;
					
							if (newWidth <= minWidth) {
						
								newWidth = minWidth;
								tx = minWidth - parseInt(oldWidthBaseMode) + parseInt(oldLeftBaseMode);
						
							}
						}
				
						contentImageStyle.width = newWidth + "px";
						parentModeStyle.width = newWidth + "px";
						contentStyle.width = newWidth + "px";
						
						var newHeight = 0;
				
						if (parseInt(ty) > parseInt(oldTopBaseMode)) {
					
							newHeight = parseInt(ty) - parseInt(oldTopBaseMode);
							newHeight = parseInt(oldHeightBaseMode) - parseInt(newHeight);
					
							if (newHeight <= minHeight) {
								newHeight = minHeight;
								ty = parseInt(oldHeightBaseMode) + parseInt(oldTopBaseMode) - minHeight;
							}
				
						} else {
					
							newHeight = parseInt(oldTopBaseMode) - parseInt(ty);
							newHeight = parseInt(oldHeightBaseMode) + parseInt(newHeight);
					
							if (newHeight <= minHeight) {
						
								newHeight = minHeight;
								ty = minHeight - parseInt(oldHeightBaseMode) + parseInt(oldTopBaseMode);
						
							}
				
						}
				
						contentImageStyle.height = newHeight + "px";
						parentModeStyle.height = newHeight + "px";
						contentStyle.height = newHeight + "px";
				
						parentModeStyle.top = parseInt(ty) + "px";
						parentModeStyle.left = parseInt(tx) + "px";
   			
   				}
				
					var tempModeTool = global.modeTool;
				
					tempModeTool.isModeCross(parentMode);
					tempModeTool.showPointer(parentMode);
					tempModeTool.changeBaseModeAndLine(parentMode, true);
				
					global.smallTool.drawMode(parentMode);
			
				} 

			};
		
			doc.onmouseup = function(event) {
			
				event = event || window.event;
			
				global.modeTool.moveable = false;
			
				if (parentMode.releaseCapture) {
					parentMode.releaseCapture();
				} else if (window.releaseEvents) {
					window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
				}
			
				var afterTopBaseMode = parentMode.offsetTop,
				afterLeftBaseMode = parentMode.offsetLeft,
				afterWidthBaseMode = parentMode.offsetWidth,
				afterHeightBaseMode = parentMode.offsetHeight;
		
				undoRedoEvent.setRedo(function () {
			
					parentModeStyle.left = afterLeftBaseMode + "px";
					parentModeStyle.top = afterTopBaseMode + "px";
					parentModeStyle.width = afterWidthBaseMode + "px";
					parentModeStyle.height = afterHeightBaseMode + "px";
			
					contentImageStyle.left = "0px";
					contentImageStyle.top = "0px";
					contentImageStyle.width = afterWidthBaseMode + "px";
					contentImageStyle.height = afterHeightBaseMode + "px";
				
					contentStyle.top = "0px";
					contentStyle.left = "0px";
					contentStyle.width = afterWidthBaseMode + "px";
					contentStyle.height = afterHeightBaseMode + "px";
			
					tempModeTool.showPointer(parentMode);
					tempModeTool.changeBaseModeAndLine(parentMode, true);
    		
    			global.smallTool.drawMode(parentMode);
			
				});
	
   			doc.onmousemove = null;
   			doc.onmouseup = null;

			};
		
		}
	
	},
	
	isActiveMode : function (mode) {
		return mode.style.visibility == "visible";
	},
	
	getActiveMode : function () {
	
		var activeMode,
		tempModeTool = com.workflowGraph.Global.modeTool;
	
		this.forEach(function (modeId) {
		
			var mode = $id(modeId);
		
			if (tempModeTool.isActiveMode(mode)) {
				activeMode = mode;
			}
		
		});
	
		return activeMode;
	
	},
	
	getSonNode : function (mode, nodeClassName) {
	
		for (var copyNode = mode.firstChild; copyNode != null; copyNode = copyNode.nextSibling) {
		
			if (copyNode.nodeType == 1) {
				var className = copyNode.className;
			
				if (className == nodeClassName) {
					return copyNode;
				}
			
				if (className == "content" && nodeClassName == "backImg") {
				
					for(var sonNode = copyNode.firstChild; sonNode != null; sonNode = sonNode.nextSibling) {
					
						if (sonNode.nodeType == 1) {
							return sonNode;
						}
					
					} 
				
				}
			
			}
		
		}
	
	},
	
	setIndex : function (mode, idIndex) {

		mode.id = "module" + idIndex;
	
		for (var copyNode = mode.firstChild; copyNode != null; copyNode = copyNode.nextSibling) {
		
			if (copyNode.nodeType == 1) {
			
				var className = copyNode.className;
				copyNode.id = className + idIndex;
			
				if (className == "content") {
				
					for(var sonNode = copyNode.firstChild; sonNode != null; sonNode = sonNode.nextSibling) {
					
						if (sonNode.nodeType == 1) {
							sonNode.id = "backImg" + idIndex;
							break;
						}
					
					} 
				
				}
			
			}
		
		}
	
		return mode;

	},
	
	copy : function (mode) {
	
		var self = this,
		copyObj = mode.cloneNode(true),
		idIndex = self.getNextIndex();
	
		self.setIndex(copyObj, idIndex);
	
		var copyObjStyle = copyObj.style;
	
		copyObjStyle.left = parseInt(copyObjStyle.left) + PathGlobal.copyModeDec + "px";
		copyObjStyle.top = parseInt(copyObjStyle.top) + PathGlobal.copyModeDec + "px";
	
		var baseMode = new BaseMode();
		baseMode.id = copyObj.id;
		
		var global = com.workflowGraph.Global;
	
		global.modeMap.put(baseMode.id, baseMode);
	
		var tempLineTool = global.lineTool;
		tempLineTool.pathBody.appendChild(copyObj);
		this.initEvent(idIndex);
	
		return copyObj;
	
	},
	
	flip : function (idIndex, titleHTML) {
	
		var mode = com.workflowGraph.Global.modeMap.get("module" + idIndex);
	
		if (mode.isFilp) {
			return;
		}
	
		mode.isFilp = true;
	
		var backImg = $id("backImg" + idIndex),
		tempHeight = backImg.height,
		content = $id("content" + idIndex),
		contentStyle = content.style;
	
		mode.modeHeigh = tempHeight;
	
		contentStyle.width = backImg.width + "px";
		contentStyle.fontSize = (tempHeight - parseInt(tempHeight * 0.15)) + "px";
		contentStyle.lineHeight = tempHeight + "px";
		contentStyle.height = tempHeight + "px";
	
		var modeDiv = $id(mode.id),
		modeDivStyle = modeDiv.style;
	
		modeDivStyle.width = backImg.width + "px";
		modeDivStyle.height = tempHeight + "px";
	
		mode.inc = mode.modeHeigh / 10;

		this.doFlip(idIndex, titleHTML);
	
	},
	
	doFlip : function (idIndex, titleHTML) {
		
		var backImg = $id("backImg" + idIndex);
	
		if (!backImg) {
			return;
		}
		
		var global = com.workflowGraph.Global,
		
		ht = backImg.height,
		mode = global.modeMap.get("module" + idIndex);
	
		ht = ht - mode.inc;
	
		if (ht < 1) {
			ht = 1;
		}
		
		if (ht <= 1) {
		
			mode.inc =- mode.inc;
		
		} else if (ht >= mode.modeHeigh) {
			
			$id("backImg" + idIndex).style.height = mode.modeHeigh + "px";
			mode.modeHeigh = 0;
			mode.isFilp = false;
			mode.inc =- mode.inc;
			
			var contentStyle = $id("content" + idIndex).style;
			
			contentStyle.width = 0 + "px";
			contentStyle.height = 0 + "px";
			contentStyle.lineHeight = 0 + "px";
			contentStyle.fontSize = 0 + "px";
			
			var titleDiv = $id("title" + idIndex);
			
			if (titleHTML == 'undefined' || !titleHTML) {
			} else {
				titleDiv.innerHTML = titleHTML;
			}
			
			this.showPointerId(idIndex);
			
			return;
		
		} else {
			$id("backImg" + idIndex).style.height = ht + "px";
		}

		setTimeout(function () {
			global.modeTool.doFlip(idIndex, titleHTML);
		}, PathGlobal.pauseTime);

	},
	
	isModeCross : function (moveMode) {
  
		var moveModeLeft = parseInt(moveMode.offsetLeft),
  	moveModeWidth = moveMode.offsetWidth + moveModeLeft,
  	moveModeWidthHlef = parseInt(moveMode.offsetWidth / 2) + moveModeLeft,
  	
		moveModeTop = parseInt(moveMode.offsetTop),
		moveModeHeight = moveMode.offsetHeight + moveModeTop,
		moveModeHeightHlef = parseInt(moveMode.offsetHeight / 2)+ moveModeTop,
		
		leftCross = $id("leftCross"),
		topCross = $id("topCross"),
	
		leftCrossStyle = leftCross.style,
		topCrossStyle = topCross.style,
			
	  modeKeys = com.workflowGraph.Global.modeMap.getKeys(),
	  	
	  isTopCross = false,
	  isLeftCross = false,
	  modeKeysLength = modeKeys.length;
	  	
		for (var i = modeKeysLength; i--;) {
	  		
			var mode = $id(modeKeys[i]);
	  	
	  	if (moveMode.id == mode.id) {
	  		continue;
	  	}
			
			var left = parseInt(mode.offsetLeft),
			xWidth = mode.offsetWidth + left,
			xWidthHlef = parseInt(mode.offsetWidth / 2) + left,
	  		
			top = parseInt(mode.offsetTop),
			yHeight = mode.offsetHeight + top,
			yHeightHlef = parseInt(mode.offsetHeight / 2) + top;
				
			if (moveModeLeft == left || moveModeLeft == xWidth) {
				
				leftCross.style.left = moveModeLeft;
				isLeftCross = true;
				leftCross.style.visibility = "visible";
			
			}
				
			if (moveModeWidth == left || moveModeWidth == xWidth) {
				
				leftCrossStyle.left = moveModeWidth;
				isLeftCross = true;
				leftCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeWidthHlef == left || moveModeWidthHlef == xWidthHlef) {
				
				leftCrossStyle.left = moveModeWidthHlef;
				isLeftCross = true;
				leftCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeWidthHlef == xWidth) {
				
				leftCrossStyle.left = moveModeWidthHlef;
				isLeftCross = true;
				leftCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeLeft == xWidthHlef || moveModeWidth == xWidthHlef) {
				
				leftCrossStyle.left = xWidthHlef;
				isLeftCross = true;
				leftCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeTop == top || moveModeTop == yHeight) {
				
				topCrossStyle.top = moveModeTop;
				isTopCross = true;
				topCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeTop == yHeightHlef || yHeightHlef == moveModeHeightHlef || yHeightHlef == moveModeHeight) {
				
				topCrossStyle.top = yHeightHlef;
				isTopCross = true;
				topCrossStyle.visibility = "visible";
			
			}
			
			if (moveModeHeightHlef == top || moveModeHeightHlef == yHeight) {
			
				topCrossStyle.top = moveModeHeightHlef;
				isTopCross = true;
				topCrossStyle.visibility = "visible";
			
			}
			
			if (yHeightHlef == moveModeHeightHlef) {
				
				topCrossStyle.top = yHeightHlef;
				isTopCross = true;
				topCrossStyle.visibility = "visible";
				
			}
				
			if (moveModeHeight == top || moveModeHeight == yHeight) {
					
				topCrossStyle.top = moveModeHeight;
				isTopCross = true;
				topCrossStyle.visibility = "visible";
					
			}
	
		}
			
		if (!isTopCross) {
			topCrossStyle.visibility = "hidden";
		}
			
		if (!isLeftCross) {
			leftCrossStyle.visibility = "hidden";
		}
	  
	},



    svgMode : function(obj,name, left, top, width, height) {

        var mode,
            self = this,
            doc = document;
        if (name == "rect" || name == "rectr") {

            mode = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');

            mode.setAttribute("x", left);
            mode.setAttribute("y", top);
            mode.setAttribute("width", width);
            mode.setAttribute("height", height);
            mode.setAttribute("style", "fill:white;stroke:black;stroke-width:2;")

            if (name == "rectr") {
                mode.setAttribute("rx", "10")
                mode.setAttribute("ry", "10")
            }

        }

        obj.appendChild(mode);
    }



}
var Map = com.workflowGraph.Map = function () {
	
	var self = this;
	
	self.map = new Object();
	self.length = 0;

}

Map.prototype = {
	
	size : function() {
		return this.length;
	},
	
	clear : function() {
	
		var self = this;
		
		self.map = new Object();
		self.length = 0;
	
	},
	
	put : function(key, value) {

		var self = this;
		
		if (!self.map['_' + key]) {
			++self.length;
		}
	      
		self.map['_' + key] = value;
	
	},
	
	putAll : function (objMap) {
	
		var keys = objMap.getKeys(),
		keyLength = keys.length,
		
		self = this;
		
		for (var i = keyLength; i--;) {
			var k = keys[i];
			self.put(k, objMap.get(k));
		}
		
	},
	
	remove : function(key) {
  
	  var self = this;
	  
		if (self.map['_' + key]) { 
			--self.length;
			return delete self.map['_' + key];
		} else {
			return false;
		}
			
	},
	
	containsKey : function(key) {
		return this.map['_' + key] ? true:false;
	},
    
	get : function(key) {
		var self = this;
		return self.map['_' + key] ? self.map['_' + key]:null;
	},

	inspect : function() {
       	
		var str = '',
	  self = this;
	  
		for (var each in self.map) {
			str+= '\n'+ each + '  Value:'+ self.map[each];
		}
	  
	  return str;
	},
       
	getKeys : function() {
          
		var kyeArray = new Array(),
		i = 0,
	  
	    self = this;
	           
		for (var each in self.map) {      
			kyeArray[i++] = each.replace('_', '');
		}
			
		return kyeArray;
		
	}

}
var BaseMode = com.workflowGraph.BaseMode = function () {
	
	var self = this;
	
	self.id;
	self.lineMap = new Map();
	
	self.prop = {
			attri1 : '2',
			attri2 : '3',
			attri3 : '4'
	}
	
}

var BuildLine = com.workflowGraph.BuildLine = function () {
	
	var self = this;
	
	self.id;
	self.index;
	self.xIndex;
	self.wIndex;
	self.type;
	self.xBaseMode;
	self.wBaseMode;
	
	self.prop = {
			attri1 : '2',
			attri2 : '3',
			attri3 : '4',
			attri4 : '5'
	}
	
}

var Point = com.workflowGraph.Point = function () {
	
	var self = this;
	
	self.x = 0;
	self.y = 0;
	self.index = 0;

}

Point.prototype.equal = function(point) {
    var result = false;
    if (this.x == point.x && this.y == point.y) {
        result = true;
    }
    return result;
}

Point.prototype.empty = function() {

    var result = false;
    var self = this;
    if (this.x == 0 && this.y == 0 || this.x == "0" && this.y == "0") {
        result = true;
    }
    return result;

}

var KeyDownFactory = com.workflowGraph.KeyDownFactory = function () {}

KeyDownFactory.prototype = {

	removeNode : function () {
		
		var global = com.workflowGraph.Global,
	
		tempLineTool = global.lineTool,
		tempBaseTool = global.baseTool,
		pathBody = tempLineTool.pathBody,
		svgBody = tempLineTool.svgBody,
		
		tempSmallTool = global.smallTool,
		tempModeTool = global.modeTool,
		
		activeModeArray = [],
		activeModeMap = [],
		i = 0,
		
		isRemoveMode = false,
		activeLineArray = [],
		activeLineMap = [],
		j = 0,
		isRemoveLine = false,
		baseLineModeMap = null;
		
		tempModeTool.forEach(function(modeId) {
			
			var mode = $id(modeId);
			
			if (tempModeTool.isActiveMode(mode)) {
				
				activeModeMap[i] = global.modeMap.get(mode.id);
				activeModeArray[i++] = mode;

				baseLineModeMap = global.modeMap.get(modeId).lineMap,
				
				baseLineKey = baseLineModeMap.getKeys(),
				baseLineKeyLength = baseLineKey.length;
		
				for (var k = baseLineKeyLength; k--;) {
		
					var buildLine = baseLineModeMap.get(baseLineKey[k]),
					line = $id(buildLine.id);
					
					if (line) {
						
						activeLineMap[j] = com.workflowGraph.Global.lineMap.get(line.id);
						activeLineArray[j++] = line;
			
						global.lineTool.removeNode(buildLine.id);
						
					}
					
				}
				
				global.modeTool.removeNode(modeId);
				
				isRemoveMode = true;
				
			}
			
		});
		
		global.baseTool.clearContext();
		
		if (isRemoveMode) {
			
			var undoRedoModeEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
				var activeLineLength = activeLineArray.length,
						dragBody = null;
			
				for (var j = activeLineLength; j--;) {
				
					var activeLine = activeLineArray[j],
							lineId = activeLine.getAttribute("id");
				
					if (tempLineTool.isVML) {
						
						activeLine.setAttribute("coordsize", "100,100");
						activeLine.setAttribute("filled", "f");
						activeLine.setAttribute("strokeweight", PathGlobal.strokeweight + "px");
						activeLine.setAttribute("strokecolor", PathGlobal.lineColor);
						
						dragBody = pathBody;
					
					} else if (tempLineTool.isSVG) {
						dragBody = svgBody;
					}
					
					if (!$id(lineId)) {
						
						dragBody.appendChild(activeLine);
					
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineHead'));
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineMiddle'));
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineEnd'));
					
						tempLineTool.drag(activeLine);
				
						global.lineMap.put(activeLine.id, activeLineMap[j]);
						tempSmallTool.drawLine(activeLine);
					
					}
	
				}
				
				var activeModeLength = activeModeArray.length;
				
				for (var i = activeModeLength; i--;) {
				
					var activeMode = activeModeArray[i];
				
					global.modeMap.put(activeMode.id, activeModeMap[i]);
				
					pathBody.appendChild(activeMode);
					tempModeTool.showPointer(activeMode);
				
					tempSmallTool.drawMode(activeMode);
				
				}
			
			}, PathGlobal.removeMode);
		  
			undoRedoModeEvent.setRedo(function () {
				
				var activeLineLength = activeLineArray.length;
				for (var i = activeLineLength; i--;) {
				
					var activeLine = activeLineArray[i];
					tempLineTool.removeNode(activeLine.id);
				
				}
			
				var activeModeLength = activeModeArray.length;
				
				for (var i = activeModeLength; i--;) {
				
					var activeMode = activeModeArray[i];
					global.modeTool.removeNode(activeMode.id);
				
				}
			
			});
		
		}

		tempLineTool.forEach(function(lineId) {
			
			var line = $id(lineId);
			
			if (tempLineTool.isActiveLine(line)) {
				
				activeLineMap[j] = com.workflowGraph.Global.lineMap.get(line.id);
				activeLineArray[j++] = line;
				
				tempLineTool.removeNode(line.id);
				isRemoveLine = true;
				
			}
		
		});
		
		if (isRemoveLine) {
			
			var undoRedoLineEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
				var activeLineLength = activeLineArray.length,
						dragBody = null;
			
				for (var j = activeLineLength; j--;) {
				
					var activeLine = activeLineArray[j],
							lineId = activeLine.getAttribute("id");
				
					if (tempLineTool.isVML) {
						
						activeLine.setAttribute("coordsize", "100,100");
						activeLine.setAttribute("filled", "f");
						activeLine.setAttribute("strokeweight", PathGlobal.strokeweight + "px");
						activeLine.setAttribute("strokecolor", PathGlobal.lineColor);
						
						dragBody = pathBody;
					
					} else if (tempLineTool.isSVG) {
						dragBody = svgBody;
					}
					
					if (!$id(lineId)) {
						
						dragBody.appendChild(activeLine);
					
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineHead'));
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineMiddle'));
						dragBody.appendChild(tempLineTool.createRect(lineId + 'lineEnd'));
					
						tempLineTool.drag(activeLine);
				
						global.lineMap.put(activeLine.id, activeLineMap[j]);
						tempSmallTool.drawLine(activeLine);
						
					}
	
				}
			
			}, PathGlobal.remodeLine);
		
			undoRedoLineEvent.setRedo(function () {
			
				var activeLineLength = activeLineArray.length;
			
				for (var i = activeLineLength; i--;) {
				
					var activeLine = activeLineArray[i];
					tempLineTool.removeNode(activeLine.id);
				
				}
			
			});
		
		}
	},
	
	copyNode : function () {
	
		var global = com.workflowGraph.Global,
		tempModeTool = global.modeTool,
		
		activeModeArray = [],
		i = 0,
		
		tempSmallTool = global.smallTool;
		
		tempModeTool.forEach(function (modeId) {
			
			var mode = $id(modeId);
			
			if (tempModeTool.isActiveMode(mode)) {
				
				var copyObj = global.modeTool.copy(mode);
				
				activeModeArray[i++] = copyObj;
				tempModeTool.hiddPointer(mode);
				tempSmallTool.drawMode(copyObj);
				
			}
			
		});
		
		var tempLineTool = global.lineTool;
		
		if (activeModeArray.length > 0) {
			
			var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
			
				var activeModeLength = activeModeArray.length;
			
				for (var i = activeModeLength; i--;) {
				
					var activeMode = activeModeArray[i];
				
					if (activeMode && activeMode.id && $id(activeMode.id)) {
				
						global.modeMap.remove(activeMode.id);
				
						tempLineTool.pathBody.removeChild(activeMode);
						tempSmallTool.removeMode(activeMode.id);
				
					}
				
				}
			
			}, PathGlobal.copyMode);
		
			undoRedoEvent.setRedo(function () {
			
				var activeModeLength = activeModeArray.length;
			
				for (var i = activeModeLength; i--;) {
				
					var activeMode = activeModeArray[i];
				
					var baseMode = new BaseMode();
					baseMode.id = activeMode.id;
					global.modeMap.put(activeMode.id, baseMode);
				
					tempLineTool.pathBody.appendChild(activeMode);
					
					tempModeTool.showPointer(activeMode);
					tempSmallTool.drawMode(activeMode);
				
				}
			
			});
		
		}
		
	}
	
}


var keyDownFactory = new KeyDownFactory();

function KeyDown(event) {

    event = event || window.event;

    if (event.keyCode == 46) {
        deleteNode();
    }
    if (event.ctrlKey) {
        switch (event.keyCode) {
            case 77: deleteNode(); break;
            //case 86: keyDownFactory.copyNode(); break;
        }
    }
}
var SmallMapTool = com.workflowGraph.SmallMapTool = function (smallMap, body) {
	
	var self = this;
	
	self.smallMap = $id(smallMap);
	self.body = $id(body);
	self.multiple = self.getMultiple();
	self.defaultColor = PathGlobal.defaultColor;
	self.checkColor = "#00ff00";

	self.widthPercent = self.smallMap.offsetWidth / parseInt(self.body.scrollWidth) / self.multiple;
	self.heightPercent = self.smallMap.offsetHeight / parseInt(self.body.scrollHeight) / self.multiple;
	
	self.percent = 0;
	
	self.initPercent();

	self.smallModeMap = new Map();
	self.smallLineMap = new Map();
	
	var doc = document;

	if (com.workflowGraph.Global.lineTool.isSVG) {
		
		self.svgBody = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
		self.svgBody.setAttribute("id", "smallSvgContext");
		self.svgBody.setAttribute("height", '100%');
		self.svgBody.setAttribute("width", '100%');
    self.svgBody.setAttribute("style", "position:absolute;z-index:0;");
		
		self.smallMap.appendChild(self.svgBody);
		
	}
	
	self.smallBody = doc.createElement("div");
	self.smallBody.id = "smallBodyId";
	
	var smallBodyStyle = self.smallBody.style;
	smallBodyStyle.fontSize = "0px";
	smallBodyStyle.borderWidth = "2px";
	smallBodyStyle.borderColor = '#0F0';
	smallBodyStyle.borderStyle= "solid";
	smallBodyStyle.position = "absolute";
	smallBodyStyle.cursor = "pointer";
	
	self.drag(self.smallBody);
	self.smallMap.appendChild(self.smallBody);
	
	self.scalingDiv = doc.createElement("div");
	self.scalingDiv.id = "scalingId";
	self.scalingDiv.setAttribute("class", "scaling");
	self.scalingDiv.setAttribute("className", "scaling");
	
	self.dragScaling(self.scalingDiv);
	self.smallMap.appendChild(self.scalingDiv);
	
	self.initSmallBody();

}

SmallMapTool.prototype = {
	
	dragScaling : function (scalingDiv) {
		
		var global = com.workflowGraph.Global;
		
		scalingDiv.ondragstart = function () {
				return false;
		};
		
		scalingDiv.onmousedown = function(event) {
			
			var multiple = 1,
			tempSmallTool = global.smallTool,
			
			scalingDivStyle = scalingDiv.style,
			smallBodyStyle = tempSmallTool.smallBody.style,
		
			oldWidth = smallBodyStyle.width,
			oldHeight = smallBodyStyle.height;
			
			event = event || window.event;
			
			if (scalingDiv.setCapture) {
				scalingDiv.setCapture();
			} else if (window.captureEvents) {
				window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
			
			var x = event.layerX ? event.layerX : event.offsetX,
					y = event.layerY ? event.layerY : event.offsetY,
			
			doc = document;
			
			doc.onmousemove = function (event) {
				
				event = event || window.event;
				
				if (!event.pageX) {
					event.pageX = event.clientX;
				} 
			
	   		if (!event.pageY) {
	   			event.pageY = event.clientY;
	   		}
	   	
	   		var tx = event.pageX - x,
	   				ty = event.pageY - y,
	   		
				smallMap = tempSmallTool.smallMap,
				leftTop = global.baseTool.sumLeftTop(smallMap);
				
				tx = tx - parseInt(leftTop[0]);
				ty = ty - parseInt(leftTop[1]);
			
				if (global.baseTool.isIE) {
					tx = tx - 4;
					ty = ty - 4;
				}
	   		
				scalingDivStyle.left = tx + "px";
	    	scalingDivStyle.top = ty + "px";
	    	
	    	var newWidth = tx + 1 - parseInt(smallBodyStyle.left),
	    			newHeight = ty + 1 - parseInt(smallBodyStyle.top);
	    	
	    	if (newWidth < 1) {
	    		newWidth = 1;
	    	}
	    	
	    	if (newHeight < 1) {
	    		newHeight = 1;
	    	}
	    	
	    	smallBodyStyle.width = newWidth + "px";
	    	smallBodyStyle.height = newHeight + "px";
	    	
	    	multiple = parseInt(smallBodyStyle.width) / parseInt(oldWidth);
	    	
	    	if (multiple < PathGlobal.defaultMaxMag) {
	    		multiple = PathGlobal.defaultMaxMag;
	    	} else if (multiple > PathGlobal.defaultMinMag) {
	    		multiple = PathGlobal.defaultMinMag;
	    	}
	    	
	    	global.undoRedoEventFactory.clear();
	
			};
			
			doc.onmouseup = function (event) {
				
				event = event || window.event;
				
				if (scalingDiv.releaseCapture) {
					scalingDiv.releaseCapture();
				} else if (window.releaseEvents) {
					window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
				}
				
				global.lineTool.initScaling(multiple);
				global.modeTool.initScaling(multiple);
				global.baseTool.initScaling(multiple);
				
				tempSmallTool.initSmallBody();
				
	   		doc.onmousemove = null;
	   		doc.onmouseup = null;
	
			};
			
		}
		
	},

	drag : function (smallBody) {
		
		var global = com.workflowGraph.Global;
	
		smallBody.ondragstart = function () {
				return false;
		};
		
		smallBody.onmousedown = function(event) {
			
			event = event || window.event;
			
			if (smallBody.setCapture) {
				smallBody.setCapture();
			} else if (window.captureEvents) {
				window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
			}
			
			var x = event.layerX ? event.layerX : event.offsetX,
					y = event.layerY ? event.layerY : event.offsetY,
			
			doc = document;
			
			doc.onmousemove = function (event) {
				
				event = event || window.event;
				
				if (!event.pageX) {
					event.pageX = event.clientX;
				} 
			
	   		if (!event.pageY) {
	   			event.pageY = event.clientY;
	   		}
	   	
	   		var tx = event.pageX - x,
	   				ty = event.pageY - y,
	   		
	   		tempSmallTool = global.smallTool,
	   		smallMap = tempSmallTool.smallMap,
	   		
	   		leftTop = global.baseTool.sumLeftTop(smallMap);
				
				tx = tx - parseInt(leftTop[0]);
				ty = ty - parseInt(leftTop[1]);
	   		
	   		if (tx < 0) {
	   			tx = 0;
	   		}
	   		
	   		if (ty < 0) {
	   			ty = 0;
	   		}
	   		
				smallBody.style.left = tx + "px";
	    	smallBody.style.top = ty + "px";
	    	
	    	var tempLineTool = global.lineTool,
	    	tempSmallTool = global.smallTool,
	    	
	    	pathBody = $id(tempLineTool.pathBody.id);
	    	
	    	pathBody.scrollLeft = parseInt(tx / tempSmallTool.widthPercent);
	    	pathBody.scrollTop = parseInt(ty / tempSmallTool.heightPercent);
	    	
	    	tempSmallTool.initSmallBody();
	
			};
			
			doc.onmouseup = function (event) {
				
				event = event || window.event;
				
				if (smallBody.releaseCapture) {
					smallBody.releaseCapture();
				} else if (window.releaseEvents) {
					window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
				}
	
	   		doc.onmousemove = null;
	   		doc.onmouseup = null;
	
			};
			
		}
		
	},

	initSmallBody : function () {
	
		var self = this,
		smallBodyStyle = self.smallBody.style;
		
		smallBodyStyle.left = self.body.scrollLeft * self.widthPercent + "px";
		smallBodyStyle.top = self.body.scrollTop * self.heightPercent + "px";
		smallBodyStyle.width = self.body.offsetWidth * self.widthPercent + "px";
		smallBodyStyle.height = self.body.offsetHeight * self.heightPercent + "px";
		
		var scalingDivStyle = self.scalingDiv.style,
		
		left = parseInt(smallBodyStyle.left) + parseInt(smallBodyStyle.width),
		top = parseInt(smallBodyStyle.top) + parseInt(smallBodyStyle.height);
	
		if (com.workflowGraph.Global.baseTool.isIE) {
			left = left - 4;
			top = top - 4;
		}
		
		scalingDivStyle.left = left + "px";
		scalingDivStyle.top = top + "px";
		
	},

	getMultiple : function () {
	
		var self = this,
		bodyStyle = self.body.style,
		
		multiple = (parseInt(self.body.scrollWidth) + parseInt(self.body.scrollHeight)) / (parseInt(bodyStyle.width) + parseInt(bodyStyle.height));
		
		if (multiple > 1.82) {
			multiple = multiple - 0.82;
		} else if (multiple < 1.2) {
			multiple = 1.2;
		}
		
		return multiple;
	
	},

	initPercent : function () {
	
		var self = this;
		self.multiple = self.getMultiple();
		
		self.widthPercent = self.smallMap.offsetWidth / parseInt(self.body.scrollWidth);
		self.heightPercent = self.smallMap.offsetHeight / parseInt(self.body.scrollHeight);
		
		self.percent = self.heightPercent <= self.widthPercent ? self.heightPercent : self.widthPercent;
	
	},

	activeMode : function (modeId) {
		
		var global = com.workflowGraph.Global;
		
		global.modeTool.clear();
		
		var smallObjStyle = $id("small" + modeId).style;
		
		smallObjStyle.borderWidth = "1px";
		smallObjStyle.borderColor = global.smallTool.checkColor;
		smallObjStyle.borderStyle= "solid";
		
		stopEvent = true;
		
	},

	drawMode : function (mode) {

		var smallObj = null,
		self = this;
		
		if ($id("small" + mode.id)) {
			smallObj = $id("small" + mode.id);
		} else {
			
			smallObj = document.createElement("img");
			smallObj.ondragstart = function () {
				return false;
			};
			smallObj.id = "small" + mode.id;
			smallObj.style.position = "absolute";
			
			smallObj.onclick = function () {
				
				var global = com.workflowGraph.Global;
				
				global.modeTool.flip(mode.id.substring("modelu".length));
				global.smallTool.activeMode(mode.id);
			
			}
	
			self.smallMap.appendChild(smallObj);
			
		}
		
		self.smallModeMap.put(smallObj.id, smallObj);
		
		smallObj = $id(smallObj.id);
		
		var imageId = mode.id.replace("module", "backImg");
		
		smallObj.src = $id(imageId).src;
		
		var smallObjStyle = smallObj.style;
		smallObjStyle.fontSize = "0px";
			
		smallObjStyle.left = mode.offsetLeft * self.widthPercent + "px";
		smallObjStyle.top = mode.offsetTop * self.heightPercent + "px";
		smallObjStyle.width = mode.offsetWidth * self.percent + "px";
		smallObjStyle.height = mode.offsetHeight * self.percent + "px";
	
		smallObjStyle.borderWidth = "1px";
		smallObjStyle.borderColor = com.workflowGraph.Global.smallTool.checkColor;
		smallObjStyle.borderStyle= "solid";
	
	},
	
	_smallPath : function (path) {
		
		var tempLineTool = com.workflowGraph.Global.lineTool,
				paths = tempLineTool.getPathArray(path),
				pathLength = paths.length,
				self = this;
				
		for (var i = pathLength; i--;) {
			
			if (i % 2 == 1) {
				paths[i] = parseInt(paths[i] * self.heightPercent);
			} else {
				paths[i] = parseInt(paths[i] * self.widthPercent);
			}
			
		}
		
		return tempLineTool.arrayToPath(paths);
		
	},

	drawLine : function (line) {
		
		var global = com.workflowGraph.Global,
	
		tempLineTool = global.lineTool,
		
		path = tempLineTool.getPath(line),


		head = tempLineTool.getLineHead(path),
		end = tempLineTool.getLineEnd(path),
	
		self = this,
			
		headPoint1 = parseInt(head[0]) * self.widthPercent,
		headPoint2 = parseInt(head[1]) * self.heightPercent,
			
		endPoint1 = parseInt(end[0]) * self.widthPercent,
		endPoint2 = parseInt(end[1]) * self.heightPercent,
		
		brokenType = line.getAttribute("brokenType");


		path = self._smallPath(path);
		
		var lineObj = null;
		
		if (self.smallLineMap.get("small" + line.id) && $id("small" + line.id)) {

			lineObj = $id("small" + line.id);
			global.lineTool.setPath(lineObj, path, true);
			
		} else {
		
			if (tempLineTool.isSVG) {
			
				lineObj = document.createElementNS('http://www.w3.org/2000/svg', "path");
	    
	    	    lineObj.setAttribute("id", "small" + line.id);
	    	    lineObj.setAttribute("style", "fill:none; stroke:" + PathGlobal.lineColor + "; stroke-width:1");
	    	
	    	    global.lineTool.setPath(lineObj, path, true);
	    
	    	    self.svgBody.appendChild(lineObj);
	    
			} else if (tempLineTool.isVML) {

				lineObj = document.createElement('<v:shape id="small' + line.id + '" style="WIDTH:100;POSITION:absolute;HEIGHT:100" coordsize="100,100" filled="f" strokeweight="1px" strokecolor="' + PathGlobal.lineColor + '" path="' + path + '"></v:shape>'); 
				self.smallMap.appendChild(lineObj);
			
			}
			
			self.smallLineMap.put(lineObj.id, lineObj);
		
		}
	
	},

	drawAll : function () {
	
		var self = this;
		
		self.drawAllMode();
		self.drawAllLine();
		
	},

	drawAllMode : function () {
		
		var global = com.workflowGraph.Global;
		
		global.modeTool.forEach(function (modeId) {
			global.smallTool.drawMode($id(modeId));
		});
		
	},

	drawAllLine : function () {

		var global = com.workflowGraph.Global;
		
		global.lineTool.forEach(function (lineId) {
			global.smallTool.drawLine($id(lineId));
		});
		
	},

	removeAll : function () {
	
		var self = this;
		
		self.removeAllMode();
		self.removeAllLine();
	
	},

	removeAllMode : function () {
		com.workflowGraph.Global.modeTool.forEach(this.removeMode);
	},

	removeAllLine : function () {
		com.workflowGraph.Global.lineTool.forEach(this.removeLine);
	},

	removeMode : function (modeId) {
	
		var smallMode = $id("small" + modeId);
		this.smallModeMap.remove(smallMode.id)
		smallMode.parentNode.removeChild(smallMode);
		
	},

	removeLine : function (lineId) {
	
		var smallLine = $id("small" + lineId);
		smallLine.parentNode.removeChild(smallLine);
		
	},

	clear : function () {
		this.forEachMode(this.clearMode);
	},

	clearMode : function (node) {
			
		if (node) {
				
			if (node.id.indexOf("module") > 0) {
				node.style.border = "none";
			}
				
		}
		
	},

	forEachMode : function (fn) {
	
		var self = this;
		var mapLength = self.smallMap.childNodes.length;
		
		for (var i = mapLength; i--;) {
			
			if (fn) {
				fn(self.smallMap.childNodes[i]);
			}
			
		}
		
	},

	initDraw : function () {
	
		var self = this;
		
		self.removeAll();
		self.initPercent();
		self.drawAll();
		
	}

}
var ControlTool = com.workflowGraph.ControlTool = function (mainBody) {
	
	var self = this,
	doc = document;
	self.mainBody = mainBody;
	self.indexId;
	
	var inputFunction = function (inputText, isNoStyle) {
		
		inputText.onkeydown = function (event) {
			
			event = event || window.event;
			
			if (event.keyCode == 13) {
				self.submit();
			}
			
		}
		
		if (isNoStyle) {
			return;
		}
		
		inputText.setAttribute("class", "inputComm");
		inputText.setAttribute("className", "inputComm");
		
		inputText.onclick = function () {
		
			this.setAttribute("class", "inputClick");
			this.setAttribute("className", "inputClick");
		
		}
	
		inputText.onblur = function () {
		
			this.setAttribute("class", "inputComm");
			this.setAttribute("className", "inputComm");
	
		}
		
	}
	
	self.inputTitle = $id("inputTitle");
	inputFunction(self.inputTitle);
	
	self.inputWidth = $id("inputWidth");
	inputFunction(self.inputWidth);
	
	self.inputHeight = $id("inputHeight");
	inputFunction(self.inputHeight);
	
	self.inputTop = $id("inputTop");
	inputFunction(self.inputTop);
	
	self.inputLeft = $id("inputLeft");
	inputFunction(self.inputLeft);
	
	self.inputImgSrc = $id("inputImgSrc");
	inputFunction(self.inputImgSrc);
	
	self.modeContent = $id("modeContent");
	inputFunction(self.modeContent, true);
	
}

ControlTool.prototype = {
	
	submit : function () {

		var global = com.workflowGraph.Global,
		    tempControlTool = global.controlTool;

		if (!$id("module" + tempControlTool.indexId) || !$id("line" + tempControlTool.indexId)) {
            console.log(tempControlTool.indexId);
			return;
		}


		var mode = $id("module" + tempControlTool.indexId),
		modeStyle = mode.style,

        line = $id("line" + tempControlTool.indexId),

		img = $id("backImg" + tempControlTool.indexId),
		imgStyle = img.style,
		
		content = $id("content" + tempControlTool.indexId),
		contentStyle = content.style,
		
		title = $id("title" + tempControlTool.indexId),
		titleStyle = title.style,
		
		modeWidth = parseInt(mode.offsetWidth),
		modeHeight = parseInt(mode.offsetHeight),
		modeTop = parseInt(modeStyle.top),
		modeLeft = parseInt(modeStyle.left),
		
		imgWidth = parseInt(img.offsetWidth),
		imgHeight = parseInt(img.offsetHeight),
		imgTop = parseInt(imgStyle.top),
		imgLeft = parseInt(imgStyle.left),
		imgSrc = img.src,
		
		contentWidth = parseInt(content.offsetWidth),
		contentHeight = parseInt(content.offsetHeight),
		contentTop = parseInt(contentStyle.top),
		contentLeft = parseInt(contentStyle.left),
		
		modeContent = mode.getAttribute("modeContent"),
		
		titleInnerHTML = title.innerHTML,
		
		tempModeTool = global.modeTool;



		var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
	
			if (modeWidth) {
				modeStyle.width = modeWidth + "px";
			}
			
			if (modeHeight) {
				modeStyle.height = modeHeight + "px";
			}
			
			if (modeTop) {
				modeStyle.top = modeTop + "px";
			}
			
			if (modeLeft) {
				modeStyle.left = modeLeft + "px";
			}
		
			if (imgWidth) {
				imgStyle.width = imgWidth + "px";
			}
			
			if (imgHeight) {
				imgStyle.height = imgHeight + "px";
			}
			
			if (imgTop) {
				imgStyle.top = imgTop + "px";
			}
			
			if (imgLeft) {
				imgStyle.left = imgLeft + "px";
			}
			
			if (imgSrc) {
				img.src = imgSrc;
			}
			
			if (contentWidth) {
				contentStyle.width = contentWidth + "px";
			}
			
			if (contentHeight) {
				contentStyle.height = contentHeight + "px";
			}
			
			if (contentTop) {
				contentStyle.top = contentTop + "px";
			}
			
			if (contentLeft) {
				contentStyle.left = contentLeft + "px";
			}
			
			if (modeContent) {
				mode.setAttribute("modeContent", modeContent);
			}
			
			tempModeTool.showPointer(mode);
			tempModeTool.changeBaseModeAndLine(mode, true);
			
			title.innerHTML = titleInnerHTML;
			
			global.smallTool.drawMode(mode);
				
		}, PathGlobal.updateMode);
		
		modeStyle.width = tempControlTool.inputWidth.value + "px";
		modeStyle.height = tempControlTool.inputHeight.value + "px";
		modeStyle.top = tempControlTool.inputTop.value + "px";
		modeStyle.left = tempControlTool.inputLeft.value + "px";
		
		imgStyle.width = tempControlTool.inputWidth.value + "px";
		imgStyle.height = tempControlTool.inputHeight.value + "px";
		imgStyle.top = tempControlTool.inputTop.value + "px";
		imgStyle.left = tempControlTool.inputLeft.value + "px";
		img.src = tempControlTool.inputImgSrc.value;
		
		contentStyle.width = tempControlTool.inputWidth.value + "px";
		contentStyle.height = tempControlTool.inputHeight.value + "px";
		contentStyle.top = tempControlTool.inputTop.value + "px";
		contentStyle.left = tempControlTool.inputLeft.value + "px";

		mode.setAttribute("modeContent", tempControlTool.modeContent.value);
        mode.setAttribute("nodeName", tempControlTool.inputTitle.value);
		
		tempModeTool.isModeCross(mode);
	    tempModeTool.changeBaseModeAndLine(mode, true);
	  
		title.innerHTML = "";
		
		tempModeTool.flip(tempModeTool.getModeIndex(mode), tempControlTool.inputTitle.value);
		
	    global.smallTool.drawMode(mode);
	  
	    var afterModeWidth = parseInt(mode.offsetWidth),
		    afterModeHeight = parseInt(mode.offsetHeight),
		    afterModeTop = parseInt(modeStyle.top),
		    afterModeLeft = parseInt(modeStyle.left),
		
		    afterImgWidth = parseInt(img.offsetWidth),
		    afterImgHeight = parseInt(img.offsetHeight),
		    afterImgTop = parseInt(imgStyle.top),
		    afterImgLeft = parseInt(imgStyle.left),
		    afterImgSrc = img.src,
		
		    afterContentWidth = parseInt(content.offsetWidth),
		    afterContentHeight = parseInt(content.offsetHeight),
		    afterContentTop = parseInt(contentStyle.top),
		    afterContentLeft = parseInt(contentStyle.left),
		
		    afterModeContent = tempControlTool.modeContent.value,
		
		    afterTitleInnerHTML = tempControlTool.inputTitle.value;
	  
	        undoRedoEvent.setRedo(function () {
			
                modeStyle.width = afterModeWidth + "px";
                modeStyle.height = afterModeHeight + "px";
                modeStyle.top = afterModeTop + "px";
                modeStyle.left = afterModeLeft + "px";

                imgStyle.width = afterImgWidth + "px";
                imgStyle.height = afterImgHeight + "px";
                imgStyle.top = afterImgTop + "px";
                imgStyle.left = afterImgLeft + "px";
                img.src = afterImgSrc;

                contentStyle.width = afterContentWidth + "px";
                contentStyle.height = afterContentHeight + "px";
                contentStyle.top = afterContentTop + "px";
                contentStyle.left = afterContentLeft + "px";

                mode.setAttribute("modeContent", afterModeContent);

                tempModeTool.showPointer(mode);
                tempModeTool.changeBaseModeAndLine(mode, true);

                title.innerHTML = afterTitleInnerHTML;

                global.smallTool.drawMode(mode);
	    	
		});
	
	},
	
	reBack : function () {
	},
	
	print : function (indexId) {

	
		var mode = $id("module" + indexId),
		modeStyle = mode.style,
		
		img = $id("backImg" + indexId),
		title = $id("title" + indexId),
		
		self = this;
		
		self.indexId = indexId;
		
		self.inputWidth.value = parseInt(mode.offsetWidth) - 2;
		self.inputHeight.value = parseInt(mode.offsetHeight) - 2;
		self.inputTop.value = parseInt(modeStyle.top);
		self.inputLeft.value = parseInt(modeStyle.left);
		self.inputImgSrc.value = img.src;
		self.inputTitle.value = title.innerHTML;
		self.modeContent.value = mode.getAttribute("modeContent") || '';
	}

}
com.workflowGraph.Global = {};

function $id(id) {
	return document.getElementById(id);
}

var stopEvent = false;

String.prototype.replaceAll = function stringReplaceAll (aFindText, aRepText) {
	
	raRegExp = new RegExp(aFindText, "g");
	return this.replace(raRegExp, aRepText);

}

function message(messageStr, isClear) {
	
	var message = $id("message");
		
	if (isClear) {
		message.innerHTML = messageStr;
	} else {
		message.innerHTML += messageStr;
	}
		
}
var ContextXML = com.workflowGraph.ContextXML = function () { }

ContextXML.prototype = {
	
	setAttribute : function (name, value) {
		this[name] = value;
	},
	
	view : function () {
		var self = this,
		
		contextDiv = document.createElement("div");
		
		for (var item in self) {
			if (item == "view" || 
					item == "setAttribute" || 
					item == "style" || 
					item == "modeIds" ||
					item == "lineIds") {
				continue;	
			}
			contextDiv.setAttribute(item, self[item]);
		}
		
		var global = com.workflowGraph.Global,
		tempModeTool = global.modeTool,
		tempBaseTool = global.baseTool,
		
		contextMap = tempBaseTool.contextMap,
		contextModeMap = new Map(),
		contextLineMap = new Map(),
		
		modeIds = self.modeIds.split(","),
		modeIdsLength = modeIds.length;
		
		for (var i = modeIdsLength; i--;) {
			var modeId = modeIds[i];
			contextModeMap.put(modeId, $id(modeId));
		}
		
		var lineIds = self.lineIds.split(","),
		lineIdsLength = lineIds.length;
		
		for (var i = lineIdsLength; i--;) {
			var lineId = lineIds[i];
			contextLineMap.put(lineId, $id(lineId));
		}
		
		function contextEntry (modeMap, lineMap) {
			this.contextModeMap = modeMap;
			this.contextLineMap = lineMap;
		}
		
		var contextEntry  = new contextEntry(contextModeMap, contextLineMap);
		contextMap.put(self.id, contextEntry);
		contextDiv.style.cssText = self.style;
		
		var tempBaseTool = global.baseTool;
		
		tempBaseTool.pathBody.appendChild(contextDiv);
		tempBaseTool.contextDivDrag(contextDiv, contextEntry);
		
	}
}

var LineXML = com.workflowGraph.LineXML = function () {}

LineXML.prototype = {
	
	_lineAttrProp : "attr_prop_",
	
	setAttribute : function (name, value) {

		if (name.indexOf(this._lineAttrProp) > -1) {
			
			if (this['prop'] == null) {
				this['prop'] = {};
			}
			
			name = name.substring(this._lineAttrProp.length);
			this['prop'][name] = value;
			
		} else {
			this[name] = value;
		}
		
	},
	
	view : function () {
	
		var self = this,
		global = com.workflowGraph.Global,		
		tempLineTool = global.lineTool,
		
		line = tempLineTool.createBaseLine(self.id, self.d || self.path, self.brokenType),
		
		lineMode = new BuildLine();
		lineMode.id = line.id;
		
		if (this['prop']) {
			lineMode.prop = this['prop'];
		}
		
		line.style.cssText = self.style;
		line.setAttribute("strokeweight", self.strokeweight);
		line.setAttribute("strokecolor", self.strokecolor);
		line.setAttribute("brokenType", self.brokenType);
		
		var tempModeTool = global.modeTool,
				tempBeanXml = global.beanXml;
		
		if (self.xBaseMode) {
			
			var xDelay = function () {
				
				var xMode = global.modeMap.get(self.xBaseMode);
			
				lineMode.xBaseMode = xMode;
				lineMode.xIndex = self.xIndex;
				
				var modeLine = new BuildLine();
				modeLine.id = self.id;
				modeLine.type = true;
				modeLine.index = self.xIndex;
			
				xMode.lineMap.put(self.id + "-true", modeLine);
			
			}
			
			if (global.modeMap.get(self.xBaseMode)) {
				xDelay();
			} else {
				tempBeanXml.delay[tempBeanXml.delayIndex++] = xDelay;
			}
			
		}
		
		if (self.wBaseMode) {
			
			var yDelay = function () {
			
				var yMode = global.modeMap.get(self.wBaseMode);
			
				lineMode.wBaseMode = yMode;
				lineMode.wIndex = self.wIndex;
				
				var modeLine = new BuildLine();
				modeLine.id = self.id;
				modeLine.type = false;
				modeLine.index = self.wIndex;
				
				yMode.lineMap.put(self.id + "-false", modeLine);
			
			}
			
			if (global.modeMap.get(self.wBaseMode)) {
				yDelay();
			} else {
				tempBeanXml.delay[tempBeanXml.delayIndex++] = yDelay;
			}
			
		}
		
		global.smallTool.drawLine(line);
		global.lineMap.put(lineMode.id, lineMode);
		
		tempLineTool.baseLineIdIndex = parseInt(self.id.substring(4)) + 1;
		
	}

}

var ModeXML = com.workflowGraph.ModeXML = function () {
	
	var self = this,
	tempModeTool = com.workflowGraph.Global.modeTool;
	
	self.modeDiv = tempModeTool.createBaseMode(0, 0, "", 0, "50px", "50px");
	self.backImg = tempModeTool.getSonNode(self.modeDiv, "backImg");
	self.title = tempModeTool.getSonNode(self.modeDiv, "title");
	
}

ModeXML.prototype = {
	
	_modeAttrProp : "attr_prop_",
	
	setAttribute : function (name, value) {
	
		var self = this;
		
		if (name == "backImgSrc") {
			self.backImg.src = value;
		} else if (name == "top") {
			self.modeDiv.style.top = value + "px";
		} else if (name == "left") {
			self.modeDiv.style.left = value + "px";
		} else if (name == "width") {
			self.modeDiv.style.widht = value + "px";
			self.backImg.style.width = value + "px";
		} else if (name == "height") {
			self.modeDiv.style.height = value + "px";
			self.backImg.style.height = value + "px";
		} else if (name == "id") {
			com.workflowGraph.Global.modeTool.setIndex(self.modeDiv, value);
		} else if (name == "title") {
			self.title.innerHTML = value;
		} else if (name == "zIndex") {
			self.modeDiv.style.zIndex = value;
		} else if (name.indexOf(this._modeAttrProp) > -1) {
			
			if (this['prop'] == null) {
				this['prop'] = {};
			}
			
			name = name.substring(this._modeAttrProp.length);
			this['prop'][name] = value;
			
		} else {
			self.modeDiv.setAttribute(name, value);
		}
		
	},
	
	view : function () {
	
		var mode = new BaseMode(),
		moduleDiv = this.modeDiv,
		
		global = com.workflowGraph.Global,
		
		tempModeTool = global.modeTool;
		tempModeTool.pathBody.appendChild(moduleDiv);
		
		var modeIndex = tempModeTool.getModeIndex(moduleDiv);
		
		mode.id = moduleDiv.id;
		
		if (this['prop']) {
			mode.prop = this['prop'];
		}
		
		global.modeMap.put(mode.id, mode);
		
		tempModeTool.initEvent(modeIndex);
		tempModeTool.showPointerId(modeIndex);
		tempModeTool.hiddPointer(moduleDiv);
		
		global.smallTool.drawMode(moduleDiv);
		
		tempModeTool.baseModeIdIndex = parseInt(modeIndex) + 1;
		
	}

}

var BeanXML = com.workflowGraph.BeanXML = function () {
	
	var self = this;
	
	self.delay = [];
	self.delayIndex = 0;
	self.doc = null;
	self.create();
	self.root = self.initBeanXML();
	
}

BeanXML.prototype = {
	
	create : function () {
	
		var self = this;
		self.doc = null;
		
		if (document.all) {
			
			var xmlVersions = ["Msxml2.DOMDocument.6.0",
								"Msxml2.DOMDocument.5.0", 
								"Msxml2.DOMDocument.4.0", 
								"Msxml2.DOMDocument.3.0", 
								"MSXML2.DOMDocument", 
								"MSXML.DOMDocument", 
								"Microsoft.XMLDOM"];
												 
			var xmlVersionLength = xmlVersions.length;
			
			for (var i = xmlVersionLength; i--;) {
				
				try {
					self.doc = new ActiveXObject(xmlVersions[i]);
					break;
				} catch (err) {
					continue;
				}
				
			}
		
		} else {
			self.doc =  document.implementation.createDocument('', '', null);
		}
		
	},

	initBeanXML : function () {
 	
	 	var self = this,
	 	
		headFile = self.doc.createProcessingInstruction("xml", "version='1.0' encoding='utf8'");
		self.doc.appendChild(headFile);
	  		
		var root = self.doc.createElement("modes");
		self.doc.appendChild(root);
		
		return root;
	 	
	},

	getNodeAttribute : function (iNode) {
	
		var nodeText = [],
		k = 0,
				
		attributes = iNode.attributes,
		attributesLength = attributes.length;
				
		for (var i = attributesLength; i--;) {
					
			var attribute = attributes[i];
			
			nodeText[k++] = " ";		
			nodeText[k++] = attribute.nodeName;
			nodeText[k++] = "=\"";
			nodeText[k++] = attribute.nodeValue;
			nodeText[k++] = "\"";
	
		}
		
		return nodeText.join("");
			
	},

	getText : function (iNode, isTitle) {
	
		var nodeText = [],
		k = 0,
		
		self = this;
		
		if (isTitle) {
			
			nodeText[k++] = "<";
			nodeText[k++] = iNode.nodeName;
		
		}
	
		var childNodes = iNode.childNodes,
		childNodesLength = childNodes.length;
		
		for (var i = childNodesLength; i--;) {
			
			var node = childNodes[i];
			
			nodeText[k++] = "<";
			nodeText[k++] = node.nodeName;
			
			if (node.nodeType == 1) {
				nodeText[k++] = self.getNodeAttribute(node);
			}
			
			nodeText[k++] = ">";
			
			if (node.hasChildNodes()) {
				nodeText[k++] = self.getText(node, false);
			} 
			
			nodeText[k++] = "</";
			nodeText[k++] = node.nodeName;
			nodeText[k++] = ">";
			
	  }
	  
	  if (isTitle) {
	  	
	  	nodeText[k++] = "</";
			nodeText[k++] = iNode.nodeName;
			nodeText[k++] = ">";
	  
		}
		
		return nodeText.join("");
		
	},

	createNode : function (type, fNode) {
 	
	 	var self = this,
	 	
		node = self.doc.createElement(type);
	    
		if (fNode) {
			fNode.appendChild(node);
		} else {
			self.root.appendChild(node);
		}
	    
		return node;
	
	},

	clearNode : function () {
	
		var self = this;
		
		if (self.root) {
			
			var childNodes = self.root.childNodes,
			childNodesLength = childNodes.length;
		
			for (var i = childNodesLength; i--;) {
			
				self.root.removeChild(childNodes[i]);	
			
			}
			
		}	
		
	},
	
	_formatValue : function (value) {
		
		value = value.replaceAll("&", "&amp;");
		value = value.replaceAll("'", "&apos;");
		value = value.replaceAll('"', "&quot;");
		value = value.replaceAll('>', "&gt;");
		value = value.replaceAll('<', "&lt;");
		
		return value;
		
	},

	toXML : function () {

		var self = this;
		self.clearNode();
		
		var global = com.workflowGraph.Global,
		
		tempBaseTool = global.baseTool,
		contextMap = tempBaseTool.contextMap;
		
		tempBaseTool.forEach(contextMap, function (contextId) {
			
			var node = self.createNode("context"),
			context = $id(contextId),
			
			attributes = context.attributes,
			attributeLength = attributes.length;
			
			for (var i = attributeLength; i--;) {
				
				var attribute = attributes[i];
							
				if (attribute.nodeValue) {
					node.setAttribute(attribute.name, attribute.nodeValue);
				}
				
			}



			node.setAttribute("style", context.style.cssText);
			
			var contextEntry = contextMap.get(contextId),
					
					contextModeMap = contextEntry.contextModeMap,
					contextLineMap = contextEntry.contextLineMap,
					
					contextModeMapKeys = contextModeMap.getKeys(),
					contextLineMapKeys = contextLineMap.getKeys(),
					
					contextModeMapKeyLength = contextModeMapKeys.length,
					contextLineMapKeyLength = contextLineMapKeys.length,
					
					modeIds = [],
					lineIds = [],
					index = 0;
			
			for (var i = contextModeMapKeyLength; i--;) {
				modeIds[index++] = contextModeMapKeys[i];
			}
			
			node.setAttribute("modeIds", modeIds.join(","));
			index = 0;
			
			for (var i = contextLineMapKeyLength; i--;) {
				lineIds[index++] = contextLineMapKeys[i];
			}
			
			node.setAttribute("lineIds", lineIds.join(","));
			
		});
		
		tempBaseTool.forEach(global.modeMap, function (modeId) {

            var modeObj = global.modeMap.get(modeId);
            var modeProp = modeObj['prop'];
			var mode = $id(modeId),
			modeStyle = mode.style,
			attributes = mode.attributes,
			attributeLength = attributes.length,
            //Billy 2014-7-22 begin
            //node = self.createNode(modeProp.nodeName);
            node = self.createNode("mode");
		    //Billy 2014-7-22 end

			for (var i = attributeLength; i--;) {
				var attribute = attributes[i];
				if (attribute.name == 'style' || attribute.name == 'id') {
					continue;
				}
				if (attribute.nodeValue) {
					node.setAttribute(attribute.name, attribute.nodeValue);
				}
			}
		    //Billy 2014-7-22 begin
		    /*
			for (var modeKey in modeProp) {
                if (modeKey != "nodeName") {
                    node.setAttribute(modeKey, modeProp[modeKey]);
                }
			}
            */

			//var p = c.modeMap.get(u);
			var modeObj = global.modeMap.get(modeId);

			//var t = p.prop;
			var modeProp = modeObj.prop;

			//for (var f in t) {
			//    h.setAttribute("attr_prop_" + f, t[f])
			//}
			for (var modeKey in modeProp) {
			    node.setAttribute("attr_prop_" + modeKey, modeProp[modeKey])
			}

		    //var s = c.modeTool.getModeIndex(o);
			var modeIndex = global.modeTool.getModeIndex(mode);
		    //h.setAttribute("id", s);
			node.setAttribute("id", modeIndex);
		    //var r = $id("title" + s).innerHTML;
			var title = $id("title" + modeIndex).innerHTML;
			//h.setAttribute("title", r);
			node.setAttribute("title", title);
		    //var q = $id("backImg" + s),n = q.src;
			var backImg = $id("backImg" + modeIndex), backImgSrc = backImg.src;
			//h.setAttribute("backImgSrc", n);
			node.setAttribute("backImgSrc", backImgSrc);
		    //h.setAttribute("top", parseInt(m.top));
			node.setAttribute("top", parseInt(modeStyle.top));
			node.setAttribute("left", parseInt(modeStyle.left));
			node.setAttribute("zIndex", parseInt(modeStyle.zIndex));

		    //h.setAttribute("width", parseInt(q.offsetWidth));
			node.setAttribute("width", parseInt(backImg.offsetWidth));
			node.setAttribute("height", parseInt(backImg.offsetHeight))
		    //Billy 2014-7-22 end
		});
		
		tempBaseTool.forEach(global.lineMap, function (lineId) {
			
			var line = $id(lineId),
			
			node = self.createNode("line"),
			attributes = line.attributes,
			attributeLength = attributes.length,
			lineStyle = line.style;
			
			var strokeweight = line.getAttribute("strokeweight"),
					strokecolor = line.getAttribute("strokecolor");
			
			node.setAttribute("strokeweight", strokeweight || lineStyle.strokeWidth);
			node.setAttribute("strokecolor", strokecolor || lineStyle.stroke);
			
			for (var i = attributeLength;i--;) {
				
				var attribute = attributes[i];
				
				if (attribute.name == 'style' ||
						attribute.name == 'marker-end') {
					continue;
				}
				
				if (attribute.nodeValue) {
					node.setAttribute(attribute.name, attribute.nodeValue);
				}
			}
			
			var cssText = lineStyle.strokeWidth ? '' : ';fill: none; stroke: ' + strokecolor + '; stroke-width: ' + (strokeweight + 0.45);
			
			node.setAttribute("style", lineStyle.cssText + cssText);
			node.setAttribute("marker-end", "url(#arrow)");
			
			var buildLine = global.lineMap.get(line.id);
			
			for (var item in buildLine) {
				
				if (item === "prop") {
					continue;
				}
				
				if (typeof(buildLine[item]) == "string" || 
							typeof(buildLine[item]) == "number") {
					node.setAttribute(item, buildLine[item]);
				} else if (typeof(buildLine[item]) == "object") {
					node.setAttribute(item, buildLine[item] && buildLine[item].id ? buildLine[item].id : '');
				} else {
					node.setAttribute(item, buildLine[item] + " is unSupport");
				}
				
			}
			
			if (buildLine && buildLine['prop']) {
				
				var prop = buildLine['prop'];
				
				for (var key in prop) {
					node.setAttribute("attr_prop_" + key, prop[key]);
				}
				
			}
			
		});
		
		var textXml = self.getTextXml(self.doc);
		
	    //self.viewTextXml(textXml);
		return textXml;
		
	},
	
	loadXmlText : function () {
		
		if (document.all && window.ActiveXObject) {
			var self = this;
			return function(xml) {
					
				var xmlVersions = ["Msxml2.DOMDocument.6.0",
								   "Msxml2.DOMDocument.5.0", 
								   "Msxml2.DOMDocument.4.0", 
								   "Msxml2.DOMDocument.3.0", 
								   "MSXML2.DOMDocument", 
								   "MSXML.DOMDocument", 
								   "Microsoft.XMLDOM"];
												 
				var xmlVersionLength = xmlVersions.length;
				var result = null;
				
				for (var i = xmlVersionLength; i--;) {
				
					try {
						result = new ActiveXObject(xmlVersions[i]);
						break;
					} catch (err) {
						continue;
					}
				}
				
				result.async = 'false';
				result.loadXML(xml);
				
				return result;
			};
		} else {
			return function(xml) { 				
				return new DOMParser().parseFromString(xml, 'text/xml');
			};
		}
		
	}(),
	
	viewTextXml : function (textXml) {
			
		textXml = textXml.replaceAll("<", "&lt").replaceAll(">", "&gt");

		var viewHTML = window.open('saveXml.html', '', ''),
		i = 0,
		viewHTMLBuffer = [];
		
		viewHTMLBuffer[i++] = '<html>';
		viewHTMLBuffer[i++] = '<head>';
		viewHTMLBuffer[i++] = '<link href="css/flowPath.css" type="text/css" rel="stylesheet" />';
		viewHTMLBuffer[i++] = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
		viewHTMLBuffer[i++] = '<title></title>';
		viewHTMLBuffer[i++] = '</head>';
		viewHTMLBuffer[i++] = '<body>';
		
		viewHTMLBuffer[i++] = textXml;
		
		viewHTMLBuffer[i++] = '</body></html>';
		
		viewHTML.document.write(viewHTMLBuffer.join(""));
	
		viewHTML.document.close();

	},
	
	getTextXml : function (node) {
	
		var xml = '';
	
		if (node) {
		
			xml = node.xml;
		
			if (!xml) { 
			
				if (node.innerHTML) {
					xml = node.innerHTML;
				} else {
				
					var xmlSerializer = new XMLSerializer();
					xml = xmlSerializer.serializeToString(node);
			
				}
		
			} else {
				xml = xml.replace(/\r\n\t[\t]*/g, '').replace(/>\r\n/g, '>').replace(/\r\n/g, '\n');
			}
	
		}
	
		xml = xml.replace(/\n/g, '');
		
		xml = this._formatValue(xml);
	
		return xml;

	},

	clearHTML : function () {
		
		var global = com.workflowGraph.Global;
		
		global.undoRedoEventFactory.clear();
		global.lineTool.removeAll();
		global.modeTool.removeAll()
		global.baseTool.removeAll();
		
	},

	toHTML : function () {
	
		var self = this;
		
		self.clearHTML();
		
		if (!self.doc) {
			return;
		}
		
		var docChildNodes = self.doc.childNodes,
		docChildNodesLength = docChildNodes.length;
		
		for (var i = docChildNodesLength; i--;) {
			
			if (docChildNodes[i].nodeName == 'modes') {
				self.root = self.doc.childNodes[i];
				break;
			}
			
		}
		
		if (self.root) {
			
			var childNodes = self.root.childNodes,
			childNodesLength = childNodes.length;
		
			for (var i = childNodesLength; i--;) {
			
				var node = childNodes[i],
				nodeName = node.nodeName,
				
				attributes = node.attributes,
				attributesLength = attributes.length,
				
				xml;
				
				if (nodeName == "mode") {
					xml = new ModeXML();
				} else if (nodeName == "line") {
					xml = new LineXML();
				}	else if (nodeName == "context") {
					xml = new ContextXML();
				}
				
				for (var j = attributesLength; j--;) {
					
					var attribute = attributes[j];
					xml.setAttribute(attribute.name, attribute.value);
					
				}
				
				xml.view();
			
			}
			
			var delays = self.delay,
			delayLength = delays.length;
			
			for (var i = delayLength; i--;) {
				delays[i]();
			}
			
			delete self.delay;
			
			self.delay = [];
			self.delayIndex = 0;
			
		}	
		
	}

}
var client = com.workflowGraph.ClientTool = function (options) {
	
	this.dialog = $('#' + options.prop);
	$id(options.prop).style.width = options.dialogWidth || 328 + "px"

}

client.prototype = {
	
	_deepCopyProp : function (orgProp) {
		
		var newProp = {};
		
		for (var key in orgProp) {
			newProp[key] = orgProp[key];
		}
		
		return newProp;
		
	},
	
	_isDiffJson : function (oneJson, twoJson) {
		
		var diff = false;
		
		for (var key in oneJson) {
			
			if (oneJson[key] !== twoJson[key]) {
				diff = true;
				break;
			}
			
		}
		
		return diff;
		
	},
	
	_close : function (event) {
		
		var panelClose = $(".panel-tool-close");
		
		if (panelClose.length > 0) {
			panelClose = panelClose[0];
			panelClose.click(event);
		}
	
	},
	
	showDialog : function (event, title, obj) {
		
		var orgProp = this._deepCopyProp(obj.prop),
				self = this;
		
		this.dialog.dialog({
			
			title : title,
    	    modal : true,
    	    _attri_prop : null,

            buttons : [
                {
                    text : 'ok',
                    handler: function() {

                        var prop = obj.prop;

                        for (var key in prop) {
                            if (key !="nodeName") {
                                var inputText = $id("lineAttr_" + key);
                                prop[key] = inputText.value;
                            }
                        }
                        self._close(event);

                        var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
                            obj.prop = orgProp;
                        }, PathGlobal.editProp);

                        undoRedoEvent.setRedo(function () {
                            obj.prop = prop;
                        });

                    }
                },
                {
                    text : 'rest',
                    handler : function() {

                        var prop = obj.prop = orgProp;

                        for (var key in prop) {

                            var inputText = $id("lineAttr_" + key);
                            inputText.value = prop[key];

                        }

                    }
                }
            ]
    	
		}); 
	
	},

    showSettingDialog : function(event, title, obj) {
        var orgProp = this._deepCopyProp(obj.prop),
            self = this;

        this.dialog.dialog({

            title : title,
            modal : true,
            _attri_prop : null,

            buttons : [
                {
                    text : 'ok',
                    handler: function() {

                        obj.prop = {};
                        console.log(obj);
                        var prop = {};
                        var attrs = document.getElementById("attrs").getElementsByTagName("input");
                        var mode = document.getElementById(obj.id);
                        for (var i = 0; i < attrs.length; i++) {
                            prop[attrs[i].value] = "";
                        }
                        prop["nodeName"] = mode.getAttribute("nodeName");
                        obj.prop = prop;
                        self._close(event);

                        var undoRedoEvent = new com.workflowGraph.UndoRedoEvent(function () {
                            obj.prop = orgProp;
                        }, PathGlobal.editProp);

                        undoRedoEvent.setRedo(function () {
                            obj.prop = prop;
                        });

                    }
                },
                {
                    text : 'rest',
                    handler : function() {
                        var attrs = document.getElementById("attrs")
                        attrs.innerHTML = "";
                    }
                }
            ]

        });
    },
    //*************************************************
    addProItem: function(prop,value) {
        //var c = document,d = c.createElement("div");
        var doc = document,
				contextDiv = doc.createElement("div");

        //var b = "<table>";
        var context = '<table>';


        //for (var a in e) {
        //    b += '<tr><td align="right">&nbsp;' + e[a] + '&nbsp;:&nbsp;</td><td><input type="text" id="lineAttr_' + a + '" value="' + value[a] + '" /></td></tr>'
        //}

        for (var key in prop) {

            if (key != "nodeName") {
                context += '<tr><td align="right">&nbsp;' + prop[key] + '&nbsp;:&nbsp;</td><td><input type="text" id="lineAttr_' + key + '" value="' + prop[key] + '" /></td></tr>';
            }
        }

        //b += "</table>";
        context += '</table>';

        //d.innerHTML = b;
        contextDiv.innerHTML = context;
        //return d
        return contextDiv;
    },
    //*************************************************

	/*
	addProItem : function (prop) {
		
		var doc = document,
				contextDiv = doc.createElement("div");
		
		var context = '<table>';
		
		for (var key in prop) {

            if (key != "nodeName") {
                context += '<tr><td align="right">&nbsp;' + key + '&nbsp;:&nbsp;</td><td><input type="text" id="lineAttr_' + key + '" value="' + prop[key] + '" /></td></tr>';
            }
		}
		
		context += '</table>';
		
		contextDiv.innerHTML = context;
		
		return contextDiv;
		
	},
    */
    addProSetting : function() {
        var doc = document,
            contextDiv = doc.createElement("div");

        var button = '<button id="addAttr" onclick="graphUtils.addAttr()">添加属性</button><div id="attrs"></div>';
        contextDiv.innerHTML = button;

        return contextDiv;
    }
	
}
var Utils = com.workflowGraph.Utils = {
	
	create : function (options) {
		
		this.global = com.workflowGraph.Global;
		
		this.global.modeMap = new com.workflowGraph.Map();
  	    this.global.lineMap = new com.workflowGraph.Map();
  	    this.global.beanXml = new com.workflowGraph.BeanXML();

		var contextBody = options.contextBody,
		contextBodyDiv = $id(contextBody),
		contextWidth = options.width,
		contextHeight = options.height;
		
		this.global.baseTool = new com.workflowGraph.BaseTool(contextBodyDiv, contextWidth, contextHeight);
		this.global.modeTool = new com.workflowGraph.ModeTool(contextBodyDiv);
		this.global.lineTool = new com.workflowGraph.LineTool(contextBodyDiv);
		this.global.clientTool = new com.workflowGraph.ClientTool(options);
		
		var smallMap = options.smallMap;
		this.global.smallTool = new com.workflowGraph.SmallMapTool(smallMap, contextBody);
		
		var mainControl = $id(options.mainControl);
		this.global.controlTool = new com.workflowGraph.ControlTool(mainControl);
		
		var historyMessage = options.historyMessage;
		this.global.undoRedoEventFactory = new com.workflowGraph.UndoRedoEventFactory(historyMessage);
		this.global.undoRedoEventFactory.init();
		
		return this;
		
	}, 
	
	showLinePro : function () {
		this.global.lineTool.showProperty();
	},

    setLinePro : function() {
        this.global.lineTool.getProperty();
    },
	
	showModePro : function () {
		this.global.modeTool.showProperty();
	},

    setModePro : function() {
        this.global.modeTool.setProperty();
    },
	
	toMerge : function () {
		this.global.baseTool.toMerge();
	},
	
	toSplit : function () {
		this.global.baseTool.toSeparate()
	},
	
	toTop : function () {
		this.global.modeTool.toTop();
	},
	
	toBottom : function () {
		this.global.modeTool.toBottom();
	},
	
	printView : function () {
		this.global.baseTool.printView();
	},
	
	undo : function () {
		this.global.undoRedoEventFactory.undo();
	},
	
	redo : function () {
		this.global.undoRedoEventFactory.redo();
	},
	
	saveXml : function () {
		return this.global.beanXml.toXML();
	},
	
	loadXml : function () {
		this.global.beanXml.toHTML();
	},
	
	loadTextXml : function (textXml) {
		
		this.global.beanXml.doc = null;
		this.global.beanXml.doc = this.global.beanXml.loadXmlText(textXml);
		
		this.loadXml();
	
	},
	
	clearHtml : function () {
		this.global.beanXml.clearHTML();
	},
	
	copyNode : function () {
		keyDownFactory.copyNode();
	},
	
	removeNode : function () {
		keyDownFactory.removeNode();
	},
	
	alignLeft : function () {
		
		this.global.baseTool.toLeft();
		this.global.baseTool.clearContext();
	
	},

	alignRight : function () {
		
		this.global.baseTool.toRight();
		this.global.baseTool.clearContext();
		
	},
	
	verticalCenter : function () {
		
		this.global.baseTool.toMiddleWidth();
		this.global.baseTool.clearContext();
	
	},
	
	alignTop : function () {
		
		this.global.baseTool.toTop();
		this.global.baseTool.clearContext();
		
	},
	
	horizontalCenter : function () {
		
		this.global.baseTool.toMiddleHeight();
		this.global.baseTool.clearContext();
	
	},
	
	bottomAlignment : function () {
		
		this.global.baseTool.toBottom();
		this.global.baseTool.clearContext();
		
	},
	
	nodeDrag : function (node, isLine, lineType) {
		this.global.baseTool.drag(node, isLine, lineType);
	},
	
	closeAutoLineType : function () {
		PathGlobal.isAutoLineType = false;
	},
	
	openAutoLineType : function () {
		PathGlobal.isAutoLineType = true;
	},

    addAttr : function() {
        this.global.lineTool.addInputItem();
    },

    delAttr : function(obj) {
        this.global.lineTool.delAttr(obj);
    }

}
