using GenericWpfApp.Model;
using GenericWpfApp.View;
using GenericWpfApp.ViewModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace GenericWpfApp
{
   class WinProc
   {
      private static WinProc _proc = null;
      MainWindow _mainWindow;
      private ImpedanceCheckWindowViewModel _impedanceCheckWindowViewModel;

      private PassthroughData _passthroughData = new PassthroughData();


      private Dictionary<string, PowerModuleDataModel> _powerModuleToPowerDataModelDict = new Dictionary<string, PowerModuleDataModel>();

      public static WinProc Instance(MainWindow mainWindow = null)
      {
         if (_proc == null)
            _proc = new WinProc(mainWindow);

         return _proc;
      }
      private WinProc(MainWindow mainWindow)
      {
         _mainWindow = mainWindow;

         _powerModuleToPowerDataModelDict["UUT_P20V"] = new PowerModuleDataModel();
         _powerModuleToPowerDataModelDict["UUT_N20V"] = new PowerModuleDataModel();

         _mainWindow._mainWindowViewModel.AddPowerData(_powerModuleToPowerDataModelDict);

         _mainWindow._mainWindowViewModel.AddPassthroughData(_passthroughData.GetPassthroughDataModelDict());
      }

      public void PerformStto(ImpedanceCheckWindowViewModel impedanceCheckWindowViewModel)
      {
         _impedanceCheckWindowViewModel = impedanceCheckWindowViewModel;
         Task.Factory.StartNew(() => PerformSttoTask());
      }

      private async void PerformSttoTask()
      {
         bool forceFail = false;
         ImpedanceDataModel impedanceDataModel;

         ImpedanceCheckWindowViewModel.Images passFailImage = ImpedanceCheckWindowViewModel.Images.PASS_CHECK;
         int MAX_ITERATION = 15;
         for (int i = 1; i <= MAX_ITERATION; i++)
         {
            impedanceDataModel = new ImpedanceDataModel();
            if (i == MAX_ITERATION && forceFail)
               passFailImage = ImpedanceCheckWindowViewModel.Images.FAIL_CHECK;

            impedanceDataModel.PassFailImagePath = _impedanceCheckWindowViewModel._imageToResourcePathDict[passFailImage];
            impedanceDataModel.Description = "J17_P5_J17_P7 Measured 5 Range [0,10]";

            _impedanceCheckWindowViewModel.AddData(impedanceDataModel);

            await Task.Delay(300);
         }

         if (forceFail)
         {
            App.Current.Dispatcher.Invoke((Action)delegate
            {
               _mainWindow._impedanceCheckWindow.btnClose.Visibility = Visibility.Visible;
            });
         }
         else
         {
            App.Current.Dispatcher.Invoke((Action)delegate
            {
               _mainWindow._impedanceCheckWindow.Close();
            });
         }
      }

      public void StartPowerSupplyReadTask()
      {
         Task.Factory.StartNew(() => PowerSupplyReadTask());
      }

      private async void PowerSupplyReadTask()
      {
         //Debug.Write($"{System.Environment.CurrentManagedThreadId}");
         Random rnd = new Random();
         while (true)
         {
            rnd = new Random();

            float num = 20.0f + GenerateRandomFraction();
            _powerModuleToPowerDataModelDict["UUT_P20V"].ActualVoltage = num.ToString("0.00");
            _powerModuleToPowerDataModelDict["UUT_P20V"].ExpectedVoltage = "20.0";
            //Thread.Sleep(100);
            await Task.Delay(100);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            num = 1.0f + GenerateRandomFraction();
            _powerModuleToPowerDataModelDict["UUT_P20V"].ActualCurrent = num.ToString("0.00");
            _powerModuleToPowerDataModelDict["UUT_P20V"].ExpectedCurrent = "1.0";
            //Thread.Sleep(100);
            await Task.Delay(100);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            num = 20.0f + GenerateRandomFraction();
            _powerModuleToPowerDataModelDict["UUT_N20V"].ActualVoltage = num.ToString("0.00");
            _powerModuleToPowerDataModelDict["UUT_N20V"].ExpectedVoltage = "20.0";
            //Thread.Sleep(200);
            await Task.Delay(200);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            _mainWindow._mainWindowViewModel.UutPowerLedImagePath = _mainWindow._mainWindowViewModel._imageToResourcePathDict[MainWindowViewModel.Images.LED_ON];

            num = 5.0f + GenerateRandomFraction();
            _powerModuleToPowerDataModelDict["UUT_N20V"].ActualCurrent = num.ToString("0.00");
            _powerModuleToPowerDataModelDict["UUT_N20V"].ExpectedCurrent = "1.0";
            //Thread.Sleep(100);
            await Task.Delay(100);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            num = 70.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR1, num.ToString("0.00"));

            //Thread.Sleep(100);
            await Task.Delay(100);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            num = 30.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR2, num.ToString("0.00"));
            //Thread.Sleep(200);
            await Task.Delay(200);
            //Debug.WriteLine($"{System.Environment.CurrentManagedThreadId}");
            _mainWindow._mainWindowViewModel.UutPowerLedImagePath = _mainWindow._mainWindowViewModel._imageToResourcePathDict[MainWindowViewModel.Images.LED_OFF];
            num = 40.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR3, num.ToString("0.00"));
            //Thread.Sleep(100);
            await Task.Delay(100);
            num = 50.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR4, num.ToString("0.00"));
            //Thread.Sleep(100);
            await Task.Delay(100);
            num = 60.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR5, num.ToString("0.00"));
            //Thread.Sleep(200);
            await Task.Delay(200);
            _mainWindow._mainWindowViewModel.UutPowerLedImagePath = _mainWindow._mainWindowViewModel._imageToResourcePathDict[MainWindowViewModel.Images.LED_ON];
            num = 10.0f + GenerateRandomFraction();
            _passthroughData.SetValue(PassthroughData.Variables.VAR6, num.ToString("0.00"));
            //Thread.Sleep(1000);
            await Task.Delay(1000);
            _mainWindow._mainWindowViewModel.UutPowerLedImagePath = _mainWindow._mainWindowViewModel._imageToResourcePathDict[MainWindowViewModel.Images.LED_OFF];
         }
      }

      static float GenerateRandomFraction()
      {
         Random rnd = new Random();
         int randNum = 0;
         const int minimum = 1;

         randNum = rnd.Next(20);

         if (randNum <= minimum)
         {
            randNum += minimum;
         }

         return (float)(1.0 / (float)randNum);
      }
   }
}
