/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{cyclical2PI as e}from"../../../core/Cyclical.js";import{createAngle as t,valueInUnit as r}from"../../../core/quantity.js";import{subtract as i,dot as n,squaredLength as s,scaleAndAdd as a}from"../../../core/libs/gl-matrix-2/math/vec2.js";import{create as o}from"../../../core/libs/gl-matrix-2/factories/vec2f64.js";import{scaleAndAdd as c,subtract as p,set as g}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{create as m}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import h from"../../../geometry/Point.js";import{absoluteHeightElevationInfo as l}from"../../../support/elevationInfoUtils.js";import{VerticalHalfPlaneConstraint as f}from"../sketch/constraints.js";import{fromAnyMapPoint as d,asVec2 as u,markAsTarget as x,fromValues as S,fromVec3 as V,setDehydratedPoint as w}from"../sketch/normalizedPoint.js";import{SnappingAlgorithm as j}from"./SnappingAlgorithm.js";import{isLine as v,squaredScreenDistance as y}from"./snappingUtils.js";import{RightAngleSnappingCandidate as k}from"./candidates/RightAngleSnappingCandidate.js";import{vectorToScreenPoint as C}from"../support/viewUtils.js";import{radiansGeographicBetweenVec as _,pointFromDistanceAlongAzimuth as F}from"../../support/angularMeasurementUtils.js";class P extends j{constructor(e,t,r){super(e,t),this._measurementWorker=r}async snapNewVertex(e,t){const r=t.editGeometryOperations.data.parts.at(-1),i=[];if(!r||r.vertices.length<2)return i;const{view:n}=this,s=C(e,t.spatialReference,l,n),a=r.vertices.at(-1);v(a.leftSegment)&&await this._checkForSnappingCandidate(1,i,a.leftSegment,a,a.leftSegment.leftVertex,e,s,t);const o=r.vertices[0];return v(o.rightSegment)&&await this._checkForSnappingCandidate(2,i,o.rightSegment,o,o.rightSegment.rightVertex,e,s,t),i}async snapExistingVertex(e,t){const r=[],i=t.vertexHandle,{part:n}=i;if(n.vertices.length<3)return r;const{view:s}=this,a=C(e,t.spatialReference,l,s),o=i.leftSegment,c=i.rightSegment;if(v(o?.leftVertex.leftSegment)){const i=o.leftVertex.leftSegment;await this._checkForSnappingCandidate(3,r,i,i.rightVertex,i.leftVertex,e,a,t)}if(v(c)&&v(c.rightVertex.rightSegment)){const i=c.rightVertex.rightSegment;await this._checkForSnappingCandidate(3,r,i,i.leftVertex,i.rightVertex,e,a,t)}const p=n.getFirstVertex()?.rightSegment;return!c&&v(p)&&await this._checkForSnappingCandidate(3,r,p,p.leftVertex,p.rightVertex,e,a,t),r}async _checkForSnappingCandidate(e,t,r,i,n,s,a,o){if(!v(r)||!this.edgeExceedsShortLineThreshold(r,o))return;const c=this.view,p=d(i.pos,c,o),g=d(n.pos,c,o);await R(T,g,p,s,o,this._measurementWorker),this._checkForSnappingCandidateAlongProjectedRay(e,t,g,p,T,s,a,o)}_checkForSnappingCandidateAlongProjectedRay(e,t,r,o,p,g,h,d){const{spatialReference:w,pointer:j}=d,v=i(M,u(g),u(o)),_=n(p,v)/s(p),F=a(M,u(o),p,_),P=x(S(F[0],F[1],g[2]));if(y(h,C(P,w,l,this.view))>this.squaredProximityThreshold(j)||this.isVertical(P,o,d)||this.isVertical(o,r,d))return;const R=c(m(),o,p,Math.sign(_));t.push(new k({targetPoint:P,constraint:new f(o,V(R)),previousVertex:r,otherVertex:o,otherVertexType:1,selfSnappingType:e,isDraped:"on-the-ground"===d.elevationInfo?.mode}))}}async function R(e,t,r,i,n,s){await A(e,t,r,i,n,s)||b(e,t,r)}async function A(i,n,s,a,{spatialReference:o},c){const g=_(n,s,o,o);if(null==g)return!1;const l=_(s,a,o,o);if(null==l)return!1;const f=Math.sign(e.shortestSignedDiff(g,l))*Math.PI*.5,d=t(g+f,"radians","geographic"),u=m(),x=await c.geodeticDistanceBetweenPoints(w(new h,s,o),w(new h,a,o));return null!=x&&(F(u,s,o,r(x,"meters"),d,"geodesic"),p(i,u,s),!0)}function b(e,t,r){const n=i(M,u(r),u(t));g(e,n[1],-n[0],0)}const M=o(),T=m();export{P as RightAngleSnapper};
