using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Reflection;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

namespace EduNetworkBuilder
{
    /// <summary>
    /// We have settings that need to be loaded and saved.  Mono has issues with 
    /// properties.settings.default stuff, so we need to load/save from an xml file
    /// when we are using mono.  So this class does that
    /// </summary>
    public class NBSettings
    {
        protected bool BelongsToUser = false;
        public int FileHistoryCount = 5;
        public string LastPath = "";
        public List<string> ScoreList = new List<string>();
        public List<string> RecentFiles = new List<string>();
        public bool AutoStartPuzzles = true;
        public string ChosenLanguage = "en";
        public bool LanguageHasBeenChosen = false;
        public int MainWindowX = -1;
        public int MainWindowY = -1;
        public int MainWindowWidth = -1;
        public int MainWindowHeight = -1;
        public string ProcessingLevel = "none";
        public UInt32 NextID = 100;
        public bool AutoDHCPAllMachinesAtNetworkLoad = false; //Mainly for teachers
        public string LastTrans1Lang = "";
        public string LastTrans2Lang = "";
        public string FormLastTransDir = "";
        
        public NBSettings()
        {
            //We need this for reflection
            BelongsToUser = true; //Only true when using reflection (serialization)
        }
        public NBSettings(NBSettings fromSettings)
        {
            if (fromSettings == null) return; //Break if we are going to error out.
            Duplicate(fromSettings, this);
        }

        static void Duplicate(NBSettings FromClass, NBSettings ToClass)
        {
            if (FromClass == null) return; //Break if we are going to error out.
            if (ToClass == null) return; //Break if we are going to error out.
                                         //
            if (Properties.Settings.Default.ScoreList == null)
                Properties.Settings.Default.ScoreList = new System.Collections.Specialized.StringCollection();
            if (Properties.Settings.Default.RecentFiles == null)
                Properties.Settings.Default.RecentFiles = new System.Collections.Specialized.StringCollection();

            ToClass.LastPath = FromClass.LastPath;
            ToClass.AutoStartPuzzles = FromClass.AutoStartPuzzles;
            ToClass.ChosenLanguage = FromClass.ChosenLanguage;
            ToClass.LanguageHasBeenChosen = FromClass.LanguageHasBeenChosen;
            ToClass.MainWindowX = FromClass.MainWindowX;
            ToClass.MainWindowY = FromClass.MainWindowY;
            ToClass.MainWindowHeight = FromClass.MainWindowHeight;
            ToClass.MainWindowWidth = FromClass.MainWindowWidth;
            ToClass.BelongsToUser = FromClass.BelongsToUser;
            ToClass.AutoDHCPAllMachinesAtNetworkLoad = FromClass.AutoDHCPAllMachinesAtNetworkLoad;
            ToClass.FormLastTransDir = FromClass.FormLastTransDir;

            foreach (string one in FromClass.ScoreList)
            {
                if (!ToClass.ScoreList.Contains(one))
                    ToClass.ScoreList.Add(one);
            }
            foreach (string one in FromClass.RecentFiles)
            {
                if (!ToClass.RecentFiles.Contains(one))
                    ToClass.RecentFiles.Add(one);
            }

        }

        public NBSettings(bool UsingMono)
        {
            if(UsingMono)
            {
                try
                {
                    //Try loading from xml file
                    string filename = GetFilename();
                    if (File.Exists(filename))
                    {
                        XmlSerializer sr = new XmlSerializer(this.GetType());
                        TextReader Reader = new StreamReader(filename);
                        NBSettings settings = (NBSettings)sr.Deserialize(Reader);
                        Duplicate(settings, this);
                        Reader.Close();
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error Loading Settings:\n" + e.ToString(),"Error Loading Settings");
                }
            }
            else
            {
                if (Properties.Settings.Default.ScoreList == null)
                    Properties.Settings.Default.ScoreList = new System.Collections.Specialized.StringCollection();
                if (Properties.Settings.Default.RecentFiles == null)
                    Properties.Settings.Default.RecentFiles = new System.Collections.Specialized.StringCollection();

                LastPath = Properties.Settings.Default.LastPath;
                AutoStartPuzzles = Properties.Settings.Default.AutoStartPuzzles;
                ChosenLanguage = Properties.Settings.Default.ChosenLanguage;
                LanguageHasBeenChosen = Properties.Settings.Default.LanguageHasBeenChosen;
                MainWindowX = Properties.Settings.Default.MainWindowX;
                MainWindowY = Properties.Settings.Default.MainWindowY;
                MainWindowHeight = Properties.Settings.Default.MainWindowHeight;
                MainWindowWidth = Properties.Settings.Default.MainWindowWidth;
                AutoDHCPAllMachinesAtNetworkLoad = Properties.Settings.Default.AutoDHCP;
                LastTrans1Lang = Properties.Settings.Default.LastTrans1Lang;
                LastTrans2Lang = Properties.Settings.Default.LastTrans2Lang;
                FormLastTransDir = Properties.Settings.Default.FormTransLastDir;

                foreach (string one in Properties.Settings.Default.ScoreList)
                {
                    if (!ScoreList.Contains(one))
                        ScoreList.Add(one);
                }
            }
        }

        public void MarkAsDone(string PuzzleName)
        {            
            //we just mark it in the settings class
            if (!ScoreList.Contains(PuzzleName))
            {
                ScoreList.Add(PuzzleName);
                Save();
            }
        }

        public bool CheckIfDone(string PuzzleName)
        {            
            //we just mark it in the settings class
            if (ScoreList.Contains(PuzzleName))
                return true;
            else
                return false;

        }

        public static string GetFilename()
        {
            string BaseDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string FileName = "EduNetworkBuilder_config.xml";
            return Path.Combine(BaseDir, FileName);
        }

        public void RegisterFileAsLoaded(string FilenameWithPath)
        {
            //Remove it from these settings
            if (RecentFiles.Contains(FilenameWithPath)) RecentFiles.Remove(FilenameWithPath);
            RecentFiles.Insert(0,FilenameWithPath);
            if(RecentFiles.Count > FileHistoryCount)
                for (int index = RecentFiles.Count - 1; index >= FileHistoryCount; index--)
                    RecentFiles.RemoveAt(index);

            if (!NB.IsRunningOnMono())
            {
                if (Properties.Settings.Default.RecentFiles.Contains(FilenameWithPath))
                    Properties.Settings.Default.RecentFiles.Remove(FilenameWithPath);
                Properties.Settings.Default.RecentFiles.Insert(0, FilenameWithPath);
                if (Properties.Settings.Default.RecentFiles.Count > FileHistoryCount)
                {
                    for (int index = Properties.Settings.Default.RecentFiles.Count - 1; index >= FileHistoryCount; index--)
                        Properties.Settings.Default.RecentFiles.RemoveAt(index);
                }
                Properties.Settings.Default.Save();
            }
        }

        public List<string> GetRecentFiles()
        {
            //If we do not have a user and are not using mono, grab the settings from properties.settings
            //Otherwise, we grab the settings from this settings object
            List<string> TheFiles = new List<string>();
            if(NB.GetUser() == null && !NB.IsRunningOnMono())
            {
                foreach (string one in Properties.Settings.Default.RecentFiles)
                    TheFiles.Add(one);
            }
            else
            {
                //This is the repository of recent files.  Use it
                TheFiles.AddRange(RecentFiles);
            }
            return TheFiles;
        }

        public void Save()
        {
            Save(NB.IsRunningOnMono());
        }

        public UInt64 IssueID()
        {
            //return the id and increment it.
            return NextID++;
        }
        public void Save(bool UsingMono)
        {
            if(UsingMono)
            {
                //Save it to an XML file.
                try
                {
                    string filename = GetFilename();
                    if(!Directory.Exists(Path.GetDirectoryName(filename)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(filename));
                    }
                    XmlSerializer sr = new XmlSerializer(this.GetType());
                    TextWriter writer = new StreamWriter(filename);
                    sr.Serialize(writer, this);
                    writer.Close();
                }
                catch(Exception e)
                {
                    MessageBox.Show("ERROR Saving Settings:\n" + e.ToString(),"Error saving settings.");
                }
            }
            else
            {
                if (Properties.Settings.Default.ScoreList == null)
                    Properties.Settings.Default.ScoreList = new System.Collections.Specialized.StringCollection();
                if(NB.GetUser() == null)
                {
                    Properties.Settings.Default.AutoStartPuzzles = AutoStartPuzzles;
                    Properties.Settings.Default.LanguageHasBeenChosen = LanguageHasBeenChosen;
                }
                else
                {
                    Properties.Settings.Default.AutoStartPuzzles = AutoStartPuzzles;
                    Properties.Settings.Default.LanguageHasBeenChosen = LanguageHasBeenChosen;
                }
                Properties.Settings.Default.LastPath = LastPath;
                Properties.Settings.Default.ChosenLanguage = ChosenLanguage;
                Properties.Settings.Default.MainWindowX = MainWindowX;
                Properties.Settings.Default.MainWindowY = MainWindowY;
                Properties.Settings.Default.MainWindowHeight = MainWindowHeight;
                Properties.Settings.Default.MainWindowWidth = MainWindowWidth;
                Properties.Settings.Default.AutoDHCP = AutoDHCPAllMachinesAtNetworkLoad;
                Properties.Settings.Default.LastTrans1Lang = LastTrans1Lang;
                Properties.Settings.Default.LastTrans2Lang = LastTrans2Lang;
                Properties.Settings.Default.FormTransLastDir = FormLastTransDir;

                Properties.Settings.Default.ScoreList.Clear();
                foreach(string One in ScoreList)
                {
                    Properties.Settings.Default.ScoreList.Add(One);
                }

                Properties.Settings.Default.Save();
            }
        }

    }
}
