import binarySearch from"../../Core/binarySearch.js";import ClockRange from"../../Core/ClockRange.js";import ClockStep from"../../Core/ClockStep.js";import defined from"../../Core/defined.js";import DeveloperError from"../../Core/DeveloperError.js";import JulianDate from"../../Core/JulianDate.js";import knockout from"../../ThirdParty/knockout.js";import createCommand from"../createCommand.js";import ToggleButtonViewModel from"../ToggleButtonViewModel.js";const monthNames=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],realtimeShuttleRingAngle=15,maxShuttleRingAngle=105;function numberComparator(t,e){return t-e}function getTypicalMultiplierIndex(t,e){const i=binarySearch(e,t,numberComparator);return i<0?~i:i}function angleToMultiplier(t,e){if(Math.abs(t)<=realtimeShuttleRingAngle)return t/realtimeShuttleRingAngle;const i=realtimeShuttleRingAngle,o=maxShuttleRingAngle;let n;const l=0;let r;return t>0?(n=Math.log(e[e.length-1]),r=(n-l)/(o-i),Math.exp(l+r*(t-i))):(n=Math.log(-e[0]),r=(n-l)/(o-i),-Math.exp(l+r*(Math.abs(t)-i)))}function multiplierToAngle(t,e,i){if(i.clockStep===ClockStep.SYSTEM_CLOCK)return realtimeShuttleRingAngle;if(Math.abs(t)<=1)return t*realtimeShuttleRingAngle;const o=e[e.length-1];t>o?t=o:t<-o&&(t=-o);const n=realtimeShuttleRingAngle,l=maxShuttleRingAngle;let r;const a=0;let u;return t>0?(r=Math.log(o),u=(r-a)/(l-n),(Math.log(t)-a)/u+n):(r=Math.log(-e[0]),u=(r-a)/(l-n),-((Math.log(Math.abs(t))-a)/u+n))}function AnimationViewModel(t){if(!defined(t))throw new DeveloperError("clockViewModel is required.");const e=this;this._clockViewModel=t,this._allShuttleRingTicks=[],this._dateFormatter=AnimationViewModel.defaultDateFormatter,this._timeFormatter=AnimationViewModel.defaultTimeFormatter,this.shuttleRingDragging=!1,this.snapToTicks=!1,knockout.track(this,["_allShuttleRingTicks","_dateFormatter","_timeFormatter","shuttleRingDragging","snapToTicks"]),this._sortedFilteredPositiveTicks=[],this.setShuttleRingTicks(AnimationViewModel.defaultTicks),this.timeLabel=void 0,knockout.defineProperty(this,"timeLabel",(function(){return e._timeFormatter(e._clockViewModel.currentTime,e)})),this.dateLabel=void 0,knockout.defineProperty(this,"dateLabel",(function(){return e._dateFormatter(e._clockViewModel.currentTime,e)})),this.multiplierLabel=void 0,knockout.defineProperty(this,"multiplierLabel",(function(){const t=e._clockViewModel;if(t.clockStep===ClockStep.SYSTEM_CLOCK)return"Today";const i=t.multiplier;return i%1===0?`${i.toFixed(0)}x`:`${i.toFixed(3).replace(/0{0,3}$/,"")}x`})),this.shuttleRingAngle=void 0,knockout.defineProperty(this,"shuttleRingAngle",{get:function(){return multiplierToAngle(t.multiplier,e._allShuttleRingTicks,t)},set:function(t){t=Math.max(Math.min(t,maxShuttleRingAngle),-maxShuttleRingAngle);const i=e._allShuttleRingTicks,o=e._clockViewModel;if(o.clockStep=ClockStep.SYSTEM_CLOCK_MULTIPLIER,Math.abs(t)===maxShuttleRingAngle)return void(o.multiplier=t>0?i[i.length-1]:i[0]);let n=angleToMultiplier(t,i);if(e.snapToTicks)n=i[getTypicalMultiplierIndex(n,i)];else if(0!==n){const t=Math.abs(n);if(t>100){const e=t.toFixed(0).length-2,i=Math.pow(10,e);n=Math.round(n/i)*i|0}else t>realtimeShuttleRingAngle?n=Math.round(n):t>1?n=+n.toFixed(1):t>0&&(n=+n.toFixed(2))}o.multiplier=n}}),this._canAnimate=void 0,knockout.defineProperty(this,"_canAnimate",(function(){const t=e._clockViewModel,i=t.clockRange;if(e.shuttleRingDragging||i===ClockRange.UNBOUNDED)return!0;const o=t.multiplier,n=t.currentTime,l=t.startTime;let r=!1;if(i===ClockRange.LOOP_STOP)r=JulianDate.greaterThan(n,l)||n.equals(l)&&o>0;else{const e=t.stopTime;r=JulianDate.greaterThan(n,l)&&JulianDate.lessThan(n,e)||n.equals(l)&&o>0||n.equals(e)&&o<0}return r||(t.shouldAnimate=!1),r})),this._isSystemTimeAvailable=void 0,knockout.defineProperty(this,"_isSystemTimeAvailable",(function(){const t=e._clockViewModel,i=t.clockRange;if(i===ClockRange.UNBOUNDED)return!0;const o=t.systemTime;return JulianDate.greaterThanOrEquals(o,t.startTime)&&JulianDate.lessThanOrEquals(o,t.stopTime)})),this._isAnimating=void 0,knockout.defineProperty(this,"_isAnimating",(function(){return e._clockViewModel.shouldAnimate&&(e._canAnimate||e.shuttleRingDragging)}));const i=createCommand((function(){const t=e._clockViewModel;t.shouldAnimate?t.shouldAnimate=!1:e._canAnimate&&(t.shouldAnimate=!0)}));this._pauseViewModel=new ToggleButtonViewModel(i,{toggled:knockout.computed((function(){return!e._isAnimating})),tooltip:"Pause"});const o=createCommand((function(){const t=e._clockViewModel,i=t.multiplier;i>0&&(t.multiplier=-i),t.shouldAnimate=!0}));this._playReverseViewModel=new ToggleButtonViewModel(o,{toggled:knockout.computed((function(){return e._isAnimating&&t.multiplier<0})),tooltip:"Play Reverse"});const n=createCommand((function(){const t=e._clockViewModel,i=t.multiplier;i<0&&(t.multiplier=-i),t.shouldAnimate=!0}));this._playForwardViewModel=new ToggleButtonViewModel(n,{toggled:knockout.computed((function(){return e._isAnimating&&t.multiplier>0&&t.clockStep!==ClockStep.SYSTEM_CLOCK})),tooltip:"Play Forward"});const l=createCommand((function(){e._clockViewModel.clockStep=ClockStep.SYSTEM_CLOCK}),knockout.getObservable(this,"_isSystemTimeAvailable"));this._playRealtimeViewModel=new ToggleButtonViewModel(l,{toggled:knockout.computed((function(){return t.clockStep===ClockStep.SYSTEM_CLOCK})),tooltip:knockout.computed((function(){return e._isSystemTimeAvailable?"Today (real-time)":"Current time not in range"}))}),this._slower=createCommand((function(){const t=e._clockViewModel,i=e._allShuttleRingTicks,o=t.multiplier,n=getTypicalMultiplierIndex(o,i)-1;n>=0&&(t.multiplier=i[n])})),this._faster=createCommand((function(){const t=e._clockViewModel,i=e._allShuttleRingTicks,o=t.multiplier,n=getTypicalMultiplierIndex(o,i)+1;n=0;--e)o=l[e],0!==o&&r.push(-o);Array.prototype.push.apply(r,l),this._allShuttleRingTicks=r},Object.defineProperties(AnimationViewModel.prototype,{slower:{get:function(){return this._slower}},faster:{get:function(){return this._faster}},clockViewModel:{get:function(){return this._clockViewModel}},pauseViewModel:{get:function(){return this._pauseViewModel}},playReverseViewModel:{get:function(){return this._playReverseViewModel}},playForwardViewModel:{get:function(){return this._playForwardViewModel}},playRealtimeViewModel:{get:function(){return this._playRealtimeViewModel}},dateFormatter:{get:function(){return this._dateFormatter},set:function(t){if("function"!==typeof t)throw new DeveloperError("dateFormatter must be a function");this._dateFormatter=t}},timeFormatter:{get:function(){return this._timeFormatter},set:function(t){if("function"!==typeof t)throw new DeveloperError("timeFormatter must be a function");this._timeFormatter=t}}}),AnimationViewModel._maxShuttleRingAngle=maxShuttleRingAngle,AnimationViewModel._realtimeShuttleRingAngle=realtimeShuttleRingAngle;export default AnimationViewModel;