/* COPYRIGHT Esri - https://js.arcgis.com/5.0.18/LICENSE.txt */
import{LRUCache as e}from"../../../../core/LRUCache.js";import{getOrCreateMapValue as t}from"../../../../core/MapUtils.js";import{throwIfAborted as s}from"../../../../core/promiseUtils.js";import{getMetersPerVerticalUnitForSR as n}from"../../../../core/units.js";import{getEndpoint as o}from"../../../../geometry/support/curves/curveUtils.js";import{getMetersPerUnit as i}from"../../../../symbols/support/unitConversionUtils.js";function r(e=!1,t){if(e){const{elevationInfo:e,alignPointsInFeatures:s}=t;return new u(e,s)}return new a}class a{async alignCandidates(e,t,s){return e}notifyElevationSourceChange(){}}const c=1024;class u{constructor(t,s){this._elevationInfo=t,this._alignPointsInFeatures=s,this._alignmentsCache=new e(c),this._cacheVersion=0}async alignCandidates(e,t,s){const n=this._elevationInfo;return null==n||"absolute-height"!==n.mode||n.featureExpressionInfo?this._alignComputedElevationCandidates(e,t,s):(p(e,t,n),e)}notifyElevationSourceChange(){this._alignmentsCache.clear(),this._cacheVersion++}async _alignComputedElevationCandidates(e,n,o){const i=new Map;for(const s of e)t(i,s.objectId,d).push(s);const[r,a,c]=this._prepareQuery(i,n),u=await this._alignPointsInFeatures(r,o);s(o);if(c!==this._cacheVersion)return this._alignComputedElevationCandidates(e,n,o);this._applyCacheAndResponse(r,u,a);const{drapedObjectIds:h,failedObjectIds:l}=u,p=[];for(const t of e){const{objectId:e}=t;h.has(e)&&"edge"===t.type&&(t.draped=!0),l.has(e)||p.push(t)}return p}_prepareQuery(e,t){const s=[],n=[];for(const[o,i]of e){const e=[];for(const t of i)this._addToQueriesOrCachedResult(o,t.target,e,n),"edge"===t.type&&(this._addToQueriesOrCachedResult(o,t.start,e,n),this._addToQueriesOrCachedResult(o,t.end,e,n));0!==e.length&&s.push({objectId:o,points:e})}return[{spatialReference:t.toJSON(),pointsInFeatures:s},n,this._cacheVersion]}_addToQueriesOrCachedResult(e,t,s,n){const o=l(e,t),i=this._alignmentsCache.get(o);null==i?s.push(t):n.push(new h(t,i))}_applyCacheAndResponse(e,{elevations:t,drapedObjectIds:s,failedObjectIds:n},o){for(const a of o)a.apply();let i=0;const r=this._alignmentsCache;for(const{objectId:a,points:c}of e.pointsInFeatures){if(n.has(a)){i+=c.length;continue}const e=!s.has(a);for(const s of c){const n=l(a,s),o=t[i++];s.z=o,e&&r.put(n,o,1)}}}}class h{constructor(e,t){this.point=e,this.z=t}apply(){this.point.z=this.z}}function l(e,{x:t,y:s,z:n,spatialReference:o}){return`${e}-${t}-${s}-${n??0}}-wkid:${o?.wkid}`}function p(e,t,s){const{offset:r,unit:a}=s;if(null==r)return;const c=n(t),u=r*(i(a??"meters")/c);for(const n of e)switch(n.type){case"edge":n.start.z+=u,n.end.z+=u,n.curve&&(o(n.curve)[2]+=u);continue;case"vertex":n.target.z+=u;continue}}function d(){return[]}export{r as getSnappingCandidateElevationAligner};
