using Hawkeye.VisionBuilder.UI.Sources.Emulation;
using Inspectron.Settings;
using Inspectron.Settings.Windows.Configuration;
using Lindt.Colorballs.Duo.Utils;
using Ninject;
using Ninject.Extensions.ChildKernel;
using OpenCvSharp;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using VisionBuilder.UI.Camera;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Commands;
using VisionBuilder.UI.Common.Plugins;
using VisionBuilder.UI.Common.Processing;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.Common.ViewModel.Classes;
using VisionBuilder.UI.Common.ViewModel.Interfaces.UI;
using VisionBuilder.UI.Console;
using VisionBuilder.UI.IOCommander;
using VisionBuilder.UI.Recipes.HawkeyeRecipe;
using VisionBuilder.UI.Ringbuffer;
using VisionBuilder.UI.Statistics;
using VisionBuilder.UI.Windows.Settings;

namespace VisionBuilder.UI.Windows.Test
{
    internal static class Program
    {
        private const string CAMERA1 = "Camera 1";
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {

            //AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
            //{
            //    File.AppendAllText("timeout_log.txt",
            //        $"[{DateTime.Now:O}] {e.Exception.GetType().FullName}: {e.Exception.Message}\n" +
            //        $"{e.Exception.StackTrace}\n" +
            //        $"--- Inner: {e.Exception.InnerException}\n\n");
            //};
            // To customize application configuration such as set high DPI settings or default font,
            // see https://aka.ms/applicationconfiguration.
            ApplicationConfiguration.Initialize();
            // In your application startup code
            MaterialSkin.MaterialSkinManager.ConfigureForInspectron();
            CommandLineParser commandLineParser = new CommandLineParser(args);


            InspectronSettings settings = new InspectronSettings("..\\Data\\Config");

            var mainKernel = Common.VisionBuilder.CreateMainKernel(settings);

            var profile = commandLineParser.GetStringArgument("profile", 'p');

            mainKernel.UsePlugins(profile);


            mainKernel
                .UseConsole()
                .UseIOCommander([CAMERA1])
                .UseIOCommanderWindowsDebug()
                .UseIOCommanderVirtualInput()
                .UseWindowsServices()
                .RegisterGlobalPlugins()
                ;

            mainKernel.Get<ILoadingService>().StartLoading("Camera initialization");
            

            // CAMERA 1 //
            ChildKernel kernelCamera1 = new ChildKernel(mainKernel);
            
            
            // MODULES //
            kernelCamera1
                .RegisterCamera(CAMERA1)
                .UseStatistics(CAMERA1)
                .UseRingbuffer(CAMERA1)
                .UseHawkeyeRecipes(CAMERA1)
                .UseCameraIOCommander(CAMERA1)
                .RegisterCameraPlugins(CAMERA1)
                ;
            
            
            // LOAD SETTINGS //
            mainKernel.RegisterSettings();
            kernelCamera1.RegisterSettings();
            settings.LoadSettings();

            // Create camera and bind it
            // Must be done after settings are loaded
            kernelCamera1.UseCamera();

            // initialize modules
            mainKernel.InitializeModules(); 
            kernelCamera1.InitializeModules();

            mainKernel.Get<ILoadingService>().StopLoading("Camera initialization");

            

            var mainWindowVm = mainKernel.Get<MainWindowVM>();
            mainWindowVm.SingleCameraVms = [
                kernelCamera1.Get<SingleCameraVM>()
            ];
            
            var form = mainKernel.Get<Form1>();

            settings.LoadSettings();

            Application.Run(form);
        }
    }

  

   
}