import{CameraMoveDirection}from"../interface/camera";import{REQUEST_TYPE}from"./model-api";import{extend}from"../common/util";import EventEmitter,{DTEvent}from"../common/event-emitter";import{NOTIFICATION_TYPE}from"./model-api";import{CameraEvent}from"../common/constant";const emitter=new EventEmitter;function getNumberPosition(a){let b;return b="x"in a?a:"model"in a?a.model.position:a.position,b}export function createDefaultCameraOptions(){return{}}export default function createCamera(a){const b=async(b,c={})=>{var d,f;let g;if("x"in b)return e({lookAt:b,duration:c.duration});g=b.modelId;await a.invoke(REQUEST_TYPE.FocusToTargetObject,{ObjectId:g,Duration:(null!==(d=c.duration)&&void 0!==d?d:2e3)/1e3,DistanceScale:null!==(f=c.zoom)&&void 0!==f?f:5})},c=(b,c)=>{let d;d="model"in b?b.model:b;let e,f,{relative:g,phi:h,theta:i}=c||{};if(g){let{x:a,y:b,z:c}=g;e={X:a,Y:b,Z:c}}(h||i)&&(f={X:i||45,Y:h||45,Z:0});const j=()=>{a.invoke(REQUEST_TYPE.CameraFllowTargetObject,{ObjectId:d.modelId,RelativePosition:e,RelativeEulerAngles:f})},k=()=>{a.invoke(REQUEST_TYPE.CameraFllowTargetObject,{ObjectId:"",RelativePosition:e,RelativeEulerAngles:f})};return j(),{continue:()=>{j()},stop:()=>{k()}}},d=b=>{let c,d;b.target?c=b.target.modelId:d={X:i.x,Y:i.y,Z:i.z};const e=b.speed||36;return a.invoke(REQUEST_TYPE.HoverAroundTarget,{ObjectId:c,Position:d,Time:e,Active:!0}),()=>{a.invoke(REQUEST_TYPE.HoverAroundTarget,{ObjectId:c,Position:d,Time:e,Active:!1})}},e=async b=>{var c;let d;if(b.lookAt){let a;if("x"in b.lookAt)a=b.lookAt;else{var e,f,g,h,i,j;let c;if("model"in b.lookAt){var k,l;c=await(null===(k=(l=b.lookAt.model).getTransform)||void 0===k?void 0:k.call(l))}else{var m,n;c=await(null===(m=(n=b.lookAt).getTransform)||void 0===m?void 0:m.call(n))}a={x:(null===(e=c)||void 0===e||null===(f=e.Position)||void 0===f?void 0:f.X)||0,y:(null===(g=c)||void 0===g||null===(h=g.Position)||void 0===h?void 0:h.Y)||0,z:(null===(i=c)||void 0===i||null===(j=i.Position)||void 0===j?void 0:j.Z)||0}}d={X:a.x,Y:a.y,Z:a.z}}let o;if(b.position){let{x:a,y:c,z:d}=getNumberPosition(b.position);o={X:a,Y:c,Z:d}}let p;void 0===b.phi&&void 0===b.theta&&(b.position||b.lookAt)||(p={X:void 0===b.theta?45:b.theta,Y:void 0===b.phi?45:b.phi,Z:0});let q=p?15:void 0;return b.distance&&(q=b.distance),await a.invoke(REQUEST_TYPE.ChangeViewPoint,{Duration:(null!==(c=b.duration)&&void 0!==c?c:2e3)/1e3,LookAtPosition:d,EulerAngles:p,Position:o,Distance:q})},f=async()=>{await a.invoke(REQUEST_TYPE.StopCameraAnimation)},g=async(b,c,d)=>{if(!b)throw new Error("direction is required");const e=b.charAt(0).toUpperCase()+b.slice(1).toLowerCase();if(!(e in CameraMoveDirection))throw new Error("direction is not a valid direction");await a.invoke(REQUEST_TYPE.MoveCamera,{MoveDirection:e,Offset:c||10,Duration:d/1e3})};let h={x:0,y:0,z:0},i={x:0,y:0,z:0},j=a.addNotificationListener(NOTIFICATION_TYPE.CameraViewPointChanged,a=>{let{Position:b,LookAtPosition:c}=a;c&&(i={x:c.X,y:c.Y,z:c.Z}),b&&(h={x:b.X,y:b.Y,z:b.Z}),emitter.emit(new DTEvent(CameraEvent.Change,{position:h,lookAt:i}))});return extend({get target(){return{x:i.x,y:i.y,z:i.z}},get position(){return{x:h.x,y:h.y,z:h.z}},set position(a){e({position:a,duration:0}).then(()=>{h=a})},lookAt:(a,b=0,c=0)=>{let d={x:0,y:0,z:0};"number"==typeof a?(d.x=a,d.y=b||0,d.z=c||0):d=a,e({lookAt:d,duration:1}).then(()=>{i=d})},fit:d,setZoom:function(a){throw new Error("Function not implemented.")},flyTo:(a,b)=>e({lookAt:a,...b}),travel:(a,b={})=>{let c=0,d=!1;const f=h=>{if(!d){let d=getNumberPosition(h);const i=e({lookAt:d,...b});i.then(()=>{if(b.process&&b.process.call(g,a.indexOf(h)),c==a.length-1){if("loop"!==b.mode&&"reverse"!==b.mode)return;"reverse"===b.mode&&a.reverse(),c=0}else c++;b.duration&&0<b.duration?setTimeout(()=>{f(a[c])},b.delay):f(a[c])})}};f(a[c]);const g={clear:()=>{a=[],c=0},insert:(b,c)=>{c===void 0&&(c=a.length-1),Array.isArray(b)&&"number"!=typeof b[0]?a.splice(c,0,...b):a.splice(c,0,b)},remove:(b,c=1)=>{a.splice(b,c)},continue(){d},pause(){d},stop:()=>{d||(d=!0)}};return g},stop:async function(){await f()},follow:c,faceTo:b,dispose:()=>{j()},move:g,update:async()=>{await a.invoke(REQUEST_TYPE.GetCameraTransform).then(a=>{let{Position:b}=a;b&&(h={x:b.X,y:b.Y,z:b.Z})}),await a.invoke(REQUEST_TYPE.GetCameraLookAtPosition).then(a=>{let{LookAtPosition:b}=a;b&&(i={x:b.X,y:b.Y,z:b.Z})}),emitter.emit(new DTEvent(CameraEvent.Change,{position:h,lookAt:i}))}},emitter)}