package client.gui.element;

import org.lwjgl.opengl.GL11;

import client.Client;
import client.gui.Formatter;
import client.gui.Gui;
import client.renderer.Drawing;
import client.renderer.Drawing.Vec2i;
import client.window.Button;
import client.window.Keysym;
import common.init.SoundEvent;
import common.sound.EventType;
import common.sound.PositionedSound;
import common.util.Util;

public abstract class Element {
	public static final int BASE_HEIGHT = 18;
	
	protected final Client gm = Client.CLIENT;
	
	protected Gui gui;
	protected Formatter format;
	protected String text = "";
	
	protected int pos_x;
	protected int pos_y;
	protected int size_x;
	protected int size_y;
	protected int text_x = 0;
	protected int text_y = 0;
	
	protected final int margin_x1 = this.getMarginX();
	protected final int margin_y1 = this.getMarginY();
	protected final int margin_x2 = this.getMarginX();
	protected final int margin_y2 = this.getMarginY();
	
	public boolean visible = true;
	public boolean enabled = true;
	
	public Element(int x, int y, int w, int h, Formatter formatter) {
		this.pos_x = x;
		this.pos_y = y;
		this.size_x = w;
		this.size_y = h <= 0 ? BASE_HEIGHT : h;
		this.format = formatter;
//		gui_update_style(this, 1);
//		if(type != ElemType.SLIDER) {
//			this.margin_x1 = this.margin_x2 = (type == ElemType.FIELD || type == ElemType.DROPDOWN_HANDLE) ? this.border : 0;
//			this.margin_y1 = this.margin_y2 = (type == ElemType.FIELD || type == ElemType.DROPDOWN_HANDLE) ? this.border : 0;
//		}
	}
	
	public void setGui(Gui gui) {
		if(gui == null)
			throw new NullPointerException("gui");
		if(this.gui != null)
			throw new IllegalStateException("GUI bereits gesetzt");
		this.gui = gui;
	}
	
	protected int getMarginX() {
		return 1;
	}
	
	protected int getMarginY() {
		return 1;
	}
	
	public final int getX() {
		return this.pos_x;
	}
	
	public final int getY() {
		return this.pos_y;
	}
	
	public final int getWidth() {
		return this.size_x;
	}
	
	public final int getHeight() {
		return this.size_y;
	}
	
//	protected boolean isTextCenteredX() {
//		return true;
//	}
//	
//	protected boolean isTextCenteredY() {
//		return true;
//	}
	
//	protected boolean hasLinebreak() {
//		return false;
//	}
	
	public boolean canHover() {
		return true;
	}
	
	public boolean canClick() {
		return this.canHover();
	}

	public boolean inside(int x, int y) {
		return (x >= this.pos_x) && (x < (this.pos_x + this.size_x)) && (y >= this.pos_y) && (y < (this.pos_y + this.size_y));
	}

	public boolean intersects(Element elem) {
		return (elem.pos_y + elem.size_y) > this.pos_y && elem.pos_y < (this.pos_y + this.size_y) && (elem.pos_x + elem.size_x) > this.pos_x && elem.pos_x < (this.pos_x + this.size_x);
	}
	
	public void updateText() {
		Vec2i size = Drawing.getSize(this.text);
		this.text_x = ((this.size_x - (this.margin_x1 + this.margin_x2)) - size.xpos) / 2;
		this.text_y = ((this.size_y - (this.margin_y1 + this.margin_y2)) - size.ypos + 1) / 2;
	}
	
	public void setText(String str) {
		this.text = str;
		this.updateText();
	}
	
	public String getText() {
		return this.text;
	}
	
	protected void formatText() {
		if(this.format != null) {
			this.text = this.format.use(this);
			this.updateText();
		}
	}
	
	public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) {
		
	}
	
	public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) {
		
	}
	
	public void mouserel() {
		
	}
	
	public void drag(int x, int y) {
		
	}
	
	public void character(char code) {
		
	}
	
	public void key(Keysym key, boolean ctrl, boolean shift) {
		
	}
	
	public void select() {
		
	}
	
	public void deselect() {
		
	}
	
	public void update() {
		
	}
	
	public void setSelected() {
		if(this.gui != null)
			this.gui.select(this);
	}
	
	public void setDeselected() {
		if(this.gui != null && this.gui.selected == this)
			this.gui.deselect();
	}
	
	public void shift(int shift_x, int shift_y) {
		this.pos_x += shift_x;
		this.pos_y += shift_y;
	}
	
	public void reformat() {
		if(this.format != null) {
//			boolean flag = this.r_dirty;
			this.formatText();
//			if(!flag && !this.visible)
//				this.r_dirty = false;
		}
	}
	
	protected void drawBackground() {
		if(this.enabled)
			Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, this.gm.style.fill_top, this.gm.style.fill_btm, 0xff000000, this.gm.style.brdr_top, this.gm.style.brdr_btm);
		else
			Drawing.drawGradientBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, Util.mulColor(this.gm.style.fill_top, 0.5f), Util.mulColor(this.gm.style.fill_btm, 0.5f), 0xff000000, Util.mulColor(this.gm.style.brdr_top, 0.5f), Util.mulColor(this.gm.style.brdr_btm, 0.5f));
//		Drawing.drawGradient2GradBorder(this.pos_x, this.pos_y, this.size_x, this.size_y, this.gm.style.fill_top, this.gm.style.fill_btm, 0xff000000, 
//				this.gm.style.brdr_top, Drawing.mixColor(this.gm.style.brdr_top, this.gm.style.brdr_btm), Drawing.mixColor(this.gm.style.brdr_top, this.gm.style.brdr_btm), this.gm.style.brdr_btm);
	}
	
	protected void drawForeground(int x1, int y1, int x2, int y2) {
		Drawing.drawText(this.text, x1 + this.text_x, y1 + this.text_y, this.enabled ? this.gm.style.text_base : Util.mulColor(this.gm.style.text_base, 0.5f));
	}
	
	public void draw() {
//		if(this.r_dirty) {
			if(this.visible) {
//				WCF.glScissor(this.pos_x, (this.gm.fb_y - (this.pos_y + this.size_y)) < 0 ? 0 : (this.gm.fb_y - (this.pos_y + this.size_y)), this.size_x, this.size_y);
//				WCF.glEnable(WCF.GL_SCISSOR_TEST);
//				WCF.glClear(WCF.GL_COLOR_BUFFER_BIT);
//				WCF.glDisable(WCF.GL_SCISSOR_TEST);
				this.drawBackground();
//				if(this.selected == this && this.type == ElemType.DROPDOWN_HANDLE)
//				continue;
				int x1 = this.pos_x + this.margin_x1;
				int y1 = this.pos_y + this.margin_y1;
				int x2 = this.size_x - (this.margin_x1 + this.margin_x2);
				int y2 = this.size_y - (this.margin_y1 + this.margin_y2);
				// if(elem.type == ElemType.FIELD) {
				this.gm.scissor(x1 < 0 ? 0 : x1, (this.gm.fbY - (y1 + y2)) < 0 ? 0 : (this.gm.fbY - (y1 + y2)), x2 < 0 ? 0 : x2, y2 < 0 ? 0 : y2);
				GL11.glEnable(GL11.GL_SCISSOR_TEST);
				// }
	//			if(this.type == ElemType.CUSTOM)
	//				this.func(this, 1);
	//			else
				this.drawForeground(x1, y1, x2, y2);
				// logd("DBG", "%d @ %d %d -> %d %d", elem.id, x1, y1, elem.pos_x + x2, elem.pos_y + y2);
				// if(elem.type == ElemType.FIELD) {
				GL11.glDisable(GL11.GL_SCISSOR_TEST);
					// glScissor(0, 0, sys.fb_x, sys.fb_y);
				// }
			}
//			else {
//				WCF.glScissor(this.pos_x, (this.gm.fb_y - (this.pos_y + this.size_y)) < 0 ? 0 : (this.gm.fb_y - (this.pos_y + this.size_y)), this.size_x, this.size_y);
//				// logd("DBG", "%d @ %d %d -> %d %d", elem.id, elem.pos_x, elem.pos_y, elem.pos_x + elem.size_x, elem.pos_y + elem.size_y);
//				WCF.glEnable(WCF.GL_SCISSOR_TEST);
////				if(this.type == ElemType.CUSTOM)
////					this.func(this, 0);
////				else
//				WCF.glClear(WCF.GL_COLOR_BUFFER_BIT);
//				WCF.glDisable(WCF.GL_SCISSOR_TEST);
//				this.r_dirty = false;
//			}
			// this.r_dirty = this.visible;
			// logd("DBG", "@ r");
//			if(this.visible) {
//			}
//			else {
//			}
//		}
	}
	
	public void drawOverlay() {
		
	}
	
	public void drawHover() {
		Drawing.drawRect(this.pos_x, this.pos_y, this.size_x, this.size_y, Gui.HOVER_COLOR);
	}
	
	public void drawPress() {
		Drawing.drawRect(this.pos_x, this.pos_y, this.size_x, this.size_y, Gui.PRESS_COLOR);
	}
	
	public void playSound() {
		this.gm.getSoundManager().playSound(new PositionedSound(SoundEvent.CLICK, EventType.UI_INTERFACE));
	}
}
