private async void convertFiles(object sender, RoutedEventArgs e)
        {
            mainMenu.IsEnabled        = false;
            SpinnerConvert.Visibility = Visibility.Visible;
            tbConvert.Text            = "Converting";
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.InitialDirectory = Settings.Default.lastConvertedPath;
            openFileDialog.Multiselect      = true;

            string operationType = (sender as MenuItem).Tag.ToString();

            //await DdtFileUtils.Ddt2PngAsync(@"D:\Development\Resource Manager\Resource Manager\bin\Release\netcoreapp3.1\Art\ui\alerts\alert_treatyend_bump.ddt");



            if (operationType == "totga")
            {
                openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt";
                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await DdtFileUtils.Ddt2TgaAsync(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "topng")
            {
                openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt";
                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await DdtFileUtils.Ddt2PngAsync(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxml")
            {
                openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            var data = await File.ReadAllBytesAsync(file);


                            if (Alz4Utils.IsAlz4File(data))
                            {
                                data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                            }
                            else
                            {
                                if (L33TZipUtils.IsL33TZipFile(data))
                                {
                                    data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                                }
                            }


                            using MemoryStream stream = new MemoryStream(data);
                            XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                            var newName = Path.ChangeExtension(file, "");

                            xmb.file.Save(newName);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "jsontoxml")
            {
                openFileDialog.Filter = "JSON files (*.json)|*.json";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            var data = await File.ReadAllBytesAsync(file);


                            if (Alz4Utils.IsAlz4File(data))
                            {
                                data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                            }
                            else
                            {
                                if (L33TZipUtils.IsL33TZipFile(data))
                                {
                                    data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                                }
                            }
                            string json = await File.ReadAllTextAsync(file);

                            var xml = JsonConvert.DeserializeXmlNode(json);

                            var newName = Path.ChangeExtension(file, "");



                            xml.Save(newName);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "xmbtojson")
            {
                openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            var data = await File.ReadAllBytesAsync(file);


                            if (Alz4Utils.IsAlz4File(data))
                            {
                                data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                            }
                            else
                            {
                                if (L33TZipUtils.IsL33TZipFile(data))
                                {
                                    data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                                }
                            }


                            using MemoryStream stream = new MemoryStream(data);

                            XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                            string json = JsonConvert.SerializeXmlNode(xmb.file);
                            await File.WriteAllTextAsync(Path.ChangeExtension(file, "json"), json);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "xmltojson")
            {
                openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            XmlDocument xml = new XmlDocument();
                            xml.Load(file);
                            string json = JsonConvert.SerializeXmlNode(xml);
                            await File.WriteAllTextAsync(Path.ChangeExtension(file, "json"), json);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "jsontoxmblegacy")
            {
                openFileDialog.Filter = "JSON files (*.json)|*.json";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            string json = await File.ReadAllTextAsync(file);

                            var xml = JsonConvert.DeserializeXmlNode(json);
                            await XMBFile.CreateXMBFileL33T(xml, file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "jsontoxmbde")
            {
                openFileDialog.Filter = "JSON files (*.json)|*.json";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            string json = await File.ReadAllTextAsync(file);

                            var xml = JsonConvert.DeserializeXmlNode(json);
                            await XMBFile.CreateXMBFileALZ4(xml, file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxmbde")
            {
                openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*";

                if (openFileDialog.ShowDialog() == true)
                {
                    Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                    Settings.Default.Save();
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await XMBFile.CreateXMBFileALZ4(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxmbcc")
            {
                openFileDialog.Filter = "Age of Empires 3 xml files (*.*)|*.*";
                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (var file in openFileDialog.FileNames)
                    {
                        Settings.Default.lastConvertedPath = Path.GetDirectoryName(openFileDialog.FileName);
                        Settings.Default.Save();
                        try
                        {
                            await XMBFile.CreateXMBFileL33T(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }



            tbConvert.Text            = "Convert";
            SpinnerConvert.Visibility = Visibility.Collapsed;
            mainMenu.IsEnabled        = true;
        }
        private async void convertFiles(object sender, RoutedEventArgs e)
        {
            mainMenu.IsEnabled        = false;
            SpinnerConvert.Visibility = Visibility.Visible;
            tbConvert.Text            = "Converting";
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Multiselect = true;

            string operationType = (sender as MenuItem).Tag.ToString();

            //await DdtFileUtils.Ddt2PngAsync(@"D:\Development\Resource Manager\Resource Manager\bin\Release\netcoreapp3.1\Art\ui\alerts\alert_treatyend_bump.ddt");

            if (operationType == "topng")
            {
                openFileDialog.Filter = "Age of Empires 3 ddt files (*.ddt)|*.ddt";
                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await DdtFileUtils.Ddt2PngAsync(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxml")
            {
                openFileDialog.Filter = "Age of Empires 3 xmb files (*.xmb)|*.xmb";

                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            var data = await File.ReadAllBytesAsync(file);


                            if (Alz4Utils.IsAlz4File(data))
                            {
                                data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                            }
                            else
                            {
                                if (L33TZipUtils.IsL33TZipFile(data))
                                {
                                    data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                                }
                            }


                            using MemoryStream stream = new MemoryStream(data);
                            XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                            var newName = Path.ChangeExtension(file, "");

                            xmb.file.Save(newName);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxmbde")
            {
                openFileDialog.Filter = "Age of Empires 3 xml files (*.xml)|*.xml";

                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await XMBFile.CreateXMBFileALZ4(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }
            if (operationType == "toxmbcc")
            {
                openFileDialog.Filter = "Age of Empires 3 xml files (*.xml)|*.xml";
                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (var file in openFileDialog.FileNames)
                    {
                        try
                        {
                            await XMBFile.CreateXMBFileL33T(file);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Conversion error - " + Path.GetFileName(file), MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
            }



            tbConvert.Text            = "Convert";
            SpinnerConvert.Visibility = Visibility.Collapsed;
            mainMenu.IsEnabled        = true;
        }
        public async Task saveFiles(List <BarEntry> files, string savePath, bool Decompress, CancellationToken token, bool convertDDTToPNG, bool convertDDTToTGA, bool convertXMB, bool OneFolder, bool SavePNGasBMP, bool AutoJSONConversion, Color OverlayColor)
        {
            ResetProgress();
            if (files.Count == 0)
            {
                return;
            }

            using var input = File.OpenRead(barFilePath);

            long filesSize = files.Sum(x => (long)x.FileSize2);

            foreach (var file in files)
            {
                if (token.IsCancellationRequested)
                {
                    while (extractingState == 1)
                    {
                        await Task.Delay(1000);
                    }
                }
                if (token.IsCancellationRequested && extractingState == 2)
                {
                    ResetProgress();
                    return;
                }
                // Locate the file within the BAR file.
                input.Seek(file.Offset, SeekOrigin.Begin);


                string ExtractPath = Path.Combine(savePath, file.FileNameWithRoot);
                if (OneFolder)
                {
                    ExtractPath = Path.Combine(savePath, file.fileNameWithoutPath);
                }

                Directory.CreateDirectory(Path.GetDirectoryName(ExtractPath));


                var data = new byte[file.FileSize2];
                await input.ReadAsync(data, 0, data.Length);

                // XMB and decompress
                if (file.Extension != ".XMB" && (L33TZipUtils.IsL33TZipFile(data) || Alz4Utils.IsAlz4File(data)) && Decompress)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }
                }

                // WAV or MP3
                if (file.Extension == ".WAV" || file.Extension == ".MP3")
                {
                    if (file.isCompressed == 2)
                    {
                        data = await soundUtils.DecryptSound(data);
                    }
                }

                // Save PNG as BMP, skip saving as PNG
                if (file.Extension == ".PNG" && SavePNGasBMP)
                {
                    using var memory = new MemoryStream(data);
                    Bitmap img = new Bitmap(memory);


                    PixelFormat fmt1 = img.PixelFormat;
                    byte        bpp1 = 4;

                    Rectangle  rect    = new Rectangle(Point.Empty, new Size(img.Width, img.Height));
                    BitmapData bmpData = img.LockBits(rect, ImageLockMode.ReadWrite, fmt1);

                    int    size1  = bmpData.Stride * bmpData.Height;
                    byte[] pixels = new byte[size1];
                    Marshal.Copy(bmpData.Scan0, pixels, 0, size1);

                    for (int y = 0; y < img.Height; y++)
                    {
                        for (int x = 0; x < img.Width; x++)
                        {
                            int index = y * bmpData.Stride + x * bpp1;
                            var alpha = pixels[index + 3];
                            if (alpha < 255)
                            {
                                pixels[index]     = (byte)(pixels[index] * OverlayColor.B / 255);     //b
                                pixels[index + 1] = (byte)(pixels[index + 1] * OverlayColor.G / 255); //g
                                pixels[index + 2] = (byte)(pixels[index + 2] * OverlayColor.R / 255); //r
                                pixels[index + 3] = 255;
                            }
                        }
                    }

                    Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length);
                    img.UnlockBits(bmpData);
                    using (Graphics g = Graphics.FromImage(img))
                    {
                        g.DrawImage(new Bitmap(memory), Point.Empty);
                    }
                    img.Save(ExtractPath, System.Drawing.Imaging.ImageFormat.Png);
                    CurrentProgress += (double)file.FileSize2 / filesSize;
                    continue;
                }


                // Save data
                await File.WriteAllBytesAsync(ExtractPath, data);


                // Additionaly convert xmb
                if (file.Extension == ".XMB" && convertXMB)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }

                    using MemoryStream stream = new MemoryStream(data);
                    XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                    xmb.file.Save(Path.ChangeExtension(ExtractPath, ""));
                }

                // Additionaly convert xmb -> json
                if (file.Extension == ".XMB" && AutoJSONConversion)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }

                    using MemoryStream stream = new MemoryStream(data);
                    XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                    string json = JsonConvert.SerializeXmlNode(xmb.file);
                    await File.WriteAllTextAsync(Path.ChangeExtension(ExtractPath, "json"), json);
                }

                // Additionaly convert xml -> json
                if (file.Extension == ".XML" && AutoJSONConversion)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }

                    using MemoryStream stream = new MemoryStream(data);
                    XmlDocument xml = new XmlDocument();
                    xml.Load(stream);
                    string json = JsonConvert.SerializeXmlNode(xml);
                    await File.WriteAllTextAsync(Path.ChangeExtension(ExtractPath, "json"), json);
                }



                // Additionaly convert ddt to png
                if (file.Extension == ".DDT" && convertDDTToPNG)
                {
                    await DdtFileUtils.DdtBytes2PngAsync(data, ExtractPath);
                }
                // Additionaly convert ddt to tga
                if (file.Extension == ".DDT" && convertDDTToTGA)
                {
                    await DdtFileUtils.DdtBytes2TgaAsync(data, ExtractPath);
                }



                CurrentProgress += (double)file.FileSize2 / filesSize;
            }
            ResetProgress();
        }
        public async Task saveFiles(List <BarEntry> files, string savePath, bool Decompress, CancellationToken token, bool convertDDT, bool convertXMB)
        {
            ResetProgress();
            if (files.Count == 0)
            {
                return;
            }

            using var input = File.OpenRead(barFilePath);

            long filesSize = files.Sum(x => (long)x.FileSize2);

            foreach (var file in files)
            {
                if (token.IsCancellationRequested)
                {
                    while (extractingState == 1)
                    {
                        await Task.Delay(1000);
                    }
                }
                if (token.IsCancellationRequested && extractingState == 2)
                {
                    ResetProgress();
                    return;
                }
                // Locate the file within the BAR file.
                input.Seek(file.Offset, SeekOrigin.Begin);

                Directory.CreateDirectory(Path.Combine(savePath, Path.GetDirectoryName(file.FileNameWithRoot)));



                var data = new byte[file.FileSize2];
                await input.ReadAsync(data, 0, data.Length);


                if (file.Extension != ".XMB" && (L33TZipUtils.IsL33TZipFile(data) || Alz4Utils.IsAlz4File(data)) && Decompress)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }
                }

                if (file.Extension == ".WAV" || file.Extension == ".MP3")
                {
                    if (file.isCompressed == 2)
                    {
                        data = await soundUtils.DecryptSound(data);
                    }
                }

                await File.WriteAllBytesAsync(Path.Combine(savePath, file.FileNameWithRoot), data);



                if (file.Extension == ".XMB" && convertXMB)
                {
                    if (Alz4Utils.IsAlz4File(data))
                    {
                        data = await Alz4Utils.ExtractAlz4BytesAsync(data);
                    }
                    else
                    {
                        if (L33TZipUtils.IsL33TZipFile(data))
                        {
                            data = await L33TZipUtils.ExtractL33TZippedBytesAsync(data);
                        }
                    }

                    using MemoryStream stream = new MemoryStream(data);
                    XMBFile xmb = await XMBFile.LoadXMBFile(stream);

                    var newName = Path.ChangeExtension(Path.Combine(savePath, file.FileNameWithRoot), "");

                    xmb.file.Save(newName);
                }

                if (file.Extension == ".DDT" && convertDDT)
                {
                    await DdtFileUtils.DdtBytes2PngAsync(data, Path.Combine(savePath, file.FileNameWithRoot));
                }


                CurrentProgress += (double)file.FileSize2 / filesSize;
            }
            ResetProgress();
        }