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