using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ImageCatalog_2;
using ImageCatalog_2.Services;
using MaddoShared;
using Microsoft.Extensions.Logging;

namespace ImageCatalog;

public delegate void XyThreadAdd(string Info);

public partial class MainForm
{
    private readonly DataModel Model;
        
    private readonly ILogger<MainForm> _logger;

    private readonly ImageCreationStuff _imageCreationService;

    private readonly ParametriSetup _parametriSetup;
    private readonly PicSettings _picSettings;
    
    public MainForm(DataModel model, ImageCreationStuff imageCreationStuff, PicSettings picSettings, ParametriSetup parametriSetup, ILogger<MainForm> logger)
    {
        Model = model;
        _imageCreationService = imageCreationStuff;
        _parametriSetup = parametriSetup;
        _picSettings = picSettings;
        
        _logger = logger;

        _logger.LogDebug("Start");

        InitializeComponent();

        BindControls();

        _Button3.Name = "Button3";
        _Button2.Name = "Button2";
        _Button8.Name = "Button8";
        _CheckBox18.Name = "CheckBox18";
        _CheckBox4.Name = "CheckBox4";
        _CheckBox12.Name = "CheckBox12";
        _PictureBox1.Name = "PictureBox1";
        _Button4.Name = "Button4";
        _Label27.Name = "Label27";
        _Button7.Name = "Button7";
        _Button5.Name = "Button5";
        //_btnCreaCatalogo.Name = "btnCreaCatalogo";
        _Button6.Name = "Button6";
        _btnCreaCatalogoAsync.Name = "btnCreaCatalogoAsync";

        var version = Assembly.GetExecutingAssembly().GetName().Version;
        _Label27.Text = $"Version: {version.Major}.{version.Minor}.{version.Build}.{version.Revision}";

        _results = new ConcurrentBag<string>();
        UiUpdateEvent += OnUiUpdateEvent;
    }

    protected void BindControls()
    {
        //txtSorgente.DataBindings.Add(new Binding("Text", SourcePath, ""));
    }

    private event EventHandler<Tuple<string, int>> UiUpdateEvent;

    delegate void SetTextCallback(Label target, string text);

    private void SetText(Label target, string text)
    {
        if (InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { target, text });
        }
        else
        {
            target.Text = text;
        }
    }

    delegate void SetProgressCallback(ProgressBar target, int amount, int maximum);

    private void SetProgress(ProgressBar target, int amount, int maximum)
    {
        if (InvokeRequired)
        {
            SetProgressCallback d = new SetProgressCallback(SetProgress);
            this.Invoke(d, new object[] { target, amount, maximum });
        }
        else
        {
            target.Maximum = maximum;
            target.Value = amount;
        }
    }

    private void OnUiUpdateEvent(object sender, Tuple<string, int> args)
    {
        SetProgress(ProgressBar1, _results.Count, args.Item2);
        SetText(Label18, _results.Count.ToString());
        SetText(Label10, args.Item1);
        SetText(lblFotoTotaliNum, args.Item2.ToString());
    }

    /* TODO ERROR: Skipped DefineDirectiveTrivia */
    private bool StopAttivo;
    private bool WaterSelectColor = false;

    // Private ContaFotoCuori As Integer
    // Private TaskCuori() As PicInfo
    
    private int ContaImmaginiThread;
    private int maxThreads = 15;
    private int minThreads = 5;

    private ConcurrentBag<string> _results;

    private void setDefaults()
    {
        //txtSorgente.Text = "";
        Model.SourcePath = string.Empty;
        Model.DestinationPath = string.Empty;
        TextBox3.Text = "tn_";
        Model.HorizontalText = "";
        TextBox5.Text = "350";
        TextBox6.Text = "350";
        TextBox27.Text = "2240";
        TextBox28.Text = "2240";
        TextBox9.Text = "0";
        TextBox11.Text = "20";
        TextBox12.Text = "8";
        // TextBox13.Text = ""
        TextBox10.Text = "";
        TextBox14.Text = "430";
        TextBox15.Text = "430";
        TextBox16.Text = "290";
        txtFilePerCartella.Text = "99";
        TextBox19.Text = "100";
        txtSuffissoCartelle.Text = "";
        txtCifreContatore.Text = "2";
        TextBox25.Text = "50";
        TextBox26.Text = "";
        TextBox7.Text = 4.ToString();
        TextBox8.Text = 4.ToString();
        TextBox34.Text = "Yellow";
        TextBox30.Text = "20";
        TextBox31.Text = "6";
        TextBox32.Text = "85";
        TextBox33.Text = "30";
        ComboBox1.Items.Add("Alto");
        ComboBox1.Items.Add("Basso");
        ComboBox1.SelectedIndex = 1;
        ComboBox2.Items.Add("Sinistra");
        ComboBox2.Items.Add("Centro");
        ComboBox2.Items.Add("Destra");
        ComboBox2.SelectedIndex = 1;

        // Create a obejct of InstalledFontCollection
        var InstalledFonts = new InstalledFontCollection();
        // Gets the array of FontFamily objects associated with this FontCollection.
        var fontfamilies = InstalledFonts.Families;

        // Populates font combobox with the font name

        foreach (FontFamily fontFamily in fontfamilies)
            ComboBox3.Items.Add(fontFamily.Name);
        ComboBox3.Text = ComboBox3.Items[0].ToString();

        // ComboBox3.Items.Add("Arial")
        // ComboBox3.Items.Add("Arial Black")
        // ComboBox3.Items.Add("Arial Narrow")
        // ComboBox3.Items.Add("Comic Sans MS")
        // ComboBox3.Items.Add("Courier New")
        // ComboBox3.Items.Add("System")
        // ComboBox3.Items.Add("Times New Roman")
        // ComboBox3.Items.Add("Verdana")
        // ComboBox3.Items.Add("Wingdings")
        // ComboBox3.SelectedIndex = 7

        ComboBox4.Items.Add("Sinistra");
        ComboBox4.Items.Add("Centro");
        ComboBox4.Items.Add("Destra");
        ComboBox4.SelectedIndex = 2;
        ComboBox5.Items.Add("Alto");
        ComboBox5.Items.Add("Centro");
        ComboBox5.Items.Add("Basso");
        ComboBox5.SelectedIndex = 2;
    }


    private void Form1_Load(object sender, EventArgs e)
    {
        bindingSource1.DataSource = Model;
        Application.EnableVisualStyles();
        setDefaults();
        // /* TODO ERROR: Skipped IfDirectiveTrivia */
        // AllocConsole();
        // /* TODO ERROR: Skipped EndIfDirectiveTrivia */
        _logger.LogInformation("Programma Avviato");
        //Console.WriteLine("Programma avviato");
    }

    private void FixPaths()
    {
        Model.SourcePath = FixPath(Model.SourcePath);
        Model.DestinationPath = FixPath(Model.DestinationPath);
    }

    private string FixPath(string path)
    {
        if (string.IsNullOrWhiteSpace(path))
        {
            return string.Empty;
        }

        // Trim leading/trailing quotes
        path = path.Trim().Trim('"');

        // Normalize directory separators
        path = path.Replace('/', Path.DirectorySeparatorChar)
            .Replace('\\', Path.DirectorySeparatorChar);

        // Remove trailing separators then add one back
        path = path.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;

        return path;
    }

    private void lockUI()
    {
        Model.UiEnabled = false;
        //TabControl1.Enabled = false;
        //Button5.Enabled = false;
        //Button6.Enabled = false;
        //btnCreaCatalogoAsync.Enabled = false;
    }

    private void unlockUI()
    {
        Model.UiEnabled = true;
        //TabControl1.Enabled = true;
        //Button5.Enabled = true;
        //Button6.Enabled = true;
        //btnCreaCatalogoAsync.Enabled = true;
    }

    private string CalcTime(DateTime timeStart, DateTime timeStop, int numFoto)
    {
        long timediffH, timediffS;
        long timediffM;
        
        TimeSpan timeDiff = timeStop - timeStart;

        timediffM = (int)timeDiff.TotalMinutes;
        timediffS = (int)timeDiff.TotalSeconds;
        timediffH = (int)timeDiff.TotalHours;
        
        // timediffM = DateAndTime.DateDiff(DateInterval.Minute, timeStart, timeStop);
        // timediffS = DateAndTime.DateDiff(DateInterval.Second, timeStart, timeStop);
        // timediffH = DateAndTime.DateDiff(DateInterval.Hour, timeStart, timeStop);
       
        double fotoSec = numFoto / (double)timediffS;
        double fotoMin = numFoto / (double)timediffM;
        double fotoOra = numFoto / (double)timediffH;
        string s = "S: " + timediffS.ToString() + "; F/s: " +
                   fotoSec.ToString(
                       "0.000"); // + " F/m: " + fotoMin.ToString("0.00") + " F/h: " + fotoOra.ToString("0.00")
        return s;
    }

    private string SelectFolder(string startingFolder)
    {
        var dialog = new FolderBrowserDialog();
        dialog.InitialDirectory = startingFolder;
        if (dialog.ShowDialog() != DialogResult.OK) return string.Empty;
        
        var directoryScelta = FixPath(dialog.SelectedPath); // dialog.FileName;

        return directoryScelta;
    }

    private void Button2_Click(object sender, EventArgs e)
    {
        var dialogResult = SelectFolder(Model.SourcePath);
        if (!string.IsNullOrWhiteSpace(dialogResult))
        {
            Model.SourcePath = dialogResult;
        }
    }

    private void Button3_Click(object sender, EventArgs e)
    {
        var dialogResult = SelectFolder(Model.DestinationPath);
        if (!string.IsNullOrWhiteSpace(dialogResult))
        {
            Model.DestinationPath = dialogResult;
        }
    }

    private void Button5_Click(object sender, EventArgs e)
    {
        var SaveFileDlg = new SaveFileDialog();

        // SaveFileDlg.InitialDirectory = "c:\"
        SaveFileDlg.Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*";
        SaveFileDlg.FilterIndex = 0;
        SaveFileDlg.RestoreDirectory = true;
        if (DialogResult.OK == SaveFileDlg.ShowDialog())
        {
            string IlNome = SaveFileDlg.FileName;
            _parametriSetup.NomeFileSetup = IlNome;
            _parametriSetup.AggiornaParametro("DirSorgente", Model.SourcePath);
            _parametriSetup.AggiornaParametro("DirDestinazione", Model.DestinationPath);
            _parametriSetup.AggiornaParametro("DirSottoDirectory", chkAggiornaSottodirectory.Checked);
            _parametriSetup.AggiornaParametro("DirDividiDestinazione", chkCreaSottocartelle.Checked);
            _parametriSetup.AggiornaParametro("DirDividiNumFile", txtFilePerCartella.Text);
            _parametriSetup.AggiornaParametro("DirDividiSuffisso", txtSuffissoCartelle.Text);
            _parametriSetup.AggiornaParametro("DirDividiNumCifre", txtCifreContatore.Text);
            if (rdbNumProgressiva.Checked == true)
            {
                _parametriSetup.AggiornaParametro("DirDividiTipoNumerazione", "Progressiva");
            }
            else
            {
                _parametriSetup.AggiornaParametro("DirDividiTipoNumerazione", "Files");
            }

            _parametriSetup.AggiornaParametro("MiniatureCrea", CheckBox1.Checked);
            _parametriSetup.AggiornaParametro("MiniatureSuffisso", TextBox3.Text);
            _parametriSetup.AggiornaParametro("MiniatureAltezza", TextBox5.Text);
            _parametriSetup.AggiornaParametro("MiniatureLarghezza", TextBox6.Text);
            _parametriSetup.AggiornaParametro("MiniatureAddScritta", RadioButton3.Checked);
            _parametriSetup.AggiornaParametro("MiniatureAddOrario", RadioButton4.Checked);
            _parametriSetup.AggiornaParametro("FotoAltezza", TextBox27.Text);
            _parametriSetup.AggiornaParametro("FotoLarghezza", TextBox28.Text);
            // SetupIni.AggiornaParametro("FotoCodice", TextBox13.Text)
            // SetupIni.AggiornaParametro("FotoDimOriginali", CheckBox2.Checked)

            _parametriSetup.AggiornaParametro("FontDimensione", TextBox11.Text);
            _parametriSetup.AggiornaParametro("FontDimensioneMiniatura", TextBox25.Text);
            _parametriSetup.AggiornaParametro("FontBold", CheckBox3.Checked);
            _parametriSetup.AggiornaParametro("FontNome", ComboBox3.Text);
            _parametriSetup.AggiornaParametro("TestoTesto", Model.HorizontalText);
            _parametriSetup.AggiornaParametro("TestoTrasparente", TextBox9.Text);
            _parametriSetup.AggiornaParametro("TestoMargine", TextBox12.Text);
            _parametriSetup.AggiornaParametro("TestoPosizione", ComboBox1.Text);
            _parametriSetup.AggiornaParametro("TestoAllineamento", ComboBox2.Text);
            _parametriSetup.AggiornaParametro("MarchioFile", TextBox10.Text);
            _parametriSetup.AggiornaParametro("MarchioAltezza", TextBox14.Text);
            _parametriSetup.AggiornaParametro("MarchioLarghezza", TextBox15.Text);
            _parametriSetup.AggiornaParametro("MarchioMargine", TextBox16.Text);
            _parametriSetup.AggiornaParametro("MarchioAllOrizzontale", ComboBox4.Text);
            _parametriSetup.AggiornaParametro("MarchioAllVerticale", ComboBox5.Text);
            _parametriSetup.AggiornaParametro("MarchioTrasparenza", TextBox19.Text);
            _parametriSetup.AggiornaParametro("MarchioAggiungi", CheckBox5.Checked);
            _parametriSetup.AggiornaParametro("TempoGara", CheckBox7.Checked);
            _parametriSetup.AggiornaParametro("Orario", CheckBox8.Checked);
            _parametriSetup.AggiornaParametro("EtichettaOrario", TextBox18.Text);
            _parametriSetup.AggiornaParametro("GeneraleForzaJpg", chkForzaJpg.Checked);
            _parametriSetup.AggiornaParametro("GeneraleRotazioneAutomatica", chkRotazioneAutomatica.Checked);
            _parametriSetup.AggiornaParametro("GrandezzaVerticale", TextBox30.Text);
            _parametriSetup.AggiornaParametro("MargineVerticale", TextBox31.Text);
            _parametriSetup.AggiornaParametro("DimensioniOriginali", CheckBox15.Checked);
            _parametriSetup.AggiornaParametro("TestoVerticale", Model.VerticalText);
            _parametriSetup.AggiornaParametro("NomeMiniatura", RadioButton6.Checked);
            _parametriSetup.AggiornaParametro("DataFoto", CheckBox16.Checked);
            _parametriSetup.AggiornaParametro("NumeroFoto", CheckBox17.Checked);
            _parametriSetup.AggiornaParametro("ColoreTestoRGB", TextBox34.Text);
            _parametriSetup.AggiornaParametro("TempoSmall", RadioButton5.Checked);
            _parametriSetup.AggiornaParametro("NumTempoSmall", RadioButton7.Checked);
            _parametriSetup.AggiornaParametro("CompressioneJpeg", TextBox32.Text);
            _parametriSetup.AggiornaParametro("CompressioneJpegMiniatura", TextBox33.Text);
            // 2021
            _parametriSetup.AggiornaParametro("ChunkSize", TextBox8.Text);
            _parametriSetup.AggiornaParametro("ThreadsCount", TextBox7.Text);
            _parametriSetup.SalvaParametriSetup();
            Text = "Image Catalog - " + LeggiSoloNomeFile(IlNome);
        }
    }

    private void Button6_Click(object sender, EventArgs e)
    {
        var openFileDialog = new OpenFileDialog();

        // openFileDialog.InitialDirectory = TextBox1.Text
        openFileDialog.Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*";
        openFileDialog.FilterIndex = 0;
        openFileDialog.RestoreDirectory = true;
        if (DialogResult.OK == openFileDialog.ShowDialog())
        {
            string IlNome = openFileDialog.FileName;
            _parametriSetup.NomeFileSetup = IlNome;
            _parametriSetup.CaricaParametriSetup();
            Model.SourcePath = _parametriSetup.LeggiParametroString("DirSorgente");
            Model.DestinationPath = _parametriSetup.LeggiParametroString("DirDestinazione");
            chkAggiornaSottodirectory.Checked = _parametriSetup.LeggiParametroBoolean("DirSottoDirectory");
            chkCreaSottocartelle.Checked = _parametriSetup.LeggiParametroBoolean("DirDividiDestinazione");
            txtFilePerCartella.Text = _parametriSetup.LeggiParametroString("DirDividiNumFile");
            txtSuffissoCartelle.Text = _parametriSetup.LeggiParametroString("DirDividiSuffisso");
            txtCifreContatore.Text = _parametriSetup.LeggiParametroString("DirDividiNumCifre");
            string TestoTemp = _parametriSetup.LeggiParametroString("DirDividiTipoNumerazione");
            if (TestoTemp.ToUpper() == "PROGRESSIVA")
            {
                rdbNumProgressiva.Checked = true;
            }
            else
            {
                rdbNumFiles.Checked = true;
            }

            CheckBox1.Checked = _parametriSetup.LeggiParametroBoolean("MiniatureCrea");
            TextBox3.Text = _parametriSetup.LeggiParametroString("MiniatureSuffisso");
            TextBox5.Text = _parametriSetup.LeggiParametroString("MiniatureAltezza");
            TextBox6.Text = _parametriSetup.LeggiParametroString("MiniatureLarghezza");
            RadioButton3.Checked = _parametriSetup.LeggiParametroBoolean("MiniatureAddScritta");
            RadioButton4.Checked = _parametriSetup.LeggiParametroBoolean("MiniatureAddOrario");
            TextBox27.Text = _parametriSetup.LeggiParametroString("FotoAltezza");
            TextBox28.Text = _parametriSetup.LeggiParametroString("FotoLarghezza");
            // TextBox13.Text = SetupIni.LeggiParametroString("FotoCodice")
            // CheckBox2.Checked = SetupIni.LeggiParametroBoolean("FotoDimOriginali")

            TextBox11.Text = _parametriSetup.LeggiParametroString("FontDimensione");
            TextBox25.Text = _parametriSetup.LeggiParametroString("FontDimensioneMiniatura");
            CheckBox3.Checked = _parametriSetup.LeggiParametroBoolean("FontBold");
            ComboBox3.Text = _parametriSetup.LeggiParametroString("FontNome");
            if (string.IsNullOrEmpty(TextBox25.Text))
            {
                TextBox25.Text = "0";
            }

            Model.HorizontalText = _parametriSetup.LeggiParametroString("TestoTesto");
            TextBox9.Text = _parametriSetup.LeggiParametroString("TestoTrasparente");
            TextBox12.Text = _parametriSetup.LeggiParametroString("TestoMargine");
            ComboBox1.Text = _parametriSetup.LeggiParametroString("TestoPosizione");
            ComboBox2.Text = _parametriSetup.LeggiParametroString("TestoAllineamento");
            TextBox10.Text = _parametriSetup.LeggiParametroString("MarchioFile");
            TextBox14.Text = _parametriSetup.LeggiParametroString("MarchioAltezza");
            TextBox15.Text = _parametriSetup.LeggiParametroString("MarchioLarghezza");
            TextBox16.Text = _parametriSetup.LeggiParametroString("MarchioMargine");
            ComboBox4.Text = _parametriSetup.LeggiParametroString("MarchioAllOrizzontale");
            ComboBox5.Text = _parametriSetup.LeggiParametroString("MarchioAllVerticale");
            TextBox19.Text = _parametriSetup.LeggiParametroString("MarchioTrasparenza");
            CheckBox5.Checked = _parametriSetup.LeggiParametroBoolean("MarchioAggiungi");
            CheckBox7.Checked = _parametriSetup.LeggiParametroBoolean("TempoGara");
            CheckBox8.Checked = _parametriSetup.LeggiParametroBoolean("Orario");
            TextBox18.Text = _parametriSetup.LeggiParametroString("EtichettaOrario");
            chkForzaJpg.Checked = _parametriSetup.LeggiParametroBoolean("GeneraleForzaJpg");
            chkRotazioneAutomatica.Checked = _parametriSetup.LeggiParametroBoolean("GeneraleRotazioneAutomatica");
            TextBox30.Text = _parametriSetup.LeggiParametroString("GrandezzaVerticale");
            TextBox31.Text = _parametriSetup.LeggiParametroString("MargineVerticale");
            CheckBox15.Checked = _parametriSetup.LeggiParametroBoolean("DimensioniOriginali");
            Model.VerticalText = _parametriSetup.LeggiParametroString("TestoVerticale");
            RadioButton6.Checked = _parametriSetup.LeggiParametroBoolean("NomeMiniatura");
            CheckBox16.Checked = _parametriSetup.LeggiParametroBoolean("DataFoto");
            CheckBox17.Checked = _parametriSetup.LeggiParametroBoolean("NumeroFoto");
            RadioButton5.Checked = _parametriSetup.LeggiParametroBoolean("TempoSmall");
            RadioButton7.Checked = _parametriSetup.LeggiParametroBoolean("NumTempoSmall");
            TextBox32.Text = _parametriSetup.LeggiParametroString("CompressioneJpeg");
            TextBox33.Text = _parametriSetup.LeggiParametroString("CompressioneJpegMiniatura");
            TextBox34.Text = _parametriSetup.LeggiParametroString("ColoreTestoRGB");
            if (File.Exists(TextBox10.Text))
            {
                PictureBox1.Image = Image.FromFile(TextBox10.Text);
                if (PictureBox1.Image.Height >= PictureBox1.Image.Width)
                {
                    PictureBox1.Height = 160;
                    PictureBox1.Width =  
                        (int)(160 * PictureBox1.Image.Width / (double)PictureBox1.Image.Height);
                }
                else
                {
                    PictureBox1.Width = 224;
                    PictureBox1.Height =
                        (int)(224 * PictureBox1.Image.Height / (double)PictureBox1.Image.Width);
                }
            }

            Text = "Image Catalog - " + LeggiSoloNomeFile(IlNome);

            // 2021
            TextBox8.Text = _parametriSetup.LeggiParametroString("ChunkSize");
            TextBox7.Text = _parametriSetup.LeggiParametroString("ThreadsCount");
        }
    }

    private void SetPicSettings(string SourcePath, string DestPath)
    {
        var SourceDir = new DirectoryInfo(SourcePath);
        var DestDirStart = new DirectoryInfo(DestPath);
        DirectoryInfo DestDir = null;
        _picSettings.DirectorySorgente = SourcePath;
        _picSettings.DirectoryDestinazione = Model.DestinationPath;

        // _picSettings.DestDir = DestDir
        // _picSettings.SourceDir = SourceDir
        // _picSettings.DestDirStart = DestDirStart

        _picSettings.DimStandard = int.Parse(TextBox11.Text);
        _picSettings.DimStandardMiniatura = int.Parse(TextBox25.Text);
        _picSettings.UsaOrarioMiniatura = CheckBox12.Checked;
        _picSettings.UsaOrarioTestoApplicare = CheckBox8.Checked;
        _picSettings.UsaTempoGaraTestoApplicare = CheckBox7.Checked;
        _picSettings.UsaRotazioneAutomatica = chkRotazioneAutomatica.Checked;
        _picSettings.UsaForzaJpg = chkForzaJpg.Checked;
        if (CheckBox17.Checked)
        {
            _picSettings.TestoNome = true;
        }
        else
        {
            _picSettings.TestoNome = false;
        }

        if (CheckBox16.Checked)
        {
            _picSettings.NomeData = true;
        }
        else
        {
            _picSettings.NomeData = false;
        }

        _picSettings.TestoFirmaStart = Model.HorizontalText;
        _picSettings.TestoFirmaStartV = Model.VerticalText;
        _picSettings.DataPartenza = DateTimePicker1.Value;
        _picSettings.TestoOrario = TextBox18.Text;
        _picSettings.AltezzaSmall = int.Parse(TextBox6.Text);
        _picSettings.LarghezzaSmall = int.Parse(TextBox5.Text);
        _picSettings.CreaMiniature = CheckBox1.Checked;
        _picSettings.AggiungiScritteMiniature = RadioButton3.Checked;
        _picSettings.AggTempoGaraMin = RadioButton5.Checked;
        _picSettings.AggNumTempMin = RadioButton7.Checked;
        _picSettings.DimVert = int.Parse(TextBox30.Text);
        _picSettings.MargVert = int.Parse(TextBox31.Text);

        // _picSettings.NomeFileChild = childFile.Name
        _picSettings.Suffisso = TextBox3.Text;
        // _picSettings.Codice = TextBox13.Text

        _picSettings.Trasparenza = int.Parse(TextBox9.Text);
        _picSettings.IlFont = ComboBox3.SelectedItem.ToString();
        _picSettings.Grassetto = CheckBox3.Checked;
        _picSettings.Posizione = ComboBox1.SelectedItem.ToString();
        _picSettings.Allineamento = ComboBox2.SelectedItem.ToString();
        _picSettings.Margine = int.Parse(TextBox12.Text);
        _picSettings.LogoAltezza = int.Parse(TextBox14.Text);
        _picSettings.LogoLarghezza = int.Parse(TextBox15.Text);
        _picSettings.FontColoreRGB = ColorTranslator.FromHtml(TextBox34.Text);
        _picSettings.LogoAggiungi = CheckBox5.Checked;
        _picSettings.LogoNomeFile = TextBox10.Text;
        _picSettings.LogoTrasparenza = TextBox19.Text;
        _picSettings.LogoMargine = TextBox16.Text;
        _picSettings.LogoPosizioneH = ComboBox4.Text;
        _picSettings.LogoPosizioneV = ComboBox5.Text;
        _picSettings.FotoGrandeDimOrigina = CheckBox15.Checked;
        _picSettings.AltezzaBig = int.Parse(TextBox27.Text);
        _picSettings.LarghezzaBig = int.Parse(TextBox28.Text);
        _picSettings.DimMin = int.Parse(TextBox25.Text);
        _picSettings.TestoMin = RadioButton6.Checked;
        _picSettings.JpegQuality = int.Parse(TextBox32.Text);
        _picSettings.JpegQualityMin = int.Parse(TextBox33.Text);
    }

    private List<FileInfo> getFiles(DirectoryInfo sourceDir)
    {
        var picList = new List<FileInfo>();
        foreach (var childFile in sourceDir.GetFiles("*.jpg"))
            picList.Add(childFile);
        return picList;
    }

    private void setLabel17Text(string text)
    {
        if (lblFotoTotaliNum.InvokeRequired)
        {
            lblFotoTotaliNum.Invoke(new Action<string>(setLabel17Text), text);
        }
        else
        {
            lblFotoTotaliNum.Text = text;
        }
    }

    private void setLabel10Text(string text)
    {
        if (Label10.InvokeRequired)
        {
            Label10.Invoke(new Action<string>(setLabel10Text), text);
        }
        else
        {
            Label10.Text = text;
        }
    }

    public void stepProgressBar()
    {
        if (ProgressBar1.InvokeRequired)
        {
            ProgressBar1.Invoke(new System.Windows.Forms.MethodInvoker(ProgressBar1.PerformStep));
        }
        else
        {
            ProgressBar1.PerformStep();
        }

        setLabel18Text(ProgressBar1.Value.ToString());
    }

    private void setProgressBarMaximum(int value)
    {
        if (ProgressBar1.InvokeRequired)
        {
            ProgressBar1.Invoke(new Action<int>(setProgressBarMaximum), (object)value);
        }
        else
        {
            ProgressBar1.Maximum = value;
        }
    }

    private void setProgressBarValue(int value)
    {
        if (ProgressBar1.InvokeRequired)
        {
            ProgressBar1.Invoke(new Action<int>(setProgressBarValue), (object)value);
        }
        else
        {
            ProgressBar1.Value = value;
        }
    }

    private void setLabel18Text(string text)
    {
        if (Label18.InvokeRequired)
        {
            Label18.Invoke(new Action<string>(setLabel18Text), text);
        }
        else
        {
            Label18.Text = text;
        }
    }

    private void setLabel43Text(string text)
    {
        if (Label43.InvokeRequired)
        {
            Label43.Invoke(new Action<string>(setLabel43Text), text);
        }
        else
        {
            Label43.Text = text;
        }
    }

    private int getNumerazione()
    {
        int numerazione;
        if (rdbNumProgressiva.Checked)
        {
            numerazione = (int)FileHelper.numerazione.Progressiva;
        }
        else
        {
            numerazione = (int)FileHelper.numerazione.Files;
        }

        return numerazione;
    }

    private NumerazioneType GetNumerazioneEnum()
    {
        NumerazioneType numerazioneType;
        if (rdbNumProgressiva.Checked)
        {
            numerazioneType = NumerazioneType.Progressiva; // FileHelper.numerazione.Progressiva
        }
        else
        {
            numerazioneType = NumerazioneType.Files;
        } // FileHelper.numerazione.Files

        return numerazioneType;
    }
    

    private void CopyDirectoryFile(string SourcePath, string DestPath, bool OverWrite = false)
    {
        var SourceDir = new DirectoryInfo(SourcePath);
        var DestDir = new DirectoryInfo(DestPath);
        if (SourceDir.Exists)
        {
            if (!DestDir.Exists)
            {
                DestDir.Create();
                // copy all the files of the current directory
            }

            foreach (var childFile in SourceDir.GetFiles())
            {
                if (OverWrite)
                {
                    childFile.CopyTo(Path.Combine(DestDir.FullName, childFile.Name), true);
                }
                // if overwrite = false, copy the file only if it does not exist
                // this is done to avoid an IOException if a file already exists
                // this way the other files can be copied anyway...
                else if (!File.Exists(Path.Combine(DestDir.FullName, childFile.Name)))
                {
                    childFile.CopyTo(Path.Combine(DestDir.FullName, childFile.Name), false);
                }
                // copy all the sub-directories by recursively calling this same routine
            }

            foreach (var subDir in SourceDir.GetDirectories())
                CopyDirectoryFile(subDir.FullName, Path.Combine(DestDir.FullName, subDir.Name), OverWrite);
        }
    }

    public Size NewthumbSize(int currentwidth, int currentheight, int MaxPixel, string TipoSize)
    {
        // Calculate the Size of the New image  
        // *** Larghezza, Altezza, Auto

        double tempMultiplier;
        if ((TipoSize.ToUpper() ?? "") == ("Larghezza".ToUpper() ?? ""))
        {
            tempMultiplier = MaxPixel / (double)currentwidth;
        }
        else if ((TipoSize.ToUpper() ?? "") == ("Altezza".ToUpper() ?? ""))
        {
            tempMultiplier = MaxPixel / (double)currentheight;
        }
        else if (currentheight > currentwidth) // portrait  
        {
            tempMultiplier = MaxPixel / (double)currentheight;
        }
        else
        {
            tempMultiplier = MaxPixel / (double)currentwidth;
        }

        var NewSize = new Size((int)Math.Round(currentwidth * tempMultiplier),
            (int)Math.Round(currentheight * tempMultiplier));
        return NewSize;
    }

    private void Button7_Click(object sender, EventArgs e)
    {
        StopAttivo = true;
        //MyPool.StopThreadPool();
        try
        {
            _mainToken?.Cancel();
        }
        catch (Exception exception)
        {
            _logger.LogError(exception.Message);
            _logger.LogInformation("Ignora questo errore");
            // Console.WriteLine(exception);
            // Console.WriteLine("Ignora questo errore");
        }

        unlockUI();
    }

    private void Button4_Click(object sender, EventArgs e)
    {
        var openFileDialog = new OpenFileDialog();

        // openFileDialog.InitialDirectory = TextBox1.Text
        openFileDialog.Filter = "Immagini jpg (*.jpg)|*.jpg|Immagini gif (*.gif)|*.gif|Tutti i file (*.*)|*.*";
        if (TextBox10.Text.Length > 0)
        {
            openFileDialog.FileName = TextBox10.Text;
        }

        openFileDialog.FilterIndex = 0;
        openFileDialog.RestoreDirectory = true;
        if (DialogResult.OK == openFileDialog.ShowDialog())
        {
            TextBox10.Text = openFileDialog.FileName;
            PictureBox1.Image = Image.FromFile(TextBox10.Text);
            if (PictureBox1.Image.Height >= PictureBox1.Image.Width)
            {
                PictureBox1.Height = 160;
                PictureBox1.Width =
                    (int)(160 * PictureBox1.Image.Width / (double)PictureBox1.Image.Height);
            }
            else
            {
                PictureBox1.Width = 224;
                PictureBox1.Height =
                    (int)(224 * PictureBox1.Image.Height / (double)PictureBox1.Image.Width);
            }
        }
    }

    private string LeggiSoloNomeFile(string FileName)
    {
        string Testo = FileName;
        string Risposta = "";
        var Nomi = Testo.Split(new char[] { '\\' });
        if (Nomi.Length > 1)
        {
            Risposta = Nomi[Nomi.Length - 1];
        }

        return Risposta;
    }

    private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        // GetColor()
        // GetPixelColor(PictureBox1.PointToScreen(e.Location)).ToArgb.ToString("X8")
    }

    private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            WaterSelectColor = true;
        }
        else
        {
            WaterSelectColor = false;
        }
    }

    private Color[] GetPixelColor(Point screenLocation)
    {
        // Dim bm As New Bitmap(1, 1, Imaging.PixelFormat.Format24bppRgb)
        // Dim g As Graphics = Graphics.FromImage(bm)
        // g.CopyFromScreen(screenLocation, New Point(0, 0), New Size(1, 1))
        // Dim result As Color = bm.GetPixel(0, 0)
        // g.Dispose()
        // bm.Dispose()
        // Return result
        return null;
    }

    private void Button8_Click(object sender, EventArgs e)
    {
        var MyDialog = new ColorDialog();
        MyDialog.AllowFullOpen = true;
        // If TextBox22.Text.Length > 0 And TextBox23.Text.Length > 0 And TextBox24.Text.Length > 0 Then
        // If CType(TextBox22.Text, Integer) >= 0 And CType(TextBox23.Text, Integer) >= 0 And CType(TextBox24.Text, Integer) >= 0 Then
        // MyDialog.Color = Color.FromArgb(0, CType(TextBox22.Text, Integer), CType(TextBox23.Text, Integer), CType(TextBox24.Text, Integer))
        // End If
        // End If

        if (MyDialog.ShowDialog() == DialogResult.OK)
        {
            // TextBox22.Text = MyDialog.Color.R.ToString
            // TextBox23.Text = MyDialog.Color.G.ToString
            // TextBox24.Text = MyDialog.Color.B.ToString
            TextBox34.Text = ColorTranslator.ToHtml(MyDialog.Color);
            TextBox34.BackColor = MyDialog.Color;
        }
    }

    private void TextBox27_TextChanged(object sender, EventArgs e)
    {
    }

    private void CheckBox18_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox4.Checked = false;
        CheckBox12.Checked = false;
    }

    private void CheckBox4_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox18.Checked = false;
    }

    private void CheckBox12_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox18.Checked = false;
    }

    private void Label27_Click(object sender, EventArgs e)
    {
    }

    private CancellationTokenSource? _mainToken;

    private async void Button1_Click(object sender, EventArgs e)
    {
        _logger.LogInformation("Avvio elaborazione...");
        lockUI();
        // Dim timeStart As Date
        // Dim timeStop As Date
        _mainToken?.Dispose();
        _mainToken = new CancellationTokenSource();
        var token = _mainToken.Token;
            
        // timeStart = TimeOfDay
        FixPaths();
        Label10.Text = "Elaborazione in corso...";
        lblFotoTotaliNum.Text = "0";
        Label18.Text = "0";
        Label43.Text = "-s";
        SetPicSettings(Model.SourcePath, Model.DestinationPath);
        ProgressBar1.Minimum = 0;
        ProgressBar1.Step = 1;
        ProgressBar1.Value = 0;

        // Await CreaCatalogoParallel()
       
        var imageCreationOptions = new ImageCreationStuff.Options
        {
            AggiornaSottodirectory = chkAggiornaSottodirectory.Checked,
            CreaSottocartelle = chkCreaSottocartelle.Checked,
            FilePerCartella = int.Parse(txtFilePerCartella.Text),
            SuffissoCartelle = txtSuffissoCartelle.Text,
            CifreContatore = int.Parse(txtCifreContatore.Text),
            NumerazioneType = GetNumerazioneEnum(),
            SourcePath = Model.SourcePath,
            DestinationPath = Model.DestinationPath,
            MaxThreads = int.Parse(TextBox7.Text),
            ChunksSize = int.Parse(TextBox8.Text),
            LinearExecution = rdbVecchioMetodo.Checked
        };

        try
        {
            _results = [];
            _currentAmount = 0;
            _previousAmount = 0;
            timer1.Tick += Timer1OnTick;

            timer1.Interval = 1000 * 60;
            timer1.Enabled = true;

            string time = await _imageCreationService.CreaCatalogoParallel(imageCreationOptions, _results, UiUpdateEvent, token);
            Label43.Text = time;
            timer1.Enabled = false;
        }
        catch (OperationCanceledException operationCanceledException)
        {
            _logger.LogInformation("Operazione Cancellata");
            //Console.WriteLine("Operazione cancellata");
        }
        finally
        {
            _mainToken?.Dispose();
            _mainToken = null;

            timer1.Tick -= Timer1OnTick;
        }

        Label10.Text = "Finito";
        unlockUI();
    }

    private int _currentAmount = 0;
    private int _previousAmount = 0;

    private void Timer1OnTick(object sender, EventArgs e)
    {
        _previousAmount = _currentAmount;
        _currentAmount = _results.Count;
        int diff = _currentAmount - _previousAmount;
        SetText(Label43, $"{diff} f/m");
    }

    private void UpdateCounter(string text)
    {
        Label10.Invoke(new Action(() => Label10.Text = text));
    }
}

public class PicInfo
{
    public DirectoryInfo DirSource, DirDest, DirDestStart;
    public string NomeImmagine;

    public PicInfo(DirectoryInfo Dir_Source, DirectoryInfo Dir_Dest, DirectoryInfo Dir_DestStart,
        string Nome_Immagine)
    {
        DirSource = Dir_Source;
        DirDest = Dir_Dest;
        DirDestStart = Dir_DestStart;
        NomeImmagine = Nome_Immagine;
    }
}