/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import e from"../../../core/Error.js";import{whenOrAbort as t,throwIfAborted as s,allSettledValues as r,isAborted as o,createAbortError as n}from"../../../core/promiseUtils.js";import{removeFile as i,makeRelative as a}from"../../../core/urlUtils.js";import l from"../../Point.js";async function c(e,t,s){switch(t.source.type){case"client":case"service":return u(e,t,s);case"loadable":return t.source.load(e,s);default:t.source}}async function u(r,o,n){const{source:i}=o,{loadGLTFMesh:a}=await t(import("./loadGLTFMesh.js"),n),c=await f(i,n);s(n);const u=a(new l({x:0,y:0,z:0,spatialReference:r.spatialReference}),c.url,{resolveFile:m(c),signal:n?.signal,expectedType:c.type,unitConversionDisabled:o.unitConversionDisabled});u.then(()=>c.dispose(),()=>c.dispose());const{mesh:{vertexAttributes:p,components:d},meta:{isDracoDecompressed:h}}=await u;if(h)throw new e("mesh-load-external:draco-not-supported","The provided mesh uses Draco compression which is not supported.");r.vertexAttributes=p,r.components=d}function m(e){const t=i(e.url);return s=>{const r=a(s,t,t),o=r?r.replace(/^ *\.\//,""):null;return(o?e.files.get(o):null)??s}}async function f(t,s){switch(t.type){case"client":return Array.isArray(t.files)?h(t.files):d(t.files);case"service":return w(t.assets,s);default:throw new e("mesh-load-external:invalid-source","Invalid source type")}}async function p(e,t){const{parts:r,assetMimeType:o,assetName:n}=e;if(1===r.length)return new j(r[0].partUrl);const i=await e.toBlob(t);return s(t),j.fromBlob(i,M(n,o))}function d(e){return j.fromBlob(e,M(e.name,e.type))}function h(t){if(!t.length)throw new e("mesh-load-external:missing-assets","There must be at least one file to load");return T(t.map(e=>({name:e.name,mimeType:e.type,source:d(e)})))}async function w(t,i){if(!t.length)throw new e("mesh-load-external:missing-assets","There must be at least one file to load");const a=await r(t.map(async e=>{const t=await p(e);return s(i),{name:e.assetName,mimeType:e.assetMimeType,source:t}}));if(o(i))throw a.forEach(e=>e.source.dispose()),n();return T(a)}const y=/^model\/gltf\+json$/,g=/^model\/gltf-binary$/,b=/\.gltf$/i,v=/\.glb$/i;function x({mimeType:e,source:t,name:s}){return y.test(e)||b.test(s)?{url:t.url,type:"gltf"}:g.test(e)||v.test(s)?{url:t.url,type:"glb"}:null}function T(t){const s=new Map;let r=null,o=null;for(const e of t){const{source:t,name:n}=e;r??=x(e),"ESRI3DO_NORM.glb"===n&&(o=x(e)),s.set(n,t.url),t.files.forEach((e,t)=>s.set(t,e))}const n=o??r;if(null==n)throw new e("mesh-load-external:missing-files","Missing files to load external mesh source");return new j(n.url,()=>t.forEach(({source:e})=>e.dispose()),s,n.type)}class j{constructor(e,t=()=>{},s=new Map,r){this.url=e,this.dispose=t,this.files=s,this.type=r}static fromBlob(e,t){const s=URL.createObjectURL(e);return new j(s,()=>URL.revokeObjectURL(s),void 0,t)}}function M(e,t){return y.test(t)||b.test(e)?"gltf":g.test(t)||b.test(e)?"glb":void 0}export{c as loadExternal};
