public Card PlayCard(Card cardTemp)
        {
            if(CanPlayCard(cardTemp))
            {
                this.mana.PayMana(cardTemp.manaCost); // paghi il costo di mana.
                if (cardTemp.castLimit > 0)
                    castCounter[cardTemp.name] -= 1;
                int idTemp = 2;
                List<List<Enums.Target>> validTargets = new List<List<Enums.Target>>(); // target validi delle microazioni contenute in OnAppear. A stessono indice corrispondo Microazione e Target validi.

                switch (cardTemp.type)
                {
                    case Enums.Type.Elemental:
                        Elemental ElemTemp = (Elemental)cardTemp; // cast a Elemental.
                        foreach (Card cTemp in Game.AllCardsOnBoard) // assegna ID all'elementale.
                            if (idTemp <= cTemp.id)
                                idTemp = cTemp.id + 1;
                        ElemTemp.id = idTemp;
                        cardsOnBoard.Insert(0, ElemTemp); // lo mette sul board inserendolo in prima posizione.
                        Game.AllCardsOnBoard.Add(ElemTemp);
                        Game.AllyElementals.Add(ElemTemp.target); // aggiunge a lista di bersagli validi sul board.
                        if (ElemTemp.onAppear != null) // controlla se ci sono microazioni in OnAppear.
                            if (ElemTemp.onAppear.Count > 0)
                            {
                                foreach (string microAct in ElemTemp.onAppear)
                                    validTargets.Insert(0, MicroActions.getTargets(microAct));
                                //qui ci sarebbe da mandare i target all'interfaccia che fa illuminare i target validi, prende quello selezionato
                                //dall'utente e lo rimanda indietro come target effettivo della microazione.

                                //foreach (string microaction in ElemTemp.onAppear) -- e qui andrebbero passati i Target effettivi alla chiamata delle MicroActions.
                                    //ElemTemp.processMicroaction(ElemTemp.onAppear);                                        
                            }
                        return ElemTemp;

                    case Enums.Type.Spirit:
                        Spirit SpiritTemp = (Spirit)cardTemp; // cast a Spirit
                        foreach (Card cTemp in Game.AllCardsOnBoard) // assegna ID all'elementale.
                            if (idTemp <= cTemp.id)
                                idTemp = cTemp.id + 1;
                        SpiritTemp.id = idTemp;
                        cardsOnBoard.Add(SpiritTemp); // lo mette sul board in ultima posizione.
                        Game.AllCardsOnBoard.Add(SpiritTemp);
                        Game.AllySpirits.Add(SpiritTemp.target);//aggiunge a lista bersagli validi sul board.
                        return SpiritTemp;

                    case Enums.Type.Ritual:
                        Ritual ritualTemp = (Ritual)cardTemp; // cast a Ritual
                        foreach (Power powTemp in ritualTemp.powers)
                            foreach (string microAct in powTemp.microActions)
                                validTargets.Insert(0, MicroActions.getTargets(microAct));
                        //stesso discorso che per gli Elementals.
                        return ritualTemp;

                    default:
                        return null;                        
                }                       
            }
            return null;
        }
        public Card getCardByName(string name)
        {
            foreach (Invocation InvTemp in Invocations)
                if (InvTemp.name == name)
                {
                    Card card = new Card(name);
                    card = card.initFromInvocation(InvTemp);
                    return card;
                }

            return null;
        }
        public void OpponentPlayCard(Card card)
        {

            //qui va' presa la carta ed aggiunta all'opponent
            opponent.cardsOnBoard.Add(card);

            Game.AllCardsOnBoard.Add(card);
            Game.EnemyElementals.Add(card.target); //!!!!!!ATTENTO IL TARGET E' DA VALORIZZARE aggiunge a lista di bersagli validi sul board.

        }
        public bool CanPlayCard(Card cardTemp)
        {
            bool canPlay = true;
            if (this.mana.CanPay(cardTemp.manaCost) && cardsOnBoard != null) //controlla che si possa pagare
                if (cardTemp.castLimit > 0) // check sul CastCounter. Se hai già raggiunto il castLimit, ritorna false.
                {
                    foreach (KeyValuePair<string, int> ktemp in castCounter)
                        if (ktemp.Key == cardTemp.name)
                            if (ktemp.Value == 0)  // ogni volta che si gioca una carta, si decrementa questo valore. Se è a 0 è raggiunto il castlimit.
                                canPlay = false;
                }
                switch (cardTemp.type)
                {
                    case Enums.Type.Elemental:

                    if (cardsOnBoard.Count < 4) // controlla che il board non sia pieno
                    {
                        int elemCount = 0; // se è 3, ci sono già 3 elementali sul tuo board e ritorna false.
                        foreach (Card cTemp in cardsOnBoard)
                            if (cTemp.type == Enums.Type.Elemental)
                                elemCount += 1;
                        if (elemCount == 3)
                        {
                            canPlay = false;
                            break;
                        }
                        
                        Elemental elemCard = (Elemental)cardTemp;
                            foreach (Elemental elemTemp in cardsOnBoard)
                                if (elemCard.from != "" && elemCard.from != elemTemp.name)
                                    canPlay = false;
                        
                    }
                        break;
                    case Enums.Type.Spirit:

                        if (cardsOnBoard.Count < 4) // controlla che il board non sia pieno
                            foreach (Card Ctemp in cardsOnBoard)
                                if (Ctemp.type == Enums.Type.Spirit)
                                    canPlay = false;
                        break;
                    case Enums.Type.Ritual:

                    List<Enums.Target> targetList = null;
                    foreach (Power powTemp in cardTemp.powers)
                        foreach (string microaction in powTemp.microActions)
                            foreach (Enums.Target targTemp in MicroActions.getTargets(microaction))
                                targetList.Add(targTemp);
                    foreach (Enums.Target tTemp in targetList)
                    {
                        if (tTemp==Enums.Target.Enemy)
                            if (Game.EnemyElementals.Count == 0)
                                canPlay = false;
                        if (tTemp==Enums.Target.Ally)
                            if (Game.AllyElementals.Count == 0)
                                canPlay = false;
                        if (tTemp==Enums.Target.Spirit)
                            if (Game.EnemySpirits.Count == 0 && Game.AllySpirits.Count == 0)
                                canPlay = false;
                    }
                        break;
                }
            return canPlay;        
        }
        public Card PlayCard(Card cardTemp)
        {
            if (CanPlayCard(cardTemp))
            {
                List <List < Enums.Target >> validTargets = new List<List<Enums.Target>>();
                this.mana.PayMana(cardTemp.manaCost); // paghi il costo di mana.
                if (cardTemp.castLimit > 0)
                    castCounter[cardTemp.name] -= 1;
                int idTemp = 2;

                switch (cardTemp.type)
                {
                    case Enums.Type.Elemental:
                        Elemental ElemTemp = (Elemental)cardTemp; // cast a Elemental.
                        if (ElemTemp.rank == 1)

                            foreach (Card cTemp in Game.AllCardsOnBoard) // assegna ID all'elementale.
                               if (idTemp <= cTemp.id)
                                    idTemp = cTemp.id + 1;
                        ElemTemp.id = idTemp;

                if (ElemTemp.rank > 1) // da qui si attiva tutto quel che succede quando casti un rank 2 o 3 e "sovrascrive" il suo rank 1.
                        foreach (Elemental eTemp in cardsOnBoard)
                           if (eTemp.name == ElemTemp.from)
                                {
                                    ElemTemp.buff = eTemp.buff; // il rank sotto passa buff e debuff a quello sopra.
                                    ElemTemp.debuff = eTemp.debuff;
                                    foreach (Enums.Properties armor in eTemp.properties)
                                        if (armor == Enums.Properties.Armor)
                                            ElemTemp.properties.Add(Enums.Properties.Armor);
                                    ElemTemp.hasAttacked = eTemp.hasAttacked;
                                    ElemTemp.hasWeakness = eTemp.hasWeakness;
                                    ElemTemp.hasAttackedThunderborn = eTemp.hasAttackedThunderborn;
                                    ElemTemp.id = eTemp.id;
                                    foreach (Enums.Buff buff in ElemTemp.buff) // modifica Strength e Constitution in base a buff e debuff passati
                                    {
                                        if (buff == Enums.Buff.IncreasedStr)
                                            ElemTemp.strength += 1;
                                        if (buff == Enums.Buff.IncreasedCon)
                                            ElemTemp.constitution += 1;
                                    }
                                    foreach (Enums.Debuff debuff in ElemTemp.debuff)
                                    {
                                        if (debuff == Enums.Debuff.DecreasedStr)
                                            ElemTemp.strength -= 1;
                                        if (debuff == Enums.Debuff.DecreasedCon)
                                            ElemTemp.constitution -= 1;
                                    }

                                    Game.RemoveCardById(eTemp.id); // rimuove il rank sotto da ogni lista di Game.
                                    break;
                                }
                        cardsOnBoard.Insert(0, ElemTemp); // lo mette sul board inserendolo in prima posizione.
                        Game.AllCardsOnBoard.Add(ElemTemp); // lo mette nella listona di tutte le carte sul board.
                        Game.AllyElementals.Add(ElemTemp.target); // aggiunge a lista di bersagli validi sul board.
                        if (ElemTemp.onAppear.Count > 0) // controlla se ci sono microazioni in OnAppear.
                            if (ElemTemp.onAppear[0] != "")
                            {
                                foreach (string microAct in ElemTemp.onAppear)
                                    validTargets.Add(MicroActions.getTargets(microAct));
                                List<string> micActProva = new List<string>(ElemTemp.onAppear);
                                MicroActionsProcessor.AcquireMicroactions(micActProva);
                                MicroActionsProcessor.AcquireValidTargets(validTargets);
                                if (MicroActionsProcessor.canProcessMicroactions())// controlla se le microazioni hanno tutte almeno 1 target valido.
                                    MicroActionsProcessor.AcquireMicroactionsParams();
                            }
                        return ElemTemp;

                    case Enums.Type.Spirit:
                        Spirit SpiritTemp = (Spirit)cardTemp; // cast a Spirit
                        foreach (Card cTemp in Game.AllCardsOnBoard) // assegna ID all'elementale.
                            if (idTemp <= cTemp.id)
                                idTemp = cTemp.id + 1;
                        SpiritTemp.id = idTemp;
                        cardsOnBoard.Add(SpiritTemp); // lo mette sul board in ultima posizione.
                        Game.AllCardsOnBoard.Add(SpiritTemp);
                        Game.AllySpirits.Add(SpiritTemp.target);//aggiunge a lista bersagli validi sul board.
                        return SpiritTemp;

                    case Enums.Type.Ritual:
                        Ritual RitualTemp = (Ritual)cardTemp; // cast a Ritual
                        List<string> RitualMicroactions = new List<string>();
                        foreach (Power powTemp in RitualTemp.powers)
                            foreach (string microAct in powTemp.microActions)
                            {
                                validTargets.Add(MicroActions.getTargets(microAct));
                                RitualMicroactions.Add(microAct);
                            }
                        MicroActionsProcessor.AcquireMicroactions(RitualMicroactions);
                        MicroActionsProcessor.AcquireValidTargets(validTargets);
                        if (MicroActionsProcessor.canProcessMicroactions())
                            MicroActionsProcessor.AcquireMicroactionsParams();

                        return RitualTemp;

                    default:
                        return null;
                }
            }
            return null;
        }