package client.gui;

import client.Client;
import client.gui.character.GuiChar;
import client.gui.character.GuiCharacters;
import client.gui.element.ActButton;
import client.gui.element.ButtonCallback;
import client.gui.element.Label;
import client.gui.element.NavButton;
import client.gui.element.PressType;
import client.gui.options.GuiOptions;
import client.renderer.Drawing;
import client.window.Keysym;
import common.entity.npc.EntityCameraHolder;
import common.rng.Random;
import common.util.ExtMath;
import common.util.Color;

public class GuiMenu extends Gui {
	public static final GuiMenu INSTANCE = new GuiMenu();
	
	private GuiMenu() {
	}
	
	public void drawMainBackground() {
		if(this.gm.world != null)
			super.drawMainBackground();
		else
			this.gm.renderer.renderStarField(this.gm.fbX, this.gm.fbY, 0x000000, 0xffffff, (float)this.ticks + this.gm.getTickFraction(), this.rand);
	}
	
	private final Random rand = new Random();

	private Label splashLabel;
	private ActButton infoButton;

    private int ticks;
    private int hacked;
	
	private int animWidth = 32;
	private int animGrowth = 10;
	private int[] animGrow = new int[this.animWidth];
	private String animStr = "";
	private String animBack = "";
	private int animPos;
	private int animLen;
	private int animDir;
	private boolean animStep;
	
	public void init(int width, int height) {
		if(this.gm.world == null) {
	    	this.ticks = 0;
	    	this.hacked = 0;
			this.resetAnimation();
			this.add(new ActButton(0, 0, 180, 0, new ButtonCallback() {
				public void use(ActButton elem, PressType action) {
					if(action == PressType.SECONDARY) {
						GuiMenu.this.gm.joinDebugWorld();
						return;
					}
					if(GuiMenu.this.hacked == 9) {
						GuiMenu.this.hacked++;
						GuiMenu.this.splashLabel.setText(Color.VIOLET + "Hax!");
					}
					else {
						GuiMenu.this.gm.show(GuiConnect.INSTANCE);
					}
				}
			}, "Server beitreten"));
			this.add(new ActButton(0, 20, 180, 0, new ButtonCallback() {
				public void use(ActButton elem, PressType action) {
					if(GuiMenu.this.hacked == 8)
						GuiMenu.this.hacked++;
					else
						GuiMenu.this.gm.show(GuiServer.INSTANCE);
				}
			}, "Schnellverbindung"));
			this.add(new NavButton(0, 40, 180, 0, GuiPlayer.INSTANCE, "MIDI-Player"));
			this.add(new NavButton(0, 60, 180, 0, GuiOptions.getPage(), "Einstellungen"));
			this.infoButton = this.add(new ActButton(0, 80, 180, 0, new ButtonCallback() {
				public void use(ActButton elem, PressType action) {
					GuiMenu.this.gm.show(GuiMenu.this.hacked == 10 ? GuiInfo.HAX : GuiInfo.INSTANCE);
				}
			}, "Info / Mitwirkende") {
				public void drawHover() {
					if(GuiMenu.this.hacked == 10) {
						Drawing.drawRect(this.pos_x, this.pos_y, this.size_x, this.size_y, 0x287f00ff);
						GuiMenu.this.rand.setSeed(((long)this.gm.mouseX * 7652657L) ^ ((long)this.gm.mouseY * 87262826276L));
						int width = Drawing.getWidth("Hax!");
						for(int z = 0; z < 64; z++) {
							Drawing.drawText("Hax!", GuiMenu.this.rand.zrange(Math.max(1, this.gm.fbX - width)) + 
								(int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + this.gm.getTickFraction()) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), 
								GuiMenu.this.rand.zrange(Math.max(1, this.gm.fbY - Font.HEIGHT)) + 
								(int)(ExtMath.sin(((float)(GuiMenu.this.ticks + GuiMenu.this.rand.zrange(256)) + this.gm.getTickFraction()) / 100.0f * (float)Math.PI * 2.0f) * 16.0f), 
								0xff0000ff | (GuiMenu.this.rand.zrange(256) << 16));
						}
					}
					else {
						super.drawHover();
					}
				}
			});
			this.add(new ActButton(0, 110, 180, 0, new ButtonCallback() {
				public void use(ActButton elem, PressType action) {
					GuiMenu.this.gm.interrupted = true;
				}
			}, "Client schließen"));
			this.shift();
			this.add(new Label(4, 4, 200, 0, Color.VIOLET + Client.VERSION, true));
			this.splashLabel = this.add(new Label(0, 100, width, 0, ""));
			this.pickSplash();
		}
		else {
			this.add(new NavButton(0, 0, 180, 0, this.gm.charEditor ? GuiChar.INSTANCE : null, this.gm.charEditor ? "Zurück zum Editor" : "Zurück zum Spiel"));
			this.add(new NavButton(0, 20, 180, 0, GuiPlayer.INSTANCE, "MIDI-Player"));
			this.add(new NavButton(0, 40, 180, 0, GuiOptions.getPage(), "Einstellungen"));
			if(!this.gm.charEditor)
				this.add(new NavButton(0, 60, 180, 0, GuiCharacters.INSTANCE, "Charakter")).enabled = !(this.gm.player instanceof EntityCameraHolder);
			this.add(new ActButton(0, this.gm.charEditor ? 70 : 90, 180, 0, new ButtonCallback() {
				public void use(ActButton elem, PressType action) {
					GuiMenu.this.gm.unload(true);
//					GuiMenu.this.gm.displayGuiScreen(INSTANCE);
				}
			}, "Server verlassen"));
			this.shift();
		}
	}
	
	public String getTitle() {
		return this.gm.world == null ? "Hauptmenü" : "Menü";
	}

	private void pickSplash() {
		this.splashLabel.setText(Color.VIOLET + this.rand.pick(Splashes.SPLASHES));
	}
	
	private void resetAnimation() {
		this.animStr = "";
		this.animBack = "";
		this.animPos = 0;
		this.animLen = 0;
		this.animDir = 0;
		this.animStep = false;
		this.animWidth = Math.max(5, (this.gm.fbX - 5) / 10);
		this.animGrowth = this.animWidth / 15;
		this.animGrow = new int[this.animWidth];
	}
	
	private void updateAnimation() {
		if(this.animLen == 0) {
			this.animDir = this.rand.zrange(3) - 1;
			this.animLen = this.animDir == 0 ? (2 + this.rand.zrange(2)) : (8 + this.rand.zrange(96));
		}
		else {
			this.animPos += this.animDir;
			if(this.animPos == -1) {
				this.animPos = 0;
				this.animDir = 1;
			}
			else if(this.animPos == this.animWidth - 3) {
				this.animPos = this.animWidth - 4;
				this.animDir = -1;
			}
			this.animLen--;
		}
		this.animStep = !this.animStep;
		StringBuilder sb = new StringBuilder(11);
		sb.append(Color.GRAY);
		sb.append("[");
		sb.append(Color.YELLOW);
		switch(this.animDir) {
		case -1:
			sb.append((this.animStep ? '>' : '-') + "' ");
			break;
		case 0:
			sb.append("`" + (this.animStep ? 'O' : 'o') + "'");
			break;
		case 1:
			sb.append(" `" + (this.animStep ? '<' : '-'));
			break;
		}
		sb.append(Color.GRAY);
		sb.append("]");
		this.animStr = sb.toString();
		for(int z = this.animPos; z < this.animPos + 4; z++) {
			this.animGrow[z] = 0;
		}
		for(int z = 0; z < this.animGrowth; z++) {
			this.animGrow[this.rand.zrange(this.animWidth)] += 1;
		}
		sb = new StringBuilder(this.animWidth + 2);
		sb.append(Color.DARK_GREEN);
		for(int z = 0; z < this.animWidth; z++) {
			switch(this.animGrow[z] / 5) {
			case 0:
				sb.append(Color.BLACK);
				break;
			case 1:
				sb.append(Color.GRAY);
				break;
			case 2:
			case 3:
				sb.append(Color.LIGHT_GRAY);
				break;
			case 4:
			case 5:
			case 6:
				sb.append(Color.WHITE);
				break;
			case 7:
			case 8:
			case 9:
			case 10:
				sb.append(Color.MAGENTA);
				break;
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
				sb.append(Color.DARK_VIOLET);
				break;
			default:
				sb.append(Color.VIOLET);
				break;
			}
			sb.append(",.");
		}
		this.animBack = sb.toString();
	}
	
	public void updateScreen() {
		if(this.gm.world == null) {
	    	this.ticks++;
			if(this.gm.shift())
				this.pickSplash();
			this.updateAnimation();
		}
	}
	
	public void key(Keysym key, boolean ctrl, boolean shift) {
		super.key(key, ctrl, shift);
		if(this.gm.world == null) {
	    	if((key == Keysym.UP || key == Keysym.W) && (this.hacked == 0 || this.hacked == 1))
	    		this.hacked++;
	    	else if((key == Keysym.DOWN || key == Keysym.S) && (this.hacked == 2 || this.hacked == 3))
	    		this.hacked++;
	    	else if((key == Keysym.LEFT || key == Keysym.A) && (this.hacked == 4 || this.hacked == 6))
	    		this.hacked++;
	    	else if((key == Keysym.RIGHT || key == Keysym.D) && (this.hacked == 5 || this.hacked == 7))
	    		this.hacked++;
	    	else
	    		this.hacked = 0;
		}
	}
	
	/*
	protected void actionPerformed(Button button) throws IOException {
    	if(button.id == 2 && this.hacked == 8) {
    		this.hacked++;
    		return;
    	}
    	else if(button.id == 1 && this.hacked == 9) {
    		this.hacked++;
    		return;
    	}
    	if(button.id != 3 || this.hacked != 10)
    		this.hacked = 0;
		switch(button.id) {
		case 0:
			this.gm.displayGuiScreen(new GuiOptions(this));
			break;
		case 1:
			this.gm.displayGuiScreen(new GuiWorlds(this));
			break;
		case 2:
			this.gm.displayGuiScreen(new GuiMultiplayer(this));
			break;
		case 3:
            if(this.hacked == 10)
            	Log.info("Hax!");
			this.gm.displayGuiScreen(new GuiCredits(this.hacked == 10));
            this.hacked = 0;
			break;
//		case 4:
//			this.gm.displayGuiScreen(new GuiLanguage());
//			break;
		case 4:
			this.gm.shutdown();
			break;
		}
	}
	*/
	
	public void drawOverlays() {
		super.drawOverlays();
		if(this.gm.world == null) {
			int y = 99;
			int h = 16;
			int n = Drawing.getWidth(this.splashLabel.getText());
			Drawing.drawRect(0, y, this.gm.fbX / 2 - n / 2 - 10, h, 0x7f7f00ff);
			Drawing.drawRect(this.gm.fbX / 2 + n / 2 + 10, y, this.gm.fbX - (this.gm.fbX / 2 + n / 2 + 10), h, 0x7f7f00ff);
			Drawing.drawText(this.animBack, this.gm.fbX - Drawing.getWidth(this.animBack), this.gm.fbY - 18, 0xffffffff);
			Drawing.drawText(this.animStr, this.gm.fbX - Drawing.getWidth(this.animStr) - 3 - ((this.animWidth - this.animPos - 4) * 10), this.gm.fbY - 20, 0xffffffff);
		}
	}
}
