package electrosphere.renderer.ui.widgets;

import electrosphere.main.Globals;
import electrosphere.renderer.Material;
import electrosphere.renderer.Model;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils;
import electrosphere.renderer.texture.Texture;
import electrosphere.renderer.ui.Widget;
import electrosphere.renderer.ui.font.FontUtils;
import org.joml.Vector3f;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL30.glBindFramebuffer;

/**
 *
 * @author amaterasu
 */
public class TextInput extends Widget {
    
    Framebuffer widgetBuffer;
    Material customMat = new Material();
    
    Vector3f boxPosition = new Vector3f(0,0,0);
    Vector3f boxDimensions = new Vector3f(1,1,0);
    Vector3f texPosition = new Vector3f(0,0,0);
    Vector3f texScale = new Vector3f(1,1,0);
    
    String text = "";
    
    int fontWidth = 10;
    int fontHeight = 20;
    
    int linePaddingHorizonal = 2;
    int linePaddingVertical = 5;
    
    Vector3f color = new Vector3f(0,0,0);
    
    public TextInput(){
        //TODO: figure out why this has to be 1920x1080
//        widgetBuffer = FramebufferUtils.generateTextureFramebuffer(500, 500);
        widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
        customMat.setTexturePointer(widgetBuffer.getTexturePointer());
//        customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
//        customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/default_diffuse.png").getTexturePointer());
    }
    
    @Override
    public void setPositionY(int positionY) {
        float ndcY = (float)positionY/(float)Globals.WINDOW_HEIGHT;
        boxPosition.y = ndcY;
        super.setPositionY(positionY);
    }

    @Override
    public void setPositionX(int positionX) {
        float ndcX = (float)positionX/(float)Globals.WINDOW_WIDTH;
        boxPosition.x = ndcX;
        super.setPositionX(positionX);
    }

    @Override
    public void setHeight(int height) {
        float ndcHeight = (float)height/(float)parentHeight;
        boxDimensions.y = ndcHeight;
        Framebuffer newBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
        Framebuffer oldBuffer = widgetBuffer;
        widgetBuffer = newBuffer;
        customMat.setTexturePointer(widgetBuffer.getTexturePointer());
        oldBuffer.free();
//        customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
        super.setHeight(height);
    }

    @Override
    public void setWidth(int width) {
        float ndcWidth = (float)width/(float)parentWidth;
        boxDimensions.x = ndcWidth;
        System.out.println(ndcWidth);
        Framebuffer newBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
        Framebuffer oldBuffer = widgetBuffer;
        widgetBuffer = newBuffer;
        customMat.setTexturePointer(widgetBuffer.getTexturePointer());
        oldBuffer.free();
//        widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
//        customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
        super.setWidth(width);
    }
    
    @Override
    public void setParentWidth(int parentWidth){
        this.parentWidth = parentWidth;
        setWidth(width);
    }
    
    @Override
    public void setParentHeight(int parentHeight){
        this.parentHeight = parentHeight;
        setHeight(height);
    }
    
    public void setFontWidth(int width){
        fontWidth = width;
    }
    
    public void setFontHeight(int height){
        fontHeight = height;
    }
    
    public int getFontWidth(){
        return fontWidth;
    }
    
    public int getFontHeight(){
        return fontHeight;
    }
    
    public void setText(String text){
        this.text = text;
    }

    @Override
    public void draw(int parentFramebufferPointer, int parentWidth, int parentHeight) {
        widgetBuffer.bind();
        Globals.renderingEngine.setViewportSize(width, height);
        
        //monowidth for the moment
        float charWidth = (float)fontWidth/(float)width;
        float charHeight = (float)fontHeight/(float)height;
        float charSpacing = (float)linePaddingHorizonal/(float)width;
        float lineSpacing = (float)linePaddingVertical/(float)height;
        
        Model charModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_BITMAP_FONT);
        int verticalPosition = 0;
        int horizontalPosition = 0;
        int charPos = 0;
        while(charPos < text.length()){
            char currentChar = text.charAt(charPos);
            if(currentChar == '\n'){
                verticalPosition++;
                horizontalPosition = 0;
            } else {
                
                Vector3f characterPosition = new Vector3f(horizontalPosition * (charWidth + charSpacing),-verticalPosition * (charHeight + lineSpacing),0);
                Vector3f characterDimensions = new Vector3f(charWidth,charHeight,0);
                Vector3f bitMapPosition = FontUtils.getPositionOfCharacter(currentChar);
                Vector3f bitMapDimension = FontUtils.getDimensionOfCharacter(currentChar);
                
                if(charModel != null && currentChar != ' '){
                    charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mPosition", characterPosition);
                    charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mDimension", characterDimensions);
                    charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tPosition", bitMapPosition);
                    charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tDimension", bitMapDimension);
                    charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "color", color);
                    charModel.drawUI();
                }
                horizontalPosition++;
            }
            charPos++;
        }

        
        //draw the previous texture to a quad
        Globals.renderingEngine.bindFramebuffer(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", new Vector3f(0,0,0));
        planeModel.pushUniformToMesh("plane", "tDimension", new Vector3f(1,1,0));
        planeModel.meshes.get(0).setMaterial(customMat);
        planeModel.drawUI();
    }
    
}
