package Cluedo.GUI2;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import Cluedo.API.CDialog;
import Cluedo.API.CardImage;
import Cluedo.API.DisproofAlert;
import Cluedo.API.HiddenCardImage;
import Cluedo.API.LanguagePack;
import Cluedo.API.Message;
import Cluedo.API.SelectedEventListener;
import Cluedo.API.SuggestionAlert;
import Cluedo.Controller.GameController;
import Cluedo.Game.Card;
import Cluedo.Game.CardCollection;
import Cluedo.Game.Player;

public class DisproofWindow extends CDialog implements SelectedEventListener, ActionListener {

	CardImage disprovePlayer = null;
	HiddenCardImage[] candidateCards = new HiddenCardImage[3];
	JButton doneButton = null;
	
	String [] names = new String[3];
	String playerName = "";
	String suggestedBy = "";
	
	GameController gameController = null;
	SuggestionAlert originalSuggestion = null;
	
	boolean disposed = false;
	
	public static final String DEFAULT_GROUP = "disproof_window";
	
	public static String cardPath = "Resources/Cards/";
	public static String altCardPath = "../../Resources/Cards/";
	
	
	public boolean getUseless() {
		return disposed;
	}
	
	public void actionPerformed(ActionEvent e) {
	
		// Scan through the array of candidate cards until we find the index which was chosen.
		boolean found = false;
		int i = 0;
		for(i = 0; i < candidateCards.length; i++)
			if(candidateCards[i] != null)
				if(candidateCards[i].cardChosen() == true) {
					found = true;
					break;
				}

		sendMessage(found, names[i]);

	}
	
	private void sendMessage(boolean found, String name) {

		Message disproofAlert = new Message();
		disproofAlert.type = "disproofAlert";

		if(found == true) {
			// Add a new DisproofAlert to the parameters of the message
			disproofAlert.parameters.add( new DisproofAlert( name, originalSuggestion, playerName ) );
		}
		else {
			disproofAlert.parameters.add( new DisproofAlert( "", originalSuggestion, "" ) );
		}

		// Get the game controller to relay the message to all listeners
		gameController.relayMessage(disproofAlert);

		System.out.println(
			"\n[DisproofWindow:actionPerformed] Relay message... Ok\n");

		// Get rid of this dialog
		setVisible(false);
		disposed = true;
		dispose();
		
	}
	
	private Vector filterCards(Vector allCards, String playerName) {
		Vector filteredCards = new Vector();
		Player disproofPlayer = gameController.getBoard().getPlayer(playerName);
		CardCollection disproofPlayerCards = disproofPlayer.getCards();
		
		for(int i = 0; i < allCards.size(); i++) {
			if(disproofPlayerCards.containsCard((Card)allCards.elementAt(i)))
				filteredCards.add(allCards.elementAt(i));
		}
		
		return filteredCards;
	}
	
	public DisproofWindow (JFrame parent, String playerName, Vector cards, SuggestionAlert alert, GameController gameController) {
		super("Disprove the suggestion..", true);
		setParent((Frame)parent);
		this.gameController = gameController;
		this.playerName = playerName;
		this.originalSuggestion = alert;
		
		// Only setup the page if this suggestion can be disproved.
		if(playerName.equals("")) {
			sendMessage(false, "");
			disposed = true;
			dispose();

		}
		else {
		    
		    if(new File(cardPath + "folder").exists() == false) {
		        cardPath = altCardPath; 
		    }
			
			for(int i = 0; i < cards.size(); i++) {
				names[i] = "";
			}
			
			cards = filterCards(cards, playerName);
			
			for(int i = 0; i < cards.size(); i++) {
				names[i] = ((Cluedo.Game.Card)cards.elementAt(i)).getName();
			}
                	
			doneButton = new JButton(LanguagePack.getString("done_button", DEFAULT_GROUP));
			doneButton.addActionListener( this );
			
			String playerCharacter = gameController.getBoard().getPlayer(playerName).getCharacter();

			disprovePlayer = new CardImage(cardPath + playerCharacter.toLowerCase() + ".gif", playerName);
			disprovePlayer.setBorder( BorderFactory.createEtchedBorder() );
                	
                	
                	
			for(int i = 0; i < names.length; i++) {
				if(new java.io.File(cardPath + names[i].toLowerCase() + ".gif").exists() == true)
					candidateCards[i] = new HiddenCardImage(cardPath + names[i].toLowerCase() + ".gif", this, names[i]);
				else
					candidateCards[i] = new HiddenCardImage(names[i]);
			}
			
			JPanel topPage = new JPanel();
			topPage.setLayout( new BorderLayout() );
			
			Box headerPage = Box.createVerticalBox();
                	
			Box cardViewPage = Box.createHorizontalBox();
			Box bottomPage = Box.createVerticalBox();
			
			Box disprovePlayerColumn = Box.createVerticalBox();
			Box candidateCardsColumn = Box.createHorizontalBox();
			
			JPanel cardRowPanel = new JPanel();
			GridLayout newGridLayout = new GridLayout();
			newGridLayout.setHgap(10);
			cardRowPanel.setLayout( newGridLayout );
                	
			
			disprovePlayerColumn.add( disprovePlayer );
                	
			for(int i = 0; i < names.length; i++) {
				cardRowPanel.add( candidateCards[i] );
                	
				candidateCards[i].setListener( this );
				candidateCards[i].setBorder( BorderFactory.createEtchedBorder() );
                	
			}		
			
			candidateCardsColumn.add( cardRowPanel );
			JLabel titleLabel = new JLabel(
					LanguagePack.getString("disproof_caption", DEFAULT_GROUP));
			titleLabel.setFont( new Font( "Arial", Font.PLAIN, 15) );
			headerPage.add( titleLabel );
			headerPage.add( Box.createVerticalStrut(20) );
                	
			headerPage.add( new JLabel(
					addArguments(LanguagePack.getString("disproof_candidate", DEFAULT_GROUP), new String[]{playerName})) );
			headerPage.add( Box.createVerticalStrut(20) );
							
			cardViewPage.add( disprovePlayerColumn );
			cardViewPage.add( Box.createHorizontalStrut(60) );
			cardViewPage.add( candidateCardsColumn );
                	
                	
			bottomPage.add( Box.createVerticalStrut(20) );		
			bottomPage.add( new JLabel(
					LanguagePack.getString("choose_a_card", DEFAULT_GROUP)));

			bottomPage.add( Box.createVerticalStrut(30) );
			bottomPage.add( doneButton );
				
	        	
			topPage.add(headerPage, BorderLayout.NORTH);
			
			topPage.add(cardViewPage, BorderLayout.CENTER);
                	
			JLabel playerNameLabel = new JLabel( playerName );       
			playerNameLabel.setFont( new Font( "Arial", Font.BOLD, 17) );
                	
			topPage.add( playerNameLabel , BorderLayout.SOUTH);
		
			
			getContentPane().add(topPage, BorderLayout.NORTH);
			getContentPane().add(bottomPage, BorderLayout.SOUTH);
			pack();
			
		}
		doneButton.setEnabled(false);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setResizable(false);
		
		centre();
	}
	
	public void centre() {
    	Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    	Dimension frameSize = getSize();
    	frameSize.height = ((frameSize.height > screenSize.height) ? screenSize.height : frameSize.height);
    	frameSize.width = ((frameSize.width > screenSize.width) ? screenSize.width : frameSize.width);
    	setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
}

	

	public void selectedEvent() {
		for(int i = 0; i < candidateCards.length; i++)
			candidateCards[i].setEnabled(false);
		doneButton.setEnabled(true);
	}


	/**
	 * Adds relevant arguments to string from String array 
	 * 
	 * @param string
	 * @param names2
	 * @return
	 */
	private static String addArguments(String string, String[] names2) {
		for(int i=0;i<names2.length;i++)
			string = string.replaceAll("%"+(i+1), names2[i]);
		if(string.indexOf("@@") > -1) {
			string = addBreaks(string);
		}
		return string;
	}


	/**
	 * @param string
	 * @return
	 */
	private static String addBreaks(String string) {
		string = string.replaceAll("@@", "<br>");
		string = Cluedo.API.Constants.HTML_ON + string + Cluedo.API.Constants.HTML_OFF;
		return string;
	}
}
