package composition.components;

import composition.graphics.GraphicsCore;
import composition.screen.CompositeScreen;
import composition.stats.DebugX;
import javafx.geometry.VPos;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;

public abstract class Button implements Component {
	
	private Color stroke;
	private Color strokeHovered;
	private Color background;
	private Color backgroundHovered;
	private Color foreground;
	private Color foregroundHovered;
	private Font font;
	
	private GraphicsCore core;
	private CompositeScreen parent;
	
	private String name;
	private boolean enabled = true;
	private boolean initialized = false;
	private String text;
	private double x = 0;
	private double y = 0;
	private double w = 0;
	private double h = 0;
	private int choice;
	
	private boolean keyboardMode = true;
	
	private Button me = this;
	
	public abstract boolean isSelected();
	public abstract void interact();
	
	public Button(String x) {
		text = x;
		name = x;
	}
	
	public boolean getIsEnabled() {
		return enabled;
	}
	
	public void setIsEnabled(Boolean x) {
		enabled = x;
	}
	
	public int getChoice() {
		return choice;
	}
	
	public boolean contains(double x, double y) {
		boolean compareX = ((me.x + w) > x && x > me.x);
		boolean compareY = ((me.y + h) > y && y > me.y);
		
		return ((compareX) && (compareY));
	}

	@Override
	public void init(CompositeScreen s, int c) {
		try {
			parent = s;
			core = parent.getCore();
			initialized = true;
			this.choice = c;
		} catch (Exception ex) {
			DebugX.writeErr("Could not initialize Button " + getName(), ex);
		}
	}

	@Override
	public void init(CompositeScreen s, int c, double x, double y, double w, double h) {
		try {
			if (!initialized) {
				this.parent = s;
				this.core = parent.getCore();
				this.x = x;
				this.y = y;
				this.w = w;
				this.h = h;
				this.choice = c;
			}
			initialized = true;
		} catch (Exception ex) {
			DebugX.writeErr("Could not initialize Button " + getName(), ex);
		}
	}

	@Override
	public void draw() {
		if (initialized) {
			
			Color fillOld = (Color) getCore().getGraphicsContext().getFill();
			Color strokeOld = (Color) getCore().getGraphicsContext().getStroke();
			
			Color background;
			Color stroke;
			Color foreground;
			
			double wid = getCore().getTextWidth(text);
			double hei = getCore().getTextHeight(text);

			background = me.background;
			stroke = me.stroke;
			foreground = me.foreground;
			
			if (keyboardMode && isSelected()) {
				background = me.backgroundHovered;
				stroke = me.strokeHovered;
				foreground = me.foregroundHovered;
			}

			if (!keyboardMode && contains(parent.getMouse().getMousePosX(), parent.getMouse().getMousePosY())) { 
				background = me.backgroundHovered;
				stroke = me.strokeHovered;
				foreground = me.foregroundHovered;
			}
			
			if (!getIsEnabled()) {
				background = Color.rgb(33, 33, 33);
				stroke = me.stroke;
				foreground = me.foreground;
			}
			
			getCore().setFont(font);
			
			double drawW = w, drawH = h;
			
			if (w == 0) drawW = getCore().getTextWidth(text);
			if (h == 0) drawH = getCore().getTextHeight(text);
						
			getCore().getGraphicsContext().setFill(background);
			getCore().getGraphicsContext().fillRect(x, y, drawW, drawH);

			getCore().getGraphicsContext().setStroke(stroke);
			getCore().getGraphicsContext().strokeRect(x, y, drawW, drawH);
			
			double newX = Math.round(x + ((drawW - wid) / 2));
			double newY = Math.round(y + ((drawH - hei) / 2));

			getCore().getGraphicsContext().setTextAlign(TextAlignment.CENTER);
			getCore().getGraphicsContext().setTextBaseline(VPos.CENTER);
			
			getCore().drawTextAtPos(text, foreground, newX, newY);
			getCore().strokeTextAtPos(text, stroke, newX, newY);
			
			getCore().getGraphicsContext().setFill(fillOld);
			getCore().getGraphicsContext().setStroke(strokeOld);
		}
	}

	@Override
	public void update() {
		
	}

	@Override
	public GraphicsCore getCore() {
		return core;
	}

	@Override
	public double getHeight() {
		return h;
	}

	@Override
	public double getWidth() {
		return w;
	}

	@Override
	public double getX() {
		return x;
	}

	@Override
	public double getY() {
		return y;
	}

	@Override
	public void setHeight(double h) {
		this.h = h;
	}

	@Override
	public void setWidth(double w) {
		this.w = w;
	}
	
	public String getText() {
		return text;
	}
	
	public void setText(String t) {
		text = t;
	}
	
	public Font getFont() {
		return font;
	}
	
	public void setFont(Font x) {
		font = x;
	}

	@Override
	public void setPosition(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	public void setStroke(Color p) {
		stroke = p;
	}
	
	public void setBackground(Color p) {
		background = p;
	}
	
	public void setForeground(Color p) {
		foreground = p;
	}
	
	public void setStrokeWhenHovered(Color p) {
		strokeHovered = p;
	}
	
	public void setBackgroundWhenHovered(Color p) {
		backgroundHovered = p;
	}
	
	public void setForegroundWhenHovered(Color p) {
		foregroundHovered = p;
	}
	
	public String getName() {
		return name;
	}
	
	public boolean getKeyboardMode() {
		return keyboardMode;
	}
	
	public void setKeyboardMode(boolean x) {
		keyboardMode = x;
	}

}
