using GeneralModuleCore.Dtos;
using MrEModuleSdk.Devices.Mre3;
using MrEModuleSdk.Dto;
using System;

namespace Mre3Example
{
    public partial class Mre3Example
    {
        private static void RunOperationModesExample(IMrE3SdkComDeviceController controller)
        {
            Console.WriteLine("Operation modes example");
            Console.WriteLine("Cycles through all operation modes and starts the signal generator with matching unit types.");
            Console.WriteLine();

            const float amplitude = 0.25f;
            const float frequency = 1.0f;
            const float offset = 0.0f;
            const float phaseDelay1 = 0.0f;
            const float phaseDelay2 = 90.0f;
            const bool isRunning = true;
            var shape = EWaveformShape.Sine;
            var sgValues1 = new SignalGeneratorValuesDto(amplitude, frequency, offset, phaseDelay1, (int)shape, isRunning);
            var sgValues2 = new SignalGeneratorValuesDto(amplitude, frequency, offset, phaseDelay2, (int)shape, isRunning);

            foreach (EOperationMode system in Enum.GetValues(typeof(EOperationMode)))
            {
                Console.WriteLine($"Set operation mode: {system}");
                controller.SignalFlowManager.ControlModeStage.SetOperationMode(system);

                var xSystem = controller.SignalFlowManager.ControlModeStage.ReadActiveSystem(EAxis.X);
                var ySystem = controller.SignalFlowManager.ControlModeStage.ReadActiveSystem(EAxis.Y);
                Console.WriteLine($"Configured control system on axis X: {xSystem}");
                Console.WriteLine($"Configured control system on axis Y: {ySystem}");

                var xUnitType = ResolveUnitType(xSystem);
                var yUnitType = ResolveUnitType(ySystem);
                Console.WriteLine($"Resolved unit type on axis X: {xUnitType}");
                Console.WriteLine($"Resolved unit type on axis Y: {yUnitType}");

                StartSignalGenerator(controller, EAxis.X, sgValues1, xUnitType);
                StartSignalGenerator(controller, EAxis.Y, sgValues2, yUnitType);

                WaitForEnter("Observe the mirror behavior, then press Enter to continue to the next operation mode.");
                controller.SignalFlowManager.InputStage.SignalGenerator.SwitchRunning(EAxis.X, false);
                controller.SignalFlowManager.InputStage.SignalGenerator.SwitchRunning(EAxis.Y, false);
                Console.WriteLine();
            }

            Console.WriteLine("All operation modes tested.");
        }

        private static void StartSignalGenerator(IMrE3SdkComDeviceController controller, EAxis axis, SignalGeneratorValuesDto sgValues, EUnitType unitType)
        {
            controller.SignalFlowManager.InputStage.ChangeActiveSystem(axis, EmrEInputStageSystems.SignalGenerator);
            controller.SignalFlowManager.InputStage.SignalGenerator.WriteSignalGeneratorValues(sgValues, axis);
            controller.SignalFlowManager.InputStage.SignalGenerator.WriteUnitType(axis, unitType);
        }

        private static EUnitType ResolveUnitType(EMrEControlModeSystems controlMode)
        {
            switch (controlMode)
            {
                case EMrEControlModeSystems.OpenLoop:
                    return EUnitType.Current;
                case EMrEControlModeSystems.ClosedLoopOf:
                    return EUnitType.OpticalFeedback;
                case EMrEControlModeSystems.ClosedLoopAngle:
                    return EUnitType.XY;
                default:
                    return EUnitType.Undefined;
            }
        }
    }
}
