package windows;

import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JLabel;

/**
 * Clase que representa el juego.
 * 
*/
public class MyGame {
    private String source;
    private String learning;			// Language of the game, Learning language
    private int i_s;						// 
    private int i_l;	
    private ArrayList<Category> categories;		// to hold all the words in the game (in all languages)
    private ArrayList<Word> words;				// to hold all the words in the game
    private ArrayList<Word> playing;				// to hold all the words in the game
    private int i_c;
    private Word correct;
    private int score;

    /**
    * Constructor publico.
    * 
    * Inicializa el objeto.
    */
    public MyGame(){
            categories = new ArrayList<Category>();
            words = new ArrayList<Word>();
            playing = new ArrayList<Word>();
    }
    /**
    * Agrega la categoria c al juego
    * @param c      nueva categoria
    */
    public void addCategory(Category c){
            categories.add(c);
    }
    /**
    * Retorna el nombre de una categoria especifica, señalada por el indice 'i'
    * @param i      indice de categoria, deberia ser siempre menor al numero de categorias almacenadas en el juego
    * @return nombre de la categoria 'i'
    */
    public String getCategory(int i){
        if (i < categories.size())
            return categories.get(i).getName();
        else
            return "Not added";
    }
    /**
    * Retorna lista completa de todas categorias agregadas al juego
    * @return categories    lista de categorias en el juego
    */
    public ArrayList<Category> getCategories(){
        return categories;
    }
    /**
    * Prueba logica para ver si la categoria de nombre 's' ya esta guardada en el juego
    * @param s      nombre de categoria a comprobar
    * @return true: la categoria ya fue agregada al juego | false: categoria no ha sido agregada al juego
    */
    public boolean categoryExist(String s){
            for (Category c:categories)
                    if (s.equalsIgnoreCase(c.getName()))
                            return true;
            return false;
    }
    /**
    * Agrega una palabra al juego, agregandola a la categoria que corresponda
    * @param w      palabra que se desea agregar
    */
    public void addWord(Word w){
            for (Category c:categories)
                    if (w.getCategory().equalsIgnoreCase(c.getName()))
                            c.addWord(w);
    }
    /**
    * Retorna el idioma nativo
    * @return source    idioma nativo
    */
    public String getSource(){
        return source;
    }
    /**
    * Retorna la palabra correcta
    * @return correct   palabra correcta en el juego actual
    */
    public Word getCorrect(){
        return correct;
    }
    /**
    * Retorna el indice del idioma a aprender
    * @return i_l   indice del idioma a aprender
    */
    public int getLearnIndex(){
        return i_l;
    }
    /**
    * Retorna el nombre de la categoria que se esta jugando
    * @return String con el nombre de la categoria que se este jugando
    */
    public String getCurrentCatName(){
        return categories.get(i_c).getName();
    }
    /**
    * Retorna el valor del puntaje acumulado en la categoria que se este jugando
    * @return score     puntaje acumulado en la categoria
    */
    public int getScore(){
        return score;
    }
    /**
    * Retorna lista de palabras que se estan jugando actualmente
    * @return playing       lista de palabra que se estan jugando
    */
    public ArrayList<Word> getPlaying(){
        return playing;
    }
    /**
    * Aumenta en uno el score de la categoria
    */
    public void upScore(){
        score++;
    }
    /**
    * Resetea el score
    */
    public void resetScore(){
        score = 0;
    }
    /**
    * Cambia el idioma nativo por 's'
    * @param s  nuevo idioma nativo a usar
    */
    public void setSource(String s){
            if (s.equalsIgnoreCase("Ingles"))
                    learning = "English";
            else if (s.equalsIgnoreCase("Español"))
                    learning = "Spanish";
            else
                source = s;
            for (Language m:words.get(0).getLanguages())
                    if (source.equalsIgnoreCase(m.getLanguage()))
                        i_s = m.getLangID();
    }
    /**
    * Cambia el idioma a aprender por 's'
    * @param s  nuevo idioma que se desea aprender
    */
    public void setLearning(String s){
            if (s.equalsIgnoreCase("Ingles"))
                    learning = "English";
            else if (s.equalsIgnoreCase("Japones"))
                    learning = "Japanese";
            else if (s.equalsIgnoreCase("Finlandes"))
                    learning = "Finnish";
            else if (s.equalsIgnoreCase("Español"))
                    learning = "Spanish";
            else
                learning = s;
            for (Language m:words.get(0).getLanguages())
                    if(learning.equalsIgnoreCase(m.getLanguage()))
                        i_l = m.getLangID();
    }
    /**
    * Cambia el idioma nativo de 'Español' a 'Ingles' o bien de 'Ingles' a 'Español'
    */
    public void toggleSource(){
        if (source.equalsIgnoreCase("English")){
            source = "Spanish";
            i_s = 1;
        }
        else if (source.equalsIgnoreCase("Spanish")){
            source = "English";
            i_s = 0;
        }
    }
    /**
    * Agrega las palabras de todas las categorias a una lista nueva
    */
    public void addWords(){
            for (Category c:categories)
                    words.addAll(c.getWords());
    }
    /**
    * Setea las palabras a usar en una pregunta del juego, elige la palabra correcta y las 3 palabras random en el idioma a aprender
    * Uno de los botones tendra la traduccion correcta de la palabra en idioma nativo
    * @param sWord      Label en donde va la palabra en el idioma nativo
    * @param jBAns0     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns1     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns2     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns3     Boton en donde va una palabra en el idioma que se desea aprender
    */
    public void setASK(JLabel sWord, JButton jBAns0, JButton jBAns1, JButton jBAns2, JButton jBAns3){
        Random rand = new Random();
        int n0, n1, n2;
        ArrayList<String> choosing = new ArrayList<String>();

        n0 = rand.nextInt(playing.size());			// Random number from 0 to playing list's size
        correct = playing.get(n0);				// Saves a reference to the word we'll ask about
        playing.remove(correct);				// Removes word 'correct' from 'playing' list

        do {
            n0 = rand.nextInt(words.size());
        } while (correct.equals(words.get(n0)));
        do {
            n1 = rand.nextInt(words.size());
        } while (correct.equals(words.get(n1)) || (n1 == n0));
        do {
            n2 = rand.nextInt(words.size());
        } while (correct.equals(words.get(n2)) || (n2 == n0) || (n2 == n1));

        choosing.add(correct.getLearningWord(i_l));
        choosing.add(words.get(n0).getLearningWord(i_l));
        choosing.add(words.get(n1).getLearningWord(i_l));
        choosing.add(words.get(n2).getLearningWord(i_l));
        Collections.shuffle(choosing);

        sWord.setText(correct.getSourceWord(i_s));
        jBAns0.setText(choosing.get(0));
        jBAns1.setText(choosing.get(1));
        jBAns2.setText(choosing.get(2));
        jBAns3.setText(choosing.get(3));
    }
    /**
    * Avanza a la siguient pregunta de la categoria actual
    * @param sWord      Label en donde va la palabra en el idioma nativo
    * @param jBAns0     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns1     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns2     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns3     Boton en donde va una palabra en el idioma que se desea aprender
    */
    public void nextWord(JLabel sWord, JButton jBAns0, JButton jBAns1, JButton jBAns2, JButton jBAns3){//, JButton jBNext){
        setASK(sWord, jBAns0, jBAns1, jBAns2, jBAns3);
    }
    /**
    * Revisa si ya se jugaron todas las palabras de la categoria actual
    * @return true: ya se jugaron todas las palabras  | false: aun quedan palabras en la categoria
    */
    public boolean isEndOfCategory(){
        return playing.isEmpty();
    }
    /**
    * Actuliza el score de puntos a un porcentaje de aprobacion
    */
    public void endCategory(){
        score = (100*score)/(categories.get(i_c).getWords().size());
    }
    /**
    * Empieza el juego con la categoria 'i'
    * @param i          indice de la categoria a jugar
    * @param sWord      Label en donde va la palabra en el idioma nativo
    * @param jBAns0     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns1     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns2     Boton en donde va una palabra en el idioma que se desea aprender
    * @param jBAns3     Boton en donde va una palabra en el idioma que se desea aprender
    */
    public void playCategory(int i, JLabel sWord, JButton jBAns0, JButton jBAns1, JButton jBAns2, JButton jBAns3){//, JButton jBNext){
        if(i >= categories.size())
            System.exit(0);
        score = 0;
        i_c = i;
        playing.addAll(categories.get(i).getWords());
        setASK(sWord, jBAns0, jBAns1, jBAns2, jBAns3);
    }
}
