using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Workflow.Activities;
using System.Workflow.Runtime.Tracking;
namespace WWW_WorkflowHost
{
 public partial class F_FlugBuchung : Form
 {

  WorkflowInstance w;
  de.WWWings.Workflow.Buchungsdienst bd;

  public F_FlugBuchung()
  {
   InitializeComponent();
  }

  private void C_STart_Click(object s, EventArgs ee)
  {
   NeueBuchung();
  }

  /// <summary>
  /// Erzeugt eine neue Buchung
  /// </summary>
  private void NeueBuchung()
  {
   w = Program.WorkflowRuntime.CreateWorkflow(typeof(de.WWWings.Workflow.Buchungsworkflow));
   w.Start();
   this.tabControl1.DeselectTab(0);
   Print("Neuer Workflow gestartet... " + w.InstanceId);
  }

  public delegate void GetDataAsyncDelegate(string s);

  /// <summary>
  /// Erzeugung des Datenaustauschdienstes und Ereignisbindung für Workflow-Ereignisse beim Laden des GUIs
  /// </summary>
  private void F_FlugBuchung_Load(object ss, EventArgs ee)
  {
   if (Program.WFDatenDienst.GetService(typeof(de.WWWings.Workflow.Buchungsdienst)) == null)
   {
    bd = new de.WWWings.Workflow.Buchungsdienst();
    //bd.WorkflowMeldetNeuenStatus +=new EventHandler<string>(bd_WorkflowMeldetNeuenStatus);
    Program.WFDatenDienst.AddService(bd);
   }

   Program.WorkflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { Print("Workflow beendet! " + e.WorkflowInstance.InstanceId); };

   Program.WorkflowRuntime.WorkflowStarted += delegate(object sender, WorkflowEventArgs e) { Print("Workflow gestartet! " + e.WorkflowInstance.InstanceId); };

   Program.WorkflowRuntime.WorkflowLoaded += delegate(object sender, WorkflowEventArgs e)
   {
    //Print("Workflow geladen! " + e.WorkflowInstance.InstanceId);
   };

   Program.WorkflowRuntime.WorkflowIdled += delegate(object sender, WorkflowEventArgs e)
   {
    Print("Workflow wartet! " + e.WorkflowInstance.InstanceId);
    w.Unload();
   };
   Program.WorkflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
  {
   PrintError(e.Exception.Message);
   System.Windows.Forms.MessageBox.Show(e.Exception.Message, "Fehler in Buchung " + e.WorkflowInstance.InstanceId);
   w = null;
   Print("Kein Activer Workflow");

  };


   Print("Workflow Runtime ist bereit!");
  }

  void bd_WorkflowMeldetNeuenStatus(object sender, string e)
  {
   Console.WriteLine("NEUER STATUS DES WORKFLOWS: " + e);
  }

  private void C_Weiter1_Click(object sender, EventArgs e)
  {

   bd.SendePersonenDaten(w.InstanceId, this.C_Name.Text, this.C_EMail.Text);
   this.tabControl1.DeselectTab(1);
  }

  private void C_Weiter2_Click(object sender, EventArgs e)
  {
   bd.SendeFlugDaten(w.InstanceId, Convert.ToInt64(this.C_Flug.Text));
   this.tabControl1.DeselectTab(2);
  }

  private void C_Weiter3_Click(object sender, EventArgs e)
  {
   bd.SendeZahlngsDaten(w.InstanceId, "", 0, new DateTime(2007, 10, 10));
   this.tabControl1.DeselectTab(3);
  }

  private void label7_Click(object sender, EventArgs e)
  {

  }

  private void textBox1_TextChanged(object sender, EventArgs e)
  {

  }

  private void TabActivate(string Name)
  {

   foreach (TabPage p in this.tabControl1.TabPages)
   {
    //p.Focused = (p.Name == Name);
   }

  }

  private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
  {

  }

  private void WorkflowListe()
  {


  }


  private void C_Liste_SelectedIndexChanged(object sender, EventArgs e)
  {
   Guid id = new Guid(this.C_Liste.SelectedItem.ToString());
   w = Program.WorkflowRuntime.GetWorkflow(id);

   string CurrentActivity = GetCurrentActivity(w);
   Print("Aktueller Worflow: " + w.InstanceId + " wartet bei: " + CurrentActivity);

   switch (CurrentActivity)
   {
    case "WartenAufFlugDaten": this.tabControl1.SelectedIndex = 2; break;
    case "WartenAufZahlung": this.tabControl1.SelectedIndex = 3; break;
    case "WartenAufPersonenDaten": this.tabControl1.SelectedIndex = 1; break;
    default:
     break;
   }
  }

  /// <summary>
  /// Ausgabe --> Wechsel des Threads notwendig !!!
  /// </summary>
  /// <param name="s"></param>
  public void Print(string s)
  {
   Console.ForegroundColor = ConsoleColor.Yellow;
   Console.WriteLine(s);
   GetDataAsyncDelegate d = new GetDataAsyncDelegate(Print2);

   this.Invoke(d, new object[] { s });
   Console.ForegroundColor = ConsoleColor.White;
  }

  public void PrintError(string s)
  {
   Console.ForegroundColor = ConsoleColor.Red;
   Console.WriteLine(s);
   GetDataAsyncDelegate d = new GetDataAsyncDelegate(Print2);
   this.Invoke(d, new object[] { s });
   Console.ForegroundColor = ConsoleColor.White;
  }

  public void Print2(string s)
  {
   this.C_Liste.Items.Clear();

   if (w != null)
   {
    this.C_Aktuell.Text = "Aktueller Workflow: " + w.InstanceId.ToString();
   }
   else
   {
    this.tabControl1.SelectedIndex = 0;
    this.C_Aktuell.Text = "Kein aktiver Workflow!";
   }

   this.C_Status.Text = s;

   foreach (string Element in HoleAlleWorkflows().Keys)
   {
    this.C_Liste.Items.Add(Element);
   }


  }

  /// <summary>
  /// Holt Liste aller Workflow im RAM und in der Datenbank
  /// </summary>
  /// <returns></returns>
  private System.Collections.Generic.SortedDictionary<string, string> HoleAlleWorkflows()
  {
   System.Collections.Generic.SortedDictionary<string, string> liste = new System.Collections.Generic.SortedDictionary<string, string>();
   // Workflows im Speicher auflisten
   foreach (WorkflowInstance ww in Program.WorkflowRuntime.GetLoadedWorkflows())
   {
    liste.Add(ww.InstanceId.ToString(), "");
   }

   // Persistente Workflow auflisten
   foreach (SqlPersistenceWorkflowInstanceDescription ww in Program.WFPersistenzDienst.GetAllWorkflows())
   {
    if (!liste.ContainsKey(ww.WorkflowInstanceId.ToString())) liste.Add(ww.WorkflowInstanceId.ToString(), "");
   }
   return liste;
  }


  private void C_BuchungAbbrechen_Click(object sender, EventArgs e)
  {
   //w.Abort();
   w.Terminate("Abbruch auf Benutzerwunsch");
   Print("Buchung abgebrochen");
  }

  private void beendenToolStripMenuItem_Click(object sender, EventArgs e)
  {
   this.Close();
  }

  private void C_NeueBuchung_Click(object sender, EventArgs e)
  {
   NeueBuchung();
  }

  private void C_Protokoll_Click(object sender, EventArgs e)
  {
   if (w == null) return;
   System.Workflow.Runtime.Tracking.SqlTrackingQuery WFTrackingQuery;
   WFTrackingQuery = new System.Workflow.Runtime.Tracking.SqlTrackingQuery(Program.WFTrackingDienst.ConnectionString);

   SqlTrackingWorkflowInstance t;
   bool gefunden = WFTrackingQuery.TryGetWorkflow(w.InstanceId, out t);
   if (gefunden)
   {
    string ausgabe = "";

    foreach (WorkflowTrackingRecord r in t.WorkflowEvents)
    {
     ausgabe += String.Format("{0}: {1}: {2}  \n", r.EventDateTime, r.EventOrder, r.TrackingWorkflowEvent.ToString());
    }
    ausgabe += "-------------\n";
    foreach (ActivityTrackingRecord r in t.ActivityEvents)
    {
     ausgabe += String.Format("{0}: {1}: {2} {3} = {4}  \n", r.EventDateTime, r.EventOrder, r.ActivityType.Name, r.QualifiedName, r.ExecutionStatus);
    }
    System.Windows.Forms.MessageBox.Show(ausgabe, "Protokoll für Workflow " + w.InstanceId);
   }
  }

  private string GetCurrentActivity(WorkflowInstance w)
  {
   System.Workflow.Runtime.Tracking.SqlTrackingQuery WFTrackingQuery;
   WFTrackingQuery = new System.Workflow.Runtime.Tracking.SqlTrackingQuery(Program.WFTrackingDienst.ConnectionString);

   string Name = "";
   if (w == null) return "";
   SqlTrackingWorkflowInstance t;
   bool gefunden = WFTrackingQuery.TryGetWorkflow(w.InstanceId, out t);
   if (gefunden)
   {

    foreach (ActivityTrackingRecord r in t.ActivityEvents)
    {
     Name = r.QualifiedName;
    }



   }
   return Name;
  }

  private void alleBuchungenAbbrechenToolStripMenuItem_Click(object sender, EventArgs e)
  {
   foreach (SqlPersistenceWorkflowInstanceDescription ww in Program.WFPersistenzDienst.GetAllWorkflows())
   {
    WorkflowInstance w2 = Program.WorkflowRuntime.GetWorkflow(ww.WorkflowInstanceId);
    Print("Workflow wird abgebrochen: " + w2.InstanceId);

    //w2.Abort();
    w2.Terminate("Abbruch auf Benutzerwunsch");
    Print("Workflow wurde abgebrochen: " + w2.InstanceId);
   }

  }



 }
}