/// <summary>
        /// This is called by the importer when the TTModel has been populated, but
        /// before it is injected into the XIV files.  This lets us step in and do whatever
        /// other manipulations we want on it.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private async Task <bool> IntermediateStep(TTModel newModel, TTModel oldModel)
        {
            var result = false;
            await _view.Dispatcher.BeginInvoke((ThreadStart) delegate()
            {
                try
                {
                    var editorWindow = new ImportModelEditView(newModel, oldModel)
                    {
                        Owner = _view
                    };
                    result = editorWindow.ShowDialog() == true ? true : false;
                }
                catch (Exception Ex)
                {
                    throw Ex;
                }
            });

            return(result);
        }
        public ImportModelEditViewModel(ImportModelEditView view, TTModel newModel, TTModel oldModel)
        {
            _view     = view;
            _newModel = newModel;
            _oldModel = oldModel;



            // Get all the materials available.

            // Merge all the default skin materials together, since FFXIV auto-handles them anyways.
            foreach (var m in _newModel.MeshGroups)
            {
                if (m.Material == null)
                {
                    // Sanity assurance.
                    m.Material = _newModel.MeshGroups[0].Material;
                }


                var result = DefaultSkinRegex.Match(m.Material);
                if (result.Success)
                {
                    m.Material = SkinMaterial;
                }
            }

            // Calculate the model bounding box sizes.
            float minX = 9999.0f, minY = 9999.0f, minZ = 9999.0f;
            float maxX = -9999.0f, maxY = -9999.0f, maxZ = -9999.0f;

            foreach (var m in _newModel.MeshGroups)
            {
                foreach (var p in m.Parts)
                {
                    foreach (var v in p.Vertices)
                    {
                        minX = minX < v.Position.X ? minX : v.Position.X;
                        minY = minY < v.Position.Y ? minY : v.Position.Y;
                        minZ = minZ < v.Position.Z ? minZ : v.Position.Z;

                        maxX = maxX > v.Position.X ? maxX : v.Position.X;
                        maxY = maxY > v.Position.Y ? maxY : v.Position.Y;
                        maxZ = maxZ > v.Position.Z ? maxZ : v.Position.Z;
                    }
                }
            }

            Vector3 min = new Vector3(minX, minY, minZ);
            Vector3 max = new Vector3(maxX, maxY, maxZ);

            NewModelSize = Vector3.Distance(min, max);

            minX = 9999.0f; minY = 9999.0f; minZ = 9999.0f;
            maxX = -9999.0f; maxY = -9999.0f; maxZ = -9999.0f;
            foreach (var m in _oldModel.MeshGroups)
            {
                foreach (var p in m.Parts)
                {
                    foreach (var v in p.Vertices)
                    {
                        minX = minX < v.Position.X ? minX : v.Position.X;
                        minY = minY < v.Position.Y ? minY : v.Position.Y;
                        minZ = minZ < v.Position.Z ? minZ : v.Position.Z;

                        maxX = maxX > v.Position.X ? maxX : v.Position.X;
                        maxY = maxY > v.Position.Y ? maxY : v.Position.Y;
                        maxZ = maxZ > v.Position.Z ? maxZ : v.Position.Z;
                    }
                }
            }

            min = new Vector3(minX, minY, minZ);
            max = new Vector3(maxX, maxY, maxZ);

            OldModelSize = Vector3.Distance(min, max);


            AsyncInit();
        }
        public ImportModelEditViewModel(ImportModelEditView view, TTModel newModel, TTModel oldModel)
        {
            _view     = view;
            _newModel = newModel;
            _oldModel = oldModel;


            // Merge all the default skin materials together, since FFXIV auto-handles them anyways.
            foreach (var m in _newModel.MeshGroups)
            {
                if (m.Material == null)
                {
                    // Sanity assurance.
                    m.Material = _newModel.MeshGroups[0].Material;
                }


                var result = DefaultSkinRegex.Match(m.Material);
                if (result.Success)
                {
                    m.Material = SkinMaterial;
                }
            }

            // Calculate the model bounding box sizes.
            float minX = 9999.0f, minY = 9999.0f, minZ = 9999.0f;
            float maxX = -9999.0f, maxY = -9999.0f, maxZ = -9999.0f;

            foreach (var m in _newModel.MeshGroups)
            {
                foreach (var p in m.Parts)
                {
                    foreach (var v in p.Vertices)
                    {
                        minX = minX < v.Position.X ? minX : v.Position.X;
                        minY = minY < v.Position.Y ? minY : v.Position.Y;
                        minZ = minZ < v.Position.Z ? minZ : v.Position.Z;

                        maxX = maxX > v.Position.X ? maxX : v.Position.X;
                        maxY = maxY > v.Position.Y ? maxY : v.Position.Y;
                        maxZ = maxZ > v.Position.Z ? maxZ : v.Position.Z;
                    }
                }
            }

            Vector3 min = new Vector3(minX, minY, minZ);
            Vector3 max = new Vector3(maxX, maxY, maxZ);

            NewModelSize = Vector3.Distance(min, max);

            minX = 9999.0f; minY = 9999.0f; minZ = 9999.0f;
            maxX = -9999.0f; maxY = -9999.0f; maxZ = -9999.0f;
            foreach (var m in _oldModel.MeshGroups)
            {
                foreach (var p in m.Parts)
                {
                    foreach (var v in p.Vertices)
                    {
                        minX = minX < v.Position.X ? minX : v.Position.X;
                        minY = minY < v.Position.Y ? minY : v.Position.Y;
                        minZ = minZ < v.Position.Z ? minZ : v.Position.Z;

                        maxX = maxX > v.Position.X ? maxX : v.Position.X;
                        maxY = maxY > v.Position.Y ? maxY : v.Position.Y;
                        maxZ = maxZ > v.Position.Z ? maxZ : v.Position.Z;
                    }
                }
            }

            min = new Vector3(minX, minY, minZ);
            max = new Vector3(maxX, maxY, maxZ);

            OldModelSize = Vector3.Distance(min, max);

            UpdateModelSizeWarning();


            UpdateMaterialsList();



            _view.MeshNumberBox.SelectionChanged       += MeshNumberBox_SelectionChanged;
            _view.PartNumberBox.SelectionChanged       += PartNumberBox_SelectionChanged;
            _view.MaterialSelectorBox.SelectionChanged += MaterialSelectorBox_SelectionChanged;
            _view.MaterialPathTextBox.KeyDown          += MaterialPathTextBox_KeyDown;
            _view.MaterialPathTextBox.LostFocus        += MaterialPathTextBox_LostFocus;

            _view.ShapesListBox.SelectionChanged     += ShapesListBox_SelectionChanged;
            _view.AttributesListBox.SelectionChanged += AttributesListBox_SelectionChanged;

            _view.RemoveShapeButton.Click     += RemoveShapeButton_Click;
            _view.RemoveAttributeButton.Click += RemoveAttributeButton_Click;

            _view.AddAttributeBox.SelectionChanged += AddAttributeBox_SelectionChanged;
            _view.AddAttributeTextBox.KeyDown      += AddAttributeTextBox_KeyDown;

            _view.ScaleComboBox.SelectionChanged += ScaleComboBox_SelectionChanged;

            _view.MeshNumberBox.SelectedIndex = 0;
        }