package risk.lobby.client;

import org.lobby.client.*;
import risk.ui.FlashGUI.FlashRiskAdapter;

import risk.engine.*;

import risk.engine.core.*;

import java.awt.Frame;
import java.awt.Dimension;
import java.util.Map;
import java.util.HashMap;
import javax.swing.JDialog;
import java.net.URL;

import java.applet.Applet;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.BorderFactory;
import javax.swing.JProgressBar;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class LobbyGameRisk extends Risk implements LobbyGame {

	private final static String product = "Risk Lobby Client";
	private final static String version = "0.1";

	private LobbyGameChatListener lgml;

	private String newGameOptions;

	private String mapsurl;
	private RiskMap[] maps;

	private JDialog dialog;
	private GameSetupPanel gsp;

	private String myid;

	public String getGameName() {

		return "Risk";

	}

	public LobbyGameRisk(Applet a) {
		super(a);

	}



	public GameSetup newGameDialog(Frame parent, String serveroptions,String myname) { // String serveroptions is a list of maps

		if (serveroptions!=null && !serveroptions.equals(newGameOptions) ) {

			newGameOptions = serveroptions;

			dialog = new JDialog(parent,"Loading...",true);
			final JLabel loadingmap = new JLabel();
			dialog.getContentPane().add(loadingmap);
			dialog.setSize(100,100);
			dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

			new Thread() {

			    public void run() {

				//String[] split = newGameOptions.split("\\n");

				String[] split = newGameOptions.split(",");

				maps = new RiskMap[split.length];
				int[] tries = new int[split.length];

				for (int c=0;c<split.length;c++) {

					tries[c]++;

					//String mapinfo[] = split[c].split("\\ ");

					//String displayName = split[c].substring(mapinfo[0].length() + mapinfo[1].length() + 2 , split[c].length() );

					try {

						maps[c] = new RiskMap( mapsdir, split[c] );

						loadingmap.setIcon( maps[c].getIcon() );

					}
					catch(Exception ex) {

						ex.printStackTrace();

						if (tries[c] < 5) { // retry

							c--;
							try { Thread.sleep(1000); } catch(Exception ex2) { }
						}
						else { // give up

							maps[c] = new RiskMap(split[c]);
						}


					}

				}
				JDialog d = dialog;
				dialog = null;

				d.setVisible(false);
				d.dispose();

			    }
			}.start();

			dialog.setVisible(true);


		}

		if (dialog == null) {


			dialog = new JDialog(parent,"Game Options",true);

			gsp = new GameSetupPanel(maps,dialog,myname+"'s "+getGameName()+" Game");

			// @todo:
			// do noting on close
			// when close then send event to gsp

			dialog.setContentPane(gsp);
			dialog.setResizable(false);
			dialog.pack();

		}


		dialog.setVisible(true);

		String op = gsp.getOptions();

		if (op!=null) { return new GameSetup( gsp.getName(), op, gsp.getNumberOfHumanPlayers() ); }

		return null;

	}















	private ChatBox chatbox;
	private PlayerList playerlist;
	private JButton startButton;
	private Frame frame;

	public void changeButtonAction(String label,String action) {

		startButton.setText(label);
		startButton.setActionCommand(action);

	}

	public void joinGame(String gameid, String name, String optionString, ChatBox cb,PlayerList pl) {

		chatbox = cb;
		playerlist = pl;

		myid = gameid;

		//setReplay(false);

		final Box sidepanel = new Box(javax.swing.BoxLayout.Y_AXIS);

		//@todo only show this if u r a actual player

		startButton = new JButton();

		startButton.addActionListener( new ActionListener() {

			public void actionPerformed(ActionEvent ae) {

				if (ae.getActionCommand().equals("start")) {

					parser("STARTGAME");

					//startButton.setVisible(false);

					changeButtonAction("Leave","leave");

				}
				else if (ae.getActionCommand().equals("leave")) {

					parser("closegame");
				}

			}

		});


		JButton aboutButton = new JButton( resb.getString( "mainmenu.about") );

		aboutButton.addActionListener( new ActionListener() {

			public void actionPerformed(ActionEvent ae) {

				Risk.openAbout(frame,product, version);

			}

		});


		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		JPanel panel3 = new JPanel();

		panel1.add( new JLabel(name) );
		panel2.add( new JProgressBar() );
		panel3.add( startButton );
		panel3.add( aboutButton );

		sidepanel.add( panel1 );
		sidepanel.add( panel2 );
		sidepanel.add( pl );
		sidepanel.add( panel3 );
		sidepanel.add( cb );

		ImageIcon borderimage = new ImageIcon( LobbyClientGUI.class.getResource("back.jpg") );

		panel2.setBorder( BorderFactory.createMatteBorder(20, 0, 20, 0, borderimage ) );
		panel3.setBorder( BorderFactory.createMatteBorder(20, 0, 20, 0, borderimage ) );
		sidepanel.setBorder( BorderFactory.createMatteBorder(20, 20, 20, 20, borderimage ) );

		pl.setPreferredSize( new Dimension(160,160) );
		pl.setMaximumSize( new Dimension(160,160) );
		sidepanel.setPreferredSize( new Dimension(200,200) );

		FlashRiskAdapter riskadapter = new FlashRiskAdapter(this) {

			public void addPlayer(int type, String name, java.awt.Color color, String ip) {}
			public void sendDebug(String a) {  } // System.out.println("\tRISK "+ a);

			public void noInput() {

				if (gameFrame!=null) {
					gameFrame.noInput();
				}
			}

			public void startGame(boolean s) {

				gameFrame.getContentPane().add(sidepanel, java.awt.BorderLayout.EAST );
				gameFrame.pack();

				try {
					pp.load();
				}
				catch (Exception e) {
					e.printStackTrace();
				}

				gameFrame.setup(s);

				gameFrame.setVisible(true);
				gameFrame.requestFocus();

				frame = gameFrame;

			}

			public void closeGame() {

				gameFrame.setVisible(false);

			}

		};


		try {

			game = new RiskGame();

		}
		catch (Exception ex) {

			throw new RuntimeException("unable to make game!",ex);

		}

		//newgame.doshit(optionString);

		// amoung other things, the newplayer command needs to be passed with option that matches this
		// computers Risk.myAddress, or the Risk game would not know when to ask for input

		String[] split = optionString.split("\\n");

		//setReplay(true);

		if (split[0].equals("GAME_JOIN_1")) {

			myAddress = split[1];

			if (myAddress.equals("spectator")) {

				changeButtonAction("Leave","leave");

			}
			else {

				changeButtonAction("Start","start");

			}

			for (int c=2;c<split.length;c++) {

				gameMessage(split[c]);

			}

		}
		else {

			throw new RuntimeException("no other method supported for joining game");

		}



	}

	public PlayerList getPlayerList() {

		return playerlist;

	}

	public ChatBox getChatBox() {

		return chatbox;

	}

	public void addLobbyGameMoveListener(LobbyGameChatListener lgl) {

		lgml = lgl;

	}

	// must catch all messages from the gui
	public void parser(String messagefromgui) {

		// myAddress needs to be set to the alias of the player logged in (no spaces)
		// the alias or "Risk.myAddress" can be added later

		// catch all closegames from any part of the GUI
		if ("closegame".equals(messagefromgui)) {

			lgml.leaveGame(myid);

			gameMessage(myAddress+" "+ messagefromgui);

		}
		else {

			lgml.sendGameMessage(myid,messagefromgui);

		}

	}

	public synchronized void gameMessage(String message) {

		System.out.println("\tGOT: "+message);

		inbox.add(message);
		this.notify();

	}

	// pass things from the inbot to the GameParser
	public void run() {

		String message;

		while (true) {

			synchronized(this) {

				if( inbox.isEmpty() ) {
					try { this.wait(); }
					catch(InterruptedException e){}
				}

				message = (String)inbox.remove(0);

			}

			super.GameParser(message);

		}
	}


	// catch anything the game sends here and do nothing with it
	public void GameParser(String mem) { }


/*
	public static void main(String[] argv) throws Exception { // TESTING METHOD!!!!


		// server sends
		// GameId = 1
		// GameName = Risk // maybe NOT
		// JarFile = Risk.jar // or a full URL
		// LobbyGame = risk.lobby.LobbyGameRisk
		// gameOptions = list of maps that can be used

		// create a new LobbyGame

		String name = "risk.lobby.LobbyGameRisk";
		Class myclass = Class.forName( name );
		LobbyGame lobbygame = (LobbyGame)myclass.newInstance();
		lobbygame.addLobbyGameMoveListener( new LobbyGameMoveListener() );

		//selected gametype Risk
		// clicked new game
		// need to make a new game string
		String newGameOptionString = lobbygame.newGameDialog( null , 

			"http://jrisk.sourceforge.net/applet/maps/\n"+
			"http://jrisk.sourceforge.net/images/maps/\n"+
			"board.map aa.jpg Risk Board\n" +
			"board.map board.jpg Risk Board\n" +
		//	"board.map chutes.jpg Risk Board\n" +
		//	"board.map conquest.jpg Risk Board\n" +
		//	"board.map cow.jpg Risk Board\n" +
		//	"board.map europass.jpg Risk Board\n" +
		//	"board.map fortress.jpg Risk Board\n" +
		//	"board.map france.jpg Risk Board\n" +
		//	"board.map geoscape.jpg Risk Board\n" +
			"risk2.map risk2.jpg Risk II"


		); // getParent

		System.out.println("GOT START GAME OPTIONS: "+newGameOptionString);



		// send it to the server

		// sever informs lobbs that new game is made

		// people can join

		// player who made it is autojoined and the game is removed from the list if everyone leaves

		// lobby sends...


		// game starts when it fills up
//		lobbygame.joinGame(game_id_from_server , newGameOptionString + playerinfo);

		// Risk object is onyl now created
		// options are passed to it
		// game starts



		// spectator comes in

	}
*/
}
