/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import"../../../../core/has.js";import{rasterizeDash as t}from"../../../../symbols/cim/rasterizingUtils.js";import i from"./RectangleBinPack.js";import e from"../webgl/Rect.js";import s from"../../../webgl/Texture.js";import{TextureDescriptor as h}from"../../../webgl/TextureDescriptor.js";const a="dasharray-";class r{constructor(t,e,s=0){this._size=[],this._mosaicsData=[],this._textures=[],this._dirties=[],this._maxItemSize=0,this._currentPage=0,this._pageWidth=0,this._pageHeight=0,this._mosaicRects={},this.pixelRatio=1,e<=0&&console.error("Sprites mosaic defaultWidth and defaultHeight must be greater than zero!"),this._pageWidth=t,this._pageHeight=e,s>0&&(this._maxItemSize=s),this._binPack=new i(t-4,e-4)}destroy(){this.dispose()}dispose(){this._binPack=null,this._mosaicsData.length=0,this._mosaicRects={};for(const t of this._textures)t&&t.dispose();this._textures.length=0}getWidth(t){return t>=this._size.length?-1:this._size[t][0]}getHeight(t){return t>=this._size.length?-1:this._size[t][1]}getPageSize(t){return t>=this._size.length?null:this._size[t]}getTexture(t){return this._textures[t]||null}setSpriteSource(t){if(this.dispose(),this.pixelRatio=t.devicePixelRatio,0===this._mosaicsData.length){this._binPack=new i(this._pageWidth-4,this._pageHeight-4);const t=Math.floor(this._pageWidth),e=Math.floor(this._pageHeight),s=new Uint32Array(t*e);this._mosaicsData[0]=s,this._dirties.push(!0),this._size.push([this._pageWidth,this._pageHeight]),this._textures.push(void 0)}this._sprites=t}getSpriteItem(t,i=!1){let e,s,h=this._mosaicRects[t];if(h)return h;if(!this._sprites||"loaded"!==this._sprites.loadStatus)return null;if(t&&t.startsWith(a)?([e,s]=this._rasterizeDash(t),i=!0):e=this._sprites.getSpriteInfo(t),!e?.width||!e.height||e.width<0||e.height<0)return null;const r=e.width,n=e.height,[o,_,g]=this._allocateImage(r,n);return o.width<=0?null:(this._copy(o,e,_,g,i,s),h={type:"sprite",rect:o,width:r,height:n,sdf:e.sdf,simplePattern:!1,rasterizationScale:e.pixelRatio??1,samplingMode:"Linear",page:_},this._mosaicRects[t]=h,h)}getSpriteItems(t){const i={};for(const e of t)i[e.name]=this.getSpriteItem(e.name,e.repeat);return i}getMosaicItemPosition(t,i){const e=this.getSpriteItem(t,i),s=e?.rect;if(!s)return null;s.width=e.width,s.height=e.height;const h=e.width,a=e.height,r=2;return{tl:[s.x+r,s.y+r],br:[s.x+r+h,s.y+r+a],page:e.page}}bind(t,i,e=0,a=0){if(e>=this._size.length||e>=this._mosaicsData.length)return;if(!this._textures[e]){const i=new h(this._size[e][0],this._size[e][1]);i.wrapMode=33071,this._textures[e]=new s(t,i,new Uint8Array(this._mosaicsData[e].buffer))}const r=this._textures[e];r.setSamplingMode(i),this._dirties[e]&&r.setData(new Uint8Array(this._mosaicsData[e].buffer)),t.bindTexture(r,a),this._dirties[e]=!1}static _copyBits(t,i,e,s,h,a,r,n,o,_,g){let c=s*i+e,p=n*a+r;if(g){p-=a;for(let r=-1;r<=_;r++,c=((r+_)%_+s)*i+e,p+=a)for(let i=-1;i<=o;i++)h[p+i]=t[c+(i+o)%o]}else for(let l=0;l<_;l++){for(let i=0;i<o;i++)h[p+i]=t[c+i];c+=i,p+=a}}_copy(t,i,e,s,h,a){if(!this._sprites||"loaded"!==this._sprites.loadStatus||e>=this._mosaicsData.length)return;const n=new Uint32Array(a?a.buffer:this._sprites.image.buffer),o=this._mosaicsData[e],_=2,g=a?i.width:this._sprites.width;r._copyBits(n,g,i.x,i.y,o,s[0],t.x+_,t.y+_,i.width,i.height,h),this._dirties[e]=!0}_allocateImage(t,s){t+=2,s+=2;const h=Math.max(t,s);if(this._maxItemSize&&this._maxItemSize<h){const i=new e(0,0,t,s);return this._mosaicsData.push(new Uint32Array(t*s)),this._dirties.push(!0),this._size.push([t,s]),this._textures.push(void 0),[i,this._mosaicsData.length-1,[t,s]]}let a=t%4?4-t%4:4,r=s%4?4-s%4:4;1===a&&(a=5),1===r&&(r=5);const n=this._binPack.allocate(t+a,s+r);return n.width<=0?(this._dirties[this._currentPage]||(this._mosaicsData[this._currentPage]=null),this._currentPage=this._mosaicsData.length,this._mosaicsData.push(new Uint32Array(this._pageWidth*this._pageHeight)),this._dirties.push(!0),this._size.push([this._pageWidth,this._pageHeight]),this._textures.push(void 0),this._binPack=new i(this._pageWidth-4,this._pageHeight-4),this._allocateImage(t,s)):[n,this._currentPage,[this._pageWidth,this._pageHeight]]}_rasterizeDash(i){const e=/\[(.*?)\]/,s=i.match(e);if(!s)return null;const h=s[1].split(",").map(Number),a=i.slice(i.lastIndexOf("-")+1),[r,n,o]=t(h,a);return[{x:0,y:0,width:n,height:o,sdf:!0,pixelRatio:1},new Uint8Array(r.buffer)]}}export{r as default};
