using System.Threading;
using HWModules;
using SensorModules;
using SWModules;

namespace CPF.Surface_States
{
    public class DumpCPData : StateBase
    {
        public DumpCPData(string name)
        {
            stateName.Clear();
            stateName.Append(name);

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

        private enum Action : int
        {
            sendCRLF = 1,
            sendBinaverage,
            sendDA,
            sendDAH,
            restartCommandTimer,
            lastAction,
            size = lastAction
        }
        private static Action currentAction;

        public override int doStateEntryActions()
        {
            basicStateEntry();
            buoyancyEngine.closeMV();
            currentAction = (Action)1;

            SciLogger.endSampleCycle();
            return (1);
        }

        public override int doStateActions()
        {

            switch (currentAction)
            {
                case (Action.sendCRLF):
                    nextAction = sendCRLFWait();
                    break;

                case (Action.sendBinaverage):
                    nextAction = sendBinaverage();
                    break;

                case (Action.sendDA):
                    nextAction = sendDAWait();
                    break;

                case (Action.sendDAH):
                    nextAction = sendDAHWait();
                    break;

                case (Action.restartCommandTimer):
                    nextAction = restartCommandTimer();
                    break;

                case (Action.lastAction):
                    break;
            }

            currentAction = (Action)checkActionReturn(nextAction, (int)currentAction);

            return (1);
        }

        public override CPFStates checkEvents()
        {
            if (currentAction == Action.lastAction)
            {
                return (CPFStates.surfaceOps);
            }
            else
            {
                return (CPFStates.dumpCPData);
            }
        }

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

            return (1);
        }

        public override CPFStates doTimeoutAction()
        {
            return (CPFStates.surfaceOps);
        }
  
        //TODO P2 this method (and similar methods) and the one in StartCP should be moved to ctd class
        private int sendCRLFWait()
        {
            int returnVal = ctd1.waitForResponse(SBE41CTD.commands.crlf, 5, 5);

            if (returnVal == 1)
            {
                sbTemp.Clear();
                sbTemp.Append("Got CR/LF response");
                EngrLogger.writeToColumns(sbTemp);

                return ((int)Action.sendBinaverage);
            }
            else if (returnVal == 0)
            {
                return ((int)Action.sendCRLF);
            }
            else
            {
                sbTemp.Clear();
                sbTemp.Append("Didn't get CR/LF response, exiting dumpCPData");
                EngrLogger.writeToColumns(sbTemp);

                return ((int)Action.restartCommandTimer);
            }
        }

        private int sendDDWait()
        {
            EngrLogger.writeToColumns("Sending dd wait command");
            int returnValue = ctd1.waitForResponse(SBE41CTD.commands.dd);

            if (returnValue == 1)
            {
                sbTemp.Clear();
                sbTemp.Append("Good dd response; Upload sucessful");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
            else if (returnValue == 0)
            {

                sbTemp.Clear();
                sbTemp.Append("Trying again for dd response");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();

                return ((int)Action.sendDA);
            }
            else
            {

                sbTemp.Clear();
                sbTemp.Append("Didn't get dd response, restarting command timer");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
        }

        private int sendBinaverage()
        {
            EngrLogger.writeToColumns("Sending binaverage wait command");
            int returnValue = ctd1.waitForResponse(SBE41CTD.commands.binaverage);

            if (returnValue == 1)
            {
                sbTemp.Clear();
                sbTemp.Append("Got good binaverage response");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.sendDA);
            }
            else if (returnValue == 0)
            {

                sbTemp.Clear();
                sbTemp.Append("Trying again for binaverage response");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();

                return ((int)Action.sendBinaverage);
            }
            else
            {

                sbTemp.Clear();
                sbTemp.Append("Didn't get binaverage response, restarting command timer");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
        }

        private int sendDAWait()
        {
            EngrLogger.writeToColumns("Sending da wait command");
            int returnValue = ctd1.waitForResponse(SBE41CTD.commands.da);

            if (returnValue == 1)
            {
                sbTemp.Clear();
                sbTemp.Append("Good da response; Upload sucessful");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.sendDAH);
            }
            else if (returnValue == 0)
            {

                sbTemp.Clear();
                sbTemp.Append("Trying again for da response");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();

                return ((int)Action.sendDA);
            }
            else
            {

                sbTemp.Clear();
                sbTemp.Append("Didn't get da response, restarting command timer");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
        }

        private int sendDAHWait()
        {
            EngrLogger.writeToColumns("Sending dah wait command");
            int returnValue = ctd1.waitForResponse(SBE41CTD.commands.dah);

            if (returnValue == 1)
            {
                sbTemp.Clear();
                sbTemp.Append("Good dah response; Upload sucessful");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
            else if (returnValue == 0)
            {

                sbTemp.Clear();
                sbTemp.Append("Trying again for dah response");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();

                return ((int)Action.sendDAH);
            }
            else
            {

                sbTemp.Clear();
                sbTemp.Append("Didn't get dah response, restarting command timer");
                EngrLogger.writeToColumns(sbTemp);
                sbTemp.Clear();
                return ((int)Action.restartCommandTimer);
            }
        }

        private int restartCommandTimer()
        {
            ctd1.sendCRLF();       //don't need to wait for response here (According to GM legacy code)
            Thread.Sleep(1000);
            buoyancyEngine.calcPIDConstants(MissionConfig.SBE41CommandModeSamplePeriod);
            ctd1.startCommandModeTimer(MissionConfig.SBE41CommandModeSamplePeriod);

            return ((int)Action.lastAction);
        }
    }

}
