using System;
using System.Threading;
using System.Windows.Forms;
using Model;
using Telerik.OpenAccess;
using Telerik.OpenAccess.Exceptions;
using Telerik.WinControls.UI;

namespace _8_Transactions
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private delegate void ListBoxUpdateHandler(string message);

    private void UpdateListBox(string message)
    {
      lbStatus.Items.Insert(0, new RadListBoxItem(message));
    }

    public void ThreadProc(object argument)
    {
      string sql =
        "select top 10 * from orders where customerid like '%" +
        argument.ToString() +
        "'";
      Random random = new Random();

      // each thread must have its own object scope
      using (IObjectScope scope =
        Database.Get("NorthwindConnection").GetObjectScope())
      {
        scope.Transaction.Begin();

        // do some work...
    
        Query<Order> orders =
          scope.GetSqlQuery<Order>(sql, String.Empty);
        
        // modify the orders from the result set
        foreach (Order order in orders.ExecuteList())
        {
          // provide feedback
          string message = "Thread: " +
            Thread.CurrentThread.ManagedThreadId.ToString() +
            " Order: " +
            order.OrderID.ToString();

          lbStatus.Invoke(new ListBoxUpdateHandler(UpdateListBox),
            new object[] { message });

          // change some arbitrary data
          order.Freight = random.Next(1, 100);
          order.ShippedDate = DateTime.Now;
        }

        try
        {
          scope.Transaction.Commit();
        }
        catch (OptimisticVerificationException ex)
        {
          lbStatus.Invoke(new ListBoxUpdateHandler(UpdateListBox),
            new object[] { ex.Message });

          if (scope.Transaction.IsActive)
            scope.Transaction.Rollback();
        }
      }
    }

    private void btnStartThread_Click(object sender, EventArgs e)
    {
      Thread thread = new Thread(new ParameterizedThreadStart(ThreadProc));
      thread.Start("A");
      Thread thread2 = new Thread(new ParameterizedThreadStart(ThreadProc));
      thread2.Start("B");
      Thread thread3 = new Thread(new ParameterizedThreadStart(ThreadProc));
      thread3.Start("C");
    }
  }


}
