/* COPYRIGHT Esri - https://js.arcgis.com/5.0/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{getMetersPerUnit as o}from"../../../../symbols/support/unitConversionUtils.js";function i(e=!1,t){if(e){const{elevationInfo:e,alignPointsInFeatures:s}=t;return new c(e,s)}return new a}class a{async alignCandidates(e,t,s){return e}notifyElevationSourceChange(){}}const r=1024;class c{constructor(t,s){this._elevationInfo=t,this._alignPointsInFeatures=s,this._alignmentsCache=new e(r),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):(d(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,l).push(s);const[a,r,c]=this._prepareQuery(i,n),h=await this._alignPointsInFeatures(a,o);s(o);if(c!==this._cacheVersion)return this._alignComputedElevationCandidates(e,n,o);this._applyCacheAndResponse(a,h,r);const{drapedObjectIds:u,failedObjectIds:d}=h,p=[];for(const t of e){const{objectId:e}=t;u.has(e)&&"edge"===t.type&&(t.draped=!0),d.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=u(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 r of o)r.apply();let i=0;const a=this._alignmentsCache;for(const{objectId:r,points:c}of e.pointsInFeatures){if(n.has(r)){i+=c.length;continue}const e=!s.has(r);for(const s of c){const n=u(r,s),o=t[i++];s.z=o,e&&a.put(n,o,1)}}}}class h{constructor(e,t){this.point=e,this.z=t}apply(){this.point.z=this.z}}function u(e,{x:t,y:s,z:n,spatialReference:o}){return`${e}-${t}-${s}-${n??0}}-wkid:${o?.wkid}`}function d(e,t,s){const{offset:i,unit:a}=s;if(null==i)return;const r=n(t),c=i*(o(a??"meters")/r);for(const n of e)switch(n.type){case"edge":n.start.z+=c,n.end.z+=c;continue;case"vertex":n.target.z+=c;continue}}function l(){return[]}export{i as getSnappingCandidateElevationAligner};
