// Yura Mamyrin

package risk.ui.SwingGUI;

import risk.engine.*;
import risk.engine.core.*;

import java.awt.event.WindowEvent;
import javax.swing.JDialog;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.event.MouseEvent;
import java.awt.Graphics;
import javax.swing.JPanel;
import java.awt.Toolkit;
import java.awt.Dimension;
import javax.swing.JLayeredPane;
import java.awt.event.MouseListener;
import javax.swing.JTextField;
import java.awt.Frame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTabbedPane;
import javax.swing.JCheckBox;
import javax.swing.JButton;
import java.awt.GridBagConstraints;
import java.awt.BorderLayout;
import javax.swing.AbstractListModel;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JToolBar;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.SpinnerNumberModel;
import javax.swing.JSpinner;
import javax.swing.JColorChooser;
import java.awt.Color;

/**
 * <p> Options Dialog for SwingGUI </p>
 * @author Yura Mamyrin
 */

public class MapEditorViews extends JDialog implements ActionListener {

    private RiskGame map;

    private JList countriesList;
    private JList continentsList;
    private JList cardsList;
    private JList missionsList;

    private JTabbedPane tabs;
    private String[] cardTypes;

    public MapEditorViews(Frame parent) {

        super(parent, "Map Editor Views", false);

	JToolBar optionspanel = new JToolBar();

	JButton add = new JButton("Add");
	add.setActionCommand("add");
	add.addActionListener( this );
	optionspanel.add(add);

	JButton remove = new JButton("Remove");
	remove.setActionCommand("remove");
	remove.addActionListener( this );
	optionspanel.add(remove);

	JButton edit = new JButton("Edit");
	edit.setActionCommand("edit");
	edit.addActionListener( this );
	optionspanel.add(edit);

	tabs = new JTabbedPane();

	countriesList = new JList( new CountriesListModel() );
	continentsList = new JList( new ContinentsListModel() );
	cardsList = new JList( new CardsListModel() );
	missionsList = new JList( new MissionsListModel() );

	tabs.addTab("Countries",new JScrollPane( countriesList ));
	tabs.addTab("Continents",new JScrollPane( continentsList ));
	tabs.addTab("Cards",new JScrollPane( cardsList ));
	tabs.addTab("Missions",new JScrollPane( missionsList ));

	getContentPane().add(optionspanel, BorderLayout.SOUTH);
	getContentPane().add(tabs);

	cardTypes = new String[4];
	cardTypes[0] = Card.CAVALRY;
	cardTypes[1] = Card.INFANTRY;
	cardTypes[2] = Card.CANNON;
	cardTypes[3] = Card.WILDCARD;

    }

    public void setMap(RiskGame m) {

	map = m;

	((ViewTab)countriesList.getModel()).changed();
	((ViewTab)continentsList.getModel()).changed();
	((ViewTab)cardsList.getModel()).changed();
	((ViewTab)missionsList.getModel()).changed();

    }

    public void actionPerformed(ActionEvent a) {

	ViewTab current = ((ViewTab)((JList)((javax.swing.JViewport)((JScrollPane)tabs.getSelectedComponent()).getViewport()).getView()).getModel());


	if (a.getActionCommand().equals("add")) {

		current.add();

	}
	else if (a.getActionCommand().equals("remove")) {

		current.remove();

	}
	else if (a.getActionCommand().equals("edit")) {

		current.edit();

	}	
	else {

		throw new RuntimeException(a.getActionCommand());

	}

    }

	public int openEdit(Object[] message) {

			String[] options = {
			    "OK", 
			    "cancel"
			}; 

			int result = JOptionPane.showOptionDialog( 
			    this,                             // the parent that the dialog blocks 
			    message,                                    // the dialog message array 
			    "Edit", // the title of the dialog window 
			    JOptionPane.OK_CANCEL_OPTION,                 // option type 
			    JOptionPane.PLAIN_MESSAGE,            // message type 
			    null,                                       // optional icon, use null to use the default icon 
			    options,                                    // options string array, will be made into buttons 
			    options[0]                                  // option that should be made into a default button 
			);

			return result;

	}

	interface ViewTab {

		void edit();
		void remove();
		void add();
		void changed();
	}


    class CountriesListModel extends AbstractListModel implements ViewTab {

	public void changed() {
		fireContentsChanged(this,0, map.getNoCountries()-1 );
	}

	public Object getElementAt(int index) {

		if (map==null) { return null; }
		return map.getCountries()[index];

	}

	public int getSize() {

		if (map==null) { return 0; }
		return map.getNoCountries();

	}

	public void edit() {

		int sel = countriesList.getSelectedIndex();

		if (sel != -1) {

			Country country = (Country)getElementAt(sel);

			Object[] message = new Object[4];
			message[0] = new JLabel("Name:");
			message[1] = new JTextField( country.getIdString().replace('_',' ') );
			message[2] = new JLabel("Continent:");
			message[3] = new JComboBox( map.getContinents() );

			((JComboBox)message[3]).setSelectedItem( country.getContinent() );

			int result = openEdit(message);

			if (result == JOptionPane.OK_OPTION ) {

				country.setIdString( ((JTextField)message[1]).getText().replace(' ','_') );
				country.setContinent( (Continent)((JComboBox)message[3]).getSelectedItem() );

				fireContentsChanged(this,sel, sel );

				//@todo needs to refresh the map
			}

		}

	}
	public void remove() {

	}
	public void add() {

	}

    }


    class ContinentsListModel extends AbstractListModel implements ViewTab {

	public void changed() {
		super.fireContentsChanged(this, 0, map.getNoContinents()-1 );
	}

	public Object getElementAt(int index) {

		if (map==null) { return null; }
		return map.getContinents()[index];

	}

	public int getSize() {

		if (map==null) { return 0; }
		return map.getNoContinents();

	}

	private Color editcolor;

	public void edit() {

		int sel = continentsList.getSelectedIndex();

		if (sel != -1) {

			Continent continent = (Continent)getElementAt(sel);

			final Object[] message = new Object[6];
			message[0] = new JLabel("Name:");
			message[1] = new JTextField( continent.getIdString().replace('_',' ') );
			message[2] = new JLabel("Army Value:");
			message[3] = new JSpinner( new SpinnerNumberModel(continent.getArmyValue(),0,100,1) );
			message[4] = new JLabel("Color (only used in the editor):");
			message[5] = new JButton("change");

			editcolor = continent.getColor();

			((JButton)message[5]).setBackground( editcolor );
			((JButton)message[5]).setForeground( Risk.getTextColorFor(editcolor) );

			((JButton)message[5]).addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent a) {

						Color newcolor = JColorChooser.showDialog(MapEditorViews.this,"select color",editcolor);

						if (newcolor!=null) {

							editcolor = newcolor;

							((JButton)message[5]).setBackground( editcolor );
							((JButton)message[5]).setForeground( Risk.getTextColorFor(editcolor) );
						}

					}
				}
			);

			int result = openEdit(message);

			if (result == JOptionPane.OK_OPTION ) {

				continent.setIdString( ((JTextField)message[1]).getText().replace(' ','_') );
				continent.setArmyValue( ((Integer)((JSpinner)message[3]).getValue()).intValue() );
				continent.setColor(editcolor);

				fireContentsChanged(this,sel, sel );

				//@todo needs to refresh the map
			}

		}

	}
	public void remove() {

	}
	public void add() {

	}

    }


    class CardsListModel extends AbstractListModel implements ViewTab {

	public void changed() {
		super.fireContentsChanged(this, 0, map.getNoCards()-1);
	}

	public Object getElementAt(int index) {

		if (map==null) { return null; }
		return map.getCards().elementAt(index);

	}

	public int getSize() {

		if (map==null) { return 0; }
		return map.getNoCards();

	}

	public void edit() {


		int sel = cardsList.getSelectedIndex();

		if (sel != -1) {

			Card card = (Card)getElementAt(sel);

			Country country = map.getCountryInt(sel+1);

			Object[] message = new Object[2];
			message[0] = new JLabel("Type:");

			if (country == null) {

				message[1] = new JComboBox( new String[] { Card.WILDCARD } );
			}
			else {

				message[1] = new JComboBox( cardTypes );
			}

			//message[2] = new JLabel("Country:");
			//message[3] = new JComboBox( map.getCountries() );

			((JComboBox)message[1]).setSelectedItem( card.getName() );
			//((JComboBox)message[3]).setSelectedItem( card.getCountry() );

			int result = openEdit(message);

			if (result == JOptionPane.OK_OPTION ) {

				String newtype = (String)((JComboBox)message[1]).getSelectedItem();

				card.setName(newtype);

				if (Card.WILDCARD.equals(newtype)) {
					card.setCountry(null);
				}
				else {
					//card.setCountry( (Country)((JComboBox)message[3]).getSelectedItem() );

					card.setCountry( country );
				}

				fireContentsChanged(this,sel, sel );

				//@todo needs to refresh the map
			}

		}

	}
	public void remove() {

	}
	public void add() {

	}

    }


    class MissionsListModel extends AbstractListModel implements ViewTab {

	public void changed() {
		super.fireContentsChanged(this, 0, map.getNoMissions()-1);
	}

	public Object getElementAt(int index) {

		if (map==null) { return null; }
		return map.getMissions().elementAt(index);

	}

	public int getSize() {

		if (map==null) { return 0; }
		return map.getNoMissions();

	}

	public void edit() {


		int sel = missionsList.getSelectedIndex();

		if (sel != -1) {

			Mission mission = (Mission)getElementAt(sel);

			Object[] message = new Object[14];
			message[0] = new JLabel("Player:");
			message[1] = new JComboBox( map.getPlayers() );

			message[2] = new JLabel("Number of countries:");
			message[3] = new JSpinner( new SpinnerNumberModel(mission.getNoofcountries(),0,100,1) );

			message[4] = new JLabel("Number of armies:");
			message[5] = new JSpinner( new SpinnerNumberModel(mission.getNoofarmies(),0,100,1) );

			message[6] = new JLabel("Continent 1:");
			message[7] = new JComboBox( map.getContinents() );

			message[8] = new JLabel("Continent 2:");
			message[9] = new JComboBox( map.getContinents() );

			message[10] = new JLabel("Continent 3:");
			message[11] = new JComboBox( map.getContinents() );

			message[12] = new JLabel("Discription:");
			message[13] = new JTextField( mission.getDiscription() );

			// set all the values from the current one
			((JComboBox)message[1]).setSelectedItem( mission.getPlayer() );

			((JComboBox)message[7]).setSelectedItem( mission.getContinent1() );
			((JComboBox)message[9]).setSelectedItem( mission.getContinent2() );
			((JComboBox)message[11]).setSelectedItem( mission.getContinent3() );


			int result = openEdit(message);

			if (result == JOptionPane.OK_OPTION ) {

				// update mission object

				fireContentsChanged(this,sel, sel );

				//@todo needs to refresh the map
			}

		}


	}
	public void remove() {

	}
	public void add() {

	}

    }



}

