package com.iutlaval.myapplication.Game.Cards;

import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Charlemagne;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_CharlesV;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_CharlesVII;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Chretien_De_Troyes;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Christine;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Clovis;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Croisade;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Etienne;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Ferré;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Guerre_100;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Guillaume;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Heresie_Cathares;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Hugue;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Isabelle;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Jean;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Jean_Vienne;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Jeanne;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Louis;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Malediction_Templier;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Peste;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Philippe;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_PhilippeIV;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Philippe_Cacqueray;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Pierre;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Pierre_Ermite;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Pouvoir_Du_Franc;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Prise_Sainte_Terre;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Roland;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Sire_Jean;
import com.iutlaval.myapplication.Game.Cards.MoyenAge.Moyen_Age_Traite_Verdun;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_12_Travaux;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Achille;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Amazones;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Castor_Pollux;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Chant_Sirene;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Chaos;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Cheval_Troie;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Chiron;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Dédale;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Enigme_Sphinx;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Eole;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Erinyes;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Guerre_Sept_Chefs;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Hades;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Heracles;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Hermione;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Icar;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Kunée;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Minos;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Oedipie;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Perséphone;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Poseidon;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Psyché;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Rapt;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Sémélé;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Thanatos;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Titanomachie;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Toison;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Zeus;
import com.iutlaval.myapplication.Game.Cards.Mythes.Mythes_Zeus_VS_Typhon;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Charles;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Chatherine;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Chute_Constantinople;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Concile_Trente;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Constantin;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Copernic;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Decouverte_Amerique;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Elisabeth;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Ferdinand;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Fin_Guerre_Cent_Ans;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Francois;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Guerres_Italie;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Henri;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Henri_8;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Isabelle;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Ivan;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Leonard;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Machiavel;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Mehmet;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Michel_Ange;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Nobunaga;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Presse_Imprimer;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Rabelais;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Reforme;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Shakespeare;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Skanderberg;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Soliman;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Casimir;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Succession_Bourgogne;
import com.iutlaval.myapplication.Game.Cards.Renaissance.Renaissance_Vlad;

import java.util.ArrayList;
import java.util.List;

/**
 * registre de carte identique a celui du serveur permet la déserialisation des decks et cartes
 * par example si le serveur envoie un messange du genre : destruire 0
 * on comprendera detruire Mythes_Perséphone
 */
public class CardRegistery {
    public static List<Class<? extends Card>> registry;

    /**
     * initialise le registre des carte
     */
    private static void initCardRegistery()
    {
        registry = new ArrayList<>();

        //Ce sont les cartes du deck Mythes et légendes grecs
        //Créatures
        registry.add(Mythes_Perséphone.class);
        registry.add(Mythes_Chiron.class);
        registry.add(Mythes_Dédale.class);
        registry.add(Mythes_Erinyes.class);
        registry.add(Mythes_Oedipie.class);
        registry.add(Mythes_Thanatos.class);
        registry.add(Mythes_Zeus.class);
        registry.add(Mythes_Hades.class);
        registry.add(Mythes_Poseidon.class);
        registry.add(Mythes_Chaos.class);
        registry.add(Mythes_Heracles.class);
        registry.add(Mythes_Achille.class);
        registry.add(Mythes_Minos.class);
        registry.add(Mythes_Psyché.class);
        registry.add(Mythes_Castor_Pollux.class);
        registry.add(Mythes_Sémélé.class);
        registry.add(Mythes_Hermione.class);
        registry.add(Mythes_Amazones.class);
        registry.add(Mythes_Eole.class);
        //Sorts
        registry.add(Mythes_Titanomachie.class);
        registry.add(Mythes_12_Travaux.class);
        registry.add(Mythes_Icar.class);
        registry.add(Mythes_Chant_Sirene.class);
        registry.add(Mythes_Rapt.class);
        registry.add(Mythes_Toison.class);
        registry.add(Mythes_Zeus_VS_Typhon.class);
        registry.add(Mythes_Enigme_Sphinx.class);
        registry.add(Mythes_Cheval_Troie.class);
        registry.add(Mythes_Kunée.class);
        registry.add(Mythes_Guerre_Sept_Chefs.class);

        //Cartes du deck Rennaissance
        //créatures
        registry.add(Renaissance_Soliman.class);
        registry.add(Renaissance_Francois.class);
        registry.add(Renaissance_Charles.class);
        registry.add(Renaissance_Casimir.class);
        registry.add(Renaissance_Henri.class);
        registry.add(Renaissance_Henri_8.class);
        registry.add(Renaissance_Constantin.class);
        registry.add(Renaissance_Mehmet.class);
        registry.add(Renaissance_Copernic.class);
        registry.add(Renaissance_Leonard.class);
        registry.add(Renaissance_Michel_Ange.class);
        registry.add(Renaissance_Rabelais.class);
        registry.add(Renaissance_Machiavel.class);
        registry.add(Renaissance_Ivan.class);
        registry.add(Renaissance_Elisabeth.class);
        registry.add(Renaissance_Vlad.class);
        registry.add(Renaissance_Nobunaga.class);
        registry.add(Renaissance_Chatherine.class);
        registry.add(Renaissance_Ferdinand.class);
        registry.add(Renaissance_Isabelle.class);
        registry.add(Renaissance_Skanderberg.class);
        registry.add(Renaissance_Shakespeare.class);
        //sorts
        registry.add(Renaissance_Fin_Guerre_Cent_Ans.class);
        registry.add(Renaissance_Guerres_Italie.class);
        registry.add(Renaissance_Chute_Constantinople.class);
        registry.add(Renaissance_Presse_Imprimer.class);
        registry.add(Renaissance_Decouverte_Amerique.class);
        registry.add(Renaissance_Concile_Trente.class);
        registry.add(Renaissance_Succession_Bourgogne.class);
        registry.add(Renaissance_Reforme.class);

        //Cartes du deck Moyen-age
        //créatures
        registry.add(Moyen_Age_Clovis.class);
        registry.add(Moyen_Age_Charlemagne.class);
        registry.add(Moyen_Age_Hugue.class);
        registry.add(Moyen_Age_Philippe.class);
        registry.add(Moyen_Age_Louis.class);
        registry.add(Moyen_Age_CharlesV.class);
        registry.add(Moyen_Age_CharlesVII.class);
        registry.add(Moyen_Age_PhilippeIV.class);
        registry.add(Moyen_Age_Jeanne.class);
        registry.add(Moyen_Age_Jean.class);
        registry.add(Moyen_Age_Pierre.class);
        registry.add(Moyen_Age_Etienne.class);
        registry.add(Moyen_Age_Ferré.class);
        registry.add(Moyen_Age_Isabelle.class);
        registry.add(Moyen_Age_Jean_Vienne.class);
        registry.add(Moyen_Age_Sire_Jean.class);
        registry.add(Moyen_Age_Philippe_Cacqueray.class);
        registry.add(Moyen_Age_Guillaume.class);
        registry.add(Moyen_Age_Christine.class);
        registry.add(Moyen_Age_Chretien_De_Troyes.class);
        registry.add(Moyen_Age_Pierre_Ermite.class);
        registry.add(Moyen_Age_Roland.class);
        //sorts
        registry.add(Moyen_Age_Traite_Verdun.class);
        registry.add(Moyen_Age_Peste.class);
        registry.add(Moyen_Age_Croisade.class);
        registry.add(Moyen_Age_Guerre_100.class);
        registry.add(Moyen_Age_Malediction_Templier.class);
        registry.add(Moyen_Age_Prise_Sainte_Terre.class);
        registry.add(Moyen_Age_Heresie_Cathares.class);
        registry.add(Moyen_Age_Pouvoir_Du_Franc.class);
    }

    /**
     * retourne l'index de la carte donné
     * et lance une runtime exception si la carte n'existe pas car cela veut dire que le serveur
     * est incompatible avec le client
     * @param class1 class de la carte recherché
     * @return index de la carte
     */
    public static int indexOf(Class<? extends Card> class1) {
        if(registry == null)initCardRegistery();
        int a = registry.indexOf(class1);

        if(a == -1){
            throw new RuntimeException("Class not found :"+class1.getName());
        }
        //if the class is not found default to 0
        return a != -1 ? a : 0;
    }

    /**
     * retourne la class de la carte a l'index donné
     * @param index l'index de la carte
     * @return class de la carte
     */
    public static Class<? extends Card> get(int index) {
        if(registry == null)initCardRegistery();
        if(registry.size() <= index || index < 0) return null;
        return registry.get(index);
    }

    /**
     * retourne l'index de la carte
     * @param card
     * @return
     */
    public static int indexOf(Card card) {
        if(registry == null)initCardRegistery();
        return indexOf(card.getClass());
    }
}
