#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 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_ST DAL = new de.WWWings.DAL.Passagier_DataManager_ST();

  /// <summary>
  /// Einzelbuchung.
  /// </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 de.WWWings.Buchung_BLManager.Buchen(this.PID, Flugnummer).Buchungscode;
   }
  }

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

   return b;
  }

  /// <summary>
  /// Mehrfachbuchung (als Transaktion)
  /// </summary>
  /// <param name="Flugnummern"></param>
  public long Buchen(long[] Flugnummern)
  {
   Buchung b = new Buchung(Flugnummern, this.PID);
   de.WWWings.DAL.Passagier_DataManager_ST.MehrfachBuchung(b.Buchungscode, this.PID, Flugnummern);
   //d.Dispose();
   return b.Buchungscode;
  }

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

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

  public BuchungsMenge AlleBuchungen()
  {
   return de.WWWings.Buchung_BLManager.HoleBuchungenFuerPassagier(this.PID);
  }
 }
}
