using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace CSharpProjekt {
    public class Armee {
        List<MilitärEinheit> einheiten;

        public List<MilitärEinheit> Einheiten {
            get { return einheiten; }
            set { einheiten = value; }
        }

        public Armee() {
            einheiten = new List<MilitärEinheit>();
            AddEinheiten(Truppen.schwert, Spiel.SchwertStartwert);
            AddEinheiten(Truppen.bogen, Spiel.BogenStartwert);
            AddEinheiten(Truppen.ritter, Spiel.RitterStartwert);
        }

        public void AddEinheit(MilitärEinheit einheit) {
            einheiten.Add(einheit);
        }

        public void RemoveEinheit(Truppen einheitenTyp) {
            MilitärEinheit toRemove;
            if (einheitenTyp == Truppen.schwert) {
                foreach (MilitärEinheit einheit in einheiten) {
                    if (einheit is Schwertkämpfer) {
                        toRemove = einheit;
                        break;
                    }
                }
            } else if (einheitenTyp == Truppen.bogen) {
                foreach (MilitärEinheit einheit in einheiten) {
                    if (einheit is Bogenschütze) {
                        toRemove = einheit;
                        break;
                    }
                }
            } else if (einheitenTyp == Truppen.ritter) {
                foreach (MilitärEinheit einheit in einheiten) {
                    if (einheit is Ritter) {
                        toRemove = einheit;
                        break;
                    }
                }
            }
        }

        public void AddEinheiten(Truppen einheitenTyp, int anzahl) {
            for (int i = 0; i < anzahl; i++) {
                if (einheitenTyp == Truppen.schwert)
                    AddEinheit(new Schwertkämpfer());
                else if (einheitenTyp == Truppen.bogen)
                    AddEinheit(new Bogenschütze());
                else if (einheitenTyp == Truppen.ritter)
                    AddEinheit(new Ritter());
            }
        }

        public void RemoveEinheiten(Truppen einheitenTyp, int anzahl) {
            for (int i = 0; i < anzahl; i++) {
                if (einheiten.Count <= 0)
                    return;
                RemoveEinheit(einheitenTyp);
            }
        }

        public void EinheitenZahlAendern(Truppen einheitenTyp, int aenderung) {
            if (aenderung == 0)
                return;
            if (aenderung > 0) {
                AddEinheiten(einheitenTyp, aenderung);
            } else {
                RemoveEinheiten(einheitenTyp, -aenderung);
            }
        }

        public int EinheitenAnzahl(Truppen einheitenTyp) {
            int anzahl = 0;

            foreach (MilitärEinheit einheit in einheiten) {
                if (einheit.EinheitenTyp == einheitenTyp)
                    anzahl++;
            }

            return anzahl;
        }

        /// <summary>
        /// Bestimmt die Kampfstärke dieser Armee beim Angriff wenn der Gegner sich auf offenem Feld stellt
        /// </summary>
        /// <returns></returns>
        public int AngriffsPunkte() {
            int punkte = 0;
            foreach (MilitärEinheit einheit in einheiten) {
                punkte += einheit.Angriff;
            }
            return punkte;
        }

        /// <summary>
        /// Bestimmt die Kampfstärke dieser Armee bei der Verteidigung auf offenem Feld
        /// </summary>
        /// <returns></returns>
        public int VersteidigungsPunkte() {
            int punkte = 0;
            foreach (MilitärEinheit einheit in einheiten) {
                punkte += einheit.Verteidigung;
            }
            return punkte;
        }

        /// <summary>
        /// Bestimmt die Kampfstärke dieser Armee beim Angriff auf die gegnerische Stadt
        /// </summary>
        /// <returns></returns>
        public int BelagerungsPunkte() {
            int punkte = 0;
            foreach (MilitärEinheit einheit in einheiten) {
                punkte += einheit.StadtAngriff;
            }
            return punkte;
        }

        /// <summary>
        /// Bestimmt die Kampfstärke dieser Armee bei der Verteidigung der Stadt
        /// </summary>
        /// <returns></returns>
        public int StadtVerteidigungsPunkte() {
            int punkte = 0;
            foreach (MilitärEinheit einheit in einheiten) {
                punkte += einheit.StadtVerteidigung;
            }
            return punkte;
        }

        /// <summary>
        /// Bestimmt den Bonusschaden dieser Armee bei einem gewonnenen Kampf auf offenem Feld
        /// </summary>
        /// <returns></returns>
        public int VerfolgungsPunkte() {
            int punkte = 0;
            foreach (MilitärEinheit einheit in einheiten) {
                punkte += einheit.Verfolgen;
            }
            return punkte;
        }

        /// <summary>
        /// Verteilt den Schaden den diese Armee beim Kampf genommen hat
        /// </summary>
        /// <param name="schadensPunkte">Die Kampfkraft des Gegners, eventuell modifiziert z.B. durch die Stadtmauer</param>
        /// <returns></returns>
        public int[] VerlusteErleiden(int schadensPunkte, Random rand) {
            
            int indexGetroffeneEinheit;
            int[] getöteteEinheiten = { 0, 0, 0 };

            //Schadenspunkte werden zufällig auf alle Einheiten verteilt, Einheiten die auf 0 Lebenspunkte sinken sind tot und werden entfernt
            for (int i = 0; i < schadensPunkte; i++) {
                if (einheiten.Count <= 0)
                    return getöteteEinheiten;
                indexGetroffeneEinheit = rand.Next(einheiten.Count);
                einheiten[indexGetroffeneEinheit].LebensPunkte--;
                if (einheiten.Count > 0 && einheiten[indexGetroffeneEinheit].LebensPunkte <= 0) {
                    if (einheiten[indexGetroffeneEinheit] is Schwertkämpfer)
                        getöteteEinheiten[0]++;
                    else if (einheiten[indexGetroffeneEinheit] is Bogenschütze)
                        getöteteEinheiten[1]++;
                    else if (einheiten[indexGetroffeneEinheit] is Ritter)
                        getöteteEinheiten[2]++;
                    einheiten.RemoveAt(indexGetroffeneEinheit);
                }
            }
            return getöteteEinheiten;
        }

        public void Regenerieren() {
            foreach (MilitärEinheit einheit in einheiten)
                einheit.LebensPunkte = einheit.LebensPunkteMax;
        }
    }

    public enum Truppen {
        schwert,
        bogen,
        ritter,
    }
}
