using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ICC4cPwmSdk.Device;
using ICC4cPwmSdk.Dtos;

namespace Ecc1cExample
{
    internal class Example
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Stating basic ECC-1C example...");
            Ecc1cSdkDeviceController controller;

            while (true)
            {
                controller = new Ecc1cSdkDeviceController();
                Console.WriteLine("What is the COM number of the ECC-1C?");
                var comport = Console.ReadLine();
                if (int.TryParse(comport, out var comInt))
                {
                    //Connecting to driver
                    if (controller.Connect(comInt))
                    {
                        break;
                    }
                    Console.WriteLine("Connection failed.");
                }
            }

            //Set board to PRO mode
            controller.ChangeModeToPro();

            //Getting board info
            Console.WriteLine("Board info");
            var serialNumber = controller.GetElectronicSerialNumber();
            var fwVersion =
                $"{controller.Status.GetBoardFirmwareMajorVersion()}.{controller.Status.GetBoardFirmwareMinorVersion()}.{controller.Status.GetBoardFirmwareRevisionVersion()}";

            Console.WriteLine($"Board serial number: {serialNumber}");
            Console.WriteLine($"Board firmware version: {fwVersion}");

            // In order to drive the connected product, device type of the product has to be obtained (this is not needed if
            // automatic detection is allowed)
            var connectedDevice = controller.MiscFeatures.GetDeviceType();
            Console.WriteLine();
            Console.WriteLine(
                $"Connected device: {Enum.GetName(typeof(EConnectedDeviceType), connectedDevice)}");
            Console.WriteLine();

            //Supported lens types
            var lensesTypes = new[]
            {
                EConnectedDeviceType.EL1030C,
                EConnectedDeviceType.EL1030TC,
                EConnectedDeviceType.EL1230TC,
                EConnectedDeviceType.EL1640TC,
                
            };
            

            if (!lensesTypes.Contains(connectedDevice))
            {
                Console.WriteLine("No lens connected");
            }
            else
            {
                //ECC-1C supports only one channel EChannel.Channel0
                var lensSerialNumber = controller.GetLensSerialNumber();
                Console.WriteLine(
                    $"Lens {Enum.GetName(typeof(EConnectedDeviceType), connectedDevice)} ({lensSerialNumber})");

                var lensTemperature = controller.TemperatureManager.GetDeviceTemperature();

                Console.WriteLine($"Lens temperature: {lensTemperature}°C");

                var minCurrent = controller.DeviceEeprom.GetMaxNegativeCurrent();
                var maxCurrent = controller.DeviceEeprom.GetMaxPositiveCurrent();

                Console.WriteLine($"Minimum current is {minCurrent} mA, maximum current is {maxCurrent} mA");

                Console.WriteLine();
                Console.WriteLine("Setting static current");
                //Setting input system to static input
                controller.InputStage.ChangeActiveSystem(EInputSignalStageSystem.StaticInput);

                for (var current = minCurrent; current <= maxCurrent; current += (maxCurrent - minCurrent) / 5)
                {
                    //Value has to be converted from mA to A
                    var currentInA = current / 1000;
                    Console.WriteLine($"Current {currentInA} A");
                    controller.InputStage.StaticValue.SetCurrent(currentInA);
                    //Diopter can be set similarly
                    //controller.InputStage.StaticValue.SetDiopter(lensChannel, diopterInDpt);
                    Thread.Sleep(1000);
                }

                Console.WriteLine("Setting static current to 0 A");
                controller.InputStage.StaticValue.SetCurrent(0);

                Console.WriteLine();
                Console.WriteLine("Running signal generator");

                controller.InputStage.ChangeActiveSystem(EInputSignalStageSystem.SignalGenerator);
                controller.InputStage.SignalGenerator.SetUnitType(EICC4cPwmUnitType.Current);
                controller.InputStage.SignalGenerator.SetShape(ESignalGeneratorShape.Sinusoidal);
                controller.InputStage.SignalGenerator.SetAmplitude(0.2f);
                controller.InputStage.SignalGenerator.SetFrequency(5);
                controller.InputStage.SignalGenerator.SwitchRunning(true);

                for (var i = 0; i < 5; i++)
                {
                    Console.Write(".");
                    Thread.Sleep(1000);
                }

                controller.InputStage.SignalGenerator.SwitchRunning(false);

                Console.WriteLine();
                Console.WriteLine("Signal generator stopped");

                Console.WriteLine();
                Console.WriteLine("Device EEPROM");

                var eepromVersion =
                    $"{controller.DeviceEeprom.GetEepromVersion()}.{controller.DeviceEeprom.GetEepromSubVersion()}";
                Console.WriteLine($"EEPROM version: {eepromVersion}");

                var eepromBytes = controller.DeviceEeprom.GetBytes(0, 10);
                var eepromSize = controller.DeviceEeprom.GetDeviceEepromSize();

                Console.WriteLine(
                    $"Printing {eepromBytes.Length}/{eepromSize} bytes saved in EEPROM: {string.Join(", ", eepromBytes)}");
            }

            Console.WriteLine();
            Console.WriteLine("Example finished.");
            Console.ReadLine();
        }
    }
}
