package jrummikub.view.impl;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;

import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import jrummikub.model.PlayerSettings;
import jrummikub.model.PlayerSettings.Type;
import jrummikub.util.Event;
import jrummikub.util.Event1;
import jrummikub.util.GameData;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.view.IGameListPanel;

class GameListPanel extends JPanel implements IGameListPanel {
	private static final long serialVersionUID = 1L;

	private JLabel title;
	private JList gameList;
	private JButton joinButton;
	private JButton openNewGameButton;
	private JButton cancelButton;

	private Event1<GameData> joinEvent = new Event1<GameData>();
	private Event openNewGameEvent = new Event();
	private Event cancelEvent = new Event();

	private List<GameData> games = Collections.emptyList();

	GameListPanel() {
		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.weightx = 1;
		c.weighty = 0;

		title = new JLabel();
		title.setFont(title.getFont().deriveFont(16.0f));
		title.putClientProperty("html.disable", Boolean.TRUE);
		add(title, c);

		add(Box.createVerticalStrut(3), c);

		gameList = new JList();
		gameList.setCellRenderer(new GameDataCellRenderer());
		c.weighty = 1;
		add(new JScrollPane(gameList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), c);

		c.weighty = 0;
		add(Box.createVerticalStrut(3), c);

		addButtons(c);

		setBorder(new CompoundBorder(new LineBorder(Color.BLACK),
				new EmptyBorder(10, 10, 10, 10)));
	}

	private void addButtons(GridBagConstraints c) {
		joinButton = new JButton("Beitreten");
		c.gridwidth = 1;
		add(joinButton, c);
		joinButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Object data = gameList.getSelectedValue();

				if (data instanceof GameData) {
					joinEvent.emit((GameData) data);
				}
			}
		});

		c.weightx = 0;
		add(Box.createHorizontalStrut(10), c);

		openNewGameButton = new JButton("Neues Spiel");
		c.weightx = 1;
		add(openNewGameButton, c);
		openNewGameButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				openNewGameEvent.emit();
			}
		});

		c.weightx = 0;
		add(Box.createHorizontalStrut(10), c);

		cancelButton = new JButton("Abbrechen");
		c.weightx = 1;
		c.weighty = 0;
		c.gridwidth = GridBagConstraints.REMAINDER;
		add(cancelButton, c);
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				cancelEvent.emit();
			}
		});
	}

	void reset() {
		games.clear();
	}

	@Override
	public void setChannelName(String name) {
		title.setText("Spiele in " + name + ":");
	}

	@Override
	public void setGameList(List<GameData> games) {
		this.games = games;

		Object currentGame = gameList.getSelectedValue();

		DefaultListModel model = new DefaultListModel();
		for (GameData game : games) {
			model.addElement(game);
		}
		gameList.setModel(model);

		if (games.contains(currentGame)) {
			gameList.setSelectedValue(currentGame, false);
		}
	}

	@Override
	public IEvent getOpenNewGameEvent() {
		return openNewGameEvent;
	}

	@Override
	public IEvent1<GameData> getJoinEvent() {
		return joinEvent;
	}

	@Override
	public IEvent getCancelEvent() {
		return cancelEvent;
	}

	private static class GameDataCellRenderer extends JPanel implements
			ListCellRenderer {
		private static final long serialVersionUID = -892701906163443927L;
		JLabel hostLabel, playerCountLabel;

		GameDataCellRenderer() {
			setLayout(new GridBagLayout());
			GridBagConstraints c = new GridBagConstraints();
			c.fill = GridBagConstraints.BOTH;
			c.gridwidth = 1;
			c.weightx = 1;
			c.weighty = 1;

			hostLabel = new JLabel();
			hostLabel.setOpaque(true);
			hostLabel.setHorizontalAlignment(JLabel.LEFT);
			add(hostLabel, c);

			playerCountLabel = new JLabel();
			playerCountLabel.setOpaque(true);
			playerCountLabel.setHorizontalAlignment(JLabel.RIGHT);

			c.gridwidth = GridBagConstraints.REMAINDER;
			add(playerCountLabel, c);
		}

		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			String host = "", playerCount = "";

			if (value instanceof GameData
					&& ((GameData) value).getGameSettings() != null) {
				GameData gameData = (GameData) value;

				host = gameData.getHost();
				int total = gameData.getGameSettings().getPlayerList().size();
				int occupied = total;

				for (PlayerSettings player : gameData.getGameSettings()
						.getPlayerList()) {
					if (player.getType() == Type.VACANT) {
						occupied--;
					}
				}

				playerCount = occupied + "/" + total;
			} else {
				host = String.valueOf(value);
			}

			hostLabel.setText(host);
			playerCountLabel.setText(playerCount);

			if (isSelected) {
				hostLabel.setBackground(list.getSelectionBackground());
				hostLabel.setForeground(list.getSelectionForeground());
				playerCountLabel.setBackground(list.getSelectionBackground());
				playerCountLabel.setForeground(list.getSelectionForeground());
			} else {
				hostLabel.setBackground(list.getBackground());
				hostLabel.setForeground(list.getForeground());
				playerCountLabel.setBackground(list.getBackground());
				playerCountLabel.setForeground(list.getForeground());
			}

			setEnabled(list.isEnabled());
			setFont(list.getFont());
			return this;
		}
	}
}
