using Sandbox.ModAPI.Ingame;
using System;
using System.Collections.Generic;
using VRage.Game.ModAPI.Ingame.Utilities;

namespace IngameScript
{
    partial class Program
    {
        public class SequenceableRotor : ISequenceable
        {
            public bool Running { get; private set; } = false;
            public int Step { get; set; }

            private float _velocity;
            private float _deployAngle;
            private float _stowAngle;
            private IMyMotorStator _rotor;
            private MyRotationDirection _deployDirection;
            private MyRotationDirection _stowDirection;

            public SequenceableRotor(
                IMyMotorStator rotor,
                MyIni ini,
                string sectionName)
            {
                _rotor = rotor;

                ini.TryParse(rotor.CustomData);
                _deployAngle = ini.Get(sectionName, "deployAngle").ToSingle(90F);
                _stowAngle = ini.Get(sectionName, "stowAngle").ToSingle(0F);
                _velocity = ini.Get(sectionName, "velocity").ToSingle(5F);
                switch (ini.Get(sectionName, "deployDirection").ToString("auto"))
                {
                    case "auto":
                        _deployDirection = MyRotationDirection.AUTO;
                        _stowDirection = MyRotationDirection.AUTO;
                        break;
                    case "cw":
                        _deployDirection = MyRotationDirection.CW;
                        _stowDirection = MyRotationDirection.CCW;
                        break;
                    case "ccw":
                        _deployDirection = MyRotationDirection.CCW;
                        _stowDirection = MyRotationDirection.CW;
                        break;
                }
                Step = ini.Get(sectionName, "step").ToInt32(0);
            }

            public IEnumerator<bool> Run(bool deploy = true)
            {
                float _targetAngle = setup(deploy);

                float _lastAngle = _rotor.Angle;
                while (Math.Abs(_rotor.Angle - _targetAngle) > 0.1 || _rotor.Angle != _lastAngle)
                {
                    _lastAngle = _rotor.Angle;
                    yield return true;
                }

                _rotor.RotorLock = true;
                Running = false;
            }

            private float setup(bool deploy = true)
            {
                float degAngle = deploy ? _deployAngle : _stowAngle;
                MyRotationDirection dir = deploy ? _deployDirection : _stowDirection;

                _rotor.RotorLock = false;
                _rotor.RotateToAngle(dir, degAngle, _velocity);
                Running = true;

                return degToRad(degAngle);
            }

            private float degToRad(float degrees)
            {
                return degrees * ((float)Math.PI / 180F);
            }
        }
    }
}