/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{cyclicalPI as e,cyclical2PI as t}from"../../../core/Cyclical.js";import{valueInUnit as s,createAngle as r}from"../../../core/quantity.js";import{create as i}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{absoluteHeightElevationInfo as o}from"../../../support/elevationInfoUtils.js";import{fromAnyMapPoint as n,markAsTarget as a,fromVec3 as l}from"../sketch/normalizedPoint.js";import{SnappingAlgorithm as p}from"./SnappingAlgorithm.js";import{isLine as h,editEdgeToSnappingEdge as c,squaredScreenDistance as d}from"./snappingUtils.js";import{LineSnappingCandidate as m}from"./candidates/LineSnappingCandidate.js";import{vectorToScreenPoint as g}from"../support/viewUtils.js";import{radiansGeographicBetweenVec as f,pointFromDistanceAlongAzimuth as u}from"../../support/angularMeasurementUtils.js";import{projectPointToLineLike as x}from"../../support/geometry3dUtils.js";class S extends p{constructor(e,t,s){super(e,t),this._geodesicLengthMeasurementUtils=s}snapNewVertex(e,t){const s=t.editGeometryOperations.data.parts.at(-1),r=s?.segments.length??0,i=[];if(r<1||!s)return i;const{spatialReference:n}=t,a=g(e,n,o,this.view),{view:l}=this,p=s.segments[r-1];let d=p;do{if(h(d)&&this.edgeExceedsShortLineThreshold(d,t)){const s=c(d,l,t);this._processCandidateProposal(s.left,s.right,e,a,t,i)}d=d.leftVertex.leftSegment}while(d&&d!==p);return i}snapExistingVertex(e,t){const s=[],r=t.vertexHandle,i=r.part;if(i.segments.length<2)return s;const{view:a}=this,{spatialReference:l}=t,p=g(e,l,o,a),d=r.leftSegment,m=r.rightSegment;h(d)&&h(m)&&this.edgeExceedsShortLineThreshold(d,t)&&this.edgeExceedsShortLineThreshold(m,t)&&this._processCandidateProposal(n(d.leftVertex.pos,a,t),n(m.rightVertex.pos,a,t),e,p,t,s);const f=i.segments[0];let u=f;do{if(h(u)&&u!==r.leftSegment&&u!==r.rightSegment&&this.edgeExceedsShortLineThreshold(u,t)){const r=c(u,a,t);this._processCandidateProposal(r.left,r.right,e,p,t,s)}u=u.rightVertex.rightSegment}while(u&&u!==f);return s}_processCandidateProposal(e,t,s,r,n,p){const{spatialReference:h,pointer:c}=n,f=i();j(f,e,t,s,n,this._geodesicLengthMeasurementUtils);const u=a(l(f));d(r,g(u,h,o,this.view))<this.squaredProximityThreshold(c)&&p.push(new m({lineStart:e,lineEnd:t,targetPoint:u,isDraped:"on-the-ground"===n.elevationInfo?.mode}))}}function j(e,t,s,r,i,o){v(e,t,s,r,i,o)||w(e,r,t,s)}function v(i,o,n,a,{spatialReference:l},p){const h=f(o,n,l,l);if(null==h)return!1;const c=f(n,a,l,l);if(null==c)return!1;const d=p.geodesicDistance(n,a,l);if(null==d)return!1;const m=Math.abs(e.shortestSignedDiff(h,c))>Math.PI/2?t.normalize(h+Math.PI):h;return u(i,n,l,s(d,"meters"),r(m,"radians","geographic"),"geodesic"),i[2]=a[2],!0}function w(e,t,s,r){x(t,{start:s,end:r,type:1},e),e[2]=t[2]}export{S as LineSnapper};
