//  Group D

package risk.engine.ai;

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

import java.util.*;

/**
 * <p> Class for AIHardPlayer </p>
 * @author SE Group D
 */

public class AIHardCapital extends AIHard {

	public String getPlaceArmies() {

		String output;

		    if ( game.NoEmptyCountries()==false ) {

			Continent[] cont = game.getContinents();

			/* ai attempts to gain control of a continent during initial placement */

			int territorynum = 0;
			int check = -1;
			String name="";
			int val = -1;

			for (int i=0; i<cont.length; i++) {
			    Vector ct = new Vector();
			    Continent co = cont[i];
			    ct = co.getTerritoriesContained();

			    for (int j=0; j<ct.size(); j++) {
			        if ( ((Country)ct.elementAt(j)).getOwner() == player ) { territorynum++; }
			    }

			    if (check <= territorynum) {
				check = territorynum;
				val = i;
			    }
			    territorynum = 0;
			}

			/* ..pick country from that continent */
			boolean picked = false;
			if (check > 0) {
			    Continent co = cont[val];
			    Vector ct = co.getTerritoriesContained();

			    for (int j=0; j<ct.size(); j++) {
				if ( ((Country)ct.elementAt(j)).getOwner() == null )  {
				    name=((Country)ct.elementAt(j)).getColor()+"";
				    picked = true;
				    break;
				}
			    }
			}

			if (picked == false) {
			    Continent co = cont[val];
			    Vector ct = co.getTerritoriesContained();

			    for (int j=0; j<ct.size(); j++) {
				if ( ((Country)ct.elementAt(j)).getOwner() == null )  {
				    name=((Country)ct.elementAt(j)).getColor()+"";

				    Vector v = ((Country)ct.elementAt(j)).getNeighbours();
				    for (int k=0; k<ct.size(); k++) {
					if (((Country)v.elementAt(k)).getOwner() != player) {
					    name=((Country)ct.elementAt(j)).getColor()+"";
					    break;
					}
				    }
				}
			    }
			}

			String str = expandBase(player.getTerritoriesOwned());
			if( !str.equals("none") )
                            name = str;

                        String s = blockOpponent(player);
                        if( !s.equals("none") )
                            name = s;

		        if (name.equals(""))
			    output = "autoplace";

		        else
			    output = "placearmies " + name +" 1";
		    }
		    else {

			Vector pt = player.getTerritoriesOwned();

			String name="";
			Country capital = player.getCapital();
			if (capital == null)
			    capital = findCapital();

			for (int a=0; a< pt.size() ; a++) {

			    if ( ownsNeighbours( (Country)pt.elementAt(a)) == false && ((Country)pt.elementAt(a)).getArmies() <= 11 ) {

                                name=((Country)pt.elementAt(a)).getColor()+"";
                                break;
                            }

		            if ( !(name.equals("")) ) { break; }

			}

			String st = attackCapital();
			if( !st.equals("") )
                            name = st;

                        String s = keepBlocking(player);
                        if( !s.equals("none") )
                            name = s;

                        String f = freeContinent(player);
                        if( !f.equals("none") )
                            name = f;

			String str = reinforceBase(capital);
			if (!str.equals(""))
			    name = str;

		        if ( name.equals("") )
			    output = "placearmies " + ((Country)pt.elementAt(0)).getColor() +" "+player.getExtraArmies();

		        else if (game.getSetup() )
			    output = "placearmies " + name +" "+player.getExtraArmies();

		        else
			    output = "placearmies " + name +" 1";
		    }

		return output;

	}


	public String getAttack() {

		String output="";

		    boolean chosen = false;
		    Continent[] cont = game.getContinents();
		Vector t = player.getTerritoriesOwned();
		Vector n;

		    for (int a=0; a< t.size(); a++) {
		        if ( ((Country)t.elementAt(a)).getArmies() > 1 ) {
			    if ( (Country)t.elementAt(a) != player.getCapital() ||
			    	t.size() == 1 ) {
				n = ((Country)t.elementAt(a)).getNeighbours();

				/* attack ratio set to 50% of attack force */

				int ratio = ((Country)t.elementAt(a)).getArmies();
				for (int b=0; b< n.size() ; b++) {
				    if ( ((Country)n.elementAt(b)).getOwner() != player && ((Country)n.elementAt(b)).getArmies() + (ratio / 2) < ratio  ) {
					output= "attack " + ((Country)t.elementAt(a)).getColor() + " " + ((Country)n.elementAt(b)).getColor();
				    }
				}
			    }
		        }
		    }

		    /* attempt to attack continent which is almost all owned, if scenario is there */

		    int count = 0;
		    Country attackfrom = null;
                    boolean complex = false;

                    for (int i=0; i<cont.length; i++) {

			if ( mostlyOwned( cont[i] ) == true) {

			    n = cont[i].getTerritoriesContained();

			    for (int j=0; j<n.size(); j++) {

				if ( ((Country)n.elementAt(j)).getArmies() > count
				    && ((Country)n.elementAt(j)).getOwner() == player
				    && ((Country)n.elementAt(j)) != player.getCapital()) {
					count = ((Country)n.elementAt(j)).getArmies();
					attackfrom = (Country)n.elementAt(j);
				}
			    }

			    for (int b=0; b< n.size() ; b++) {
				if ( ((Country)n.elementAt(b)).getOwner() != player && (((Country)n.elementAt(b)).getArmies()+1) < count && ((Country)n.elementAt(b)).isNeighbours(attackfrom) == true ) {
				    output= "attack " + attackfrom.getColor() + " " + ((Country)n.elementAt(b)).getColor();
				    complex = true;
				    break;
				}
			    }
			}
		    }

		    // else attempt to attack continent with the greatest territories owned, that has yet to be conquered.

		    if (complex == false) {
			int value = 0;
			Continent choice = null;

			for (int i=0; i<cont.length; i++) {

			    if ( cont[i].isOwned(player) == false) {

				n = cont[i].getTerritoriesContained();

				int check = 0;
				for (int j=0; j<n.size(); j++) {
				     if ( ((Country)n.elementAt(j)).getOwner() == player && (Country)n.elementAt(j) != player.getCapital())
					check++;
				}

				if (check > value)
				    choice = cont[i];
			    }
			}

			if (choice !=null) {

                            //System.out.println(choice.getName()); TESTING
			    n = ((Continent)choice).getTerritoriesContained();

			    for (int j=0; j<n.size(); j++) {

				if ( ((Country)n.elementAt(j)).getArmies() > count
				    && ((Country)n.elementAt(j)).getOwner() == player
				    && (Country)n.elementAt(j) != player.getCapital()) {
				    count = ((Country)n.elementAt(j)).getArmies();
				    attackfrom = (Country)n.elementAt(j);
				}
			    }

			    for (int b=0; b< n.size() ; b++) {
				if ( ((Country)n.elementAt(b)).getOwner() != player && (((Country)n.elementAt(b)).getArmies()+1) < count && ((Country)n.elementAt(b)).isNeighbours(attackfrom) == true ) {
				    output= "attack " + attackfrom.getColor() + " " + ((Country)n.elementAt(b)).getColor();
                                    break;
				}
			    }
			}
		    }

		    // check to see if there are any players to eliminate

		    Vector players = game.getPlayers();
                    Vector cankill = new Vector();

                    for (int i=0; i<players.size(); i++) {
			if (( (Player) players.elementAt(i)).getNoTerritoriesOwned() < 3 && ( (Player) players.elementAt(i)) != player)
			    cankill.addElement((Player) players.elementAt(i));
                    }

		    if (cankill.size() > 0) {
			for (int i=0; i<cankill.size(); i++) {
			Vector territories = ((Player) cankill.elementAt(i)).getTerritoriesOwned();
			for (int j=0; j<territories.size(); j++) {

			    Vector neighbours = ((Country)territories.elementAt(j)).getNeighbours();
                            for (int k=0; k<neighbours.size(); k++) {
				if (((Country) neighbours.elementAt(k)).getOwner() == player
				    && (((Country)territories.elementAt(j)).getArmies() + 1 < ((Country) neighbours.elementAt(k)).getArmies())
				    && (Country) neighbours.elementAt(k) != player.getCapital()) {
				    output= "attack " + ((Country) neighbours.elementAt(k)).getColor() + " " + ((Country)territories.elementAt(j)).getColor();
                                    //System.out.println("eliminate: " + output); TESTING
                                    break;
				}
			    }
			}
		    }
		}


		if ( output.equals("") ) {
		    output="endattack";
		}

		return output;

	}


	public String getBattleWon() {

		String output;

		   /* Attempt to safeguard critical areas when moving armies to won country */

		   Country attacker = game.getAttacker();
		   Continent continent = attacker.getContinent();
		   if (continent.isOwned(player) == true || mostlyOwned(continent) == true) {

		       /* Set 50% security limit */
		       if (attacker.getArmies() > 6)
		   	   output = "move " + (attacker.getArmies()-1);

		       else if (attacker.getArmies() > 3 && attacker.getArmies() <= 6)
			   output = "move " + (attacker.getArmies()-1);

		       else
			   output = "move all";
                   }
		   else {
		      output="move all";
		   }

		return output;

	}



	public String getCapital() {

		return "capital " + findCapital().getColor();

	}


	/**
	 * Checks if the player's capital has enough armies and checks if its neighbours has enough armies
	 * @param capital The capital country
	 * @return String Returns the name of the capital
	 */
	public String reinforceBase(Country capital) {
	 String str = "";
	 boolean foundCap = false;
	 Vector players = game.getPlayers();
	 for (int i=0; i<players.size(); i++) {
	    Player p2 = (Player) players.elementAt(i);
	    Country cap = p2.getCapital();
	    if (p2 == player)
		cap = capital;
	    if (cap != null && cap.getOwner() == player && cap.getArmies() < 8) {
		    str = cap.getColor()+"";
		    foundCap = true;
		    break;
	    }
	 }

	 if (foundCap == false) {
	    boolean found = false;
	    for (int i=0; i<players.size(); i++) {
		Player p2 = (Player) players.elementAt(i);
		Country cap = p2.getCapital();
		if (p2 == player)
		    cap = capital;
		if (cap != null && cap.getOwner() == player) {
		    Vector v = cap.getNeighbours();
		    for (int j=0; j<v.size(); j++) {
			Country c = (Country) v.elementAt(j);
			if (c.getOwner() == player && c.getArmies() < 4) {
			    str = c.getColor()+"";
			    found = true;
			    break;
			}
		    }
		}
		if (found == true)
		    break;
    	    }
         }
         return str;
	}


	/**
	 * get the best capital position for the current player
	 *
	 */
	public Country findCapital() {

		Vector pt = player.getTerritoriesOwned();
		Country country = null;
		int difference = 100;
		for (int i=0; i<pt.size(); i++) {
			int count = 0;
			Country c1 = (Country) pt.elementAt(i);
			Vector v = c1.getNeighbours();
			for (int j=0; j<v.size(); j++) {
				Country c2 = (Country) v.elementAt(j);
				if (c2.getOwner() == player) {
					count++;
				}
			}
			int temp = v.size() - count;
			if (temp < difference) {
				difference = temp;
				country = c1;
			}
			count = 0;
		}
		return country;

	}

    /**
     * Checks through the enemy's capital and finds a neighbouring territory owned by the reinforcing player
     * @return String Returns the name of the reinforcing territory
     */
    public String attackCapital() {
	String str = "";
	Vector players = game.getPlayers();
	Country capital = null;
	for (int i=0; i<players.size(); i++) {
	    Player p2 = (Player) players.elementAt(i);
	    capital = p2.getCapital();
	    if (capital != null && capital.getOwner() != player)
	    	break;
    	}
    	if (capital != null) {
	    Vector v = capital.getNeighbours();
	    for (int i=0; i<v.size(); i++) {
		Country c = (Country) v.elementAt(i);
		if (c.getOwner() == player) {
		    str = c.getColor()+"";
		    break;
	        }
	    }
        }
        return str;
    }

    /**
     * Checks through the player's current owned territories and picks a neighbour if it is free
     * @param pt The player's territories
     * @return String Returns the name of the country if found, returns "none" otherwise
     */
    public String expandBase(Vector pt) {
        String str = "none";
	boolean found = false;
	for (int i=0; i<pt.size(); i++) {
	    Country c1 = (Country) pt.elementAt(i);
	    Vector v = c1.getNeighbours();
	    for (int j=0; j<v.size(); j++) {
		Country c2 = (Country) v.elementAt(j);
		if (c2.getOwner() == null) {
		    str = c2.getColor()+"";
		    found = true;
		    break;
	        }
            }
	    if (found == true)
	        break;
        }
        return str;
    }

}
