/* COPYRIGHT Esri - https://js.arcgis.com/5.1.0/LICENSE.txt */
import{cyclicalPI as e,cyclical2PI as t}from"../../../core/Cyclical.js";import{valueInUnit as r,createAngle as n}from"../../../core/quantity.js";import{create as s}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,squaredScreenDistance as d}from"./snappingUtils.js";import{LineSnappingCandidate as f}from"./candidates/LineSnappingCandidate.js";import{vectorToScreenPoint as g}from"../support/viewUtils.js";import{radiansGeographicBetweenVec as u,pointFromDistanceAlongAzimuth as w}from"../../support/angularMeasurementUtils.js";import{projectPointToLineLike as x}from"../../support/geometry3dUtils.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),n=r?.segments.length??0;if(n<1||!r)return[];const{spatialReference:s}=t,i=g(e,s,o,this.view),{view:a}=this,l=r.segments[n-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,n=r.part;if(n.segments.length<2)return[];const{view:s}=this,{spatialReference:i}=t,l=g(e,i,o,s),p=r.leftSegment,c=r.rightSegment,d=[];h(p)&&h(c)&&this.edgeExceedsShortLineThreshold(p,t)&&this.edgeExceedsShortLineThreshold(c,t)&&d.push(new y(a(p.leftVertex.pos,s,t),a(c.rightVertex.pos,s,t)));const f=n.segments[0];let u=f;do{if(h(u)&&u!==r.leftSegment&&u!==r.rightSegment&&this.edgeExceedsShortLineThreshold(u,t)){const e=m(u,s,t);d.push(new y(e.left,e.right))}u=u.rightVertex.rightSegment}while(u&&u!==f);return this._processCandidateProposals(d,e,l,t)}async _processCandidateProposals(e,t,r,n){if(!e.length)return[];const s=await j(e.map(({lineEnd:e})=>e),t,n,this._measurementWorker);return e.map(({lineStart:e,lineEnd:i},o)=>this._processCandidateProposal(e,i,t,r,n,s[o]??null)).filter(e=>void 0!==e)}_processCandidateProposal(e,t,r,n,i,a){const{spatialReference:c,pointer:h}=i,m=s();P(m,e,t,r,i,a);const u=l(p(m));if(!(d(n,g(u,c,o,this.view))>=this.squaredProximityThreshold(h)))return new f({lineStart:e,lineEnd:t,targetPoint:u,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},n){if(!e.length)return[];const s=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 n.geodeticDistanceBetweenPointsMany(s,o)}catch{return new Array(e.length).fill(null)}}function P(e,t,r,n,s,i){v(e,t,r,n,s,i)||E(e,n,t,r)}function v(s,i,o,a,{spatialReference:l},p){const c=u(i,o,l,l);if(null==c)return!1;const h=u(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 w(s,o,l,r(p,"meters"),n(m,"radians","geographic"),"geodesic"),s[2]=a[2],!0}function E(e,t,r,n){x(t,{start:r,end:n,type:1},e),e[2]=t[2]}export{S as LineSnapper};
