// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// PackedGLEnums_autogen.h:
//   Declares ANGLE-specific enums classes for GLEnum and functions operating
//   on them.

#ifndef COMMON_PACKEDGLENUMS_H_
#define COMMON_PACKEDGLENUMS_H_

#include "common/PackedEGLEnums_autogen.h"
#include "common/PackedGLEnums_autogen.h"

#include <array>
#include <bitset>
#include <cstddef>

#include <EGL/egl.h>

#include "common/bitset_utils.h"

namespace angle
{

// Return the number of elements of a packed enum, including the InvalidEnum element.
template <typename E>
constexpr size_t EnumSize()
{
    using UnderlyingType = typename std::underlying_type<E>::type;
    return static_cast<UnderlyingType>(E::EnumCount);
}

// Implementation of AllEnums which allows iterating over all the possible values for a packed enums
// like so:
//     for (auto value : AllEnums<MyPackedEnum>()) {
//         // Do something with the enum.
//     }

template <typename E>
class EnumIterator final
{
  private:
    using UnderlyingType = typename std::underlying_type<E>::type;

  public:
    EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {}
    EnumIterator &operator++()
    {
        mValue++;
        return *this;
    }
    bool operator==(const EnumIterator &other) const { return mValue == other.mValue; }
    bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; }
    E operator*() const { return static_cast<E>(mValue); }

  private:
    UnderlyingType mValue;
};

template <typename E, size_t MaxSize = EnumSize<E>()>
struct AllEnums
{
    EnumIterator<E> begin() const { return {static_cast<E>(0)}; }
    EnumIterator<E> end() const { return {static_cast<E>(MaxSize)}; }
};

// PackedEnumMap<E, T> is like an std::array<T, E::EnumCount> but is indexed with enum values. It
// implements all of the std::array interface except with enum values instead of indices.
template <typename E, typename T, size_t MaxSize = EnumSize<E>()>
class PackedEnumMap
{
    using UnderlyingType = typename std::underlying_type<E>::type;
    using Storage        = std::array<T, MaxSize>;

  public:
    using InitPair = std::pair<E, T>;

    constexpr PackedEnumMap() = default;

    constexpr PackedEnumMap(std::initializer_list<InitPair> init) : mPrivateData{}
    {
        // We use a for loop instead of range-for to work around a limitation in MSVC.
        for (const InitPair *it = init.begin(); it != init.end(); ++it)
        {
#if (__cplusplus < 201703L)
            // This horrible const_cast pattern is necessary to work around a constexpr limitation.
            // See https://stackoverflow.com/q/34199774/ . Note that it should be fixed with C++17.
            const_cast<T &>(const_cast<const Storage &>(
                mPrivateData)[static_cast<UnderlyingType>(it->first)]) = it->second;
#else
            mPrivateData[static_cast<UnderlyingType>(it->first)] = it->second;
#endif
        }
    }

    // types:
    using value_type      = T;
    using pointer         = T *;
    using const_pointer   = const T *;
    using reference       = T &;
    using const_reference = const T &;

    using size_type       = size_t;
    using difference_type = ptrdiff_t;

    using iterator               = typename Storage::iterator;
    using const_iterator         = typename Storage::const_iterator;
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // No explicit construct/copy/destroy for aggregate type
    void fill(const T &u) { mPrivateData.fill(u); }
    void swap(PackedEnumMap<E, T, MaxSize> &a) noexcept { mPrivateData.swap(a.mPrivateData); }

    // iterators:
    iterator begin() noexcept { return mPrivateData.begin(); }
    const_iterator begin() const noexcept { return mPrivateData.begin(); }
    iterator end() noexcept { return mPrivateData.end(); }
    const_iterator end() const noexcept { return mPrivateData.end(); }

    reverse_iterator rbegin() noexcept { return mPrivateData.rbegin(); }
    const_reverse_iterator rbegin() const noexcept { return mPrivateData.rbegin(); }
    reverse_iterator rend() noexcept { return mPrivateData.rend(); }
    const_reverse_iterator rend() const noexcept { return mPrivateData.rend(); }

    // capacity:
    constexpr size_type size() const noexcept { return mPrivateData.size(); }
    constexpr size_type max_size() const noexcept { return mPrivateData.max_size(); }
    constexpr bool empty() const noexcept { return mPrivateData.empty(); }

    // element access:
    reference operator[](E n)
    {
        ASSERT(static_cast<size_t>(n) < mPrivateData.size());
        return mPrivateData[static_cast<UnderlyingType>(n)];
    }

    constexpr const_reference operator[](E n) const
    {
        ASSERT(static_cast<size_t>(n) < mPrivateData.size());
        return mPrivateData[static_cast<UnderlyingType>(n)];
    }

    const_reference at(E n) const { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
    reference at(E n) { return mPrivateData.at(static_cast<UnderlyingType>(n)); }

    reference front() { return mPrivateData.front(); }
    const_reference front() const { return mPrivateData.front(); }
    reference back() { return mPrivateData.back(); }
    const_reference back() const { return mPrivateData.back(); }

    T *data() noexcept { return mPrivateData.data(); }
    const T *data() const noexcept { return mPrivateData.data(); }

    bool operator==(const PackedEnumMap &rhs) const { return mPrivateData == rhs.mPrivateData; }
    bool operator!=(const PackedEnumMap &rhs) const { return mPrivateData != rhs.mPrivateData; }

    template <typename SubT = T>
    typename std::enable_if<std::is_integral<SubT>::value>::type operator+=(
        const PackedEnumMap<E, SubT, MaxSize> &rhs)
    {
        for (E e : AllEnums<E, MaxSize>())
        {
            at(e) += rhs[e];
        }
    }

  private:
    Storage mPrivateData;
};

// PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It
// implements the std::bitset interface except with enum values instead of indices.
template <typename E, typename DataT = uint32_t>
using PackedEnumBitSet = BitSetT<EnumSize<E>(), DataT, E>;

}  // namespace angle

namespace gl
{

TextureType TextureTargetToType(TextureTarget target);
TextureTarget NonCubeTextureTypeToTarget(TextureType type);

TextureTarget CubeFaceIndexToTextureTarget(size_t face);
size_t CubeMapTextureTargetToFaceIndex(TextureTarget target);
bool IsCubeMapFaceTarget(TextureTarget target);

constexpr TextureTarget kCubeMapTextureTargetMin = TextureTarget::CubeMapPositiveX;
constexpr TextureTarget kCubeMapTextureTargetMax = TextureTarget::CubeMapNegativeZ;
constexpr TextureTarget kAfterCubeMapTextureTargetMax =
    static_cast<TextureTarget>(static_cast<uint8_t>(kCubeMapTextureTargetMax) + 1);
struct AllCubeFaceTextureTargets
{
    angle::EnumIterator<TextureTarget> begin() const { return kCubeMapTextureTargetMin; }
    angle::EnumIterator<TextureTarget> end() const { return kAfterCubeMapTextureTargetMax; }
};

constexpr std::array<ShaderType, 2> kAllGLES2ShaderTypes = {ShaderType::Vertex,
                                                            ShaderType::Fragment};

constexpr ShaderType kShaderTypeMin = ShaderType::Vertex;
constexpr ShaderType kShaderTypeMax = ShaderType::Compute;
constexpr ShaderType kAfterShaderTypeMax =
    static_cast<ShaderType>(static_cast<uint8_t>(kShaderTypeMax) + 1);
struct AllShaderTypes
{
    angle::EnumIterator<ShaderType> begin() const { return kShaderTypeMin; }
    angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; }
};

constexpr size_t kGraphicsShaderCount = static_cast<size_t>(ShaderType::EnumCount) - 1u;
// Arrange the shader types in the order of rendering pipeline
constexpr std::array<ShaderType, kGraphicsShaderCount> kAllGraphicsShaderTypes = {
    ShaderType::Vertex, ShaderType::TessControl, ShaderType::TessEvaluation, ShaderType::Geometry,
    ShaderType::Fragment};

using ShaderBitSet = angle::PackedEnumBitSet<ShaderType, uint8_t>;
static_assert(sizeof(ShaderBitSet) == sizeof(uint8_t), "Unexpected size");

template <typename T>
using ShaderMap = angle::PackedEnumMap<ShaderType, T>;

const char *ShaderTypeToString(ShaderType shaderType);

TextureType SamplerTypeToTextureType(GLenum samplerType);
TextureType ImageTypeToTextureType(GLenum imageType);

bool IsMultisampled(gl::TextureType type);
bool IsArrayTextureType(gl::TextureType type);

bool IsStaticBufferUsage(BufferUsage useage);

enum class PrimitiveMode : uint8_t
{
    Points                 = 0x0,
    Lines                  = 0x1,
    LineLoop               = 0x2,
    LineStrip              = 0x3,
    Triangles              = 0x4,
    TriangleStrip          = 0x5,
    TriangleFan            = 0x6,
    Unused1                = 0x7,
    Unused2                = 0x8,
    Unused3                = 0x9,
    LinesAdjacency         = 0xA,
    LineStripAdjacency     = 0xB,
    TrianglesAdjacency     = 0xC,
    TriangleStripAdjacency = 0xD,
    Patches                = 0xE,

    InvalidEnum = 0xF,
    EnumCount   = 0xF,
};

template <>
constexpr PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from)
{
    if (from >= static_cast<GLenum>(PrimitiveMode::EnumCount))
    {
        return PrimitiveMode::InvalidEnum;
    }

    return static_cast<PrimitiveMode>(from);
}

constexpr GLenum ToGLenum(PrimitiveMode from)
{
    return static_cast<GLenum>(from);
}

static_assert(ToGLenum(PrimitiveMode::Points) == GL_POINTS, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::Lines) == GL_LINES, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineLoop) == GL_LINE_LOOP, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineStrip) == GL_LINE_STRIP, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::Triangles) == GL_TRIANGLES, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleStrip) == GL_TRIANGLE_STRIP,
              "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleFan) == GL_TRIANGLE_FAN, "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LinesAdjacency) == GL_LINES_ADJACENCY,
              "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::LineStripAdjacency) == GL_LINE_STRIP_ADJACENCY,
              "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TrianglesAdjacency) == GL_TRIANGLES_ADJACENCY,
              "PrimitiveMode violation");
static_assert(ToGLenum(PrimitiveMode::TriangleStripAdjacency) == GL_TRIANGLE_STRIP_ADJACENCY,
              "PrimitiveMode violation");

std::ostream &operator<<(std::ostream &os, PrimitiveMode value);

enum class DrawElementsType : size_t
{
    UnsignedByte  = 0,
    UnsignedShort = 1,
    UnsignedInt   = 2,
    InvalidEnum   = 3,
    EnumCount     = 3,
};

template <>
constexpr DrawElementsType FromGLenum<DrawElementsType>(GLenum from)
{

    GLenum scaled = (from - GL_UNSIGNED_BYTE);
    // This code sequence generates a ROR instruction on x86/arm. We want to check if the lowest bit
    // of scaled is set and if (scaled >> 1) is greater than a non-pot value. If we rotate the
    // lowest bit to the hightest bit both conditions can be checked with a single test.
    static_assert(sizeof(GLenum) == 4, "Update (scaled << 31) to sizeof(GLenum) * 8 - 1");
    GLenum packed = (scaled >> 1) | (scaled << 31);

    // operator ? with a simple assignment usually translates to a cmov instruction and thus avoids
    // a branch.
    packed = (packed >= static_cast<GLenum>(DrawElementsType::EnumCount))
                 ? static_cast<GLenum>(DrawElementsType::InvalidEnum)
                 : packed;

    return static_cast<DrawElementsType>(packed);
}

constexpr GLenum ToGLenum(DrawElementsType from)
{
    return ((static_cast<GLenum>(from) << 1) + GL_UNSIGNED_BYTE);
}

#define ANGLE_VALIDATE_PACKED_ENUM(type, packed, glenum)                 \
    static_assert(ToGLenum(type::packed) == glenum, #type " violation"); \
    static_assert(FromGLenum<type>(glenum) == type::packed, #type " violation")

ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedByte, GL_UNSIGNED_BYTE);
ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedShort, GL_UNSIGNED_SHORT);
ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedInt, GL_UNSIGNED_INT);

std::ostream &operator<<(std::ostream &os, DrawElementsType value);

enum class BlendEquationType
{
    Add             = 0,  // GLenum == 0x8006
    Min             = 1,  // GLenum == 0x8007
    Max             = 2,  // GLenum == 0x8008
    Unused          = 3,
    Subtract        = 4,  // GLenum == 0x800A
    ReverseSubtract = 5,  // GLenum == 0x800B

    Multiply   = 6,   // GLenum == 0x9294
    Screen     = 7,   // GLenum == 0x9295
    Overlay    = 8,   // GLenum == 0x9296
    Darken     = 9,   // GLenum == 0x9297
    Lighten    = 10,  // GLenum == 0x9298
    Colordodge = 11,  // GLenum == 0x9299
    Colorburn  = 12,  // GLenum == 0x929A
    Hardlight  = 13,  // GLenum == 0x929B
    Softlight  = 14,  // GLenum == 0x929C
    Unused2    = 15,
    Difference = 16,  // GLenum == 0x929E
    Unused3    = 17,
    Exclusion  = 18,  // GLenum == 0x92A0

    HslHue        = 19,  // GLenum == 0x92AD
    HslSaturation = 20,  // GLenum == 0x92AE
    HslColor      = 21,  // GLenum == 0x92AF
    HslLuminosity = 22,  // GLenum == 0x92B0

    InvalidEnum = 23,
    EnumCount   = InvalidEnum
};

using BlendEquationBitSet = angle::PackedEnumBitSet<gl::BlendEquationType>;

template <>
constexpr BlendEquationType FromGLenum<BlendEquationType>(GLenum from)
{
    if (from <= GL_FUNC_REVERSE_SUBTRACT)
    {
        const GLenum scaled = (from - GL_FUNC_ADD);
        return (scaled == static_cast<GLenum>(BlendEquationType::Unused))
                   ? BlendEquationType::InvalidEnum
                   : static_cast<BlendEquationType>(scaled);
    }
    if (from <= GL_EXCLUSION_KHR)
    {
        const GLenum scaled =
            (from - GL_MULTIPLY_KHR + static_cast<uint32_t>(BlendEquationType::Multiply));
        return (scaled == static_cast<GLenum>(BlendEquationType::Unused2) ||
                scaled == static_cast<GLenum>(BlendEquationType::Unused3))
                   ? BlendEquationType::InvalidEnum
                   : static_cast<BlendEquationType>(scaled);
    }
    if (from <= GL_HSL_LUMINOSITY_KHR)
    {
        return static_cast<BlendEquationType>(from - GL_HSL_HUE_KHR +
                                              static_cast<uint32_t>(BlendEquationType::HslHue));
    }
    return BlendEquationType::InvalidEnum;
}

constexpr GLenum ToGLenum(BlendEquationType from)
{
    if (from <= BlendEquationType::ReverseSubtract)
    {
        return static_cast<GLenum>(from) + GL_FUNC_ADD;
    }
    if (from <= BlendEquationType::Exclusion)
    {
        return static_cast<GLenum>(from) - static_cast<GLenum>(BlendEquationType::Multiply) +
               GL_MULTIPLY_KHR;
    }
    return static_cast<GLenum>(from) - static_cast<GLenum>(BlendEquationType::HslHue) +
           GL_HSL_HUE_KHR;
}

ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Add, GL_FUNC_ADD);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Min, GL_MIN);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Max, GL_MAX);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Subtract, GL_FUNC_SUBTRACT);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, ReverseSubtract, GL_FUNC_REVERSE_SUBTRACT);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Multiply, GL_MULTIPLY_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Screen, GL_SCREEN_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Overlay, GL_OVERLAY_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Darken, GL_DARKEN_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Lighten, GL_LIGHTEN_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colordodge, GL_COLORDODGE_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colorburn, GL_COLORBURN_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Hardlight, GL_HARDLIGHT_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Softlight, GL_SOFTLIGHT_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Difference, GL_DIFFERENCE_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Exclusion, GL_EXCLUSION_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslHue, GL_HSL_HUE_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslSaturation, GL_HSL_SATURATION_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslColor, GL_HSL_COLOR_KHR);
ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslLuminosity, GL_HSL_LUMINOSITY_KHR);

std::ostream &operator<<(std::ostream &os, BlendEquationType value);

enum class BlendFactorType
{
    Zero = 0,  // GLenum == 0
    One  = 1,  // GLenum == 1

    MinSrcDstType    = 2,
    SrcColor         = 2,   // GLenum == 0x0300
    OneMinusSrcColor = 3,   // GLenum == 0x0301
    SrcAlpha         = 4,   // GLenum == 0x0302
    OneMinusSrcAlpha = 5,   // GLenum == 0x0303
    DstAlpha         = 6,   // GLenum == 0x0304
    OneMinusDstAlpha = 7,   // GLenum == 0x0305
    DstColor         = 8,   // GLenum == 0x0306
    OneMinusDstColor = 9,   // GLenum == 0x0307
    SrcAlphaSaturate = 10,  // GLenum == 0x0308
    MaxSrcDstType    = 10,

    MinConstantType       = 11,
    ConstantColor         = 11,  // GLenum == 0x8001
    OneMinusConstantColor = 12,  // GLenum == 0x8002
    ConstantAlpha         = 13,  // GLenum == 0x8003
    OneMinusConstantAlpha = 14,  // GLenum == 0x8004
    MaxConstantType       = 14,

    // GL_EXT_blend_func_extended

    Src1Alpha = 15,  // GLenum == 0x8589

    Src1Color         = 16,  // GLenum == 0x88F9
    OneMinusSrc1Color = 17,  // GLenum == 0x88FA
    OneMinusSrc1Alpha = 18,  // GLenum == 0x88FB

    InvalidEnum = 19,
    EnumCount   = 19
};

template <>
constexpr BlendFactorType FromGLenum<BlendFactorType>(GLenum from)
{
    if (from <= 1)
        return static_cast<BlendFactorType>(from);
    if (from >= GL_SRC_COLOR && from <= GL_SRC_ALPHA_SATURATE)
        return static_cast<BlendFactorType>(from - GL_SRC_COLOR + 2);
    if (from >= GL_CONSTANT_COLOR && from <= GL_ONE_MINUS_CONSTANT_ALPHA)
        return static_cast<BlendFactorType>(from - GL_CONSTANT_COLOR + 11);
    if (from == GL_SRC1_ALPHA_EXT)
        return BlendFactorType::Src1Alpha;
    if (from >= GL_SRC1_COLOR_EXT && from <= GL_ONE_MINUS_SRC1_ALPHA_EXT)
        return static_cast<BlendFactorType>(from - GL_SRC1_COLOR_EXT + 16);
    return BlendFactorType::InvalidEnum;
}

constexpr GLenum ToGLenum(BlendFactorType from)
{
    const GLenum value = static_cast<GLenum>(from);
    if (value <= 1)
        return value;
    if (from >= BlendFactorType::MinSrcDstType && from <= BlendFactorType::MaxSrcDstType)
        return value - 2 + GL_SRC_COLOR;
    if (from >= BlendFactorType::MinConstantType && from <= BlendFactorType::MaxConstantType)
        return value - 11 + GL_CONSTANT_COLOR;
    if (from == BlendFactorType::Src1Alpha)
        return GL_SRC1_ALPHA_EXT;
    return value - 16 + GL_SRC1_COLOR_EXT;
}

ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Zero, GL_ZERO);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, One, GL_ONE);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcColor, GL_SRC_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcColor, GL_ONE_MINUS_SRC_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlpha, GL_SRC_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcAlpha, GL_ONE_MINUS_SRC_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstAlpha, GL_DST_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstAlpha, GL_ONE_MINUS_DST_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstColor, GL_DST_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstColor, GL_ONE_MINUS_DST_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlphaSaturate, GL_SRC_ALPHA_SATURATE);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantColor, GL_CONSTANT_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantColor, GL_ONE_MINUS_CONSTANT_COLOR);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantAlpha, GL_CONSTANT_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantAlpha, GL_ONE_MINUS_CONSTANT_ALPHA);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Alpha, GL_SRC1_ALPHA_EXT);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Color, GL_SRC1_COLOR_EXT);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Color, GL_ONE_MINUS_SRC1_COLOR_EXT);
ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Alpha, GL_ONE_MINUS_SRC1_ALPHA_EXT);

std::ostream &operator<<(std::ostream &os, BlendFactorType value);

enum class VertexAttribType
{
    Byte               = 0,   // GLenum == 0x1400
    UnsignedByte       = 1,   // GLenum == 0x1401
    Short              = 2,   // GLenum == 0x1402
    UnsignedShort      = 3,   // GLenum == 0x1403
    Int                = 4,   // GLenum == 0x1404
    UnsignedInt        = 5,   // GLenum == 0x1405
    Float              = 6,   // GLenum == 0x1406
    Unused1            = 7,   // GLenum == 0x1407
    Unused2            = 8,   // GLenum == 0x1408
    Unused3            = 9,   // GLenum == 0x1409
    Unused4            = 10,  // GLenum == 0x140A
    HalfFloat          = 11,  // GLenum == 0x140B
    Fixed              = 12,  // GLenum == 0x140C
    MaxBasicType       = 12,
    UnsignedInt2101010 = 13,  // GLenum == 0x8368
    HalfFloatOES       = 14,  // GLenum == 0x8D61
    Int2101010         = 15,  // GLenum == 0x8D9F
    UnsignedInt1010102 = 16,  // GLenum == 0x8DF6
    Int1010102         = 17,  // GLenum == 0x8DF7
    InvalidEnum        = 18,
    EnumCount          = 18,
};

template <>
constexpr VertexAttribType FromGLenum<VertexAttribType>(GLenum from)
{
    GLenum packed = from - GL_BYTE;
    if (packed <= static_cast<GLenum>(VertexAttribType::MaxBasicType))
        return static_cast<VertexAttribType>(packed);
    if (from == GL_UNSIGNED_INT_2_10_10_10_REV)
        return VertexAttribType::UnsignedInt2101010;
    if (from == GL_HALF_FLOAT_OES)
        return VertexAttribType::HalfFloatOES;
    if (from == GL_INT_2_10_10_10_REV)
        return VertexAttribType::Int2101010;
    if (from == GL_UNSIGNED_INT_10_10_10_2_OES)
        return VertexAttribType::UnsignedInt1010102;
    if (from == GL_INT_10_10_10_2_OES)
        return VertexAttribType::Int1010102;
    return VertexAttribType::InvalidEnum;
}

constexpr GLenum ToGLenum(VertexAttribType from)
{
    // This could be optimized using a constexpr table.
    if (from == VertexAttribType::Int2101010)
        return GL_INT_2_10_10_10_REV;
    if (from == VertexAttribType::HalfFloatOES)
        return GL_HALF_FLOAT_OES;
    if (from == VertexAttribType::UnsignedInt2101010)
        return GL_UNSIGNED_INT_2_10_10_10_REV;
    if (from == VertexAttribType::UnsignedInt1010102)
        return GL_UNSIGNED_INT_10_10_10_2_OES;
    if (from == VertexAttribType::Int1010102)
        return GL_INT_10_10_10_2_OES;
    return static_cast<GLenum>(from) + GL_BYTE;
}

ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Byte, GL_BYTE);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedByte, GL_UNSIGNED_BYTE);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Short, GL_SHORT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedShort, GL_UNSIGNED_SHORT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int, GL_INT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt, GL_UNSIGNED_INT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Float, GL_FLOAT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloat, GL_HALF_FLOAT);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Fixed, GL_FIXED);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int2101010, GL_INT_2_10_10_10_REV);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloatOES, GL_HALF_FLOAT_OES);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt2101010, GL_UNSIGNED_INT_2_10_10_10_REV);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int1010102, GL_INT_10_10_10_2_OES);
ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt1010102, GL_UNSIGNED_INT_10_10_10_2_OES);

std::ostream &operator<<(std::ostream &os, VertexAttribType value);

enum class TessEvaluationType
{
    Triangles             = 0,
    Quads                 = 1,
    Isolines              = 2,
    EqualSpacing          = 3,
    FractionalEvenSpacing = 4,
    FractionalOddSpacing  = 5,
    Cw                    = 6,
    Ccw                   = 7,
    PointMode             = 8,
    InvalidEnum           = 9,
    EnumCount             = 9
};

template <>
constexpr TessEvaluationType FromGLenum<TessEvaluationType>(GLenum from)
{
    if (from == GL_TRIANGLES)
        return TessEvaluationType::Triangles;
    if (from == GL_QUADS)
        return TessEvaluationType::Quads;
    if (from == GL_ISOLINES)
        return TessEvaluationType::Isolines;
    if (from == GL_EQUAL)
        return TessEvaluationType::EqualSpacing;
    if (from == GL_FRACTIONAL_EVEN)
        return TessEvaluationType::FractionalEvenSpacing;
    if (from == GL_FRACTIONAL_ODD)
        return TessEvaluationType::FractionalOddSpacing;
    if (from == GL_CW)
        return TessEvaluationType::Cw;
    if (from == GL_CCW)
        return TessEvaluationType::Ccw;
    if (from == GL_TESS_GEN_POINT_MODE)
        return TessEvaluationType::PointMode;
    return TessEvaluationType::InvalidEnum;
}

constexpr GLenum ToGLenum(TessEvaluationType from)
{
    switch (from)
    {
        case TessEvaluationType::Triangles:
            return GL_TRIANGLES;
        case TessEvaluationType::Quads:
            return GL_QUADS;
        case TessEvaluationType::Isolines:
            return GL_ISOLINES;
        case TessEvaluationType::EqualSpacing:
            return GL_EQUAL;
        case TessEvaluationType::FractionalEvenSpacing:
            return GL_FRACTIONAL_EVEN;
        case TessEvaluationType::FractionalOddSpacing:
            return GL_FRACTIONAL_ODD;
        case TessEvaluationType::Cw:
            return GL_CW;
        case TessEvaluationType::Ccw:
            return GL_CCW;
        case TessEvaluationType::PointMode:
            return GL_TESS_GEN_POINT_MODE;
        default:
            return GL_INVALID_ENUM;
    }
}

ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Triangles, GL_TRIANGLES);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Quads, GL_QUADS);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Isolines, GL_ISOLINES);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, EqualSpacing, GL_EQUAL);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalEvenSpacing, GL_FRACTIONAL_EVEN);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalOddSpacing, GL_FRACTIONAL_ODD);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Cw, GL_CW);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Ccw, GL_CCW);
ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, PointMode, GL_TESS_GEN_POINT_MODE);

std::ostream &operator<<(std::ostream &os, TessEvaluationType value);

// Typesafe object handles.

template <typename T>
struct ResourceTypeToID;

template <typename T>
struct IsResourceIDType;

// Clang Format doesn't like the following X macro.
// clang-format off
#define ANGLE_ID_TYPES_OP(X) \
    X(Buffer)                \
    X(FenceNV)               \
    X(Framebuffer)           \
    X(MemoryObject)          \
    X(Path)                  \
    X(ProgramPipeline)       \
    X(Query)                 \
    X(Renderbuffer)          \
    X(Sampler)               \
    X(Semaphore)             \
    X(Texture)               \
    X(TransformFeedback)     \
    X(VertexArray)
// clang-format on

#define ANGLE_DEFINE_ID_TYPE(Type)          \
    class Type;                             \
    struct Type##ID                         \
    {                                       \
        GLuint value;                       \
    };                                      \
    template <>                             \
    struct ResourceTypeToID<Type>           \
    {                                       \
        using IDType = Type##ID;            \
    };                                      \
    template <>                             \
    struct IsResourceIDType<Type##ID>       \
    {                                       \
        static constexpr bool value = true; \
    };

ANGLE_ID_TYPES_OP(ANGLE_DEFINE_ID_TYPE)

#undef ANGLE_DEFINE_ID_TYPE
#undef ANGLE_ID_TYPES_OP

// Shaders and programs are a bit special as they share IDs.
struct ShaderProgramID
{
    GLuint value;
};

template <>
struct IsResourceIDType<ShaderProgramID>
{
    constexpr static bool value = true;
};

class Shader;
template <>
struct ResourceTypeToID<Shader>
{
    using IDType = ShaderProgramID;
};

class Program;
template <>
struct ResourceTypeToID<Program>
{
    using IDType = ShaderProgramID;
};

template <typename T>
struct ResourceTypeToID
{
    using IDType = void;
};

template <typename T>
struct IsResourceIDType
{
    static constexpr bool value = false;
};

template <typename T>
bool ValueEquals(T lhs, T rhs)
{
    return lhs.value == rhs.value;
}

// Util funcs for resourceIDs
template <typename T>
typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator==(const T &lhs,
                                                                           const T &rhs)
{
    return lhs.value == rhs.value;
}

template <typename T>
typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator!=(const T &lhs,
                                                                           const T &rhs)
{
    return lhs.value != rhs.value;
}

template <typename T>
typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator<(const T &lhs,
                                                                          const T &rhs)
{
    return lhs.value < rhs.value;
}

// Used to unbox typed values.
template <typename ResourceIDType>
GLuint GetIDValue(ResourceIDType id);

template <>
inline GLuint GetIDValue(GLuint id)
{
    return id;
}

template <typename ResourceIDType>
inline GLuint GetIDValue(ResourceIDType id)
{
    return id.value;
}

// First case: handling packed enums.
template <typename EnumT, typename FromT>
typename std::enable_if<std::is_enum<EnumT>::value, EnumT>::type PackParam(FromT from)
{
    return FromGLenum<EnumT>(from);
}

// Second case: handling non-pointer resource ids.
template <typename EnumT, typename FromT>
typename std::enable_if<!std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type
PackParam(FromT from)
{
    return {from};
}

// Third case: handling pointer resource ids.
template <typename EnumT, typename FromT>
typename std::enable_if<std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type
PackParam(FromT from)
{
    static_assert(sizeof(typename std::remove_pointer<EnumT>::type) ==
                      sizeof(typename std::remove_pointer<FromT>::type),
                  "Types have different sizes");
    static_assert(
        std::is_same<
            decltype(std::remove_pointer<EnumT>::type::value),
            typename std::remove_const<typename std::remove_pointer<FromT>::type>::type>::value,
        "Data types are different");
    return reinterpret_cast<EnumT>(from);
}

struct UniformLocation
{
    int value;
};

struct UniformBlockIndex
{
    uint32_t value;
};
}  // namespace gl

namespace egl
{
MessageType ErrorCodeToMessageType(EGLint errorCode);
}  // namespace egl

namespace egl_gl
{
gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget);
gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget);
gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget);
}  // namespace egl_gl

#endif  // COMMON_PACKEDGLENUMS_H_
