using System;
using System.Windows;
using System.IO;
using System.ComponentModel;
using System.Net;
using SharpCompress.Common;
using SharpCompress.Reader;

namespace Launcher
{
    /// <summary>
    /// Interaction logic for Patch.xaml
    /// </summary>
    public partial class Patch : Window
    {
        public Patch()
        {
            InitializeComponent();
        }

        public static string IP;
        public static string Bin;
        public string VersionPath = "reslauncher/Version.dat";
        public string PatchTo = Path.GetTempPath();
        public string Database = "http://192.168.1.19/patches/Patch.txt"; // Text file with patches
        public string Settings = "http://192.168.1.19/patches/settings.txt"; // Settings files. IP Goes first, then Exe name second. Format is IP=127.0.0.1 (new line) Exe=Game.exe or bin whichever

        public string[] PatchList = null;
        public string[] VersionContent = null;
        public int ClientVersion;
        public int ServerVersion;
        public int VersionNeeded;

        WebClient Downloader = new WebClient();

        public string CurrentFile;
        public string Applying;

        public void Main(object sender, EventArgs e)
        {
            Downloader.DownloadProgressChanged += new DownloadProgressChangedEventHandler(Downloader_ProgressChanged);
            Downloader.DownloadFileCompleted += new AsyncCompletedEventHandler(Downloader_DownloadFileCompleted);

            string[] IPContent = Downloader.DownloadString(Settings).Split('\n');
            IP = IPContent[0].Split('=')[1];

            string[] BinContent = Downloader.DownloadString(Settings).Split('\n');
            Bin = BinContent[1].Split('=')[1];

            VersionContent = File.ReadAllLines(VersionPath);
            VersionContent[0] = Methods.Decrypt(VersionContent[0]);

            PatchList = Downloader.DownloadString(Database).Split('\n');
            ClientVersion = Convert.ToInt32(VersionContent[0].Split('=')[1]);
            ServerVersion = Methods.CountPatches(Database);

            if (ClientVersion == ServerVersion)
            {
                Methods.RunGame(this, Bin, "-i " + IP);
            }
            else
            {
                Progress.Value = 0;
                VersionNeeded = ClientVersion + 1;
                Downloader.DownloadFileAsync(new Uri(PatchList[VersionNeeded].Split('\t')[1]), PatchTo + @"\EG-NOXUSPatch" + VersionNeeded + ".rar");
            }
        }

        private void Downloader_ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            Progress.Value = e.ProgressPercentage;
            Status.Text = String.Format("Downloading Patch {0}...", VersionNeeded.ToString());
            Percent.Text = String.Format("{0}%", Progress.Value.ToString());

            if (Percent.Text == "100%")
            {
                Progress.Value = 100; // lagging ui fix
            }
        }

        private void Downloader_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            CurrentFile = PatchTo + @"\EG-NOXUSPatch" + VersionNeeded + ".rar";

            BackgroundWorker Apply = new BackgroundWorker();
            Apply.WorkerReportsProgress = true;
            Apply.WorkerSupportsCancellation = true;
            Apply.DoWork += new DoWorkEventHandler(Apply_DoWork);
            Apply.ProgressChanged += new ProgressChangedEventHandler(Apply_ProgressChanged);
            Apply.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Apply_RunWorkerCompleted);
            Apply.RunWorkerAsync();
        }

        private void Apply_DoWork(object sender, DoWorkEventArgs e)
        {
            string string0 = CurrentFile;
            using (Stream stream = File.OpenRead(string0))
            {
                IReader reader = ReaderFactory.Open(stream, Options.KeepStreamsOpen);
                // Count entries first (?)
                int int0 = 0; // int 0 is how many files are done out of num, or total number
                int num = 0;
                while (reader.MoveToNextEntry())
                {
                    if (reader.Entry.IsDirectory)
                    {
                        continue;
                    }
                    num++;
                }

                stream.Close();

                // Create a new stream to actually extract
                using (Stream newStream = File.OpenRead(string0))
                {
                    IReader newReader = ReaderFactory.Open(newStream, Options.KeepStreamsOpen);
                    
                    while (newReader.MoveToNextEntry())
                    {
                        if (newReader.Entry.IsDirectory)
                        {
                            continue;
                        }
                        if (!Directory.Exists(Path.GetDirectoryName(string.Concat(Directory.GetCurrentDirectory(), "\\", newReader.Entry.FilePath))))
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(string.Concat(Directory.GetCurrentDirectory(), "\\", newReader.Entry.FilePath)));
                        }

                        Applying = Path.GetFileName(newReader.Entry.FilePath);
                        char[] chrArray = new char[] { '\\' };

                        try
                        {
                            newReader.WriteEntryToDirectory((Directory.GetCurrentDirectory()).TrimEnd(chrArray), ExtractOptions.Overwrite | ExtractOptions.ExtractFullPath);
                        }
                        catch
                        {
                            Methods.WriteLog(String.Format("Could not apply {0}. Skipping file.", Path.GetFileName(newReader.Entry.FilePath)));
                            continue;
                        }

                        int0++;

                        double percentPacket = ((double)int0 / num) * 100;
                        ((BackgroundWorker)sender).ReportProgress(Convert.ToInt32(percentPacket));
                    }
                }
            }
            File.Delete(string0);
        }

        private void Apply_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Status.Text = String.Format("Applying {0}...", Applying);
            Progress.Value = e.ProgressPercentage;
            Percent.Text = String.Format("{0}%", Progress.Value.ToString());

            if (Percent.Text == "100%")
            {
                Progress.Value = 100; // lagging ui fix
            }
        }

        private void Apply_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Methods.WriteLog(String.Format("Patch completed, version {0}", VersionNeeded));
            VersionNeeded = VersionNeeded + 1;
            ClientVersion = ClientVersion + 1;
            File.WriteAllText(VersionPath, Methods.Encrypt("Version=" + ClientVersion.ToString()));

            if (ServerVersion == ClientVersion)
            {
                Methods.RunGame(this, Bin, "-i " + IP);
            }
            else
            {
                Progress.Value = 0;
                Downloader.DownloadFileAsync(new Uri(PatchList[VersionNeeded].Split('\t')[1]), PatchTo + @"\EG-NOXUSPatch" + VersionNeeded + ".rar");
            }
        }
    }
}
