/*
 COPYRIGHT 2009 ESRI

 TRADE SECRETS: ESRI PROPRIETARY AND CONFIDENTIAL
 Unpublished material - all rights reserved under the
 Copyright Laws of the United States and applicable international
 laws, treaties, and conventions.

 For additional information, contact:
 Environmental Systems Research Institute, Inc.
 Attn: Contracts and Legal Services Department
 380 New York Street
 Redlands, California, 92373
 USA

 email: contracts@esri.com
 */
//>>built
define("esri/SnappingManager",["dojo/_base/declare","dojo/_base/connect","dojo/_base/lang","dojo/_base/array","dojo/_base/Color","dojo/_base/Deferred","dojo/has","dojo/keys","esri/kernel","esri/graphic","esri/geometry/ScreenPoint","esri/geometry/Extent","esri/symbols/SimpleMarkerSymbol","esri/symbols/SimpleLineSymbol","esri/tasks/query"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9,_a,_b,_c,_d,_e,_f){var _10=_1(null,{declaredClass:"esri.SnappingManager",constructor:function(_11){_11=_11||{};if(!_11.map){console.error("map is not specified for SnappingManager");}this.map=_11.map;this.tolerance=_11.tolerance||15;this.layerInfos=[];if(_11.layerInfos){this.layerInfos=_11.layerInfos;}else{var i;for(i=0;i<this.map.graphicsLayerIds.length;i++){var _12=this.map.getLayer(this.map.graphicsLayerIds[i]);this.layerInfos.push({"layer":_12});}if(this.map.loaded){this.layerInfos.push({"layer":this.map.graphics});}else{var _13=_2.connect(this.map,"onLoad",this,function(map){_2.disconnect(_13);_13=null;this.layerInfos.push({"layer":this.map.graphics});this.setLayerInfos(this.layerInfos);});}}if(_11.snapPointSymbol){this.snapPointSymbol=_11.snapPointSymbol;}else{this.snapPointSymbol=new _d(_d.STYLE_CROSS,15,new _e(_e.STYLE_SOLID,new _5([0,255,255]),1),new _5([0,255,0,0]));}if(_11.alwaysSnap){this.alwaysSnap=_11.alwaysSnap;}else{this.alwaysSnap=false;}if(_11.snapKey){this.snapKey=_11.snapKey;}else{this.snapKey=_8.copyKey;}this._SelectionLyrQuery=new _f();this._SelectionLyrQuery.spatialRelationship=_f.SPATIAL_REL_INTERSECTS;this._snappingGraphic=new _a();this.setLayerInfos(this.layerInfos);this._currentGraphicOption={snapToPoint:true,snapToVertex:true,snapToEdge:true};this._snappingCallback=_3.hitch(this,this._snappingCallback);},getSnappingPoint:function(_14){var _15=this.layers,_16=this.tolerance,map=this.map,_17=this.layerOptions,_18=map.toMap(_14.offset(-_16,_16)),_19=map.toMap(_14.offset(_16,-_16)),_1a=new _c(_18.x,_18.y,_19.x,_19.y,map.spatialReference),_1b=new _f();_1b.geometry=_1a;_1b.spatialRelationship=_f.SPATIAL_REL_INTERSECTS;var _1c=[],_1d=[],_1e,_1f=this._extractPointsAndLines,_20=new _6(),_21=0,_22,_23=_1a.xmin,_24=_1a.xmax;_4.forEach(_15,function(_25,idx){if(_25.visible&&_25.loaded&&_25.declaredClass==="esri.layers.FeatureLayer"&&_25.mode!==_25.constructor.MODE_SELECTION){_21++;}});if(map.spatialReference._isWrappable()){_23=_c.prototype._normalizeX(_1a.xmin,map.spatialReference._getInfo()).x;_24=_c.prototype._normalizeX(_1a.xmax,map.spatialReference._getInfo()).x;}var _26=new _c(_23,_1a.ymin,_24,_1a.ymax,map.spatialReference);_4.forEach(_15,function(_27,idx){if(_27.declaredClass==="esri.layers.GraphicsLayer"&&_27.visible){var _28=[];_4.forEach(_27.graphics,function(_29){if(_29){if(_29.visible&&_26.intersects(_29.geometry)){_28.push(_29);}}});var _2a=_1f(_28,_17[idx]);_1c=_1c.concat(_2a[0]);_1d=_1d.concat(_2a[1]);}});var _2b=_3.hitch(this,function(_2c){_21--;if(_2c instanceof Error){var msg="getSnappingPoint: query features failed";console.log(msg);}else{var _2d=_1f(_2c.features,_17[_22]);_1c=_1c.concat(_2d[0]);_1d=_1d.concat(_2d[1]);}if(!_21){_1e=this._getSnappingPoint(_1c,_1d,_14);_20.callback(_1e);}});var _2e=false;_4.forEach(_15,function(_2f,idx){if(_2f.visible&&_2f.loaded){_22=idx;if((_2f.declaredClass==="esri.layers.FeatureLayer")&&_2f.mode!==_2f.constructor.MODE_SELECTION){_2e=true;_2f.queryFeatures(_1b,_2b,_2b);}}});if(!_2e){_1e=this._getSnappingPoint(_1c,_1d,_14);_20.callback(_1e);}return _20;},setLayerInfos:function(_30){this.layers=[];this.layerOptions=[];var i;for(i=0;i<_30.length;i++){this.layers.push(_30[i].layer);this.layerOptions.push({snapToPoint:true,snapToVertex:true,snapToEdge:true});if(_30[i].snapToPoint===false){this.layerOptions[i].snapToPoint=_30[i].snapToPoint;}if(_30[i].snapToVertex===false){this.layerOptions[i].snapToVertex=_30[i].snapToVertex;}if(_30[i].snapToEdge===false){this.layerOptions[i].snapToEdge=_30[i].snapToEdge;}}this._featurePtsFromSelectionLayer=[];this._featureLinesFromSelectionLayer=[];this._selectionLayers=[];this._selectionLayerOptions=[];_4.forEach(this.layers,function(_31,idx){if(_31.declaredClass==="esri.layers.FeatureLayer"&&_31.mode===_31.constructor.MODE_SELECTION){this._selectionLayers.push(_31);this._selectionLayerOptions.push(this.layerOptions[idx]);}},this);this.layerInfos=_30;},destroy:function(){_2.disconnect(this._onExtentChangeConnect);this._killOffSnapping();this._featurePtsFromSelectionLayer=this._featureLinesFromSelectionLayer=this._currentFeaturePts=this._currentFeatureLines=this.layers=this.map=null;},_startSelectionLayerQuery:function(){_2.disconnect(this._onExtentChangeConnect);this._mapExtentChangeHandler(this._selectionLayers,this._selectionLayerOptions,this.map.extent);this._onExtentChangeConnect=_2.connect(this.map,"onExtentChange",_3.hitch(this,"_mapExtentChangeHandler",this._selectionLayers,this._selectionLayerOptions));},_stopSelectionLayerQuery:function(){_2.disconnect(this._onExtentChangeConnect);},_mapExtentChangeHandler:function(_32,_33,_34){this._featurePtsFromSelectionLayer=[];this._featureLinesFromSelectionLayer=[];var _35;this._SelectionLyrQuery.geometry=_34;var _36=_3.hitch(this,function(_37){if(_37 instanceof Error){var msg="getSnappingPoint: query features failed";console.log(msg);}else{var _38=this._extractPointsAndLines(_37.features,_33[_35]);this._featurePtsFromSelectionLayer=this._featurePtsFromSelectionLayer.concat(_38[0]);this._featureLinesFromSelectionLayer=this._featureLinesFromSelectionLayer.concat(_38[1]);}});_4.forEach(_32,function(_39,idx){if(_39.visible&&_39.loaded){_35=idx;_39.queryFeatures(this._SelectionLyrQuery,_36,_36);}},this);},_extractPointsAndLines:function(_3a,_3b){var _3c=[],_3d=[];var i,j;_4.forEach(_3a,function(_3e,idx){if(_3e.visible&&_3e.geometry){if(_3e.geometry.type==="point"&&_3b.snapToPoint){_3c.push(_3e.geometry);}else{if(_3e.geometry.type==="polyline"){for(i=0;i<_3e.geometry.paths.length;i++){_3d.push("lineStart");for(j=0;j<_3e.geometry.paths[i].length;j++){var _3f=_3e.geometry.getPoint(i,j);if(_3b.snapToVertex){_3c.push(_3f);}if(_3b.snapToEdge){_3d.push(_3f);}}_3d.push("lineEnd");}}else{if(_3e.geometry.type==="polygon"){for(i=0;i<_3e.geometry.rings.length;i++){_3d.push("lineStart");for(j=0;j<_3e.geometry.rings[i].length;j++){var _40=_3e.geometry.getPoint(i,j);if(_3b.snapToVertex){_3c.push(_40);}if(_3b.snapToEdge){_3d.push(_40);}}_3d.push("lineEnd");}}}}}});return [_3c,_3d];},_getSnappingPoint:function(_41,_42,_43){var _44,_45,_46=this.tolerance;var map=this.map;var _47=this.map._getFrameWidth();_41=_41.concat(this._featurePtsFromSelectionLayer);_42=_42.concat(this._featureLinesFromSelectionLayer);if(this._currentGraphic){var _48=this._extractPointsAndLines([this._currentGraphic],this._currentGraphicOption);_41=_41.concat(_48[0]);_42=_42.concat(_48[1]);}var _49,_4a;_4.forEach(_41,function(pt,idx){var _4b=map.toScreen(pt,true);if(_47!==-1){_4b.x=_4b.x%_47;if(_4b.x<0){_4b.x+=_47;}if(map.width>_47){var _4c=(map.width-_47)/2;while(_4b.x<_4c){_4b.x+=_47;}}}_44=Math.sqrt((_4b.x-_43.x)*(_4b.x-_43.x)+(_4b.y-_43.y)*(_4b.y-_43.y));if(_44<=_46){_46=_44;_49=_4b.x;_4a=_4b.y;}});if(_49){var _4d=new _b(_49,_4a);_4d=map.toMap(_4d);_45=_4d;}else{var _4e,_4f,i,j;_46=this.tolerance;for(i=0;i<_42.length;i++){if(_42[i]==="lineStart"){for(j=i+1;j<_42.length;j++){if(_42[j+1]!=="lineEnd"&&_42[j+1]!=="lineStart"&&_42[j]!=="lineEnd"&&_42[j]!=="lineStart"){var _50=map.toScreen(_42[j],true),_51=map.toScreen(_42[j+1],true),_52=(_50.x>=_51.x)?_50:_51,_53=(_50.x>=_51.x)?_51:_50;if(_47!==-1){_52.x=_52.x%_47;if(_52.x<0){_52.x+=_47;}_53.x=_53.x%_47;if(_53.x<0){_53.x+=_47;}if(_53.x>_52.x){_53.x-=_47;}}var x1=_52.x,y1=_52.y,x2=_53.x,y2=_53.y;var _54,_55,_56,_57,_58,_59;if(x1===x2){_54=x1;_55=_43.y;_56=_57=x1;_58=(y1<=y2)?y1:y2;_59=(y1<=y2)?y2:y1;}else{if(y1===y2){_54=_43.x;_55=y1;_56=(x1<=x2)?x1:x2;_57=(x1<=x2)?x2:x1;_58=_59=y1;}else{var a=(y2-y1)/(x2-x1),b=(y1*x2-x1*y2)/(x2-x1),_5a=(x1-x2)/(y2-y1),_5b=(_43.y*y2-_43.y*y1-_43.x*x1+_43.x*x2)/(y2-y1);_54=(b-_5b)/(_5a-a);_55=a*_54+b;_56=(x1<=x2)?x1:x2;_57=(x1<=x2)?x2:x1;_58=(y1<=y2)?y1:y2;_59=(y1<=y2)?y2:y1;}}if(_54>=_56&&_54<=_57&&_55>=_58&&_55<=_59){var _5c=Math.sqrt((_43.x-_54)*(_43.x-_54)+(_43.y-_55)*(_43.y-_55));if(_5c<=_46){_46=_5c;_4e=_54;_4f=_55;}}else{var _5d=Math.sqrt((x1-_43.x)*(x1-_43.x)+(y1-_43.y)*(y1-_43.y));var _5e=Math.sqrt((x2-_43.x)*(x2-_43.x)+(y2-_43.y)*(y2-_43.y));var _5f;if(_5d<=_5e){_5f=_5d;_54=x1;_55=y1;}else{_5f=_5e;_54=x2;_55=y2;}if(_5f<=_46){_46=_5f;_4e=_54;_4f=_55;}}}if(_42[j]==="lineEnd"){i=j;break;}}}}if(_4e){var _60=new _b(_4e,_4f);_60=map.toMap(_60);_45=_60;}}return _45;},_setGraphic:function(_61){this._currentGraphic=_61;},_addSnappingPointGraphic:function(){var map=this.map;var _62=this.snapPointSymbol;this._snappingGraphic.setSymbol(_62);map.graphics.add(this._snappingGraphic);},_setUpSnapping:function(){var map=this.map;this._onSnapKeyDown_connect=_2.connect(map,"onKeyDown",this,"_onSnapKeyDownHandler");this._onSnapKeyUp_connect=_2.connect(map,"onKeyUp",this,"_onSnapKeyUpHandler");this._onSnappingMouseMove_connect=_2.connect(map,"onMouseMove",this,"_onSnappingMouseMoveHandler");this._onSnappingMouseDrag_connect=_2.connect(map,"onMouseDrag",this,"_onSnappingMouseMoveHandler");if(this.alwaysSnap){this._activateSnapping();}},_killOffSnapping:function(){_2.disconnect(this._onSnapKeyDown_connect);_2.disconnect(this._onSnapKeyUp_connect);_2.disconnect(this._onSnappingMouseMove_connect);_2.disconnect(this._onSnappingMouseDrag_connect);this._deactivateSnapping();},_onSnapKeyDownHandler:function(evt){if(evt.keyCode===this.snapKey){_2.disconnect(this._onSnapKeyDown_connect);if(this.alwaysSnap){this._deactivateSnapping();}else{this._activateSnapping();}}},_activateSnapping:function(){this._snappingActive=true;this._addSnappingPointGraphic();if(this._currentLocation){this._onSnappingMouseMoveHandler(this._currentLocation);}},_onSnapKeyUpHandler:function(evt){if(evt.keyCode===this.snapKey){this._onSnapKeyDown_connect=_2.connect(this.map,"onKeyDown",this,"_onSnapKeyDownHandler");if(this.alwaysSnap){this._activateSnapping();}else{this._deactivateSnapping();}}},_deactivateSnapping:function(){this._snappingActive=false;this._snappingPoint=null;this.map.graphics.remove(this._snappingGraphic);this._snappingGraphic.setGeometry(null);},_onSnappingMouseMoveHandler:function(evt){this._currentLocation=evt;this._snappingPoint=null;if(this._snappingActive){this._snappingGraphic.hide();var _63=this.getSnappingPoint(evt.screenPoint);_63.addCallback(this._snappingCallback);}},_snappingCallback:function(_64){this._snappingPoint=_64;if(_64){this._snappingGraphic.show();this._snappingGraphic.setGeometry(_64);}}});if(_7("extend-esri")){_9.SnappingManager=_10;}return _10;});