//
// Created by sfd on 25-4-21.
//

#include "Shader.h"
#include "Platform/OpenGL/OpenGLShader.h"
#include "Renderer.h"


namespace Hazel
{
     Ref<Shader> Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc)
     {
          switch (Renderer::GetAPI())
          {
          case RendererAPI::API::NONE: return nullptr;
          case RendererAPI::API::OPENGL: return std::make_shared<OpenGLShader>(name, vertexSrc, fragmentSrc);
          }

          HZ_CORE_ERROR("Unknown RendererAPI");
          return nullptr;
     }

     Ref<Shader> Shader::Create(const std::string& filepath)
     {
          switch (Renderer::GetAPI())
          {
          case RendererAPI::API::NONE: return nullptr;
          case RendererAPI::API::OPENGL: return std::make_shared<OpenGLShader>(filepath);
          }

          HZ_CORE_ERROR("Unknown RendererAPI");
          return nullptr;
     }

     void ShaderLibrary::Add(const std::string& name, const Ref<Shader>& shader)
     {
          if (Exists(name))
          {
               HZ_CORE_ERROR("Shader already exists");
               return;
          }
          m_Shaders[name] = shader;
     }

     void ShaderLibrary::Add(const Ref<Shader>& shader)
     {
          auto& name = shader->GetName();
          Add(name, shader);
     }

     Ref<Shader> ShaderLibrary::Load(const std::string& filepath)
     {
          auto shader = std::make_shared<OpenGLShader>(filepath);
          Add(shader);
          return shader;
     }

     Ref<Shader> ShaderLibrary::Load(const std::string& name, const std::string& filepath)
     {
          auto shader = std::make_shared<OpenGLShader>(filepath);
          Add(name, shader);
          return shader;
     }

     Ref<Shader> ShaderLibrary::Get(const std::string& name)
     {
          if (!Exists(name))
          {
               HZ_CORE_ERROR("Shader not found");
               return nullptr;
          }
          return m_Shaders[name];
     }

    bool ShaderLibrary::Exists(const std::string& name) const
    {
        return m_Shaders.contains(name);
    }
}
