using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MaddoLibrary.Base.Log;
using Newtonsoft.Json;

namespace CatalogLib
{
    public class PicSettings
    {
        private static PicSettings _instance = new PicSettings();

        public static PicSettings Instance
        {
            get { return _instance; }
        }

        private Dictionary<string, object> _settingsDict = new Dictionary<string, object>();

        public PicSettings()
        {
            SetDefaults();
        }

        public string SerializeSettings()
        {
            return JsonConvert.SerializeObject(_settingsDict);
        }

        public void DeserializeSettings(string serializedData)
        {
            _settingsDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(serializedData);


        }

        public void SetBase(string key, object value)
        {
            if (_settingsDict.ContainsKey(key))
            {
                _settingsDict[key] = value;
            }
            else
            {
                _settingsDict.Add(key, value);
            }
        }

        public void SetString(string key, string value)
        {
            SetBase(key, value);
        }

        public void SetInt(string key, int value)
        {
            SetBase(key, value);
        }

        public void SetBool(string key, bool value)
        {
            SetBase(key, value);
        }

        public void SetDouble(string key, double value)
        {
            SetBase(key, value);
        }

        public void SetFloat(string key, float value)
        {
            SetBase(key, value);
        }

        public void Set<T>(string key, T value)
        {
            SetBase(key, value);
        }

        public bool Exists(string key)
        {
            return _settingsDict.ContainsKey(key);
        }

        public int GetInt(string key, int defaultValue = 0)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                SetInt(key, defaultValue);
            }

            if (_settingsDict[key] is int) return (int)_settingsDict[key];
            Debug.WriteLine($"Error while parsing {key}");
            //return defaultValue;

            int r;

            if (int.TryParse(_settingsDict[key].ToString(), out r))
            {
                SetInt(key, r);

            }
            else
            {
                SetInt(key, defaultValue);
            }
            return (int)_settingsDict[key];
            //return (int) _settingsDict[key];

            //return _settingsDict.ContainsKey(key) ? (int)_settingsDict[key] : defaultValue;
        }

        public double GetDouble(string key, double defaultValue = 0)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                SetDouble(key, defaultValue);
                // setdouble default
            }

            if (_settingsDict[key] is double) return (double)_settingsDict[key];
            Debug.WriteLine($"Error while parsing {key}");

            double d;
            if (double.TryParse(_settingsDict[key].ToString(), out d))
            {
                SetDouble(key, d);
                // setdouble key r
            }
            else
            {
                SetDouble(key, defaultValue);
                //setdouble defaultvalue
            }
            return (double)_settingsDict[key];
        }

        public float GetFloat(string key, float defaultValue = 0)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                SetFloat(key, defaultValue);
            }

            if (_settingsDict[key] is float f) return f;
            MaddoLogger.LogError("Error while parsing {0}", key);

            float fl = 0;
            SetFloat(key, float.TryParse(_settingsDict[key].ToString(), out f) ? fl : defaultValue);
            return (float)_settingsDict[key];
        }



        public T Get<T>(string key, T defaultValue)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                Set<T>(key, defaultValue);
                // setdouble default
            }

            return (T)_settingsDict[key];
        }




        public string GetString(string key, string defaultValue = "")
        {
            if (!_settingsDict.ContainsKey(key))
            {
                SetString(key, defaultValue);
            }
            return (string)_settingsDict[key];

            //return _settingsDict.ContainsKey(key) ? (string)_settingsDict[key] : defaultValue;
        }

        public bool GetBool(string key, bool defaultValue = false)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                SetBool(key, defaultValue);
                return defaultValue;
            }
            return (bool)_settingsDict[key];



            //return _settingsDict.ContainsKey(key) && (bool)_settingsDict[key];
        }


        public object GetObject(string key, object defaultValue = null)
        {
            if (!_settingsDict.ContainsKey(key))
            {
                Set(key, defaultValue);
                return defaultValue;
            }
            return _settingsDict[key];

            //return _settingsDict.ContainsKey(key) ? _settingsDict[key] : defaultValue;
        }

        public T GetEnum<T>(string name, T defaultValue)
        {
            return (T)Enum.Parse(typeof(T), GetString(name, defaultValue.ToString()));
        }

        public void SetDefaults()
        {

        }

        public bool DirAggiornaSottoDirectory
        {
            get => this.GetBool("DirAggiornaSottoDirectory", true);
            set => this.SetBool("DirAggiornaSottoDirectory", value);
        }

        public bool Grassetto
        {
            get { return GetBool("Grassetto"); }
            set { SetBool("Grassetto", value); }
        }

        public string IlFont //todo
        {
            get { return GetString(""); }
            set { }
        }

        public bool TestoMin //todo
        {
            get { return false; }
            set { }
        }

        public bool AggTempoGaraMin //todo
        {
            get { return false; }
            set { }
        }

        public bool UsaTempoGaraTestoApplicare //todo
        {
            get { return false; }
            set { }
        }

        public bool AggNumTempMin //todo
        {
            get { return false; }
            set { }
        }

        public bool CreaMiniature //todo
        {
            get { return false; }
            set { }
        }

        public bool AggiungiScritteMiniature
        {
            get { return false; }
            set { }
        }

        public string Suffisso
        {
            get { return string.Empty; }
            set { }
        }

        public string Codice
        {
            get { return null; }
            set { }
        }

        public int Trasparenza
        {
            get { return 0; }
        }



        public DateTime DataPartenza { get; set; }
        public string TestoOrario { get; internal set; }
        public int DimStandard { get; internal set; }
        public int DimStandardMiniatura { get; internal set; }
        public bool UsaOrarioTestoApplicare { get; set; }
        public bool UsaOrarioMiniatura { get; set; }
        public string TestoFirmaStart { get; set; }
        public string TestoFirmaStartV { get; set; }
        public bool UsaForzaJpg { get; set; }

        public string DirectorySorgente
        {
            get { return GetString("DirSorgente"); }
            set { SetString("DirSorgente", value); }
        }

        public string DirectoryDestinazione
        {
            get { return GetString("DirDestinazione"); }
            set { SetString("DirDestinazione", value); }
        }

        public int Margine
        {
            get => GetInt("Margin", 1);
            set => SetInt("Margin", value);
        }
        public float MargVert { get; set; }
        public string Allineamento { get; set; }

        public bool GeneraleForzaJPG
        {
            get { return GetBool("GeneraleForzaJPG", true); }
            set { SetBool("GeneraleForzaJPG", value); }
        }

        public bool GeneraleRotazioneAutomatica
        {
            get { return GetBool("GeneraleRotazioneAutomatica", true); }
            set { SetBool("GeneraleRotazioneAutomatica", value); }
        }

        public bool GeneraleSovrascriviFile
        {
            get { return GetBool("GeneraleSovrascriviFile"); }
            set { SetBool("GeneraleSovrascriviFile", value); }
        }

        public bool SubdirCreaSottoCartelle
        {
            get { return GetBool("SubdirCreaSottoCartelle"); }
            set { SetBool("SubdirCreaSottoCartelle", value); }
        }

        public int SubdirIntervalloFile
        {
            get { return GetInt("SubdirIntervalloFile", 99); }
            set { SetInt("SubdirIntervalloFile", value); }
        }

        public string SubdirSuffisso
        {
            get { return GetString("SubdirSuffisso"); }
            set { SetString("SubdirSuffisso", value); }
        }

        public int SubdirCifreContatore
        {
            get { return GetInt("SubdirCifreContatore", 2); }
            set { SetInt("SubdirCifreContatore", value); }
        }

        public bool SubdirNumerazioneProgressiva
        {
            get { return GetBool("SubdirNumerazioneProgressiva", true); }
            set { SetBool("SubdirNumerazioneProgressiva", value); }
        }

        public bool SubdirNumerazioneFiles
        {
            get { return GetBool("SubdirNumerazioneFiles", false); }
            set { SetBool("SubdirNumerazioneFiles", value); }
        }

        public int FotoAltezza
        {
            get { return GetInt("FotoAltezza", 2240); }
            set { SetInt("FotoAltezza", value); }
        }

        public int FotoLarghezza
        {
            get { return GetInt("FotoLarghezza", 2240); }
            set { SetInt("FotoLarghezza", value); }
        }

        public int CompressioneJpeg
        {
            get { return GetInt("CompressioneJpeg", 85); }
            set { SetInt("CompressioneJpeg", value); }
        }

        public bool FotoMantieniDimensioni
        {
            get { return GetBool("FotoMantieniDimensioni", true); }
            set { SetBool("FotoMantieniDimensioni", value); }
        }

        public string FotoSuffisso
        {
            get { return GetString("FotoSuffisso"); }
            set { SetString("FotoSuffisso", value); }
        }


        public bool EnableThumbnails
        {
            get { return GetBool("EnableThumbnails", false); }
            set { SetBool("EnableThumbnails", value); }
        }
        public bool EnableLogo
        {
            get { return GetBool("EnableLogo", false); }
            set { SetBool("EnableLogo", value); }
        }

        #region Text

        public bool EnableText
        {
            get { return GetBool("EnableText", false); }
            set { SetBool("EnableText", value); }
        }

        public string NomeFont
        {
            get { return GetString("nomeFont", "Verdana"); }
            set { SetString("nomeFont", value); }
        }

        public double DimensioneFont
        {
            get { return Get<double>("dimensioneFont", 1); }
            set { SetDouble("dimensioneFont", value); }
        }

        public string TestoApplicareOrizzontale
        {
            get
            {
                return Get<string>("TestoApplicareOrizzontale", "");
            }
            set
            {
                Set<string>("TestoApplicareOrizzontale", value);
            }
        }

        public string ColoreTestoRGB
        {
            get { return GetString("coloreTestoRGB", "#000000"); }
            set
            {
                Set("coloreTestoRGB", value);

            }
        }

        public bool FotoRidimensiona
        {
            get => GetBool("FotoRidimensiona", false);
            set => Set("FotoRidimensiona", value);
        }

        public Positions TextPosition
        {
            get => GetEnum("TextPosition", Positions.Alto); //(Positions)Enum.Parse(typeof(Positions), GetString("TextPosition", Positions.Alto.ToString()));
            set => SetString("TextPosition", value.ToString());
        }

        public Alignments TextAlignment
        {
            get => GetEnum("TextAlignment", Alignments.Centro);
            set => SetString("TextAlignment", value.ToString());
        }

        public bool Threading
        {
            get => GetBool("Threading", true);
            set => SetBool("Threading", value);
        }

        public ResizeModes ResizeMode
        {
            get => GetEnum("ResizeMode", ResizeModes.Bicubic);
            set => SetString("ResizeMode", value.ToString());
        }

        public ResizeDimensions ResizeDimension
        {
            get => GetEnum("ResizeDimension", CatalogLib.ResizeDimensions.LatoCorto);
            set => SetString("ResizeDimension", value.ToString());
        }

        public string LogoPath
        {
            get => GetString("LogoPath");
            set => SetString("LogoPath", value);
        }

        public int LogoWidth
        {
            get => GetInt("LogoWidth");
            set => SetInt("LogoWidth", value);
        }

        public int LogoHeight
        {
            get => GetInt("LogoHeight");
            set => SetInt("LogoHeight", value);
        }

        public string LogoMargin
        {
            get => GetString("LogoMargin");
            set => SetString("LogoMargin", value);
        }

        public Positions LogoPosition
        {
            get => GetEnum("LogoPositions", Positions.Alto);
            set => SetString("LogoPositions", value.ToString());
        }

        public Alignments LogoAlignment
        {
            get => GetEnum("LogoAlignments", Alignments.Centro);
            set => SetString("LogoAlignments", value.ToString());
        }

        public ResizeDimensions LogoResizeSide
        {
            get => GetEnum("LogoResizeMode", ResizeDimensions.LatoCorto);
            set => SetString("LogoResizeMode", value.ToString());
        }

        #endregion

        #region Enums



        #endregion
    }
}