// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+

#pragma once

#include <vector>
#include "GLExt.h"
#include "GLFont.h"
#include "ColorTheme.h"
#include "cubic_math.h"

class GLPanelEdges {
public:
    float left;
    float right;
    float top;
    float bottom;
    
    GLPanelEdges(): left(0), right(0), top(0), bottom(0) {
    }
    
    GLPanelEdges(float l, float r, float t, float b) {
        left = l;
        right = r;
        top = t;
        bottom = b;
    }
};

class GLPanel {
private:
    std::vector<float> glPoints;
    std::vector<float> glColors;
    
    void genArrays();
    void setViewport();
    
public:
    typedef enum GLPanelFillType { GLPANEL_FILL_NONE, GLPANEL_FILL_SOLID, GLPANEL_FILL_GRAD_X, GLPANEL_FILL_GRAD_Y, GLPANEL_FILL_GRAD_BAR_X, GLPANEL_FILL_GRAD_BAR_Y } GLPanelFillType;
    typedef enum GLPanelCoordinateSystem { GLPANEL_Y_DOWN_ZERO_ONE, GLPANEL_Y_UP_ZERO_ONE, GLPANEL_Y_UP, GLPANEL_Y_DOWN } GLPanelCoordinateSystem;
    float pos[2] = {0.0f,0.0f};
    float rot[3] = { 0.0f,0.0f,0.0f };
    float size[2] = { 0.0f,0.0f };
    float view[2] = { 0.0f,0.0f };
    GLPanelFillType fillType;
    GLPanelCoordinateSystem coord;
    float marginPx;
    GLPanelEdges borderPx;
    RGBA4f fill[2];
    RGBA4f borderColor;
    bool contentsVisible, visible;
    CubicVR::mat4 transform, transformInverse;
    CubicVR::mat4 localTransform;
    float min, mid, max;
    // screen dimensions
    CubicVR::vec2 vmin, vmax;
    // unit dimensions
    CubicVR::vec2 umin, umax, ucenter;
    // pixel dimensions
    CubicVR::vec2 pdim, pvec;
    GLuint srcBlend, dstBlend;
    
    std::vector<GLPanel *> children;
    
    GLPanel();
    virtual ~GLPanel() = default;;
    
    void setPosition(float x, float y);


    void setSize(float w, float h);
    float getWidth();
    float getHeight();
    float getWidthPx() const;
    float getHeightPx() const;
    void setCoordinateSystem(GLPanelCoordinateSystem coord);
    
    bool hitTest(CubicVR::vec2 pos_in, CubicVR::vec2 &result) const;
    
    void setFill(GLPanelFillType fill_mode);
    void setFillColor(const RGBA4f& color1);
    void setFillColor(const RGBA4f& color1, const RGBA4f& color2);
    void setMarginPx(float marg);

    void setBorderColor(const RGBA4f& clr);
    void setBorderPx(float bord);
    void setBorderPx(float bordl, float bordr, float bordt, float bordb);
    
    void setBlend(GLuint src, GLuint dst);
    
    void addChild(GLPanel *childPanel);
    void removeChild(GLPanel *childPanel);
    
    void drawChildren();
    virtual void drawPanelContents();
    void calcTransform(CubicVR::mat4 transform);
    void draw();
};


class GLTextPanel : public GLPanel {
private:
    std::string textVal;
    GLFont::Align horizAlign;
    GLFont::Align vertAlign;
    bool useNativeFont;
public:
    GLTextPanel();
    
    void drawPanelContents() override;
    
    void setText(std::string text, GLFont::Align hAlign = GLFont::GLFONT_ALIGN_CENTER, GLFont::Align vAlign = GLFont::GLFONT_ALIGN_CENTER , bool useNativeFont = false);
    std::string getText();
};

class GLTestPanel : public GLPanel {
public:
    GLTestPanel() : GLPanel() {
        
    }
    
    void drawPanelContents() override;
};
