//
// Created by sebastian on 29.07.26.
//

#include "Attribute.h"
#include <iostream>

using namespace engine;

Attribute::Attribute(const unsigned int attributeNumber, const unsigned int dataType, const int componentCount, const bool normalized)
    : m_attributeNumber(attributeNumber), m_dataType(dataType),
    m_componentCount(componentCount), m_normalized(normalized),
    m_bytesPerVertex(calcBytesPerVertex()) {}

Attribute::Attribute(const unsigned int attributeNumber, const unsigned int dataType, const int componentCount)
    : m_attributeNumber(attributeNumber), m_dataType(dataType),
    m_componentCount(componentCount), m_normalized(false),
    m_bytesPerVertex(calcBytesPerVertex()) {}

void Attribute::enable(bool enable) const {
    if (enable) {
        glEnableVertexAttribArray(m_attributeNumber);
    } else {
        glDisableVertexAttribArray(m_attributeNumber);
    }
}

void Attribute::link(const int offset, const int stride) {
    glVertexAttribPointer(m_attributeNumber, m_componentCount, m_dataType, m_normalized, stride, reinterpret_cast<void*>(offset));
}

int Attribute::calcBytesPerVertex() const {
    switch (m_dataType) {
        case GL_FLOAT:
        case GL_UNSIGNED_INT:
        case GL_INT:
            return 4 * m_componentCount;
        case GL_SHORT:
        case GL_UNSIGNED_SHORT:
            return 2 * m_componentCount;
        case GL_BYTE:
        case GL_UNSIGNED_BYTE:
            return 1 * m_componentCount;
        case GL_UNSIGNED_INT_2_10_10_10_REV:
            return 4; // gepackt: 4 Bytes gesamt, unabhängig von componentCount
        default:
            std::cerr << "Unsupported data type for attribute\n";
            return 0;
    }
}

void IntAttribute::link(int offset, int stride) {
    glVertexAttribIPointer(m_attributeNumber, m_componentCount, GL_INT, stride,
                        reinterpret_cast<void*>(offset));
}
