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