using System.Threading;
using HWModules;
using SWModules;

using System;


namespace CPF.Surface_States
{
    //TODO P2 could combine this state with dumpCPData and do both in parallel (except when no cp data) to save some time
    public class SurfaceOpsSetBellows : StateBase
    {
        public SurfaceOpsSetBellows(string name)
        {
            stateName.Clear();
            stateName.Append(name);

            ECTimeout = 60 * 60 * 1000;         //minutes
        }

        private enum Action : int
        {
            setBellows = 1,
            wait,
            lastAction,
            size = lastAction  //this is an abstract way to get the length of the Action enumeration for every class
        }
 
        private static Action currentAction;
        private static double setBellowsPosition = double.NaN;

        private static DateTime lastUpdateTime;

        public override int doStateEntryActions()
        {
            basicStateEntry();

            //TODO P2 not exactly sure where this actually works
            buoyancyEngine.setPumpMotorAccDeacc1e9();
            
            setBellowsPosition = MissionConfig.SOSetBellowsPosition;

            sbTemp.Clear();
            sbTemp.Append("Inflating bellows to Surface Ops position = ");
            sbTemp.Append(setBellowsPosition.ToString("f1"));
            sbTemp.Append(" at ");
            sbTemp.Append(MissionConfig.SOSetBellowsJV.ToString());
            sbTemp.Append(" cps");
            EngrLogger.writeToColumns(sbTemp);
            sbTemp.Clear();

            currentAction = (Action)1;

            lastUpdateTime = DateTime.Now;

            return (1);
        }

        TimeSpan bellowsPositionUpdatePeriod = new TimeSpan(0, 0, 10);
    
        public override int doStateActions()
        {
            double bellowsPosition;
            bool updatePeriodExpired;
  

            //TODO P2 this needs a rethink so it makes sure the elmo has accepted the command and just checks the bellows position
            switch (currentAction)
            {
                case (Action.setBellows):
                    updatePeriodExpired = ((DateTime.Now - lastUpdateTime) > bellowsPositionUpdatePeriod);

                    if (updatePeriodExpired)
                    {
                        bellowsPosition = buoyancyEngine.getBellowsPositionStringPot(false);
                        if (bellowsPosition > setBellowsPosition)
                        {
                            sbTemp.Clear();
                            sbTemp.Append("Bellows Position = ");
                            sbTemp.Append(bellowsPosition.ToString("f2"));
                            sbTemp.Append(" , Increasing buoyancy");
                            EngrLogger.writeToColumns(sbTemp);

                            buoyancyEngine.increaseBuoyancy(MissionConfig.SOSetBellowsJV);
                        }
                        else if (bellowsPosition < (setBellowsPosition + 3.0))
                        {
                            sbTemp.Clear();
                            sbTemp.Append("Bellows Position = ");
                            sbTemp.Append(bellowsPosition.ToString("f2"));
                            sbTemp.Append(" , Decreasing buoyancy");
                            EngrLogger.writeToColumns(sbTemp);

                            buoyancyEngine.decreaseBuoyancy(MissionConfig.SOSetBellowsJV);
                        }
                        lastUpdateTime = DateTime.Now;
                    }
                    break;
                case (Action.wait):
                    break;
                case (Action.lastAction):
                    break;

            }

            //This is the method that call the concrete state error handler
            //Action return == 0 or > 0 are just re-returned
            currentAction = (Action)checkActionReturn(nextAction, (int)currentAction);

            return (1);
        }

        public override CPFStates checkEvents()
        {
            double bellowsPosition;

            bellowsPosition = buoyancyEngine.getBellowsPositionStringPot(false);
 
            if ( (bellowsPosition <= setBellowsPosition) && (bellowsPosition >= (setBellowsPosition - 3.0)) )
            {
                buoyancyEngine.stopMotor();

                if (SV.ProfileNum == 0)
                    return (CPFStates.recovery);
                else
                    return (CPFStates.dumpCPData);
            }
            else
                return (CPFStates.surfaceOpsSetBellows);
        }

        public override int doExitActions(bool timedOut)
        {
            if (timedOut)
            {
                basicStateExit(true);
            }
            else
            {
                basicStateExit(false);
            }

            return (1);
        }

        public override CPFStates doTimeoutAction()
        {
            if ((currentAction == Action.lastAction) && (SV.ProfileNum == 0))
                return (CPFStates.preMissionDelay);

            else if ((currentAction == Action.lastAction) && (SV.ProfileNum > 0))
                return (CPFStates.dumpCPData);

            //if for some reason got stuck in setting bellows, still need to get to DumpCPData to offload data and restart SBE41 Command timer
            else if ((SV.ProfileNum > 0))
                return (CPFStates.dumpCPData);

            else
                return (CPFStates.surfaceOps);
        }
    }
}
