#pragma once

#include <frostbite2D/types/type_alias.h>
#include <frostbite2D/types/type_math.h>
#include <frostbite2D/types/type_color.h>
#include <cstdint>

namespace frostbite2D {

enum class BlendMode {
  None,
  Normal,
  Additive,
  Screen,
  Premultiplied,
  Subtractive,
  Multiply
};

enum class PrimitiveType {
  Triangles,
  TriangleStrip,
  TriangleFan,
  Quads
};

struct Vertex {
  Vec2 position;
  Vec2 texCoord;
  float r, g, b, a;
  
  Vertex() = default;
  Vertex(const Vec2& pos, const Vec2& uv, float cr, float cg, float cb, float ca)
      : position(pos), texCoord(uv), r(cr), g(cg), b(cb), a(ca) {}
};

struct Quad {
  Vertex vertices[4];
  
  Quad() = default;
  
  static Quad create(const Rect& rect, float cr = 1.0f, float cg = 1.0f, 
                     float cb = 1.0f, float ca = 1.0f) {
    Quad q;
    Vec2 bl(rect.left(), rect.bottom());
    Vec2 br(rect.right(), rect.bottom());
    Vec2 tl(rect.left(), rect.top());
    Vec2 tr(rect.right(), rect.top());
    
    q.vertices[0] = Vertex(bl, Vec2(0, 0), cr, cg, cb, ca);
    q.vertices[1] = Vertex(br, Vec2(1, 0), cr, cg, cb, ca);
    q.vertices[2] = Vertex(tl, Vec2(0, 1), cr, cg, cb, ca);
    q.vertices[3] = Vertex(tr, Vec2(1, 1), cr, cg, cb, ca);
    
    return q;
  }
  
  static Quad createTextured(const Rect& destRect, const Rect& srcRect,
                         const Vec2& texSize, float cr = 1.0f, 
                         float cg = 1.0f, float cb = 1.0f, float ca = 1.0f) {
    Quad q;
    
    Vec2 bl(destRect.left(), destRect.bottom());
    Vec2 br(destRect.right(), destRect.bottom());
    Vec2 tl(destRect.left(), destRect.top());
    Vec2 tr(destRect.right(), destRect.top());
    
    Vec2 uvBL(srcRect.left() / texSize.x, srcRect.bottom() / texSize.y);
    Vec2 uvBR(srcRect.right() / texSize.x, srcRect.bottom() / texSize.y);
    Vec2 uvTL(srcRect.left() / texSize.x, srcRect.top() / texSize.y);
    Vec2 uvTR(srcRect.right() / texSize.x, srcRect.top() / texSize.y);
    
    q.vertices[0] = Vertex(bl, uvBL, cr, cg, cb, ca);
    q.vertices[1] = Vertex(br, uvBR, cr, cg, cb, ca);
    q.vertices[2] = Vertex(tl, uvTL, cr, cg, cb, ca);
    q.vertices[3] = Vertex(tr, uvTR, cr, cg, cb, ca);
    
    return q;
  }
};

}
