package pl8_ex2;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.Scanner;

/**
 *
 * @author TBM - APROG 2011/2012 1NB
 */
public class PL8_EX2 {

    static Formatter out = new Formatter(System.out);
    static Scanner in = new Scanner(System.in);
    static final String cartas="23456789TJQKA";

        
    // calcula o fatorial
    //
    private static long fatorial(long num) {
        long fact = 1;
        for (long i = num; i > 1; i = i - 1) {
            fact = fact * i;
        }
        return fact;
    }
    
    
    // lê a informação do ficheiro para um vetor de mãos
    //
    private static int lerFicheiro(String[][] vMaos) throws FileNotFoundException {
        String[] arr;
        String s;
        int i = 0;
        Scanner input = new Scanner(new File("maos.txt"));

        // enquanto tiver dados para ler
        while (input.hasNext()) {
            s = input.nextLine();
            arr = s.split(" "); // divide informação pelo espaço ' ' e coloca num vetor de Strings

            vMaos[i][0] = String.valueOf(arr[0].charAt(0));
            vMaos[i][1] = String.valueOf(arr[0].charAt(1));
            vMaos[i][2] = String.valueOf(arr[1].charAt(0));
            vMaos[i][3] = String.valueOf(arr[1].charAt(1));

            i++;
        }

        // fecha o ficheiro
        if (input != null) {
            input.close();
        }

        return i;
    }

    // visualisa o vetor de mãos
    //
    private static void visualizaMaos(String[][] vMaos, int n) {

        for (int i = 0; i < n; i++) {
            out.format("%s%s %s%s%n", vMaos[i][0], vMaos[i][1], vMaos[i][2], vMaos[i][3]);
        }
    }

    // escreve um ficheiro de teste
    //
    private static void escreveFichTeste() throws FileNotFoundException {
        Formatter output = new Formatter(new File("teste.txt"));

        output.format("%c %c %c %c %n", '\u2665', '\u2666', '\u2663', '\u2660');

        if (output != null) {
            output.close();
        }
    }

    // escreve o vetor de mõas ordenadas para ficheiro
    //
    private static void escreveFicheiroMaos(String[][] vMaos, int n) throws FileNotFoundException {
        Formatter output = new Formatter(new File("ordenadas.txt"));

        for (int i = 0; i < n; i++) {
            output.format("%s%s %s%s%n", vMaos[i][0], vMaos[i][1], vMaos[i][2], vMaos[i][3]);
        }

        if (output != null) {
            output.close();
        }
    }

    // verificar se uma dada carta de um dado naipe existe
    //
    private static boolean existeCarta(String[][] vMaos, int n, char carta, char naipe) {

        for (int i = 0; i < n; i++) {
            if (vMaos[i][0].charAt(0) == carta && vMaos[i][1].charAt(0) == naipe
                    || vMaos[i][2].charAt(0) == carta && vMaos[i][3].charAt(0) == naipe) {
                return true;
            }
        }

        return false;
    }

    // verificar se existem cartas fora de um determinado naipe
    // escreve para ficheiro se não existir
    private static void existeCartasEscreve(String[][] vMaos, int n, char naipe, Formatter f) {
        char carta;

        // ver se existem Ases
        if (!existeCarta(vMaos, n, 'A', naipe)) {
            f.format("%c%c", 'A', naipe);
        }

        // ver se existem Reis
        if (!existeCarta(vMaos, n, 'K', naipe)) {
            f.format("%c%c", 'K', naipe);
        }

        // ver se existem Damas
        if (!existeCarta(vMaos, n, 'Q', naipe)) {
            f.format("%c%c", 'Q', naipe);
        }

        // ver se existem Valetes
        if (!existeCarta(vMaos, n, 'J', naipe)) {
            f.format("%c%c", 'J', naipe);
        }

        // ver se existem T (dez)
        if (!existeCarta(vMaos, n, 'T', naipe)) {
            f.format("%c%c", 'T', naipe);
        }

        // ver se existem do 9 ao 2 (duque)
        for (int c = 9; c >= 2; c--) {
            carta = Character.forDigit(c, 10);

            if (!existeCarta(vMaos, n, carta, naipe)) {
                f.format("%c%c", carta, naipe);
            }
        }

    }

    // escreve em ficheiro as cartas que não constam das mãos
    //
    private static void escreveFicheiroCF(String[][] vMaos, int n) throws FileNotFoundException {
        Formatter output = new Formatter(new File("cartasfora.txt"));

        // copas
        existeCartasEscreve(vMaos, n, '\u2665', output);
        output.format("%n");

        // espadas  
        existeCartasEscreve(vMaos, n, '\u2660', output);
        output.format("%n");

        // ouros
        existeCartasEscreve(vMaos, n, '\u2666', output);
        output.format("%n");

        // paus
        existeCartasEscreve(vMaos, n, '\u2663', output);
        output.format("%n");

        if (output != null) {
            output.close();
        }
    }

    // compara duas mãos de cartas e devolve se a 1ª é maior, igual ou menor que a segunda 
    //
    private static int maiorParMao(char c11, char c12, char c21, char c22) {
        long peso_mao1,peso_mao2;
        
        // apurar o peso de cada mão através da soma do fatorial do seu índice
        peso_mao1=fatorial(cartas.indexOf(c11))+fatorial(cartas.indexOf(c12));
        peso_mao2=fatorial(cartas.indexOf(c21))+fatorial(cartas.indexOf(c22));
        
        if( peso_mao1 > peso_mao2 ){
            return 1;
        }
        else if( peso_mao1 < peso_mao2 ){
            return -1;
        }
                
        return 0;
    }

    // escreve em ficheiro as cartas que não constam das mãos
    //
    private static void ordenarMaos(String[][] vMaos, int n) {
        String aux;

        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                if (maiorParMao(vMaos[i][0].charAt(0), vMaos[i][2].charAt(0),
                                vMaos[j][0].charAt(0), vMaos[j][2].charAt(0)) < 0) {

                    // troca a 1 carta
                    aux = vMaos[i][0];
                    vMaos[i][0] = vMaos[j][0];
                    vMaos[j][0] = aux;

                    aux = vMaos[i][1];
                    vMaos[i][1] = vMaos[j][1];
                    vMaos[j][1] = aux;

                    // troca a 2 carta
                    aux = vMaos[i][2];
                    vMaos[i][2] = vMaos[j][2];
                    vMaos[j][2] = aux;

                    aux = vMaos[i][3];
                    vMaos[i][3] = vMaos[j][3];
                    vMaos[j][3] = aux;
                }

            }
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        int nelem;
        String[][] vMaos = new String[10][4];

        //criar um ficheiro de teste
        escreveFichTeste();

        // le do ficheiro
        nelem = lerFicheiro(vMaos);
        System.out.println(nelem);
        visualizaMaos(vMaos, nelem);

        // ordena as mãos
        ordenarMaos(vMaos, nelem);

        // cria o novo ficheiro com as mãos ordenadas
        escreveFicheiroMaos(vMaos, nelem);

        // cria o novo ficheiro com as cartas fora
        escreveFicheiroCF(vMaos, nelem);
    }
}
