private void RaiseAddHeader(ShaderGroup group)
        {
            string name = "Header";
            IEnumerable <string> headers = group.Shaders.Where((s) => s.ShaderType == ShaderType.Header).Select((s) => s.Name);

            int counter = 0;

            while (headers.Contains(name + ".hlsli"))
            {
                ++counter;
                name = "Header_" + counter.ToString("D3");
            }

            Shader shader = new Shader(name + ".hlsli", ShaderType.Header);

            group.AddShader(shader);
            group.Save(Workspace);

            ShadersFlattened.Add(shader);
        }
        private void RaiseNewShader()
        {
            if (IsValid)
            {
                if (_isInEditMode)
                {
                    if ((_originalHasHullDomain && HasHullDomainShader == false) ||// Hull and domain will get deleted
                        (_originalHasGeometry && HasGeometryShader == false))   // Geometry will get deleted
                    {
                        MessageBoxResult result = MessageBox.Show("The new settings will result in permanently losing shaders\n\nDo you want to continue", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                        if (result != MessageBoxResult.Yes)
                        {
                            return;
                        }
                    }
                }
                ShaderGroup sg = _notification.ShaderGroup;
                Shader      shader;
                if (sg.ShaderGroupType == ShaderGroupType.Standard)
                {
                    if (HasHullDomainShader)
                    {
                        shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Hull);
                        if (shader == null)
                        {
                            sg.AddShader(new Shader("hs.hlsl", ShaderType.Hull));
                            sg.AddShader(new Shader("ds.hlsl", ShaderType.Domain));
                        }
                    }
                    else if (_isInEditMode)
                    {
                        shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Hull);
                        shader?.Delete();
                        sg.Shaders.Remove(shader);

                        shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Domain);
                        shader?.Delete();
                        sg.Shaders.Remove(shader);
                    }

                    if (HasGeometryShader)
                    {
                        shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Geometry);
                        if (shader == null)
                        {
                            sg.AddShader(new Shader("gs.hlsl", ShaderType.Geometry));
                        }
                    }
                    else if (_isInEditMode)
                    {
                        shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Geometry);
                        shader?.Delete();
                        sg.Shaders.Remove(shader);
                    }

                    shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Vertex);
                    if (shader == null)
                    {
                        sg.AddShader(new Shader("vs.hlsl", ShaderType.Vertex));
                    }
                }
                else if (_isInEditMode)
                {
                    shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Vertex);
                    shader?.Delete();
                    sg.Shaders.Remove(shader);
                    shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Hull);
                    shader?.Delete();
                    sg.Shaders.Remove(shader);
                    shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Domain);
                    shader?.Delete();
                    sg.Shaders.Remove(shader);
                    shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Geometry);
                    shader?.Delete();
                    sg.Shaders.Remove(shader);
                }

                shader = sg.Shaders.FirstOrDefault((s) => s.ShaderType == ShaderType.Pixel);
                if (shader == null)
                {
                    sg.AddShader(new Shader("ps.hlsl", ShaderType.Pixel));
                }

                if (_isInEditMode)
                {
                    foreach (Shader s in sg.Shaders)
                    {
                        s.Group = sg;
                    }
                }
                _notification.Confirmed = true;
                FinishInteraction();
            }
        }
        public MainWindowPageViewModel()
        {
            Workspace workspace = null;

            try
            {
                if (File.Exists(ShaderBoxRootFileLocation))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(Workspace));
                    using (Stream stream = File.OpenRead(ShaderBoxRootFileLocation))
                    {
                        workspace = ((Workspace)serializer.Deserialize(stream));
                    }
                }
            }
            catch (Exception)
            {
            }
            finally
            {
                if (workspace == null)
                {
                    workspace = new Workspace();
                }
                if (workspace.Shaders.Count == 0 || workspace.Shaders.FirstOrDefault((s) => s.Path == ShaderBoxSharedProject) == null)
                {
                    workspace.Shaders.Insert(0, new ShaderPath()
                    {
                        Path   = ShaderBoxSharedProject,
                        IsOpen = true
                    });
                }

                if (workspace.Models.Count == 0 || workspace.Models.FirstOrDefault((s) => s.Path == ShaderBoxBuiltInModel) == null)
                {
                    workspace.Models.Insert(0, new Model3DData()
                    {
                        Hash      = 0,
                        ImagePath = ShaderBoxBuiltInModelImage,
                        IsBuiltIn = true,
                        Name      = "Cube.obj",
                        Path      = ShaderBoxBuiltInModel
                    });
                }

                if (!File.Exists(ShaderBoxSharedProject))
                {
                    ShaderGroup group = new ShaderGroup("Shared headers [../.Shared/]", ShaderGroupType.SharedHeaders)
                    {
                        UniqueName = ShaderBoxSharedFolderName,
                        IsOpen     = true
                    };

                    Shader shader = new Shader("SB_Header.hlsli", ShaderType.Header, ShaderBoxBaseShaderLocation);
                    shader.IsBuiltIn = true;
                    group.AddShader(shader);
                    group.Save(workspace);
                }

                ShaderStorageLinker shaderStorage = new ShaderStorageLinker();
                XmlSerializer       serializer    = new XmlSerializer(typeof(ShaderGroup));
                List <ShaderPath>   toDelete      = new List <ShaderPath>();
                foreach (ShaderPath sPath in workspace.Shaders)
                {
                    try
                    {
                        using (Stream stream = File.OpenRead(sPath.Path))
                        {
                            ShaderGroup group = (ShaderGroup)serializer.Deserialize(stream);
                            group.IsOpen = sPath.IsOpen;
                            shaderStorage.ShaderGroups.Add(group);
                        }
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show($"Failed to load project: {sPath.Path}\nError: {e}", "Load error", MessageBoxButton.OK, MessageBoxImage.Error);
                        toDelete.Add(sPath);
                    }
                }
                workspace.Shaders = workspace.Shaders.Except(toDelete).ToList();

                if (!File.Exists(ShaderBoxBaseShaderLocation))
                {
                    ShaderBoxSharedFolderLocation.EnsureFolder();
                    using (StreamWriter stream = new StreamWriter(ShaderBoxBaseShaderLocation))
                    {
                        stream.Write(ShaderBoxBaseShaderContent);
                    }
                }

                _workspace = workspace;
                _workspace.PropertyChanged += new PropertyChangedEventHandler(OnResourcePropertyChanged);
                App.Container.RegisterInstance(workspace);
                App.Container.RegisterInstance(shaderStorage);

                // Resolve cyclic dependency
                foreach (ShaderGroup shaderGroup in shaderStorage.ShaderGroups)
                {
                    foreach (Shader shader in shaderGroup.Shaders)
                    {
                        shader.Group = shaderGroup;
                    }
                    foreach (AnnotationShaderGroup annotationShaderGroup in shaderGroup.AnnotationShaderGroups)
                    {
                        annotationShaderGroup.CreateUI();
                    }
                }
            }
        }