private void TileListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (tileListBox.SelectedItem == null)
            {
                e.Handled = true;
                return;
            }

            try
            {
                var selectedMap = (MapListItem)mapListBox.SelectedItem;

                if (!wdtCache.ContainsKey(selectedMap.ID))
                {
                    var reader = new WoWFormatLib.FileReaders.WDTReader();
                    reader.LoadWDT((uint)selectedMap.WDTFileDataID);
                    wdtCache.Add(selectedMap.ID, reader);
                }

                var file          = (string)tileListBox.SelectedItem;
                var splitTile     = file.Split('_');
                var fixedTileName = splitTile[0].PadLeft(2, '0') + "_" + splitTile[1].PadLeft(2, '0');
                var minimapFile   = "world\\minimaps\\" + selectedMap.Internal + "\\map" + fixedTileName + ".blp";

                if (!Listfile.TryGetFileDataID(minimapFile, out var minimapFileDataID))
                {
                    Logger.WriteLine("Unable to find filedataid for minimap file " + minimapFile);
                    minimapFileDataID = wdtCache[selectedMap.ID].tileFiles[(byte.Parse(splitTile[0]), byte.Parse(splitTile[1]))].minimapTexture;
        private void TextureListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var file = (string)textureListBox.SelectedItem;

            if (file == null)
            {
                return;
            }

            try
            {
                using (var memory = new MemoryStream())
                {
                    var blp = new WoWFormatLib.FileReaders.BLPReader();
                    if (Listfile.TryGetFileDataID(file, out var filedataid))
                    {
                        blp.LoadBLP(filedataid);
                    }
                    else
                    {
                        return;
                    }

                    var bmp = blp.bmp;

                    if (ignoreTextureAlpha)
                    {
                        bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.PixelFormat.Format32bppRgb).Save(memory, ImageFormat.Bmp);
                    }
                    else
                    {
                        bmp.Save(memory, ImageFormat.Png);
                    }

                    memory.Position = 0;

                    var bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = memory;
                    bitmapImage.CacheOption  = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                    blpImage.Source    = bitmapImage;
                    blpImage.MaxWidth  = bitmapImage.Width;
                    blpImage.MaxHeight = bitmapImage.Height;
                }
            }
            catch (Exception blpException)
            {
                Console.WriteLine(blpException.Message);
            }

            e.Handled = true;
        }
        /* Map tab */
        private void ExportTileButton_Click(object sender, RoutedEventArgs e)
        {
            var selectedMap  = (MapListItem)mapListBox.SelectedItem;
            var selectedTile = (string)tileListBox.SelectedItem;

            if (selectedMap == null || selectedTile == null)
            {
                Console.WriteLine("Nothing selected, not exporting.");
                return;
            }

            Console.WriteLine(selectedMap.Name + ", " + selectedMap.Internal + ", " + selectedTile);

            progressBar.Value       = 0;
            progressBar.Visibility  = Visibility.Visible;
            loadingLabel.Content    = "";
            loadingLabel.Visibility = Visibility.Visible;
            wmoCheckBox.IsEnabled   = false;
            m2CheckBox.IsEnabled    = false;
            exportButton.IsEnabled  = false;
            modelListBox.IsEnabled  = false;

            /* ADT specific UI */
            exportTileButton.IsEnabled = false;
            mapListBox.IsEnabled       = false;
            tileListBox.IsEnabled      = false;

            var tileList = new List <Structs.MapTile>();

            progressBar.Value    = 10;
            loadingLabel.Content = "Baking map textures, this will take a while.";

            Dispatcher.Invoke(new Action(() => { }), System.Windows.Threading.DispatcherPriority.ContextIdle, null);

            foreach (string item in tileListBox.SelectedItems)
            {
                var mapName = selectedMap.Internal.ToLower();
                var mapTile = new Structs.MapTile();
                var coord   = item.Split('_');
                mapTile.tileX = byte.Parse(coord[0]);
                mapTile.tileY = byte.Parse(coord[1]);

                var wdtFileName = "world/maps/" + mapName + "/" + mapName + ".wdt";
                if (!Listfile.TryGetFileDataID(wdtFileName, out mapTile.wdtFileDataID))
                {
                    Logger.WriteLine("Unable to find WDT fileDataID for map " + selectedMap.Internal.ToLower());
                }

                tileList.Add(mapTile);

                ConfigurationManager.RefreshSection("appSettings");
                var outdir = ConfigurationManager.AppSettings["outdir"];

                if (((ComboBoxItem)bakeSize.SelectedItem).Name != "none")
                {
                    previewControl.BakeTexture(mapTile, Path.Combine(outdir, Path.GetDirectoryName(wdtFileName), mapName.Replace(" ", "") + "_" + mapTile.tileX + "_" + mapTile.tileY + ".png"));
                }
            }

            adtexportworker.RunWorkerAsync(tileList);
        }
        private void Exportworker_DoWork(object sender, DoWorkEventArgs e)
        {
            var selectedFiles = (System.Collections.IList)e.Argument;

            var exportFormat = "OBJ";

            ConfigurationManager.RefreshSection("appSettings");
            if (ConfigurationManager.AppSettings["exportFormat"] != null && ConfigurationManager.AppSettings["exportFormat"] == "glTF")
            {
                exportFormat = "glTF";
            }

            Logger.WriteLine("ExportWorker: Export format is {0}", exportFormat);

            foreach (string selectedFile in selectedFiles)
            {
                if (!Listfile.TryGetFileDataID(selectedFile, out var fileDataID))
                {
                    Logger.WriteLine("ExportWorker: File {0} does not exist in listfile, skipping export!", selectedFile);
                    continue;
                }

                if (!CASC.FileExists(fileDataID))
                {
                    Logger.WriteLine("ExportWorker: File {0} does not exist, skipping export!", selectedFile);
                    continue;
                }

                Logger.WriteLine("ExportWorker: Exporting {0}..", selectedFile);
                try
                {
                    if (selectedFile.EndsWith(".wmo"))
                    {
                        if (exportFormat == "OBJ")
                        {
                            Exporters.OBJ.WMOExporter.ExportWMO(selectedFile, exportworker);
                        }
                        else if (exportFormat == "glTF")
                        {
                            Exporters.glTF.WMOExporter.ExportWMO(selectedFile, exportworker);
                        }
                    }
                    else if (selectedFile.EndsWith(".m2"))
                    {
                        if (exportFormat == "OBJ")
                        {
                            Exporters.OBJ.M2Exporter.ExportM2(selectedFile, exportworker);
                        }
                        else if (exportFormat == "glTF")
                        {
                            Exporters.glTF.M2Exporter.ExportM2(selectedFile, exportworker);
                        }
                    }
                    else if (selectedFile.EndsWith(".blp"))
                    {
                        ConfigurationManager.RefreshSection("appSettings");
                        var outdir = ConfigurationManager.AppSettings["outdir"];
                        try
                        {
                            if (!Listfile.FilenameToFDID.TryGetValue(selectedFile, out uint blpFileDataID))
                            {
                                throw new Exception("Unable to find filedata for filename " + selectedFile);
                            }

                            var blp = new WoWFormatLib.FileReaders.BLPReader();
                            blp.LoadBLP(blpFileDataID);

                            var bmp = blp.bmp;

                            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(selectedFile))))
                            {
                                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(selectedFile)));
                            }

                            if (ignoreTextureAlpha)
                            {
                                bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.PixelFormat.Format32bppRgb).Save(Path.Combine(outdir, Path.GetDirectoryName(selectedFile), Path.GetFileNameWithoutExtension(selectedFile)) + ".png");
                            }
                            else
                            {
                                bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(selectedFile), Path.GetFileNameWithoutExtension(selectedFile)) + ".png");
                            }
                        }
                        catch (Exception blpException)
                        {
                            Console.WriteLine(blpException.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.WriteLine("ExportWorker: Exception occured in " + ex.Source + " " + ex.Message + " " + ex.StackTrace);
                }
            }
        }
        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            worker.ReportProgress(0, "Loading listfile..");

            if (!File.Exists("listfile.csv"))
            {
                worker.ReportProgress(20, "Downloading listfile..");
                Listfile.Update();
            }
            else if (DateTime.Now.AddDays(-7) > File.GetLastWriteTime("listfile.csv"))
            {
                worker.ReportProgress(20, "Updating listfile..");
                Listfile.Update();
            }

            worker.ReportProgress(50, "Loading listfile from disk..");

            if (Listfile.FDIDToFilename.Count == 0)
            {
                Listfile.Load();
            }

            worker.ReportProgress(70, "Filtering listfile..");

            var linelist = new List <string>();

            foreach (var line in Listfile.FDIDToFilename)
            {
                if (CASC.FileExists(line.Key))
                {
                    linelist.Add(line.Value);
                }
            }

            var regex = new System.Text.RegularExpressions.Regex(@"(_\d\d\d_)|(_\d\d\d.wmo$)|(lod\d.wmo$)");

            foreach (var line in linelist)
            {
                if (showWMO && line.EndsWith("wmo"))
                {
                    if (!regex.Match(line).Success)
                    {
                        models.Add(line);
                    }
                }

                if (showM2 && line.EndsWith("m2"))
                {
                    models.Add(line);
                }

                if (line.EndsWith("blp"))
                {
                    textures.Add(line);
                }
            }

            worker.ReportProgress(80, "Sorting listfile..");

            models.Sort();
            textures.Sort();
        }
        private void UpdateFilter()
        {
            if (!MainMenu.IsEnabled)
            {
                return;
            }

            var filtered = new List <string>();

            if (TexturesTab.IsSelected)
            {
                for (var i = 0; i < textures.Count(); i++)
                {
                    if (textures[i].IndexOf(filterTextBox.Text, 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                    {
                        filtered.Add(textures[i]);
                    }
                }

                textureListBox.DataContext = filtered;
            }
            else if (MapsTab.IsSelected)
            {
                UpdateMapListView();
            }
            else if (ModelsTab.IsSelected)
            {
                if (filterTextBox.Text.StartsWith("maptile:"))
                {
                    var filterSplit = filterTextBox.Text.Remove(0, 8).Split('_');
                    if (filterSplit.Length == 3)
                    {
                        exportButton.Content = "Crawl maptile for models";

                        if (Listfile.TryGetFileDataID("world/maps/" + filterSplit[0] + "/" + filterSplit[0] + "_" + filterSplit[1] + "_" + filterSplit[2] + ".adt", out var fileDataID))
                        {
                            if (CASC.FileExists(fileDataID))
                            {
                                exportButton.IsEnabled = true;
                            }
                            else
                            {
                                exportButton.IsEnabled = false;
                            }
                        }
                        else
                        {
                            exportButton.IsEnabled = false;
                        }
                    }
                }
                else
                {
                    exportButton.Content = "Export model to OBJ!";
                }

                for (var i = 0; i < models.Count(); i++)
                {
                    if (models[i].IndexOf(filterTextBox.Text, 0, StringComparison.CurrentCultureIgnoreCase) != -1)
                    {
                        filtered.Add(models[i]);
                    }
                }

                modelListBox.DataContext = filtered;
            }
        }