/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{reallocGrowthFactor as t}from"../../../../../core/arrayUtils.js";import i from"../../../../../core/Logger.js";import{getOrCreateMapValue as e}from"../../../../../core/MapUtils.js";import{ComponentRange as h}from"./IndexRange/ComponentRange.js";import{defaultHighlightName as n}from"../../../../support/HighlightDefaults.js";class s{constructor(t,i){this.offsets=i,this._highlightsInOrder=[],this._pickability=null,this._componentHighlights=new Map,this.verticalOffsets=null,this._cachedGeometryRanges=null,this._cachedHighlightRangesMap=null,this._cachedShadowmapRanges=null;const e=this.count;this.visibility=new h(e),this.materialDataBuffer=t.getBuffer(e),this.materialDataIndices=this.materialDataBuffer.acquireIndices(e)}destroy(){for(let t=0;t<this.count;t++)this.materialDataBuffer.releaseIndex(this.materialDataIndices[t])}get count(){return this.offsets.length-1}get geometryRanges(){return null==this._cachedGeometryRanges&&(this._cachedGeometryRanges=this.visibility.computeOffsetRanges(this.offsets)),this._cachedGeometryRanges}get highlightRangesMap(){return 0===this.componentHighlights.size?null:(this._updateCachedHighlightRanges(),this._cachedHighlightRangesMap)}get shadowmapRanges(){return 0===this.componentHighlights.size?this.geometryRanges:(this._updateCachedHighlightRanges(),this._cachedShadowmapRanges)}clearHighlights(){this._componentHighlights.clear(),this.markHighlightsDirty()}markHighlightsDirty(){this._cachedHighlightRangesMap=null,this._cachedShadowmapRanges=null}markVisibilityDirty(){this._cachedGeometryRanges=null,this.markHighlightsDirty()}addComponentHighlight(t,i){const h=e(this._componentHighlights,i,()=>new Uint32Array(this.count+1)),n=0===h[t]++;return n&&this.markHighlightsDirty(),h[this.count]++,n}removeComponentHighlight(t,i){const e=this._componentHighlights,h=e.get(i);if(void 0===h)return g().warn(`Removing non-existing highlight "${i}".`),"notfound";const n=h[t];if(0===n)return g().warn(`Removing non-existent highlight "${i}".`),"notfound";const s=this.count,a=h[s];return n>1?(h[t]=n-1,h[s]=a-1,!1):(h[t]=0,1===a?e.delete(i):h[s]=a-1,this.markHighlightsDirty(),!0)}updateHighlights(t){this._updateHighlightOrder(t)&&(this.markHighlightsDirty(),this._updateCachedHighlightRanges())}_updateHighlightOrder(t){const{_highlightsInOrder:i}=this;let e=i.length!==t.length;i.length=Math.min(t.length,8);for(let h=0;h<t.length;++h){const n=t.at(h).name;i.length<h?(e=!0,i.push(n)):i[h]!==n&&(i[h]=n,e=!0)}return e}_updateCachedHighlightRanges(){if(null==this._cachedHighlightRangesMap||null==this._cachedShadowmapRanges){const{highlightRangesMap:t,shadowmapRangesMap:i}=a(this.componentHighlights,this.visibility,this.offsets,this._highlightsInOrder);this._cachedHighlightRangesMap=t,this._cachedShadowmapRanges=i}}isPickable(t){return l(this._pickability,t)}isVisible(t){return this.visibility.isVisible(t)}updatePickabilityWithCount(t,i){this._pickability=r(this.count,this._pickability,t,i)}get componentHighlights(){return this._componentHighlights}}function a(t,i,h,s){const a=new Map,g=[];if(t.size>0){let r=h.length;i.forEachComponent(i=>{let l=!1;for(let g=s.length-1;g>=0;--g){const r=s[g],o=t.get(r);if((o?.[i]??0)>0){const t=e(a,r,()=>[]),s=h[i],g=h[i+1];t.push(s),t.push(g-s),l||=r===n;break}}return l||(r!==i-1&&(g.length>0&&g.push(h[r+1]-g[g.length-1]),g.push(h[i])),r=i),!0}),g.length>0&&g.push(h[r+1]-g[g.length-1])}return{highlightRangesMap:a,shadowmapRangesMap:g}}const g=()=>i.getLogger("esri.views.3d.webgl-engine.collections.Component.ComponentData");function r(i,e,h,n){if(h>=i)return e;e??=new Uint32Array(0);const s=c(e),a=h/s|0,g=h-s*a,r=(i-1)/s|0,l=e;if(!(h<l.length*s)&&!n){const i=a+1,h=Math.ceil(l.length*t),n=r+1;let s=Math.max(i,h);s=Math.min(s,n),(e=new Uint32Array(s)).set(l)}return a<e.length&&(e[a]=u(e[a],g,!n)),e}function l(t,i){if(null==t)return!0;const e=c(t);return!(i<t.length*e)||o(t,i,e)}function o(t,i,e){const h=i/e|0,n=i-h*e;return!p(t[h],n)}function c(t){const i=8;return t.BYTES_PER_ELEMENT*i}function u(t,i,e){return t&~(1<<i)|(e?1:0)<<i}function p(t,i){return!!(t&1<<i)}export{s as ComponentData};
