package electrosphere.renderer.ui;

import electrosphere.main.Globals;
import electrosphere.renderer.Material;
import electrosphere.renderer.Model;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils;
import java.util.LinkedList;
import java.util.List;
import org.joml.Vector3f;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.*;

/**
 *
 * @author amaterasu
 */
public class Window extends Widget {
    List<Widget> widgetList = new LinkedList();
    Framebuffer widgetBuffer;
    Material customMat = new Material();
    
    Vector3f boxPosition = new Vector3f();
    Vector3f boxDimensions = new Vector3f();
    Vector3f texPosition = new Vector3f(0,0,0);
    Vector3f texScale = new Vector3f(1,1,0);
    
    public Window(int positionX, int positionY, int width, int height){
        //TODO: figure out why this has to be 1920x1080
        widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
//        widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
        customMat.setTexturePointer(widgetBuffer.getTexturePointer());
//        customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
        float ndcX =      (float)positionX/Globals.WINDOW_WIDTH;
        float ndcY =      (float)positionY/Globals.WINDOW_HEIGHT;
        float ndcWidth =  (float)width/Globals.WINDOW_WIDTH;
        float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
        this.width = width;
        this.height = height;
        boxPosition = new Vector3f(ndcX,ndcY,0);
        boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
    }

    @Override
    public void draw(int parentFramebufferPointer, int parentWidth, int parentHeight) {
        
        widgetBuffer.bind();
//        Globals.renderingEngine.setViewportSize(width, height);
        
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        for(Widget child : widgetList){
            child.draw(widgetBuffer.getFramebufferPointer(),width,height);
        }
        //this call binds the screen as the "texture" we're rendering to
        //have to call before actually rendering
        glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
        Globals.renderingEngine.setViewportSize(parentWidth, parentHeight);
        
        Model planeModel = Globals.assetManager.fetchModel(Globals.planeModelID);
        planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
        planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
        planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
        planeModel.pushUniformToMesh("plane", "tDimension", texScale);
        planeModel.meshes.get(0).setMaterial(customMat);
        planeModel.drawUI();
    }

    public void pack() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public void addWidget(Widget widget) {
        widgetList.add(widget);
        widget.setParentWidth(width);
        widget.setParentHeight(height);
        widget.setVisible(false);
    }

    public List<Widget> getWidgets() {
        return widgetList;
    }
    
    @Override
    public void setWidth(int width){
        this.width = width;
        for(Widget widget : widgetList){
            widget.setParentWidth(width);
            widget.setParentHeight(height);
        }
    }
    
    @Override
    public void setHeight(int height){
        this.height = height;
        for(Widget widget : widgetList){
            widget.setParentWidth(height);
            widget.setParentHeight(height);
        }
    }

    public void destroy() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    public void setTextureCoord(int x, int y){
        float ndcX =      (float)x/Globals.WINDOW_WIDTH;
        float ndcY =      (float)y/Globals.WINDOW_HEIGHT;
        texPosition = new Vector3f(ndcX,ndcY,0);
    }
    
    public void setTextureScale(int x, int y){
        float ndcWidth =  (float)x/Globals.WINDOW_WIDTH;
        float ndcHeight = (float)y/Globals.WINDOW_HEIGHT;
        texScale = new Vector3f(ndcWidth,ndcHeight,0);
    }
}
