// MobileGL - MobileGL/MG_State/GLState/ProgramState/ProgramState.h
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
//   https://www.gnu.org/licenses/gpl-3.0.txt
//   https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header

#pragma once
#include <Includes.h>
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "ProgramObject.h"

namespace MobileGL {
    namespace MG_State {
        namespace GLState {
            class ProgramState {
            public:
                // This function WILL actually create the program object.
                // To retrieve created program object, use GetProgramObject()
                Uint CreateProgram();
                SharedPtr<ProgramObject> GetProgramObject(Uint id);
                void MarkProgramObjectForDeletion(Uint program);
                Bool ValidateProgramObject(Uint program) const;

                void UseProgram(Uint program);

                Uint CreateShader(ShaderStage stage);
                SharedPtr<ShaderObject> GetShaderObject(Uint shader);
                void MarkShaderObjectForDeletion(Uint shader);
                Bool ValidateShaderObject(Uint shader) const;

                SharedPtr<ProgramObject> GetCurrentProgram() const { return m_currentProgram; }

            private:
                template <typename T>
                static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
                    return idx < vec.size();
                }

                template <typename T>
                static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
                    if (CheckIndexAvail(idx, vec)) return;

                    vec.reserve(std::bit_ceil(idx));
                    vec.resize(idx + 1);
                }

                IndexGenerator<Uint> m_programIndexGenerator;
                Vector<SharedPtr<ProgramObject>> m_programObjects;

                IndexGenerator<Uint> m_shaderIndexGenerator;
                Vector<SharedPtr<ShaderObject>> m_shaderObjects;

                SharedPtr<ProgramObject> m_currentProgram;
            };
        } // namespace GLState
    } // namespace MG_State
} // namespace MobileGL