import java.util.ArrayList; 
import java.io.*;
import java.awt.Color;
import java.util.Observable;
// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.87B45317-FB11-DA8E-4BF8-8F3975FE4E4D]
// </editor-fold> 
public class Jugador extends Observable{

    private int idJugador;
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.12C9C19C-30E7-B7D8-6797-CF1088C69EE7]
    // </editor-fold> 
    private Partida mPartida;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.B2B6D814-958D-A046-83BA-70C14FE423D2]
    // </editor-fold> 
    private int numEjercitos;
    
    private int numCanjes;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.53B8BA4C-D201-04E0-830D-2A761F8FA65C]
    // </editor-fold> 
    private String nombre;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.FD3420E0-E390-9ADE-4FFF-094DED8D6603]
    // </editor-fold> 
    private Carta_Mision mCarta_Mision;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.21FDBD7B-7A2D-DA68-3028-9171D334EEA1]
    // </editor-fold> 
    private ArrayList<Carta_Territorio> mCarta_Territorio;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.573DB772-DF00-6CC6-8135-A57751394B3D]
    // </editor-fold> 
    private ArrayList<Territorio> mTerritorio;
    
    private ArrayList<Continente> mContinente;
    
    private int numContinente;
    
    private int numCartas;
    
    private int numTerritorios;
    
    private Color color;

    private boolean primerTurno=true; // true si esta en el primer turno o false si no lo esta
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.193F1C92-226A-D1F6-BBBF-F13D2273A37A]
    // </editor-fold> 
    public Jugador () {
    }

    public Jugador(int numEjer, String nom, int id, Color col){
        numEjercitos=numEjer;
        nombre=nom;
        idJugador=id;
        numCanjes=0;
        color=col;
       // mPartida=val;
    }
    
    public Jugador(Jugador j){
        this.nombre=j.getNombre();
        this.numEjercitos=j.getNumEjercitos();
    }
    
    public int getnumContinentes(){
        return numContinente;
    }
    public void setnumContinentes(){
        numContinente++;
    }
    
    public int getnumCartas(){
        return numCartas;
    }
    public void setnumCartas(){
        numCartas++;
    }
    public int getnumTerritorios(){
        return numTerritorios;
    }
    public void setnumTerritorios(){
        numTerritorios++;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.371650CA-5B67-148F-5892-7665205F178B]
    // </editor-fold> 
    public int getNumEjercitos () {
        return numEjercitos;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.0EB2599D-EFB1-AD57-77AD-55A0DA8D05FB]
    // </editor-fold> 
    public void setNumEjercitos (int val) {
        numEjercitos=val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.F666CDD4-7BAF-0FD9-752F-B2F1F588CE4F]
    // </editor-fold> 
    public Carta_Mision getCarta_Mision () {
        return mCarta_Mision;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.BF63CDA9-1445-203C-3325-7A21680AEB86]
    // </editor-fold> 
    public ArrayList<Carta_Territorio> getCarta_Territorio () {
        return mCarta_Territorio;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.DC535877-5BA8-7D94-2C21-C1B05C317743]
    // </editor-fold> 
    public void setCarta_Territorio (ArrayList<Carta_Territorio> val) {
        this.mCarta_Territorio = val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.2B9172DD-5F6F-9D83-EE12-A9464CB132D4]
    // </editor-fold> 
    public ArrayList<Territorio> getTerritorio () {
        return mTerritorio;
    }
    public Territorio getTerritorio(int idt){
       boolean dev=false;
       int i;
       Territorio t=null;
       for(i=0;i<mPartida.getNumTerritorios() && dev==false;i++){
          Territorio t1=mPartida.getTerritorio().get(i);
          if(t1.getIdTerritorio()==idt){
             dev=true;
             t=t1;
          }
       }
       return t;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.8DC34B73-6816-99E8-22B1-8E5C4B923F75]
    // </editor-fold> 
    public void setTerritorio (ArrayList<Territorio> val) {
        this.mTerritorio = val;
        numTerritorios=mTerritorio.size();
    }
    
     public Continente getContinente(int idc){
       boolean dev=false;
       int i;
       Continente c=null;
       for(i=0;i<mPartida.getNumContinentes() && dev==false;i++){
          Continente c1=mPartida.getContinente().get(i);
          if(c1.getIdContinente()==idc){
             dev=true;
             c=c1;
          }
       }
       return c;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.8DC34B73-6816-99E8-22B1-8E5C4B923F75]
    // </editor-fold> 
    public void setContinente (ArrayList<Continente> val) {
        this.mContinente = val;
        numContinente=mContinente.size();
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.69895A14-2CA4-1F20-B4F0-9693D370E3AA]
    // </editor-fold> 
    public String getNombre () {
        return nombre;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.2D49BB75-1404-8B3A-574A-4B635E4D6DC8]
    // </editor-fold> 
    public void setNombre (String val) {
        this.nombre = val;
    }
 
    
    public void setCarta_Mision (Carta_Mision val) {
        this.mCarta_Mision = val;
    }
    
    public void finalizarTurno () {
        this.setPrimerTurno(false);
        System.out.println("Soy el jugador "+this.nombre+". He terminado mi turno.\n"); 
        mPartida.cambiarJugadorActivo();
        mPartida.getJugador(mPartida.getJugadorActivo()).RecalcularEjercitos();
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.6F9C923B-E71D-8228-9723-556C2C71EEAB]
    // </editor-fold> 
    public Partida getPartida () {
        return mPartida;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.3ED7DED1-7807-50C3-45D7-23ACEA6DA72E]
    // </editor-fold> 
    public void setPartida (Partida val) {
        this.mPartida = val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.C6ECC7B0-F6F4-6D44-AD10-FE3614E8F0F0]
    // </editor-fold> 
    /*public void ubicarEjercitos () {
        int i=0;
        int j=0;
        while(numEjercitos>0){
            mTerritorio.get(i).aumentarNumEjercitos(1);
            numEjercitos=numEjercitos-1;
            i++;
            if(i==numTerritorios)
                i=0;  
        }
        mPartida.muestraTerritorios();
        System.out.println("\nYa no quedan ejercitos por ubicar.");
    }*/
    
    public boolean algunoDesocupado(){
        int i;
        boolean dev=false;
        for(i=0; i<numTerritorios && dev==false; i++){
            if(mTerritorio.get(i).getNumEjercitos()==0)
                dev=true;
        }
        return dev;
    }
    
    public void ubicarEjercitos(){
        BufferedReader teclado= new BufferedReader(new InputStreamReader(System.in));
        int idTer, num=this.numEjercitos;
        boolean b=false;
        Territorio ter=null;
        if(this.getNumEjercitos()==0){
            System.out.println("No dispone de ejercitos para ubicar.");
        }
        else{        
            while(b==false || num>0){
                System.out.println("Posee "+this.getNumEjercitos()+" ejercitos disponibles, tiene que ubicarlos.");
                try{
                    System.out.println("Introduzca el numero de terriorio al que desea añadir un ejercito: "); 
                    idTer=Integer.parseInt(teclado.readLine());
                    b=this.PoseoTerritorio(idTer);
                    if(b==false){
                        System.out.println("El territorio no le pertenece, introduzca a otro.");
                    }
                    else{
                        Territorio aux=this.getTerritorio(idTer);
                        if(aux.getNumEjercitos()>0 && algunoDesocupado()==true){
                            System.out.println("Tiene territorios sin ocupar, introduzca otro.");
                        }
                        else{
                            aux.aumentarNumEjercitos(1);
                            num--;
                            this.numEjercitos--;
                            System.out.println("Se ha ubicado un ejercito en el territorio "+aux.getNomTerritorio());
                            mPartida.muestraTerritorios();
                            if(num==0)
                                System.out.println("Ha ubicado todos los ejercitos.");
                        }
                    }
                }
                catch(IOException e){
                    System.out.println(e);
                }
            }
        }
         
    }
    
    
    public boolean PoseoTerritorio(int idt){
       boolean dev=false;
       int i;
       for(i=0;i<this.numTerritorios && dev==false;i++){
          if(mTerritorio.get(i).getIdTerritorio()==idt){
             dev=true;
          }
       }
       return dev;
    }
    
    
    public void RecalcularEjercitos(){ //metodo que recalcule los ejercitos disponibles y me los devuelva
      int enc=0;
      int numejedisp=this.getnumTerritorios()/3;
      if(mContinente!=null){
        for(int i=0;i<numContinente;i++){
          numejedisp=numejedisp+mContinente.get(i).getBonificacion();
          for(int j=0;j<numCartas && enc==0;j++){
            //if( mContinente.get(i).getNomContinente()==mCarta_Territorio.get(j).getNomCarta() ){

              if( mContinente.get(i).getNomContinente().compareTo(mCarta_Territorio.get(j).getNomCarta())==0 ){
               enc=1;
               numejedisp=numejedisp+2;
            }
          }
        }
        if(numCanjes==1)
            numejedisp=numejedisp+4;
        if(numCanjes==2)
            numejedisp=numejedisp+6;
        if(numCanjes==3)
            numejedisp=numejedisp+8;
        if(numCanjes==4)
            numejedisp=numejedisp+10;
        if(numCanjes==5)
            numejedisp=numejedisp+12;
        if(numCanjes==6)
            numejedisp=numejedisp+15;
        if(numCanjes>6)
            numejedisp=numejedisp+15+((numCanjes-6)*5);
        
      }
      
      this.setNumEjercitos(numejedisp);
    }
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.C89952CF-AC89-A5F5-45F9-CC4F1275EEA5]
    // </editor-fold> 
    public void atacarTerritorio () {
        if(this.primerTurno==false){
            mPartida.muestraTerritorios();
            BufferedReader teclado= new BufferedReader(new InputStreamReader(System.in));
            int idTerr1=0,idTerr2=0;
            int nejAt=0,nejDe=0; 
            int[] lat,lde;
        
            Territorio terr1=null,terr2=null;
            boolean b=false;
            do{
                try{
                    System.out.println("Introduzca el identificador del territorio atacante: ");
                    idTerr1=Integer.parseInt(teclado.readLine());
                    b=this.PoseoTerritorio(idTerr1);
                    //nejerc=this.getTerritorio(idTerr1).getNumEjercitos();
                    if(b==false)
                        System.out.println("El territorio introducido no le pretenece, introduzca otro");
                    else{
                        Territorio aux=this.getTerritorio(idTerr1);
                        nejAt=aux.getNumEjercitos();
                        if(nejAt>1){
                            terr1=aux;
                        }
                        else
                            System.out.println("El territorio elegido no tiene suficientes ejercitos para atacar, introduzca otro.");
                    }
                }
                catch(IOException e){
                    System.out.println(e);
                }
            }while(b==false || nejAt==1);
            terr1.mostrarTerrAdy();
            do{
                try{
                    System.out.println("Introduzca el identificador del territorio atacado: ");
                    idTerr2=Integer.parseInt(teclado.readLine());
                    b=PoseoTerritorio(idTerr2);
                    if(b==true)
                        System.out.println("El territorio introducido le pretenece, introduzca otro");
                    else{
                        Territorio aux=mPartida.getTerritorio().get(idTerr2-1);
                        nejDe=aux.getNumEjercitos();
                        if(terr1.adyacente(idTerr2)==true){
                            terr2=aux;
                        }
                        else
                            System.out.println("El territorio que desea atacar no es adyacente, introduzca otro");
                    }
                }
                catch(IOException e){
                    System.out.println(e);
                }
            }while(b==true || terr1.adyacente(idTerr2)==false);
        
            Dado d=new Dado();
            if(nejAt>=3){
                lat=d.getTirada(3);
                if(nejDe>=2)
                    lde=d.getTirada(2);
                else
                    lde=d.getTirada(1);
            }
            else{
                if(nejDe>=2){
                    lat=d.getTirada(1);
                    lde=d.getTirada(2);
                }
                else{
                    lat=d.getTirada(2);
                    lde=d.getTirada(1);
                }
            }
            System.out.println("Tirada de ataque del territorio "+terr1.getNomTerritorio()+":");
            System.out.println("-----------------");
            int i;
            for(i=0;i<lat.length;i++)
                System.out.println("Dado "+(i+1)+" :"+lat[i]);
            System.out.println("Tirada de defensa del territorio "+terr2.getNomTerritorio()+":");
            System.out.println("-----------------");
            for(i=0;i<lde.length;i++)
                System.out.println("Dado "+(i+1)+" :"+lde[i]);
            int[] disminuye=d.comparar(lat, lde);
            System.out.println("El territorio "+terr1.getNomTerritorio()+" pierde "+disminuye[0]+" ejercitos.");
            System.out.println("El territorio "+terr2.getNomTerritorio()+" pierde "+disminuye[1]+" ejercitos.");
            terr1.disminuirNumEjercitos(disminuye[0]);
            terr2.disminuirNumEjercitos(disminuye[1]);
            if(terr2.getNumEjercitos()==0){
                System.out.println("\nSe ha conquistado el territorio "+terr2.getNomTerritorio());
                invadirTerritorio();
            }
        }
        else
            System.out.println("No puede atacar, los demas jugadores deben situar sus ejercitos.");
        
        setChanged();
        notifyObservers();
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.90E9EFA7-0AED-7580-1988-EABEA30248F7]
    // </editor-fold> 
    public void invadirTerritorio () {
        System.out.println("\nLa opcion de invadir territorio aun no esta implementada");
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.840B6385-AEFF-085B-0FBE-ECA7239C3B06]
    // </editor-fold> 
    public void terminarAtaque () {
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.03876686-AE2E-BDC9-7157-0E60350C0C9A]
    // </editor-fold> 
    public void transferirEjercitos () {
        mPartida.muestraTerritorios();
        BufferedReader teclado= new BufferedReader(new InputStreamReader(System.in));
        int idTerr1=0,idTerr2=0;
        Territorio terr1=null,terr2=null;
        int nejorigen=0, nejdestino=0, nejtrans=0;
        boolean b=false, ad=false;
        do{
           try{
                System.out.println("Introduzca el identificador del territorio de origen: ");
                idTerr1=Integer.parseInt(teclado.readLine());
                b=this.PoseoTerritorio(idTerr1);
                //nejerc=this.getTerritorio(idTerr1).getNumEjercitos();
                if(b==false)
                    System.out.println("El territorio introducido no le pretenece, introduzca otro");
                else{
                    Territorio aux=this.getTerritorio(idTerr1);
                    nejorigen=aux.getNumEjercitos();
                    if(nejorigen==1){
                        System.out.println("El territorio elegido no tiene suficientes ejercitos para transferir, introduzca otro.");   
                    }
                    else{
                        ad=aux.jugAdyacentes();
                        if(ad==false)
                            System.out.println("No posee territorios adyacentes a este territorio, introduzca otro");
                        else
                            terr1=aux;
                    }
                }
           }
           catch(IOException e){
             System.out.println(e);
           }
        }while(b==false || nejorigen==1 || ad==false);
        terr1.mostrarTerrAdy();
        
        do{
            try{
               System.out.println("Introduzca el identificador del territorio de destino: ");
               idTerr2=Integer.parseInt(teclado.readLine());
               b=PoseoTerritorio(idTerr2);
               if(b==false)
                System.out.println("El territorio introducido no le pretenece, introduzca otro");
               else{
                   Territorio aux=mPartida.getTerritorio().get(idTerr2-1);
                   nejdestino=aux.getNumEjercitos();
                   if(terr1.adyacente(idTerr2)==true){
                        terr2=aux;
                   }
                   else
                       System.out.println("El territorio de destino no es adyacente, introduzca otro");
               }
            }
           catch(IOException e){
               System.out.println(e);
           }
        }while(b==false || terr1.adyacente(idTerr2)==false);
        
        try{
            int aux=terr1.getNumEjercitos();
            do{
                System.out.println("Introduzca el numero de ejercitos de desee transferir: ");
                nejtrans=Integer.parseInt(teclado.readLine());
                if(nejtrans>=aux)
                    System.out.println("El territorio no tiene suficientes ejercitos para el numero que ha introducido, introduzca otro.");
                else{
                    terr1.disminuirNumEjercitos(nejtrans);
                    terr2.aumentarNumEjercitos(nejtrans);
                }
            }while(nejtrans>=aux);
        }
        catch(IOException e){
            System.out.println(e);
        }
        
        setChanged();
        notifyObservers();
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.BA2BFEBC-A035-D85B-B2C0-C516660C4DC5]
    // </editor-fold> 
    public void verCartas () {
       int i;
       for(i=0;i<this.numCartas;i++)
          System.out.println(this.mCarta_Territorio.get(i).getNomCarta());
       setChanged();
       notifyObservers();
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.C3D121FB-E2C5-8A08-8CA3-04CF014727CC]
    // </editor-fold> 
    public void cambiarCartas () {
    }

    public int getIdJugador(){
        return idJugador;
    }
    
    public void setIdjugador(int val){
        idJugador=val;
    }

    public boolean isPrimerTurno() {
        return primerTurno;
    }

    public void setPrimerTurno(boolean primerTurno) {
        this.primerTurno = primerTurno;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    
    
    
}

