 /* -----------------------------------------------------------------
    Alunos = Igor Betim de Freitas, Celso Alves, Germano Cunha Diogo
    Turma  = Paradigmas de Programacao - 71
    Prof.  = Gerson Cavalheiro
    ------------------------------------------------------------------*/

class competidor {

   protected int dist_percorrida, pot_lama, pot_areia,
                   pot_asfalto, pot_grama, pot_paralelepipedo;     
     
    /* --------------------------------------------------------
        Ja os atributos abaixo sao definidos com static, pois
        serao compartilhados para todos os objetos, ja que todos
        os objetos terao que percorrer o mesmo tamanho de cada
        segmento. Em resumo sao compartilhados por todos os objetos
        da mesma classe. Sao portanto, Membros de Classe
        ---------------------------------------------------------- */ 
   static int pos_final_lama, pos_final_areia, pos_final_grama,
              pos_final_paralelepipedo, pos_final_asfalto;                

     // Implementacao dos metodos da Classe
     
     // Construtor
   public competidor (int lama,
                      int areia,
                      int grama, 
                      int para, 
                      int asfalto) {
      pot_lama           = lama;
      pot_areia          = areia;
      pot_grama          = grama;
      pot_paralelepipedo = para;
      pot_asfalto        = asfalto;
      dist_percorrida    = 0;
   }
     // Retorna a posicao atual do corredor
   public int Retorna_Posicao() {
      return dist_percorrida;
   }
     
     /* --------------------------------------------------------
        O metodo a seguir recebe um segmento e seu tamanho e in-
        ca sua posicao final, assumindo que a ordem dos Segmentos
        a ser percorrida e Lama,Areia,Grama,Para.. e Asfalto
        --------------------------------------------------------- */
   static void Segmento_Percorrer (String Segmento, int tamanho) {
      if (Segmento == "Lama") {
         pos_final_lama = tamanho;
      }
      else if (Segmento == "Areia") {
         pos_final_areia = pos_final_lama + tamanho;
      }
      else if (Segmento == "Grama") {
         pos_final_grama = pos_final_areia + tamanho;
      }
      else if (Segmento == "Paralelepipedo") {
         pos_final_paralelepipedo = pos_final_grama + tamanho;
      }
      else if (Segmento == "Asfalto") {
         pos_final_asfalto = pos_final_paralelepipedo + tamanho;
      }
   } // Fim do metodo Segmentos a Percorrer       
     
     /* -------------------------------------------------------------
        A funcao deste metodo e retornar qual o potencial do Competi
        dor atualmente. Este nao e Static pois opera em um objeto
        -------------------------------------------------------------- */
   public int Potencial_Atual() {
      int pot_atual = 0;
      if (this.Retorna_Posicao() <= pos_final_lama) {
         pot_atual = pot_lama;
      }
      else if (this.Retorna_Posicao() <= pos_final_areia) {
         pot_atual = pot_areia;
      }
      else if (this.Retorna_Posicao() <= pos_final_grama) {
         pot_atual = pot_grama;
      }
      else if (this.Retorna_Posicao() <= pos_final_paralelepipedo) {
         pot_atual = pot_paralelepipedo;
      }
      else {
         pot_atual = pot_asfalto;
      }
      return pot_atual;
   }

     /* -------------------------------------------------------------
        A funcao deste metodo e retornar qual o proximo potencial do
        Competidor. Este nao e Static pois opera em um objeto
        -------------------------------------------------------------- */
   public int Proximo_Potencial() {
      int prx_potencial = 0;
      if (this.Retorna_Posicao() <= pos_final_lama) {
         prx_potencial = pot_areia;
      }
      else if (this.Retorna_Posicao() <= pos_final_areia) {
         prx_potencial = pot_grama;
      }
      else if (this.Retorna_Posicao() <= pos_final_grama) {
         prx_potencial = pot_paralelepipedo;
      }
      else {
         prx_potencial = pot_asfalto;
      }
      return prx_potencial;
   }             

     /* -------------------------------------------------------------
        A funcao deste metodo e retornar qual o tamanho do Segmento
        atual. Este nao e Static pois opera em um objeto
        -------------------------------------------------------------- */
   public int Tamanho_Atual() {
      int tam = 0;
      if (this.Retorna_Posicao() <= pos_final_lama) {
         tam = pos_final_lama;
      }
      else if (this.Retorna_Posicao() <= pos_final_areia) {
         tam = pos_final_areia;
      }
      else if (this.Retorna_Posicao() <= pos_final_grama) {
         tam = pos_final_grama;
      }
      else if (this.Retorna_Posicao() <= pos_final_paralelepipedo) {
         tam = pos_final_paralelepipedo;
      }
      else if (this.Retorna_Posicao() <= pos_final_asfalto) {
         tam = pos_final_asfalto;
      }
      return tam;
   }        

     /*------------------------------------------------------------------
       O metodo Caminha() faz a movimentacao do Competidor. Para isso ele
       so precisa saber em qual Segmento esta atualmente e se o numero de
       passos a ser percorrido alcanca um novo Segmento. Caso alcance, este
       numero de passos restante devera ser recalculado de acordo com o
       potencial do Competidor no proximo Segmento.
       Exemplo:
           Tamanho_Segmento_Atual      = 80
           Posicao_Atual_Competidor    = 60
           Numero de Passos a ser dado = 40
      Neste case o competidor ira caminhar 20 passos e chegara ao final do
      Segmento. Ele ainda tem mais 20 passos para dar porem no proximo
      Segmento o seu potencial e diferente. Entao fazemos um calculo
      proporcional usando uma simples regra de 3
                     20           pot_atual
                       ----------
                     X            proximo_potencial
      Ou seja, se 20 foi calculado tendo como base o potencial atual, a
      quantos passos equivalem no proximo potencial??
      Esse valor somado ao tamanho do potencial percorrido determinara
      a posicao do competidor.
     -------------------------------------------------------------------*/
   public void Caminha(int passos) {
      int distancia;
      distancia = dist_percorrida + (Potencial_Atual() * passos);
        /* --------------------------------------------------------------
           Agora verifica se o numero de passos a ser percorrido excede
           o segmento atual. 
           --------------------------------------------------------------- */
      if (distancia > Tamanho_Atual()){
         dist_percorrida = Tamanho_Atual() + ((int)
                            (distancia - Tamanho_Atual()) *
                            Proximo_Potencial() / Potencial_Atual());  
      }
      else{
         dist_percorrida = distancia;
      }
   }
}
