using System;
using System.Text;
using System.Data;
using System.Data.SqlClient; // Wymagane do dostpu do danych.
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
   protected void Page_Load(object sender, EventArgs e)
   {
      if (!IsPostBack)
      {
         BindGrid();
         ddlCustomer.DataSource = GetDataReader("Customers");
         ddlCustomer.DataBind();
         ddlShipper.DataSource = GetDataReader("Shippers");
         ddlShipper.DataBind();
         ddlProduct.DataSource = GetDataReader("Products");
         ddlProduct.DataBind();
      }
   }

   private void BindGrid()
   {
      DataSet ds = CreateDataSet(WhichTable.Orders);
      OrdersGridView.DataSource = ds.Tables[0];
      OrdersGridView.DataBind();
   }

   private SqlDataReader GetDataReader(string whichTable)
   {
      // Cig znakowy poczenia czcy z baz danych Bugs.
      string connectionString =
      "Data Source=Brahams;Initial Catalog=Northwind;Integrated Security =True";

      // Tworzenie obiektu Connection, inicjalizacja
      // cigu znakowego poczenia i jego otworzenie.
      System.Data.SqlClient.SqlConnection connection =
         new System.Data.SqlClient.SqlConnection(
         connectionString);

      connection.Open();

      // Tworzenie obiektu SqlCommand i przypisanie poczenia.
      System.Data.SqlClient.SqlCommand command =
         new System.Data.SqlClient.SqlCommand();
      command.Connection = connection;

      // Umieszczenie polecenia select.
      command.CommandText = "select * from " + whichTable;

      // Zwrot obiektu DataReader.
      return command.ExecuteReader(
         CommandBehavior.CloseConnection);
   }

   // Pobieramy szczegy zamwienia.
   public void OnSelectedIndexChangedHandler(
      Object sender, EventArgs e)
   {
      UpdateDetailsGrid();
   }

   private void UpdateDetailsGrid()
   {
      BindGrid();
      DataSet ds = CreateDataSet(WhichTable.OrderDetails);
      if (ds.Tables[0].Rows.Count > 0)
      {
         this.OrderDetailsPanel.Visible = true;
         this.DetailsGridView.DataSource = ds.Tables[0];
         this.DetailsGridView.DataBind();
      }
      else
      {
         this.OrderDetailsPanel.Visible = false;
      }
   }

   private enum WhichTable
   {
      Orders,
      OrderDetails,
   };

   private DataSet CreateDataSet(WhichTable theTable)
   {
      // Cig znakowy poczenia czcy z baz danych.
      string connectionString =
      "Data Source=Brahams;Initial Catalog=Northwind;Integrated Security =True";

      // Tworzenie obiektu Connection, inicjalizacja
      // cigu znakowego poczenia i jego otworzenie.
      System.Data.SqlClient.SqlConnection connection =
         new System.Data.SqlClient.SqlConnection(connectionString);

      DataSet dataSet = new DataSet();
      try
      {
         connection.Open();

         // Tworzenie obiektu SqlCommand i przypisanie poczenia
         System.Data.SqlClient.SqlCommand command =
            new System.Data.SqlClient.SqlCommand();
         command.Connection = connection;

         StringBuilder sb = new StringBuilder();
         if (theTable == WhichTable.Orders)
         {
            sb.Append("select OrderID, c.CompanyName, c.ContactName, ");
            sb.Append(" c.ContactTitle, c.Phone, orderDate, ");
            sb.Append(" s.CompanyName as ShipperName");
            sb.Append(" from orders o ");
            sb.Append(" join customers c on c.CustomerID = o.CustomerID");
            sb.Append(" join shippers s on s.ShipperID = o.ShipVia");
            sb.Append(" ORDER BY OrderID DESC");
         }
         else
         {
            int index = OrdersGridView.SelectedIndex;
            int theOrderID = -1;
            if (index != -1)
            {
               // Pobieramy identyfikator zamwienia z siatki danych.
               DataKey key = OrdersGridView.DataKeys[index];
               theOrderID = (int)key.Value;
            }

            sb.Append("Select od.OrderID, OrderDate, p.ProductID, ");
            sb.Append(" ProductName, od.UnitPrice, Quantity ");
            sb.Append("from Orders o ");
            sb.Append("join [Order Details] od on o.orderid = od.orderid ");
            sb.Append("join products p on p.productID = od.productid ");
            sb.Append("where od.OrderID = " + theOrderID);
         }

         command.CommandText = sb.ToString();
         SqlDataAdapter dataAdapter = new SqlDataAdapter();
         dataAdapter.SelectCommand = command;
         dataAdapter.TableMappings.Add("Table", theTable.ToString());
         dataAdapter.Fill(dataSet);
      }
      finally
      {
         connection.Close();
      }
      return dataSet;
   }

   protected void btnAdd_Click(object sender, EventArgs e)
   {
      string whichTransaction = this.rbTransactionType.SelectedValue.ToString();
      if (whichTransaction == "DB")
         UpdateDBTransaction();
      else
         UpdateConnectionTransaction();
   }

   private void UpdateConnectionTransaction()
   {
      string connectionString =
      "Data Source=Brahams;Initial Catalog=Northwind;Integrated Security =True";

      // Tworzenie obiektu Connection, inicjalizacja
      // cigu znakowego poczenia i jego otworzenie.
      System.Data.SqlClient.SqlConnection connection =
         new System.Data.SqlClient.SqlConnection(connectionString);

      // Deklaracja obiektu Command dla polecenia SQL.
      System.Data.SqlClient.SqlCommand command =
         new System.Data.SqlClient.SqlCommand();

      // Deklaracja egzemplarza SqlTransaction.
      SqlTransaction transaction = null;
      int OrderID = -1;

      try
      {
         // Cig znakowy poczenia do poczenia z baz danych Bugs.
         connection.Open();

         // Rozpoczynamy transakcj.
         transaction = connection.BeginTransaction();

         // Doczamy transakcj do obiektu Command.
         command.Transaction = transaction;

         // Doczamy poczenie do obiektu Command.
         command.Connection = connection;

         command.CommandText = "spAddOrder";
         command.CommandType = CommandType.StoredProcedure;

         // Deklaracja obiektu Parameter.
         System.Data.SqlClient.SqlParameter param;

         // Dodanie kadego parametru i ustawienie jego kierunku oraz wartoci.
         param = command.Parameters.Add("@CustomerID", SqlDbType.NChar);
         param.Direction = ParameterDirection.Input;
         param.Value = this.ddlCustomer.SelectedItem.Value;

         param = command.Parameters.Add(
            "@ShipperID", SqlDbType.Int);
         param.Direction = ParameterDirection.Input;
         param.Value = this.ddlShipper.SelectedValue;

         param = command.Parameters.Add(
            "@OrderID", SqlDbType.Int);
         param.Direction = ParameterDirection.Output;

         command.ExecuteNonQuery(); // Wykonujemy procedur skadowan.

         // Pobieramy identyfikator kolumny.
         OrderID = Convert.ToInt32(command.Parameters["@OrderID"].Value);

         // Utworzenie cigu znakowego uaktualniajcego tabel orderDetails.
         string strAddOrderDetails = "Insert into [Order Details] " +
            "(OrderID, ProductID, UnitPrice, Quantity, Discount) " +
            "values(" + OrderID + ", " + this.ddlProduct.SelectedValue + ", " +
            this.txtUnitPrice.Text + ", " + this.txtQuantity.Text + ", " +
            this.txtDiscount.Text + ")";

         // Ustawienie obiektu Command uaktualniajcego histori bdw.
         command.CommandType = CommandType.Text;
         command.CommandText = strAddOrderDetails;

         // Wykonanie polecenie Insert.
         command.ExecuteNonQuery();

         // Zatwierdzenie transakcji.
         transaction.Commit();
      }
      catch (Exception e)
      {
         Trace.Write(e.Message);
         transaction.Rollback();
      }
      finally
      {
         connection.Close();
      }
      this.txtDiscount.Text = string.Empty;
      this.txtQuantity.Text = string.Empty;
      this.txtUnitPrice.Text = string.Empty;
      this.lblNewOrderID.Text = OrderID.ToString();
   }

   private void UpdateDBTransaction()
   {
      // Cig znakowy poczenie do poczenia si z baz danych Bugs.
      string connectionString =
      "Data Source=Brahams;Initial Catalog=Northwind;Integrated Security =True";

      // Tworzenie obiektu Connection, inicjalizacja
      // cigu znakowego poczenia i jego otworzenie.
      System.Data.SqlClient.SqlConnection connection =
         new System.Data.SqlClient.SqlConnection(connectionString);
      connection.Open();

      // Utworzenie drugiego obiektu Command dla tabeli historii bdw.
      System.Data.SqlClient.SqlCommand command =
         new System.Data.SqlClient.SqlCommand();
      command.Connection = connection;

      command.CommandText = "spAddOrderTransactions";
      command.CommandType = CommandType.StoredProcedure;

      // Deklaracja obiektu parameter.
      System.Data.SqlClient.SqlParameter param;

      // Dodanie kadego parametru i ustawienie jego kierunku oraz wartoci.
      string customerID = this.ddlCustomer.SelectedValue.ToString();
      param = command.Parameters.AddWithValue("@CustomerID", customerID);
      param.DbType = DbType.StringFixedLength;
      param.Direction = ParameterDirection.Input;

      int shipperID = Convert.ToInt32(this.ddlShipper.SelectedValue);
      param = command.Parameters.AddWithValue("@ShipperID", shipperID);
      param.DbType = DbType.Int32;
      param.Direction = ParameterDirection.Input;

      int productID = Convert.ToInt32(this.ddlProduct.SelectedValue);
      param = command.Parameters.AddWithValue("@ProductID", productID);
      param.DbType = DbType.Int32;
      param.Direction = ParameterDirection.Input;

      decimal price = Convert.ToDecimal(this.txtUnitPrice.Text);
      param = command.Parameters.AddWithValue("@UnitPrice", price);
      param.DbType = DbType.Decimal;
      param.Direction = ParameterDirection.Input;

      Int16 quantity = Convert.ToInt16(this.txtQuantity.Text);
      param = command.Parameters.AddWithValue("@Quantity", quantity);
      param.DbType = DbType.Int16;
      param.Direction = ParameterDirection.Input;

      double discount = Convert.ToDouble(this.txtDiscount.Text);
      param = command.Parameters.AddWithValue("@Discount", discount);
      param.DbType = DbType.Double;
      param.Direction = ParameterDirection.Input;

      param = command.Parameters.AddWithValue("@orderID", 0);
      param.DbType = DbType.Int32;
      param.Direction = ParameterDirection.Output;

      command.ExecuteNonQuery(); // Wykonanie procedury skadowanej.

      param = command.Parameters["@OrderID"];
      int newOrderID = (int)param.Value;
      this.lblNewOrderID.Text = newOrderID.ToString();
   }

   protected void OrdersGridView_PageIndexChanging(
      object sender, GridViewPageEventArgs e)
   {
      OrdersGridView.PageIndex = e.NewPageIndex;
      this.OrderDetailsPanel.Visible = false;
      BindGrid();
   }
} // Koniec klasy.
