package jrummikub.view.impl;

import java.awt.Color;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import jrummikub.util.Event;
import jrummikub.util.IEvent;
import jrummikub.view.IView.BottomPanelType;

/**
 * A panel that is displayed before a player's turn
 */
@SuppressWarnings("serial")
class StartTurnPanel extends JPanel {
	private final static int PANEL_INSET = 15;
	private final static int PANEL_SEPARATOR = 10;
	private final static float PANEL_FIRST_LINE_HEIGHT = 0.2f;
	private final static int PANEL_MAX_WIDTH = 180;
	private final static float MAX_BUTTON_FONT_SIZE = 12;

	private JLabel startTurnLabel;
	private JLabel extraLabel;
	private JButton startTurnButton;

	private Event startTurnEvent = new Event();
	private Event acknowledgeInvalidEvent = new Event();
	private Event acknowledgeConnectionLostEvent = new Event();

	private Event buttonEvent = startTurnEvent;
	private BottomPanelType type;
	private Color currentPlayerColor;
	private String currentPlayerName;
	private String redealedPlayerName;
	private String lastStonePlayerName;

	/**
	 * Creates a new StartTurnPanel
	 */
	StartTurnPanel() {
		setLayout(null);
		setBorder(new EmptyBorder(PANEL_INSET, PANEL_INSET, PANEL_INSET,
				PANEL_INSET));

		startTurnLabel = new JLabel();
		startTurnLabel.setHorizontalAlignment(JLabel.CENTER);
		startTurnLabel.setVerticalAlignment(JLabel.CENTER);
		startTurnLabel.putClientProperty("html.disable", Boolean.TRUE);
		add(startTurnLabel);

		extraLabel = new JLabel();
		extraLabel.setHorizontalAlignment(JLabel.CENTER);
		extraLabel.setVerticalAlignment(JLabel.CENTER);
		extraLabel.putClientProperty("html.disable", Boolean.TRUE);
		add(extraLabel);

		startTurnButton = new JButton("Zug beginnen");
		startTurnButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				buttonEvent.emit();
			}
		});
		add(startTurnButton);

		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				rescale();
			}
		});
	}

	void setInitialMeldError(int points) {
		startTurnLabel.setIcon(null);
		startTurnLabel.setText("Es wurden weniger als " + points
				+ " Punkte ausgelegt.");
	}

	void setInitialMeldFirstError() {
		startTurnLabel.setIcon(null);
		startTurnLabel.setText("Vor dem Rauskommen darf nicht angelegt werden.");
	}

	IEvent getStartTurnEvent() {
		return startTurnEvent;
	}

	IEvent getAcknowledgeInvalidEvent() {
		return acknowledgeInvalidEvent;
	}

	IEvent getAcknowledgeConnectionLostEvent() {
		return acknowledgeConnectionLostEvent;
	}

	private void rescale() {
		Insets insets = getInsets();
		int x = insets.left, y = insets.top, width = getWidth() - insets.left
				- insets.right, height = getHeight() - insets.top - insets.bottom;

		if (width > PANEL_MAX_WIDTH) {
			x += (width - PANEL_MAX_WIDTH) / 4;
			width = width / 2 + PANEL_MAX_WIDTH / 2;
		}

		int firstLineHeight = (int) ((height - PANEL_SEPARATOR) * PANEL_FIRST_LINE_HEIGHT);
		int buttonWidth = width;
		int buttonHeight = height - 2 * PANEL_SEPARATOR - 2 * firstLineHeight;
		float fontSize = (float) Math.sqrt(buttonWidth * buttonHeight) / 5;
		if (fontSize > MAX_BUTTON_FONT_SIZE)
			fontSize = MAX_BUTTON_FONT_SIZE;

		if (type == BottomPanelType.START_REDEAL_TURN_PANEL
				|| type == BottomPanelType.START_LAST_TURN_PANEL) {
			startTurnLabel.setBounds(x, y, width, firstLineHeight);
			extraLabel.setBounds(x, y + firstLineHeight + PANEL_SEPARATOR, width,
					firstLineHeight);
			extraLabel.setVisible(true);
		} else {
			startTurnLabel.setBounds(x, y, width, 2 * firstLineHeight
					+ PANEL_SEPARATOR);
			extraLabel.setVisible(false);
		}
		startTurnButton.setBounds(x, y + 2 * firstLineHeight + 2 * PANEL_SEPARATOR,
				buttonWidth, buttonHeight);
		startTurnButton.setFont(startTurnButton.getFont().deriveFont(fontSize));
	}

	void setCurrentPlayerName(String playerName) {
		currentPlayerName = playerName;
		update();
	}

	void setCurrentPlayerColor(Color color) {
		currentPlayerColor = color;
		update();
	}

	void setRedealedPlayerName(String name) {
		redealedPlayerName = name;
		update();
	}

	void setLastStonePlayerName(String name) {
		lastStonePlayerName = name;
		update();
	}

	void setType(BottomPanelType type) {
		this.type = type;
		update();
	}

	private void update() {
		if (type == null) {
			return;
		}

		startTurnLabel
				.setIcon(ImageUtil.createColorIcon(currentPlayerColor, 12, 1));
		startTurnLabel.setText(currentPlayerName + " ist jetzt an der Reihe.");
		extraLabel.setText("");
		startTurnButton.setText("Zug beginnen");
		buttonEvent = startTurnEvent;

		switch (type) {
			case START_REDEAL_TURN_PANEL:
				extraLabel.setText(redealedPlayerName + " hat neu geben lassen.");
				break;

			case START_LAST_TURN_PANEL:
				extraLabel.setText(lastStonePlayerName
						+ " hat den letzten Stein gezogen.");
				break;

			case INVALID_TURN_PANEL:
				startTurnLabel.setIcon(null);
				startTurnLabel
						.setText("Es liegen ung\u00FCltige Serien auf dem Tisch.");
				startTurnButton.setText("N\u00E4chster Spieler");
				buttonEvent = acknowledgeInvalidEvent;
				break;

			case NETWORK_SERVER_CONNECTION_LOST_PANEL:
				startTurnLabel.setIcon(null);
				startTurnLabel.setText("Die Verbindung zum Server wurde getrennt.");
				startTurnButton.setText("OK");
				buttonEvent = acknowledgeConnectionLostEvent;
				break;
		}

		rescale();
	}
}
