private void ExecuteOpenCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                BusyIndicatorService.Notify(string.Concat("Opening ", System.IO.Path.GetFileName(fileName), "..."));

                try
                {
                    dispatcher(() => this.OptModel.File = null);

                    var opt = OptFile.FromFile(fileName);

                    dispatcher(() => this.OptModel.File = opt);
                    dispatcher(() => this.OptModel.UndoStackPush("open " + System.IO.Path.GetFileNameWithoutExtension(fileName)));

                    if (!this.OptModel.IsPlayable)
                    {
                        Messenger.Instance.Notify(new MainViewSelectorMessage("PlayabilityMessages"));
                        Messenger.Instance.Notify(new MessageBoxMessage(fileName + "\n\n" + "This opt will not be fully playable.", "Check Opt Playability", MessageBoxButton.OK, MessageBoxImage.Warning));
                    }
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(fileName, ex));
                }
            });
        }
        private void ExecuteImportOptCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                BusyIndicatorService.Notify(string.Concat("Importing ", System.IO.Path.GetFileName(fileName), "..."));

                var opt = this.OptModel.File;

                try
                {
                    dispatcher(() => this.OptModel.File = null);

                    var import        = OptFile.FromFile(fileName);
                    string importName = System.IO.Path.GetFileNameWithoutExtension(fileName) + "_";

                    foreach (var faceGroup in import.Meshes.SelectMany(t => t.Lods).SelectMany(t => t.FaceGroups))
                    {
                        var textures = faceGroup.Textures.ToList();
                        faceGroup.Textures.Clear();

                        foreach (var texture in textures)
                        {
                            faceGroup.Textures.Add(texture.StartsWith(importName, StringComparison.Ordinal) ? texture : (importName + texture));
                        }
                    }

                    foreach (var texture in import.Textures.Values)
                    {
                        texture.Name = texture.Name.StartsWith(importName, StringComparison.Ordinal) ? texture.Name : (importName + texture.Name);
                    }

                    foreach (var texture in import.Textures.Values)
                    {
                        opt.Textures[texture.Name] = texture;
                    }

                    foreach (var mesh in import.Meshes)
                    {
                        opt.Meshes.Add(mesh);
                    }
                }
                catch (Exception ex)
                {
                    Messenger.Instance.Notify(new MessageBoxMessage(fileName, ex));
                }

                dispatcher(() => this.OptModel.File = opt);
                dispatcher(() => this.OptModel.UndoStackPush("import " + System.IO.Path.GetFileName(fileName)));
            });
        }
        private void ExecuteConvertAllTexturesTo8BppCommand()
        {
            BusyIndicatorService.Run(dispatcher =>
            {
                string fileName = FileDialogService.GetOpenOptFileName();

                if (fileName == null)
                {
                    return;
                }

                string directory = System.IO.Path.GetDirectoryName(fileName);

                BusyIndicatorService.Notify("Converting all textures to 8 bpp...");

                var message = Messenger.Instance.Notify(new MessageBoxMessage(string.Concat("The textures of all OPTs in \"", directory, "\" will be converted to 8 bpp.\nDo you want to continue?"), "Converting textures", MessageBoxButton.YesNo, MessageBoxImage.Warning));

                if (message.Result != MessageBoxResult.Yes)
                {
                    return;
                }

                foreach (string file in System.IO.Directory.GetFiles(directory, "*.opt"))
                {
                    BusyIndicatorService.Notify(string.Concat("Converting ", System.IO.Path.GetFileName(file), " to 8 bpp..."));

                    OptFile opt = null;

                    try
                    {
                        opt = OptFile.FromFile(file);
                    }
                    catch (System.IO.InvalidDataException)
                    {
                        continue;
                    }

                    if (opt.TexturesBitsPerPixel == 8)
                    {
                        continue;
                    }

                    opt.ConvertTextures32To8();
                    opt.Save(opt.FileName);
                }

                BusyIndicatorService.Notify("Converting all textures to 8 bpp completed.");

                Messenger.Instance.Notify(new MessageBoxMessage("Converting all textures to 8 bpp completed.", "Converting textures"));
            });
        }