import createComponentCreator,{get}from"../core/component";import{extend,getElement}from"../common/util";import createScene from"./scene";import createRenderer from"./renderer";import createCamera from"./camera";import EventEmitter,{DTEvent}from"../common/event-emitter";import createUnityModelCreator from"./model";import createMappingParser from"../core/mapping";import{UnitySocket}from"./socket";import{NOTIFICATION_TYPE,REQUEST_TYPE}from"./model-api";import modelGroupCreator from"../core/model-group";import{EngineType,RenderEvent}from"../common/constant";import{startRequestAnimationFrame,stopRequestAnimationFrame}from"../core/executer";export function createUnityDefaultConfig(){return{mode:"client",displayUrl:"",plugins:[]}}export function createUnityConnector(a){return new Promise((b,c)=>{const d=new UnitySocket(a);d.AllowEmpty=!0;let e=0;const f=a.repeatLimit||5,g=a=>{e+=1,e>f&&(d.close(),c(a))};d.addListener("error",g),d.once("loaded",async()=>{d.removeListener("error",g),b(d)}),d.connect()})}export async function unityCreator(a){let b,c=await createUnityConnector(a);const d=new EventEmitter,e=createRenderer(),f=createScene(c),g=createCamera(c),h=createMappingParser("unity"),i=createUnityModelCreator(c);d.once(RenderEvent.Change,async()=>{await g.update()}),startRequestAnimationFrame();let j=[g.dispose,stopRequestAnimationFrame];const k=async()=>{const a=await c.invoke(REQUEST_TYPE.GetSceneMeta);try{const b=h("string"==typeof a?JSON.parse(a):a);return b}catch(a){throw Error("load mapping parse error")}};let l,m;const n=async(a,e=!1)=>{var f,g,h;let j;if(null!==(f=m)&&void 0!==f&&f.modelId&&((null===(g=m)||void 0===g?void 0:g.modelId)===a||(null===(h=m)||void 0===h?void 0:h.id)===a))a=m.modelId;else{var n;j=null===(n=m)||void 0===n?void 0:n.get(a,!1)}if(j&&j.modelId&&(a=j.modelId),b&&b.modelId===a)return Promise.resolve(b);d.emit(new DTEvent(RenderEvent.BeforeChange,{oldId:b&&b.modelId,currentId:a}));let o=!l;if(!l||e){l=await k();let a=await i([l]),b=createComponentCreator(a,modelGroupCreator);m=await b(l)}return o&&d.emit(new DTEvent(RenderEvent.Change,{oldId:b&&b.modelId,currentId:a})),a?await c.invoke(REQUEST_TYPE.GoIntoSpace,{SpaceId:a,Duration:1}).then(()=>(b=m.modelId===a?m:m.get(a,!1),b)):(b=m,Promise.resolve(b))};let o=document.body,p=!1;let q=c.addNotificationListener(NOTIFICATION_TYPE.CurrentSpaceChanged,a=>{var c;let{OldSpaceId:e,NewSpaceId:f}=a,g=new DTEvent(RenderEvent.Change,{oldId:e,currentId:f});(null===(c=b)||void 0===c?void 0:c.modelId)!==f&&(m.modelId===f?b=m:b=m.get(f,!1)),d.emit(g)});j.push(q);return extend({get type(){return"server"===a.mode?EngineType.UnityCloud:EngineType.UnityExe},get container(){return o},get unity(){return c},get component(){return b},get global(){return m},get model(){var a;return null===(a=b)||void 0===a?void 0:a.model},clear:async()=>{},renderer:e,scene:f,camera:g,render:n,amount:b=>{if(p)throw Error("\u4E0D\u53EF\u91CD\u590D\u6302\u8F7D.");p=!0;let c=getElement(b);if(!c)throw Error("el \u4E0D\u5B58\u5728");if(o=c,"server"===a.mode){if(!a.displayUrl)throw Error("from dt-engine: display url can not be empty.");let b=document.createElement("iframe");b.src=a.displayUrl,b.style.cssText="border: 0px; margin: 0px; padding: 0px; width: 100%; height: 100%; left: 0; top: 0; position: absolute;",b.frameBorder="no",c.appendChild(b)}d.emit(RenderEvent.Mounted)},dispose:()=>{var e;d.emit(RenderEvent.Dispose),j.forEach(a=>{a()}),j=[],null===(e=b)||void 0===e?void 0:e.dispose(),c.close(),"server"===a.mode&&o!==document.body&&(o.innerHTML=""),d.removeAllListener()},reset:async()=>{await c.invoke(REQUEST_TYPE.ResetScene),await n(void 0,!0)},createComponent:async()=>{}},d)}