#region Using directives

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

#endregion
using de.WWWings.PassagierSystem;
using de.WWWings;

namespace de.WWWings.PassagierSystem
{

    /// <summary>
    /// Diese Klasse repräsentiert einen Passagiert, der einen Flug buchen kann.
    /// </summary>
    [System.Serializable()]
    public class Passagier : de.WWWings.Person
    {

        /// <summary>
        /// Delegate für CheckInStart-Ereignis
        /// </summary>
        /// <param name="p"></param>
        public delegate void CheckInStartHandler(Passagier p);

        /// <summary>
        /// Delegarte für CheckInEnd-Ereignis
        /// </summary>
        /// <param name="p"></param>
        public delegate void CheckInEndeHandler(Passagier p);

        // ========== Klassenmitglieder
        [System.CLSCompliant(false)]
        public static de.WWWings.PassagierSystem.Passagiere Passagiere = new Passagiere();
        // ========== Attribute (Fields)
        [System.CLSCompliant(false)]
        public de.WWWings.Fluege Fluege = new de.WWWings.Fluege();
        public readonly long PID;
        private de.WWWings.Flug _AktuellerFlug = null;
        //  ========== Errechnete Attribute (Properties)
        public Flug AktuellerFlug
        {
            get
            {
                return this._AktuellerFlug;
            }
        }
        // =========== Ereignisse
        public static event CheckInStartHandler CheckInStart;
        public static event CheckInEndeHandler CheckInEnde;

        // Einfacher:
        //public static event EventHandler<Passagier> CheckInEndeAlternativ;

        // ========== Konstruktoren
        public Passagier()
        {
        }

        public Passagier(string Name, string Vorname)
            : base(Name, Vorname)
        {
            this.PID = Passagier.Passagiere.Add(this);
        }

        public Passagier(long PID)
        {
            this.PID = PID;
        }
        // ========== Methoden


        public void Arrive()
        {
            this._AktuellerFlug = null;
        }

        /// <summary>Einchecken eines Passagiers für einen Flug. Variante 1: Synchrone Ausführung</summary>
        /// <param name="Flugnummer">Die Methode erwartet eine Flugnummer</param>
        /// <returns>Die Methode liefert als Rückgabewert das Flugobjekt, wenn das Einchecken erfolgreich war.</returns>
        public Flug CheckIn(long Flugnummer)
        {
            if (CheckInStart != null)
            {
                CheckInStart(this);
            }
            this._AktuellerFlug = Flug.Fluege[Flugnummer];// FlugBLManager.HoleFlug(Flugnummer);

            System.Threading.Thread.Sleep(500); // DUMMY
            if (!(this.Fluege.ContainsKey(Flugnummer)))
            {
                throw new de.WWWings.PassagierSystem.PassagierNichtAufFlugGebucht(this.PID + "/" + Flugnummer);
            }

            else
            {
                System.Threading.Thread.Sleep(500); // DUMMY
                if (CheckInEnde != null)
                {
                    CheckInEnde(this);
                }
                return this.Fluege[Flugnummer];
            }
        }

        /// <summary>
        /// Delegate für asynchrone Ausführung des CheckIn
        /// </summary>
        /// <param name="Flugnummer"></param>
        /// <returns></returns>
        public delegate Flug CheckInDelegate(long Flugnummer);
        /// <summary>Einchecken eines Passagiers für einen Flug. Variante 2: Asynchrone Ausführung</summary>
        /// <param name="Flugnummer">Die Methode erwartet eine Flugnummer</param>
        /// <returns>Die Methode liefert als Rückgabewert das Flugobjekt, wenn das Einchecken erfolgreich war.</returns>
        public void CheckInAsync(long Flugnummer)
        {
            CheckInDelegate del = new CheckInDelegate(this.CheckIn);
            del.BeginInvoke(Flugnummer, null, del);
        }


        /// <summary>
        /// Informationen über das Passagier-Objekt werden an der Konsole ausgegeben.
        /// </summary>
        public override void Info()
        {

            Console.WriteLine("Passagier: " + this.GanzerName);
        }


        ///----- Ausimplementiert
        ///

        private DAL.Passagier_DataManager DAL = new de.WWWings.DAL.Passagier_DataManager();

        /// <summary>
        /// Einzelbuchung. Noch Dummy-Implementierung!!!
        /// </summary>
        /// <param name="Flugnummer"></param>
        /// <returns></returns>
        public long Buchen(long Flugnummer)
        {
            //if (!(Flug.Fluege.ContainsKey(Flugnummer)))
            //{
            // throw new de.WWWings.PassagierSystem.FalscheFlugnummer(this.PID + "/" + Flugnummer);
            //}
            //else
            {
                //

                return new de.WWWings.DAL.Passagier_DataManager().Buchung(this.PID, Flugnummer);
            }
        }

        public Buchung Buchen(de.WWWings.Flug flug)
        {
            this.Fluege.Add(flug.FlugNr, flug);
            Buchung b = new Buchung();
            b.Flug = flug;
            b.Passagier = this;
            return b;
        }

        /// <summary>
        /// Mehrfachbuchung (als Transaktion)
        /// </summary>
        /// <param name="Flugnummern"></param>
        public void Buchen(long[] Flugnummern)
        {
            DAL.MehrfachBuchung(this.PID, Flugnummern);
            //d.Dispose();
        }

        public long AlleBuchungenLoeschen()
        {
            return BuchungLoeschen();
        }

        private long BuchungLoeschen()
        {
            long anz = DAL.AlleBuchungenLoeschen(this.PID);
            //d.Dispose();
            return anz;
        }

        public System.Data.Common.DbDataReader AlleBuchungen()
        {

            System.Data.Common.DbDataReader r = DAL.AlleBuchungen(this.PID);
            //d.Dispose();
            return r;

        }
    }
}
