package me.hammerle.supersnuvi.rendering;

import me.hammerle.supersnuvi.gamelogic.StateRenderer;
import me.hammerle.supersnuvi.javafx.IJavaRenderer;
import me.hammerle.supersnuvi.javafx.Image;

public class Game implements IRenderer
{
    // constants
    public final static int TILE_SIZE = 32;
    
    // basic graphic stuff
    private final IJavaRenderer renderer;
    
    // rendering
    private double cameraX;
    private double cameraY;
    private double offsetX;
    private double offsetY;
    
    // world rendering
    private final StateRenderer state;
    
    public Game(IJavaRenderer renderer)
    {
        // basic graphic stuff
        this.renderer = renderer;
        // rendering
        this.cameraX = 0;
        this.cameraY = 0;
        this.offsetX = 0;
        this.offsetY = 0;
        
        this.state = new StateRenderer(this);
    }
    
    public void update() 
    {
        state.update();
    }
    
    public void render() 
    {
        offsetX = -cameraX;
        offsetY = renderer.getHeight() + cameraY;
        renderer.prepareRendering();
        
        state.render();
    }
    
    // -------------------------------------------------------------------------
    // image rendering
    // -------------------------------------------------------------------------
    
    @Override
    public void drawImage(Image image, double x, double y)
    {
        renderer.drawImage(image, offsetX + x, offsetY - y);
    }
    
    @Override
    public void drawFixedImage(Image image, double x, double y)
    {
        renderer.drawImage(image, x, y);
    }
    
    @Override
    public void drawFixedImage(Image image, double x, double y, double w, double h)
    {
        renderer.drawImage(image, x, y, w, h);
    }
    
    @Override
    public void drawFlippedImage(Image image, double x, double y)
    {
        renderer.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), 
                offsetX + x + image.getWidth(), offsetY - y, -image.getWidth(), image.getHeight());
    }
    
    @Override
    public void drawBlockImage(Image image, int x, int y, double offX, double offY)
    {
        renderer.drawImage(image, offsetX + x * TILE_SIZE + offX, offsetY - (y + 1) * TILE_SIZE + offY);
    }
    
    // -------------------------------------------------------------------------
    // primitive rendering
    // -------------------------------------------------------------------------
    
    @Override
    public double getWidth() 
    {
        return renderer.getWidth();
    }

    @Override
    public double getHeight() 
    {
        return renderer.getHeight();
    }
    
    @Override
    public void save() 
    {
        renderer.save();
    }

    @Override
    public void restore() 
    {
        renderer.restore();
    }

    @Override
    public void setFillColor(int r, int g, int b, double alpha) 
    {
        renderer.setFillColor(r, g, b, alpha);
    }

    @Override
    public void setStrokeColor(int r, int g, int b, double alpha) 
    {
        renderer.setStrokeColor(r, g, b, alpha);
    }
    
    @Override
    public void fillRectangle(double x, double y, double w, double h)
    {
        renderer.fillRectangle(x, y, w, h);
    }
    
    // -------------------------------------------------------------------------
    // text rendering
    // -------------------------------------------------------------------------
    
    @Override
    public void prepareTextDrawing(int r, int g, int b, double alpha, int width) 
    {
        renderer.prepareTextDrawing(r, g, b, alpha, width);
    }
    
    @Override
    public void stopTextDrawing() 
    {
        renderer.stopTextDrawing();
    }

    @Override
    public void drawText(double x, double y, char[] text) 
    {
        renderer.drawText(x, y, text, text.length);
    }
    
    @Override
    public void drawText(double x, double y, char[] text, int max) 
    {
        renderer.drawText(x, y, text, max);
    }

    @Override
    public double getTextWidth(int chars) 
    {
        return renderer.getTextWidth(chars);
    }

    @Override
    public double getTextHeight(int lines) 
    {
        return renderer.getTextHeight(lines);
    }
    
    // -------------------------------------------------------------------------
    // rendering utils
    // -------------------------------------------------------------------------
    
    @Override
    public int getFirstVisibleBlockX()
    {
        return Math.max(0, (int) (cameraX / TILE_SIZE) - 1);
    }
    
    @Override
    public int getFirstVisibleBlockY()
    {
        return Math.max(0, (int) (cameraY / TILE_SIZE) - 1);
    }
    
    @Override
    public int getLastVisibleBlockX()
    {
        return getFirstVisibleBlockX() + (int) (renderer.getWidth() / TILE_SIZE) + 2;
    }
    
    @Override
    public int getLastVisibleBlockY()
    {
        return getFirstVisibleBlockY() + (int) (renderer.getHeight()/ TILE_SIZE) + 2;
    }
    
    @Override
    public int toBlock(double c)
    {
        return (int) (c / TILE_SIZE);
    }

    @Override
    public double toCoord(int b)
    {
        return b * TILE_SIZE;
    }

    @Override
    public void setViewCenter(double x, double y) 
    {
        cameraX = x;
        cameraY = y;
    }
}
