package client.gui.character;

import client.gui.Font;
import client.gui.GuiConfirm;
import client.gui.GuiMenu;
import client.gui.element.ActButton;
import client.gui.element.Area;
import client.gui.element.ButtonCallback;
import client.gui.element.GuiList;
import client.gui.element.ListEntry;
import client.gui.element.NavButton;
import client.gui.element.PressType;
import client.renderer.Drawing;
import common.entity.npc.PlayerCharacter;
import common.packet.CPacketAction;
import common.packet.CPacketAction.Action;
import common.util.ExtMath;
import common.util.Color;

public class GuiCharacters extends GuiList<GuiCharacters.CharacterEntry> implements ButtonCallback
{
	protected class CharacterEntry implements ListEntry
	{
	    private final PlayerCharacter character;
	    private final boolean initial;

	    protected CharacterEntry(PlayerCharacter character, boolean initial)
	    {
	    	this.character = character;
	    	this.initial = initial;
	    }

	    public void draw(int x, int y, int width, int height, int mouseX, int mouseY, boolean hovered)
	    {
	    	if(this.initial)
	    		Drawing.drawRect(x, y, 1, 36, 0xffaf0000);
	    	String str = this.character == null ? Color.BLUE + "[" + Color.CYAN + "+" + Color.BLUE + "]" :
	    		String.format(Color.GREEN + "Level " + Color.DARK_GREEN + "%d " + Color.YELLOW + "%s " + Color.VIOLET + "%s", 
	    		character.level(), character.type(), character.name());
	    	String pos = this.character == null ? Color.BROWN + "Neuen Charakter erstellen" :
	    		String.format(Color.NEON + "%s " + Color.GRAY + "bei " + Color.ACID + "%d" + Color.GRAY + ", " + Color.ACID + "%d" + Color.GRAY + ", " + Color.ACID + "%d", 
	    		character.dim(), character.pos().getX(), character.pos().getY(), character.pos().getZ());
            Drawing.drawText(str, x + 3, y, 0xffffffff);
            Drawing.drawText(pos, x + 3, y + height - Font.HEIGHT, 0xffffffff);
	    }
	    
	    public void select(boolean dclick, int mx, int my)
	    {
	    	if(dclick)
	    		GuiCharacters.this.use(GuiCharacters.this.actionButtom, PressType.PRIMARY);
            GuiCharacters.this.updateButtons();
	    }
	}
	
	public static final GuiCharacters INSTANCE = new GuiCharacters();

    private Area descField;
    private ActButton actionButtom;
    private ActButton deleteButtom;
    
    private GuiCharacters() {
    }
    
    private void updateButtons() {
    	CharacterEntry entry = this.getSelected();
        this.descField.setText(entry == null ? "" : (entry.character == null ? "*neuer Charakter*" : String.format(Color.GRAY + "[%s%s" + Color.GRAY + "]\n" + Color.LIGHT_YELLOW + "Herkunft" + Color.LIGHT_GRAY + ": " + Color.LIGHT_BROWN + "%s\n" + Color.RESET + "%s", entry.character.align().color, entry.character.align().display, entry.character.origin() == null ? Color.DARK_GRAY + "*unbekannt*" : entry.character.origin(), entry.character.info() == null ? "*keine Beschreibung vorhanden*" : this.getSelected().character.info())));
    	this.actionButtom.setText(entry != null && entry.character == null ? "Charakter erstellen" : "Charakter spielen");
    	this.actionButtom.enabled = entry != null && !entry.initial;
    	this.deleteButtom.enabled = !this.gm.charEditor && entry != null && entry.character != null && !entry.initial;
    }
    
    public void init(int width, int height)
    {
    	super.init(width, height);
        this.setDimensions(width - 300, height, 32, height - 32);
        this.elements.clear();
    	int selected = this.gm.selectedCharacter;
    	for(PlayerCharacter character : this.gm.characterList) {
    		this.elements.add(new CharacterEntry(selected == this.elements.size() ? new PlayerCharacter(character.name(), character.info(), character.align(), this.gm.player.worldObj.dimension.getDisplay(), this.gm.player.getPosition(), character.type(), this.gm.player.experienceLevel, character.origin()) : character, selected == this.elements.size()));
    	}
    	if(!this.gm.charEditor)
    		this.elements.add(new CharacterEntry(null, false));
    	this.setSelected(ExtMath.clampi(selected, -1, this.elements.size() - 1));
        this.descField = this.add(new Area(width - 300, 32, 300, height - 64, ""));
        this.deleteButtom = this.add(new ActButton(width / 2 - 302, height - 30, 200, 0, this, "Charakter löschen"));
        this.actionButtom = this.add(new ActButton(width / 2 - 100, height - 30, 200, 0, this, ""));
        this.add(new NavButton(width / 2 + 102, height - 30, 200, 0, this.gm.charEditor ? GuiChar.INSTANCE : GuiMenu.INSTANCE, this.gm.charEditor ? "Zurück" : "Abbrechen"));
        this.updateButtons();
    }
    
	public String getTitle() {
		return "Charakter auswählen";
	}
    
    public int getSlotHeight()
    {
        return 36 + 4;
    }
    
    public void use(ActButton elem, PressType action) {
		CharacterEntry entry = GuiCharacters.this.getSelected();
		if(entry != null && GuiCharacters.this.gm.getNetHandler() != null) {
			if(elem == this.actionButtom) {
				if(entry.character == null)
					this.gm.getNetHandler().addToSendQueue(new CPacketAction(CPacketAction.Action.OPEN_EDITOR));
				else
					this.gm.getNetHandler().addToSendQueue(new CPacketAction(GuiCharacters.this.gm.charEditor ? Action.CANCEL_EDITOR : CPacketAction.Action.SELECT_CHARACTER, this.selectedElement));
			}
			else if(elem == this.deleteButtom && entry.character != null) {
				this.gm.show(new GuiConfirm(new GuiConfirm.Callback() {
					public void confirm(boolean confirmed) {
						if(confirmed)
							GuiCharacters.this.gm.getNetHandler().addToSendQueue(new CPacketAction(CPacketAction.Action.DELETE_CHARACTER, GuiCharacters.this.selectedElement));
						GuiCharacters.this.gm.show(GuiCharacters.this);
					}
				}, "Möchtest du diesen Charakter wirklich löschen?", "Der Fortschritt, die Gegenstände und die Historie\nvon \"" + entry.character.name() + "\" werden für immer verloren sein!", "Löschen", "Abbrechen"));
			}
		}
	}
}
