#ifndef OGL_DRIVER
#define OGL_DRIVER

#include "ogl.h"
#include "../driver.h"

namespace sleek
{
    namespace device
    {
        class Device;
    }
    namespace driver
    {
        class ogl_driver : public driver
        {
            public:
                ogl_driver(std::shared_ptr<device::Device>&) noexcept;
                virtual ~ogl_driver() noexcept;

                virtual void drawPixel(math::vector2di, math::pixel c = math::pixel()) const noexcept;
                virtual void drawPixel(math::vector3df, math::pixel c = math::pixel()) const noexcept;
                virtual void drawLine(math::vector2di, math::vector2di, math::pixel c = math::pixel()) const noexcept;
                virtual void drawLine(math::vector3df, math::vector3df, math::pixel c = math::pixel()) const noexcept;
                virtual void drawArc(math::vector2di, u32, u32, u32, math::pixel c = math::pixel()) const noexcept;

                virtual void drawCube(math::aabbox2di, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;
                virtual void drawCube(math::aabbox3df, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;
                virtual void drawCube(math::vector2di, math::vector2di, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;
                virtual void drawCube(math::vector3df, math::vector3df, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;

                virtual void drawCircle(math::vector2di pos, u32 radius = 5.f, math::pixel c = math::pixel()) const noexcept;

                virtual void drawPolygon(math::vector2di, math::vector2di, math::vector2di, math::pixel c = math::pixel()) const noexcept;
                virtual void drawPolygon(math::vector3df, math::vector3df, math::vector3df, math::pixel c = math::pixel()) const noexcept;
                virtual void drawPolygonList(math::vector2di *a, u32 n, math::vector2di, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;
                virtual void drawPolygonList(math::vector3df *a, u32 n, math::vector3df, math::vector3df rot = {0, 0, 0}, math::pixel c = math::pixel()) const noexcept;

                virtual void drawFBO(fbo*) const noexcept;

                virtual void drawTexture(texture*, math::vector2di pos = {0, 0}, math::vector3df rot = {0, 0, 0}) const noexcept;
                virtual void drawTexture(texture*, math::vector3df pos = {0, 0, 0}, math::vector3df rot = {0, 0, 0}) const noexcept;

                virtual void drawTextureCenter(texture*, math::vector2di pos = {0, 0}, math::vector3df rot = {0, 0, 0}) const noexcept;
                virtual void drawTextureCenter(texture*, math::vector3df pos = {0, 0, 0}, math::vector3df rot = {0, 0, 0}) const noexcept;

                virtual void drawTextureScale(texture*, math::vector2di pos = {0, 0}, math::vector3df rot = {0, 0, 0}, math::vector3df scl = {0, 0, 0}) const noexcept;
                virtual void drawTextureScale(texture*, math::vector3df pos = {0, 0, 0}, math::vector3df rot = {0, 0, 0}, math::vector3df scl = {0, 0, 0}) const noexcept;

                virtual void drawMesh(MeshBuffer*, math::vector3df, math::vector3df rot = {0, 0, 0}) const noexcept;

                virtual void setActiveMaterial(material*) noexcept;
                virtual material* getActiveMaterial() const noexcept;

                virtual void ObjectRenderBegin() const noexcept;
                virtual void ObjectRenderEnd() const noexcept;

                virtual void beginTo2D() const noexcept;
                virtual void endFrom2D() const noexcept;
            protected:
                //display list (quad and point render accelerator)
                GLuint quad, quadc, cubec;
        };
    }
}

#endif