using Inspectron.Settings;
using Lindt.Colorballs.Duo.Utils;
using Ninject;
using Ninject.Extensions.ChildKernel;
using VisionBuilder.UI.Camera;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Processing;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.IOCommander;
using VisionBuilder.UI.Recipes.HawkeyeRecipe;
using VisionBuilder.UI.Ringbuffer;
using VisionBuilder.UI.Statistics;
using VisionBuilder.UI.Windows;
using VisionBuilder.UI.Windows.Duo;

internal static class Program
{
    private const string CAMERA1 = "Camera 1";
    private const string CAMERA2 = "Camera 2";
    /// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // 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(Path.Combine("..", "Data", "Config"));

        var mainKernel = VisionBuilder.UI.Common.VisionBuilder.CreateMainKernel(settings);
        var profile = commandLineParser.GetStringArgument("profile", 'p');
        mainKernel.UsePlugins(profile);


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

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


        // CAMERAS //
        ChildKernel kernelCamera1 = new ChildKernel(mainKernel);
        ChildKernel kernelCamera2 = new ChildKernel(mainKernel);

        // MODULES //
        kernelCamera1
            .RegisterCamera(CAMERA1)
            .UseStatistics(CAMERA1)
            .UseRingbuffer(CAMERA1)
            .UseHawkeyeRecipes(CAMERA1)
            .UseCameraIOCommander(CAMERA1)
            .RegisterCameraPlugins(CAMERA1)
            ;

        kernelCamera2
            .RegisterCamera(CAMERA2)
            .UseStatistics(CAMERA2)
            .UseRingbuffer(CAMERA2)
            .UseHawkeyeRecipes(CAMERA2)
            .UseCameraIOCommander(CAMERA2)
            .RegisterCameraPlugins(CAMERA2)
            ;

        // LOAD SETTINGS //
        mainKernel.RegisterSettings();
        kernelCamera1.RegisterSettings();
        kernelCamera2.RegisterSettings();
        settings.LoadSettings();

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

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

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



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

        var form = mainKernel.Get<Form1>();

        settings.LoadSettings();

        Application.Run(form);
    }
}