using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using CatalogVbLib;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;

// Imports System.Threading

public class ImageCreatorSharp
{
    private bool FotoRuotaADestra = false;
    private bool FotoRuotaASinistra = false;

    private string TempMinText = "";
    // Private crFont1 As Font
    private string _NomeFileChild;

    private DirectoryInfo _SourceDir;
    private DirectoryInfo _DestDirStart;
    private DirectoryInfo _DestDir;

    private FileInfo _workFile;

    private string testoFirma;
    private string testoFirmaV;
    private int alphaScelta;
    private int DimensioneStandard;
    private int DimensioneStandardMiniatura;
    private DateTime dataFoto;
    private DateTime dataPartenzaI;
    private string testoOrario;
    private string testoFirmaPiccola;
    private Size thumbSizeSmall;
    private Size thumbSizeBig;
    private string nomeFileSmall;
    private string nomeFileBig;
    private string nomeFileBig2;

    private float yPosFromBottom;
    private float yPosFromBottom1;
    private float yPosFromBottom2;
    private float yPosFromBottom3;
    private float yPosFromBottom4;

    private ExifReader.Orientations _orientation;
    private DateTime? _creationDate;

    public ImageCreatorSharp()
    {
    }

    public ImageCreatorSharp(string nomeFileChild, DirectoryInfo sourceDir, DirectoryInfo destDir, DirectoryInfo destDirStart)
    {
        this.NomeFileChild = nomeFileChild;
        this.SourceDir = sourceDir;
        this.DestDir = destDir;
        this.DestDirStart = destDirStart;
        this.WorkFile = new FileInfo(nomeFileChild);
    }

    public ImageCreatorSharp(string nomeFileChild, DirectoryInfo sourceDir, DirectoryInfo destDir)
    {
        this.NomeFileChild = nomeFileChild;
        this.DestDir = destDir;
    }

    public ImageCreatorSharp(FileInfo file, DirectoryInfo destination)
    {
        this.WorkFile = file;
        this.DestDir = destination;
    }

    public async Task CreaImmagineThread(string Info)
    {
        try
        {
            await Task.Run(() =>
            {
                Console.WriteLine($"File: {WorkFile} Dest: {DestDir}");
                preparaVariabili();
                ExtractExif();
                // Dim g As System.Drawing.Image = System.Drawing.Image.FromFile(Path.Combine(SourceDir.FullName, NomeFileChild))
                using (Image g = Image.FromFile(WorkFile.FullName))
                {

                    // Dim g As System.Drawing.Image = System.Drawing.Image.FromFile(WorkFile.FullName)

                    // Imposta testo extra
                    impostaTestoExtra(g);

                    // Ruota l'immagine in base ai dati EXIF
                    Rotation(g);

                    // Forza jpeg se è selezionata l'opzione
                    System.Drawing.Imaging.ImageFormat thisFormat = g.RawFormat;
                    if (PicSettings.UsaForzaJpg == true)
                        thisFormat = System.Drawing.Imaging.ImageFormat.Jpeg;

                    prepareThumbnailSize(g);

                    using (Bitmap imgOutputBig = new Bitmap(g, thumbSizeBig.Width, thumbSizeBig.Height))
                    {
                        //Bitmap imgOutputBig = new Bitmap(g, thumbSizeBig.Width, thumbSizeBig.Height);
                        imgOutputBig.SetResolution(g.HorizontalResolution, g.VerticalResolution);

                        // Crea le miniature
                        creaMiniature(g, imgOutputBig, thisFormat);

                        AggiungiTesto(g, imgOutputBig);

                        aggiungiLogo(imgOutputBig);

                        SalvaFoto(imgOutputBig, thumbSizeBig, nomeFileBig, nomeFileSmall, thumbSizeSmall, thisFormat);
                    }


                }
            });

            // g.Dispose()

            //GC.Collect();
        }

        // PicSettings.mainForm.stepProgressBar()

        catch (Exception ex)
        {
            var e = ex.Demystify();
            Console.WriteLine(e);
            Console.WriteLine(e.Message);
            Console.WriteLine(e.StackTrace);
        }
    }

    private void ExtractExif()
    {
        using (var img = SixLabors.ImageSharp.Image.Load(_workFile.FullName))
        {
            ExifReader.Orientations finalOrientation;
            var rotation = img.Metadata?.ExifProfile?.GetValue(ExifTag.Orientation);
            if (rotation == null)
            {
                finalOrientation = ExifReader.Orientations.TopLeft;
            }
            else
            {
                finalOrientation = (ExifReader.Orientations)rotation.Value;
            }

            _orientation = finalOrientation;

            var creation = img.Metadata?.ExifProfile?.GetValue(ExifTag.DateTime);
            if (creation != null)
            {
                var succ = DateTime.TryParse(creation.Value, out var crDate);
                if (succ)
                {
                    _creationDate = crDate;
                }
                else
                {
                    _creationDate = null;
                }
            }
            else
            {
                _creationDate = null;
            }


        }
    }

    private void Rotation(System.Drawing.Image g)
    {
        FotoRuotaADestra = false;
        FotoRuotaASinistra = false;

        if (PicSettings.UsaRotazioneAutomatica == true)
        {
            if (g.PropertyIdList.Length > 0)
            {


                //ExifReader DatiExif = new ExifReader((Bitmap)g);

                switch (_orientation /*DatiExif.Orientation*/)
                {
                    case ExifReader.Orientations.BottomLeft:
                    case ExifReader.Orientations.BottomRight:
                    case ExifReader.Orientations.LeftTop:
                    case ExifReader.Orientations.LftBottom:
                        FotoRuotaASinistra = true;
                        break;
                    case ExifReader.Orientations.RightBottom:
                    case ExifReader.Orientations.RightTop:
                    case ExifReader.Orientations.TopLeft:
                    case ExifReader.Orientations.TopRight:
                        break;

                }
            }
        }

        if (FotoRuotaASinistra == true)
            g.RotateFlip(RotateFlipType.Rotate270FlipNone);
        if (FotoRuotaADestra == true)
            g.RotateFlip(RotateFlipType.Rotate90FlipNone);
    }
    /// <summary>
    ///     ''' Aggiunge Orario, tempo gara e altri
    ///     ''' </summary>
    ///     ''' <param name="g">Image</param>
    ///     ''' <remarks></remarks>
    private void impostaTestoExtra(Image g)
    {
        if (PicSettings.UsaOrarioTestoApplicare | PicSettings.UsaTempoGaraTestoApplicare | PicSettings.UsaOrarioMiniatura | PicSettings.TestoMin | PicSettings.AggTempoGaraMin | PicSettings.AggNumTempMin)
        {
            if (g.PropertyIdList.Length > 0)
            {
                //ExifReader DatiExif = new ExifReader((Bitmap)g);
                dataFoto = _creationDate ?? DateTime.Now; //DatiExif.DateTimeOriginal;
                testoFirma = PicSettings.TestoFirmaStart;
                testoFirmaV = PicSettings.TestoFirmaStartV;

                if (dataFoto.Year != 1)
                {
                    testoFirmaPiccola = dataFoto.ToShortTimeString();
                    if (PicSettings.UsaOrarioTestoApplicare == true)
                    {
                        testoFirma += " " + dataFoto.ToShortDateString() + " " + dataFoto.ToLongTimeString();
                        testoFirmaV += " " + dataFoto.ToShortDateString() + " " + dataFoto.ToLongTimeString();
                    }
                    if (PicSettings.UsaTempoGaraTestoApplicare == true)
                    {

                        var diff = dataPartenzaI - dataFoto;
                        var diffA = diff.TotalSeconds * 10000000;

                        TimeSpan Orario = new TimeSpan(0, 0, 0, (int)diffA);
                        testoFirma += " " + testoOrario + Orario.Hours.ToString("00") + ":" + Orario.Minutes.ToString("00") + ":" + Orario.Seconds.ToString("00");
                        testoFirmaV += " " + testoOrario + Orario.Hours.ToString("00") + ":" + Orario.Minutes.ToString("00") + ":" + Orario.Seconds.ToString("00");
                    }
                }
            }
        }
        else
        {
            testoFirma = PicSettings.TestoFirmaStart;
            testoFirmaV = PicSettings.TestoFirmaStartV;
        }
    }

    /// <summary>
    ///     ''' Prepara diverse variabili azzerandole, elaborandole e prendendole dalle impostazioni
    ///     ''' </summary>
    ///     ''' <remarks></remarks>
    private void preparaVariabili()
    {
        alphaScelta = System.Convert.ToInt32((255 * (100 - PicSettings.Trasparenza) / (double)100));
        testoFirma = "";
        testoFirmaV = "";
        dataPartenzaI = PicSettings.DataPartenza;
        testoOrario = PicSettings.TestoOrario;
        if (testoOrario.Length > 0)
            testoOrario += " ";
        testoFirmaPiccola = "";
        thumbSizeSmall = new Size();
        thumbSizeBig = new Size();
        nomeFileSmall = "";
        nomeFileBig2 = "";
        nomeFileBig = "";
        DimensioneStandard = PicSettings.DimStandard;
        DimensioneStandardMiniatura = PicSettings.DimStandardMiniatura;
        // nomeFileSmall = Suffisso & NomeFileChild
        // nomeFileBig = NomeFileChild
        nomeFileSmall = PicSettings.Suffisso + WorkFile.Name;
        nomeFileBig = WorkFile.Name;
    }

    private void prepareThumbnailSize(Image g)
    {
        if (g.Width > g.Height)
        {
            thumbSizeSmall = NewthumbSize(g.Width, g.Height, PicSettings.LarghezzaSmall, "Larghezza");
            Size SizeOrig = new Size(g.Width, g.Height);
            thumbSizeBig = SizeOrig;
        }
        else
        {
            thumbSizeSmall = NewthumbSize(g.Width, g.Height, PicSettings.AltezzaSmall, "Altezza");
            Size SizeOrig = new Size(g.Width, g.Height);
            thumbSizeBig = SizeOrig;
        }
    }

    private void creaMiniature(Image g, Bitmap imgOutputBig, ImageFormat thisFormat)
    {
        if (PicSettings.TestoMin)
            testoFirmaPiccola = nomeFileBig;
        else if (PicSettings.AggNumTempMin)
            testoFirmaPiccola = nomeFileBig + " ";
        // Dim yPosFromBottom4 As Single

        Font crFont1 = null/* TODO Change to default(_) if this is not a reference type */;
        Font crFont2 = null/* TODO Change to default(_) if this is not a reference type */;
        SizeF crSize1 = new SizeF();
        SizeF crSize2 = new SizeF();

        if (PicSettings.CreaMiniature == true)
        {
            if (PicSettings.AggiungiScritteMiniature == false)
            {
                if (string.Equals(PicSettings.DirectorySorgente, PicSettings.DirectoryDestinazione, StringComparison.OrdinalIgnoreCase))
                    nomeFileSmall = nomeFileSmall.Substring(0, nomeFileSmall.Length - 4) + PicSettings.Codice + nomeFileSmall.Substring(nomeFileSmall.Length - 4);
                if (PicSettings.UsaOrarioMiniatura | PicSettings.TestoMin | PicSettings.AggTempoGaraMin | PicSettings.AggNumTempMin)
                {
                    if (testoFirmaPiccola.Length > 0)
                    {
                        using (var imgOutputSmall = (Bitmap)imgOutputBig.Clone())
                        {
                            Graphics grPhoto1;
                            grPhoto1 = Graphics.FromImage(imgOutputSmall);
                            grPhoto1.SmoothingMode = SmoothingMode.AntiAlias;

                            int LarghezzaStandard1;
                            // quick fix
                            DimensioneStandardMiniatura = 50;
                            if (PicSettings.Grassetto == true)
                            {
                                crFont1 = new Font(PicSettings.IlFont, DimensioneStandardMiniatura, FontStyle.Bold);
                                crFont2 = new Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold);
                            }
                            else
                            {
                                crFont1 = new Font(PicSettings.IlFont, DimensioneStandardMiniatura);
                                crFont2 = new Font(PicSettings.IlFont, DimensioneStandard);
                            }

                            crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1);
                            crSize2 = grPhoto1.MeasureString(testoFirma, crFont1);
                            LarghezzaStandard1 = System.Convert.ToInt32(crSize1.Width);

                            if (crSize1.Width > System.Convert.ToSingle(g.Width))
                            {
                                int Conta = DimensioneStandardMiniatura;
                                do
                                {
                                    if (Conta > 20)
                                        Conta -= 5;
                                    else
                                        Conta -= 1;
                                    if (PicSettings.Grassetto == true)
                                        crFont1 = new Font(PicSettings.IlFont, Conta, FontStyle.Bold);
                                    else
                                        crFont1 = new Font(PicSettings.IlFont, Conta);
                                    crSize1 = grPhoto1.MeasureString(testoFirmaPiccola, crFont1);
                                    if (crSize1.Width < System.Convert.ToSingle(g.Width))
                                    {
                                        LarghezzaStandard1 = System.Convert.ToInt32(crSize1.Width);
                                        break;
                                    }

                                    if (Conta <= 5)
                                        break;
                                }
                                while (true);
                                DimensioneStandardMiniatura = Conta;
                            }

                            switch (PicSettings.Posizione.ToUpper())
                            {
                                case "ALTO":
                                    {
                                        yPosFromBottom1 = (PicSettings.Margine);
                                        yPosFromBottom4 = (PicSettings.MargVert);
                                        break;
                                    }

                                case "BASSO":
                                    {
                                        yPosFromBottom1 = System.Convert.ToSingle((g.Height - crSize1.Height - (g.Height * PicSettings.Margine / (double)100)));
                                        yPosFromBottom4 = System.Convert.ToSingle((g.Height - crSize1.Height - (g.Height * PicSettings.MargVert / (double)100)));
                                        break;
                                    }
                            }

                            float xCenterOfImg1 = 0;

                            StringFormat StrFormat1 = new StringFormat();
                            switch (PicSettings.Allineamento.ToUpper())
                            {
                                case "SINISTRA":
                                    {
                                        xCenterOfImg1 = System.Convert.ToSingle((PicSettings.Margine + (LarghezzaStandard1 / (double)2)));

                                        if ((LarghezzaStandard1 / (double)2) > (g.Width / (double)2) - PicSettings.Margine)
                                            xCenterOfImg1 = System.Convert.ToSingle((g.Width / (double)2));
                                        break;
                                    }

                                case "CENTRO":
                                    {
                                        xCenterOfImg1 = System.Convert.ToSingle((g.Width / (double)2));
                                        break;
                                    }

                                case "DESTRA":
                                    {
                                        xCenterOfImg1 = System.Convert.ToSingle((g.Width - PicSettings.Margine - (LarghezzaStandard1 / (double)2)));

                                        if ((LarghezzaStandard1 / (double)2) > (g.Width / (double)2) - PicSettings.Margine)
                                            xCenterOfImg1 = System.Convert.ToSingle((g.Width / (double)2));
                                        break;
                                    }
                            }
                            StrFormat1.Alignment = StringAlignment.Center;

                            SolidBrush semiTransBrush21 = new SolidBrush(Color.FromArgb(alphaScelta, 0, 0, 0));
                            SolidBrush semiTransBrush1 = new SolidBrush(Color.FromArgb(alphaScelta, PicSettings.fontColoreRGB));

                            // quick fix
                            DimensioneStandardMiniatura = PicSettings.DimMin;

                            if (PicSettings.Grassetto == true)
                                crFont1 = new Font(PicSettings.IlFont, DimensioneStandardMiniatura, FontStyle.Bold);
                            else
                                crFont1 = new Font(PicSettings.IlFont, DimensioneStandardMiniatura);
                            // asdgadfhdfhjgfsjgfjygfdhsdafa
                            if (PicSettings.TestoMin)
                            {
                                grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1);
                                grPhoto1.DrawString(nomeFileBig, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1);
                            }
                            else if (PicSettings.AggTempoGaraMin & PicSettings.UsaTempoGaraTestoApplicare)
                            {
                                var diff = dataPartenzaI - dataFoto;
                                var diffA = diff.TotalSeconds * 10000000;

                                TimeSpan Orario = new TimeSpan(0, 0, (int)diffA);/* new TimeSpan(DateTime.DateDiff(DateInterval.Second, dataPartenzaI, dataFoto) * 10000000);*/
                                string tempstr = "";


                                tempstr += Environment.NewLine + testoOrario + Orario.Hours.ToString("00") + ":" + Orario.Minutes.ToString("00") + ":" + Orario.Seconds.ToString("00");


                                grPhoto1.DrawString(tempstr, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1);
                                grPhoto1.DrawString(tempstr, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1);
                            }
                            else if (PicSettings.AggNumTempMin)
                            {
                                var diff = dataPartenzaI - dataFoto;
                                var diffA = diff.TotalSeconds * 10000000;
                                TimeSpan Orario = new TimeSpan(0, 0, (int)diffA);
                                string tempstr = "";
                                tempstr += nomeFileBig;

                                tempstr += Environment.NewLine + testoOrario + Orario.Hours.ToString("00") + ":" + Orario.Minutes.ToString("00") + ":" + Orario.Seconds.ToString("00");


                                grPhoto1.DrawString(tempstr, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1);
                                grPhoto1.DrawString(tempstr, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1);
                            }
                            else
                            {
                                grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush21, new PointF(xCenterOfImg1 + 1, yPosFromBottom1 + 1), StrFormat1);
                                grPhoto1.DrawString(testoFirmaPiccola, crFont1, semiTransBrush1, new PointF(xCenterOfImg1, yPosFromBottom1), StrFormat1);
                            }

                            // Salva la miniatura
                            //using (var g22 = Image.FromHbitmap(imgOutputSmall))


                            using (var imgOutputSmall2 = new Bitmap(imgOutputSmall, thumbSizeSmall.Width, thumbSizeSmall.Height))
                            {
                                imgOutputSmall2.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);

                                //imgOutputSmall2.Dispose();
                            }

                            //imgOutputSmall.Dispose();
                        }


                        //File.Delete(Path.Combine(DestDir.FullName, "Temp_" + nomeFileSmall));
                        //FileSystem.Kill();
                    }
                    else
                    {
                        using (Bitmap imgOutputSmall = new Bitmap(g, thumbSizeSmall.Width, thumbSizeSmall.Height))
                        {
                            imgOutputSmall.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);
                            //imgOutputSmall.Dispose();
                        }
                    }
                }
                else
                {
                    using (Bitmap imgOutputSmall = new Bitmap(g, thumbSizeSmall.Width, thumbSizeSmall.Height))
                    {
                        imgOutputSmall.Save(Path.Combine(DestDir.FullName, nomeFileSmall), thisFormat);
                        //imgOutputSmall.Dispose();
                    }
                }
            }
        }

        crFont1?.Dispose();
        crFont2?.Dispose();
    }

    private void AggiungiTesto(Image g, Bitmap imgOutputBig)
    {
        using (var grPhoto = Graphics.FromImage(imgOutputBig))
        {
            grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

            Font crFont = null/* TODO Change to default(_) if this is not a reference type */;
            SizeF crSize = new SizeF();
            int LarghezzaStandard;

            if (PicSettings.Grassetto == true)
                crFont = new Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold);
            else
                crFont = new Font(PicSettings.IlFont, DimensioneStandard);
            crSize = grPhoto.MeasureString(testoFirma, crFont);
            LarghezzaStandard = System.Convert.ToInt32(crSize.Width);

            if (crSize.Width > System.Convert.ToSingle(g.Width))
            {
                int Conta = DimensioneStandard;
                do
                {
                    if (Conta > 20)
                        Conta -= 5;
                    else
                        Conta -= 1;
                    if (PicSettings.Grassetto == true)
                        crFont = new Font(PicSettings.IlFont, Conta, FontStyle.Bold);
                    else
                        crFont = new Font(PicSettings.IlFont, Conta);
                    crSize = grPhoto.MeasureString(testoFirma, crFont);
                    if (crSize.Width < System.Convert.ToSingle(g.Width))
                    {
                        LarghezzaStandard = System.Convert.ToInt32(crSize.Width);
                        break;
                    }

                    if (Conta <= 5)
                        break;
                }
                while (true);
                DimensioneStandard = Conta;
            }


            switch (PicSettings.Posizione.ToUpper())
            {
                case "ALTO":
                    {
                        yPosFromBottom = (PicSettings.Margine);
                        yPosFromBottom3 = (PicSettings.MargVert);
                        break;
                    }

                case "BASSO":
                    {
                        yPosFromBottom = System.Convert.ToSingle((g.Height - crSize.Height - (g.Height * PicSettings.Margine / (double)100)));
                        yPosFromBottom3 = System.Convert.ToSingle((g.Height - crSize.Height - (g.Height * PicSettings.MargVert / (double)100)));
                        break;
                    }
            }

            float xCenterOfImg = 0;
            float xCenterOfImg3 = 0;
            StringFormat StrFormat = new StringFormat();
            switch (PicSettings.Allineamento.ToUpper())
            {
                case "SINISTRA":
                    {
                        xCenterOfImg = System.Convert.ToSingle((PicSettings.Margine + (LarghezzaStandard / (double)2)));
                        xCenterOfImg3 = System.Convert.ToSingle((PicSettings.MargVert + (LarghezzaStandard / (double)2)));
                        if ((LarghezzaStandard / (double)2) > (g.Width / (double)2) - PicSettings.Margine)
                            xCenterOfImg = System.Convert.ToSingle((g.Width / (double)2));
                        if ((LarghezzaStandard / (double)2) > (g.Width / (double)2) - PicSettings.MargVert)
                            xCenterOfImg3 = System.Convert.ToSingle((g.Width / (double)2));
                        break;
                    }

                case "CENTRO":
                    {
                        xCenterOfImg = System.Convert.ToSingle((g.Width / (double)2));
                        break;
                    }

                case "DESTRA":
                    {
                        xCenterOfImg = System.Convert.ToSingle((g.Width - PicSettings.Margine - (LarghezzaStandard / (double)2)));
                        xCenterOfImg3 = System.Convert.ToSingle((g.Width - PicSettings.MargVert - (LarghezzaStandard / (double)2)));
                        if ((LarghezzaStandard / (double)2) > (g.Width / (double)2) - PicSettings.Margine)
                            xCenterOfImg = System.Convert.ToSingle((g.Width / (double)2));
                        if ((LarghezzaStandard / (double)2) > (g.Width / (double)2) - PicSettings.MargVert)
                            xCenterOfImg3 = System.Convert.ToSingle((g.Width / (double)2));
                        break;
                    }
            }
            StrFormat.Alignment = StringAlignment.Center;

            SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(alphaScelta, 0, 0, 0));
            // Dim semiTransBrush As SolidBrush = New SolidBrush(Color.FromArgb(AlphaScelta, _FontColoreR, _FontColoreG, _FontColoreB))
            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(alphaScelta, PicSettings.fontColoreRGB));

            if (FotoRuotaADestra | FotoRuotaASinistra)
            {
                if (PicSettings.Grassetto == true)
                    crFont = new Font(PicSettings.IlFont, PicSettings.DimVert, FontStyle.Bold);
                else
                    crFont = new Font(PicSettings.IlFont, PicSettings.DimVert);
            }
            else if (PicSettings.Grassetto == true)
                crFont = new Font(PicSettings.IlFont, DimensioneStandard, FontStyle.Bold);
            else
                crFont = new Font(PicSettings.IlFont, DimensioneStandard);


            // qui scrive il testo (nomefilebig)
            if (PicSettings.TestoNome)
            {
                if (PicSettings.NomeData & g.PropertyIdList.Length > 0)
                {
                    //ExifReader DatiExif = new ExifReader((Bitmap)g);
                    dataFoto = _creationDate ?? DateTime.Now; //DatiExif.DateTimeOriginal;

                    grPhoto.DrawString((nomeFileBig + " " + dataFoto.ToShortDateString()), crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat);
                    grPhoto.DrawString((nomeFileBig + " " + dataFoto.ToShortDateString()), crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom), StrFormat);
                }
                else
                {
                    grPhoto.DrawString(nomeFileBig, crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat);
                    grPhoto.DrawString(nomeFileBig, crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom), StrFormat);
                }
            }

            if (PicSettings.TestoNome == false)
            {
                if (FotoRuotaADestra | FotoRuotaASinistra)
                {
                    if (PicSettings.TestoMin == false)
                    {
                        grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom3 + 1), StrFormat);
                        grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom3), StrFormat);
                    }
                    if (PicSettings.TestoMin == true)
                    {
                        grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom4 + 1), StrFormat);
                        grPhoto.DrawString(testoFirmaV, crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom4), StrFormat);
                    }
                }
                else
                {
                    grPhoto.DrawString(testoFirma, crFont, semiTransBrush2, new PointF(xCenterOfImg + 1, yPosFromBottom + 1), StrFormat);
                    grPhoto.DrawString(testoFirma, crFont, semiTransBrush, new PointF(xCenterOfImg, yPosFromBottom), StrFormat);
                }
            }

            if (string.Equals(PicSettings.DirectorySorgente, PicSettings.DirectoryDestinazione, StringComparison.OrdinalIgnoreCase))
            {
                nomeFileBig2 = nomeFileBig;
                nomeFileBig = nomeFileBig.Substring(0, nomeFileBig.Length - 4) + PicSettings.Codice + nomeFileBig.Substring(nomeFileBig.Length - 4);
            }
            //grPhoto.Dispose();

            crFont?.Dispose();
        }


    }




    private void aggiungiLogo(Bitmap imgOutputBig)
    {
        // imgOutputBig
        if (PicSettings.LogoAggiungi == true & File.Exists(PicSettings.LogoNomeFile))
        {
            Image ImmagineLogo = Image.FromFile(PicSettings.LogoNomeFile);

            Color LogoColoreTrasparente = Color.White;
            // Dim bmWatermark As Bitmap

            // * Create a Bitmap based on the previously modified photograph Bitmap
            // bmWatermark = New Bitmap(imgOutputBig)
            // bmWatermark.SetResolution(imgOutputBig.HorizontalResolution, imgOutputBig.VerticalResolution)

            // * Load this Bitmap into a new Graphic Object
            using (Graphics grWatermark = Graphics.FromImage(imgOutputBig))
            {
                ImageAttributes imageAttributes = new ImageAttributes();

                // * The first step replace the background color with one that is transparent (Alpha=0, R=0, G=0, B=0)
                ColorMap colorMap = new ColorMap();

                // * background this will be the color we search for and replace with transparency
                colorMap.OldColor = LogoColoreTrasparente;
                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

                ColorMap[] remapTable = new[] { colorMap };
                imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                // * The second color manipulation is used to change the opacity by setting the 3rd row and 3rd column to 0.3f
                float[][] colorMatrixElements = new[] { new float[] { 1.0F, 0.0F, 0.0F, 0.0F, 0.0F }, new float[] { 0.0F, 1.0F, 0.0F, 0.0F, 0.0F }, new float[] { 0.0F, 0.0F, 1.0F, 0.0F, 0.0F }, new float[] { 0.0F, 0.0F, 0.0F, System.Convert.ToSingle(PicSettings.LogoTrasparenza) / 100F, 0.0F }, new float[] { 0.0F, 0.0F, 0.0F, 0.0F, 1.0F } };
                ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
                imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                int FotoLogoH = PicSettings.LogoAltezza;
                int FotoLogoW = PicSettings.LogoLarghezza;
                double FattoreAlt = ImmagineLogo.Height / (double)FotoLogoH;
                double FattoreLarg = ImmagineLogo.Width / (double)FotoLogoW;
                Size NuovaSize;
                if (FattoreLarg > FattoreAlt)
                    NuovaSize = NewthumbSize(ImmagineLogo.Width, ImmagineLogo.Height, FotoLogoW, "Larghezza");
                else
                    NuovaSize = NewthumbSize(ImmagineLogo.Width, ImmagineLogo.Height, FotoLogoH, "Altezza");

                int MargineUsato;
                int MargineL;
                bool InPercentualeL;
                if (PicSettings.LogoMargine.EndsWith("%") == true)
                    InPercentualeL = true;
                else
                    InPercentualeL = false;
                MargineL = System.Convert.ToInt32(PicSettings.LogoMargine);
                if (InPercentualeL == true)
                    MargineUsato = System.Convert.ToInt32(imgOutputBig.Height * MargineL / (double)100);
                else
                    MargineUsato = MargineL;

                int xPosOfWm = 0;
                int yPosOfWm = 0;
                switch (PicSettings.LogoPosizioneH.ToUpper())
                {
                    case "SINISTRA":
                    case "NESSUNA":
                        {
                            xPosOfWm = MargineUsato;
                            break;
                        }

                    case "CENTRO":
                        {
                            xPosOfWm = System.Convert.ToInt32((imgOutputBig.Width - NuovaSize.Width) / (double)2);
                            break;
                        }

                    case "DESTRA":
                        {
                            xPosOfWm = ((imgOutputBig.Width - NuovaSize.Width) - MargineUsato);
                            break;
                        }
                }
                switch (PicSettings.LogoPosizioneV.ToUpper())
                {
                    case "ALTO":
                    case "NESSUNA":
                        {
                            yPosOfWm = MargineUsato;
                            break;
                        }

                    case "CENTRO":
                        {
                            yPosOfWm = System.Convert.ToInt32((imgOutputBig.Height - NuovaSize.Height) / (double)2);
                            break;
                        }

                    case "BASSO":
                        {
                            yPosOfWm = ((imgOutputBig.Height - NuovaSize.Height) - MargineUsato);
                            break;
                        }
                }

                grWatermark.DrawImage(ImmagineLogo, new Rectangle(xPosOfWm, yPosOfWm, NuovaSize.Width, NuovaSize.Height), 0, 0, ImmagineLogo.Width, ImmagineLogo.Height, GraphicsUnit.Pixel, imageAttributes);
                //grWatermark.Dispose();
            }
        }
    }


    private void SalvaFoto(Bitmap imgOutputBig, Size thumbSizeBig, string NomeFileBig, string NomeFileSmall, Size thumbSizeSmall, ImageFormat thisFormat)
    {
        using (var image1Stream = new MemoryStream())
        {



            if (PicSettings.FotoGrandeDimOrigina == false)
            {
                // attenzione non controlla se è png
                // imgOutputBig.Save(Path.Combine(_DestDir.FullName, "Temp_" & NomeFileBig), thisFormat)
                if (thisFormat.Equals(ImageFormat.Jpeg))
                {
                    MakeImageCustomQuality(imgOutputBig, image1Stream);
                }
                //SalvaImmagineCustomQuality(imgOutputBig, Path.Combine(DestDir.FullName, "Temp_" + NomeFileBig), PicSettings.jpegQuality);
                else
                {
                    imgOutputBig.Save(image1Stream, thisFormat);
                }
                //imgOutputBig.Save(Path.Combine(DestDir.FullName, "Temp_" + NomeFileBig), thisFormat);
                image1Stream.Seek(0, SeekOrigin.Begin);
                using (var g2 = Image.FromStream(image1Stream))
                {
                    thumbSizeBig = g2.Width > g2.Height ? NewthumbSize(g2.Width, g2.Height, PicSettings.LarghezzaBig, "Larghezza") : NewthumbSize(g2.Width, g2.Height, PicSettings.AltezzaBig, "Altezza");
                    using (Bitmap imgOutputBig2 = new Bitmap(g2, thumbSizeBig.Width, thumbSizeBig.Height))
                    {
                        if (thisFormat.Equals(ImageFormat.Jpeg))
                            SalvaImmagineCustomQuality(imgOutputBig2, Path.Combine(DestDir.FullName, NomeFileBig), PicSettings.jpegQuality);
                        else
                            imgOutputBig2.Save(Path.Combine(DestDir.FullName, NomeFileBig), thisFormat);

                        //imgOutputBig2.Dispose();
                    }
                }

                //imgOutputBig.Dispose();
                //g2.Dispose();
            }
            else
            {
                // 
                if (thisFormat.Equals(ImageFormat.Jpeg))
                    SalvaImmagineCustomQuality(imgOutputBig, Path.Combine(DestDir.FullName, NomeFileBig), PicSettings.jpegQuality);
                else
                    imgOutputBig.Save(Path.Combine(DestDir.FullName, NomeFileBig), thisFormat);

                //imgOutputBig.Dispose();
            }
            image1Stream.Seek(0, SeekOrigin.Begin);

            if (PicSettings.CreaMiniature)
            {
                if (PicSettings.AggiungiScritteMiniature)
                {
                    using (System.Drawing.Image g1 = PicSettings.FotoGrandeDimOrigina ? (Image)imgOutputBig.Clone() : Image.FromStream(image1Stream))
                    {
                        //if (PicSettings.FotoGrandeDimOrigina == false)
                        //    g1 = Image.FromStream(image1Stream);
                        ////g1 = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, "Temp_" + NomeFileBig));
                        //else
                        //    g1 = (Image)imgOutputBig.Clone();
                        //g1 = System.Drawing.Image.FromFile(Path.Combine(DestDir.FullName, NomeFileBig));
                        using (Bitmap imgOutputSmall = new Bitmap(g1, thumbSizeSmall.Width, thumbSizeSmall.Height))
                        {
                            if (string.Equals(PicSettings.DirectorySorgente, PicSettings.DirectoryDestinazione, StringComparison.OrdinalIgnoreCase))
                                NomeFileSmall = NomeFileSmall.Substring(0, NomeFileSmall.Length - 4) + PicSettings.Codice + NomeFileSmall.Substring(NomeFileSmall.Length - 4);
                            // 
                            if (thisFormat.Equals(ImageFormat.Jpeg))
                                SalvaImmagineCustomQuality(imgOutputSmall, Path.Combine(DestDir.FullName, NomeFileSmall), PicSettings.jpegQualityMin);
                            else
                                imgOutputSmall.Save(Path.Combine(_DestDir.FullName, NomeFileSmall), thisFormat);

                            //imgOutputSmall.Dispose();
                        }

                        //g1.Dispose();
                    }
                }
            }

            //if (File.Exists(Path.Combine(DestDir.FullName, "Temp_" + NomeFileBig)))
            //    File.Delete(Path.Combine(DestDir.FullName, "Temp_" + NomeFileBig));

        }
    }

    private void SalvaImmagineCustomQuality(Bitmap imageToSave, string nomeFileFinale, long quality)
    {
        ImageCodecInfo JgpEncoder = GetEncoder(ImageFormat.Jpeg);
        System.Drawing.Imaging.Encoder MyEncoder = System.Drawing.Imaging.Encoder.Quality;

        EncoderParameters MyEncoderParameters = new EncoderParameters(1);

        EncoderParameter MyEncoderParameter = new EncoderParameter(MyEncoder, PicSettings.jpegQuality);
        MyEncoderParameters.Param[0] = MyEncoderParameter;
        imageToSave.Save(nomeFileFinale, JgpEncoder, MyEncoderParameters);
        //imageToSave.Dispose();
    }

    private void MakeImageCustomQuality(Bitmap imageToSave, Stream destinationStream)
    {
        ImageCodecInfo JgpEncoder = GetEncoder(ImageFormat.Jpeg);
        System.Drawing.Imaging.Encoder MyEncoder = System.Drawing.Imaging.Encoder.Quality;

        EncoderParameters MyEncoderParameters = new EncoderParameters(1);

        EncoderParameter MyEncoderParameter = new EncoderParameter(MyEncoder, PicSettings.jpegQuality);
        MyEncoderParameters.Param[0] = MyEncoderParameter;
        destinationStream.Seek(0, SeekOrigin.Begin);
        imageToSave.Save(destinationStream, JgpEncoder, MyEncoderParameters);
        //imageToSave.Dispose();
    }


    private ImageCodecInfo GetEncoder(ImageFormat format)
    {
        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();


        foreach (var codec in codecs)
        {
            if (codec.FormatID == format.Guid)
                return codec;
        }
        return null/* TODO Change to default(_) if this is not a reference type */;
    }






    /// <summary>
    ///     ''' Calculate the Size of the New image
    ///     ''' </summary>
    ///     ''' <param name="currentwidth">Larghezza</param>
    ///     ''' <param name="currentheight">Altezza</param>
    ///     ''' <param name="MaxPixel"></param>
    ///     ''' <param name="TipoSize"></param>
    ///     ''' <returns></returns>
    ///     ''' <remarks></remarks>
    private Size NewthumbSize(int currentwidth, int currentheight, int MaxPixel, string TipoSize)
    {
        // e  
        // *** 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)
            tempMultiplier = MaxPixel / (double)currentheight;
        else
            tempMultiplier = MaxPixel / (double)currentwidth;

        Size NewSize = new Size(System.Convert.ToInt32(currentwidth * tempMultiplier), System.Convert.ToInt32(currentheight * tempMultiplier));

        return NewSize;
    }

    public FileInfo WorkFile
    {
        get
        {
            return _workFile;
        }
        set
        {
            _workFile = value;
        }
    }

    public DirectoryInfo DestDir
    {
        get => _DestDir;
        set => _DestDir = value;
    }

    public DirectoryInfo SourceDir
    {
        get
        {
            return _SourceDir;
        }
        set
        {
            _SourceDir = value;
        }
    }

    public DirectoryInfo DestDirStart
    {
        get
        {
            return _DestDirStart;
        }
        set
        {
            _DestDirStart = value;
        }
    }

    public string NomeFileChild
    {
        get
        {
            return _NomeFileChild;
        }
        set
        {
            _NomeFileChild = value;
        }
    }
}
