//-----------------------------------------------------------------------
//  This file is part of the Microsoft Code Samples.
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation.  See these other
//materials for detailed information regarding Microsoft code samples.
// 
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//-----------------------------------------------------------------------

#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Samples.SqlServer;

#endregion

namespace Microsoft.Samples.SqlServer
{
	partial class frmMain : Form
	{
		private SqlConnection conn;
		private SqlTransaction tran;
		private Service cartClient;
		private Conversation dialog;
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Member")]
        private object[,] itemData;

		public frmMain()
		{
			// Create a connection
			conn = new SqlConnection(
				"Initial Catalog=ssb_ShoppingCart; Data Source=localhost;Integrated Security=SSPI;");
			// Open the connection
			conn.Open();

			// Create a service object
			cartClient = new Service("ShoppingCartClient", conn);
	
			// Set FetchSize to 1 in order to process one message at a time
			// i.e. use RECEIVE TOP(1)
			cartClient.FetchSize = 1;

			// Set default timeout to 1 minute
			cartClient.WaitforTimeout = TimeSpan.FromMinutes(1);

			itemData = new object[8, 3] 
				{	{3001, "Butter", 3.45},
					{3002, "Cheese", 7.89},
					{3003, "Cornflakes", 2.69},
					{3004, "Half-dozen eggs", 1.34},
					{3005, "Orange juice", 4.89},
					{3006, "Strawberry jelly", 3.59},
					{3007, "Skim milk", 2.69},
					{3008, "Whole wheat bread", 0.99}};
			InitializeComponent();
		}

		private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
		{
			conn.Close();
		}

		private void frmMain_Load(object sender, EventArgs e)
		{
			for (int i = 0; i <= itemData.GetUpperBound(0); i++)
			{
				cboItem.Items.Add(itemData[i, 1]);
			}
			paneShop.Hide();
			paneFinish.Hide();
			paneCreateOrder.Show();
		}

		private void btnCreateOrder_Click(object sender, EventArgs e)
		{
			tran = conn.BeginTransaction();
			dialog = cartClient.BeginDialog(
				"ShoppingCartService",
				null,
				"CartContract",
				TimeSpan.FromMinutes(15),
				false,
				conn,
				tran);
			tran.Commit();
			txtConversationHandle.Text = dialog.Handle.ToString();
			txtLabelCreateOrder.BackColor = System.Drawing.Color.LightSteelBlue;
			txtLabelShop.BackColor = System.Drawing.Color.RoyalBlue;
			paneCreateOrder.Hide();
			paneShop.Show();
		}

		private void cboItem_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (cboItem.SelectedIndex >= 0)
			{
				txtUnitPrice.Text = itemData[cboItem.SelectedIndex, 2].ToString();
				btnAdd.Enabled = true;
			}
			else
			{
				btnAdd.Enabled = false;
			}
		}

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])")]
        private void btnAdd_Click(object sender, EventArgs e)
		{
			int selectedItem = cboItem.SelectedIndex;
			if (selectedItem < 0 || selectedItem > itemData.GetUpperBound(0))
				return;
			string msgString = String.Format("<LineItem>\r\n\t<ItemNumber>{0}</ItemNumber>\r\n\t<Name>{1}</Name>\r\n\t<Quantity>{2}</Quantity>\r\n\t<UnitPrice>{3}\r\n\t</UnitPrice>\r\n</LineItem>",
				itemData[selectedItem, 0], itemData[selectedItem, 1], nudQuantity.Value, itemData[selectedItem, 2]);
			MemoryStream body = new MemoryStream(Encoding.ASCII.GetBytes(msgString));

            Microsoft.Samples.SqlServer.Message message =
                new Microsoft.Samples.SqlServer.Message("AddItem", body);
			tran = conn.BeginTransaction();
			dialog.Send(message, conn, tran);
			tran.Commit();

			LogMessage(message, true);

			cboItem.SelectedIndex = -1;
			txtUnitPrice.Clear();
			nudQuantity.Value = 1;
			if (!lstItems.Items.Contains(itemData[selectedItem, 1]))
				lstItems.Items.Add(itemData[selectedItem, 1]);
			btnRemove.Enabled = true;
			btnConfirm.Enabled = true;
		}

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")]
        private void btnRemove_Click(object sender, EventArgs e)
		{
			string item = (string)lstItems.SelectedItem;
			int itemNumber = -1;
			for (int i = 0; i <= itemData.GetUpperBound(0); i++)
				if (item == (string) itemData[i, 1])
				{
					itemNumber = (int) itemData[i, 0];
					break;
				}
			if (itemNumber == -1)
				return;

			string msgString = String.Format("<LineItem>\r\n\t<ItemNumber>{0}</ItemNumber>\r\n</LineItem>",
							itemNumber);
			MemoryStream body = new MemoryStream(Encoding.ASCII.GetBytes(msgString));

            Microsoft.Samples.SqlServer.Message message = new
                Microsoft.Samples.SqlServer.Message("RemoveItem", body);
			tran = conn.BeginTransaction();
			dialog.Send(message, conn, tran);
			tran.Commit();

			LogMessage(message, true);

			lstItems.Items.Remove(item);
			if (lstItems.Items.Count <= 0)
			{
				btnRemove.Enabled = false;
				btnConfirm.Enabled = false;
			}
		}

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1306:SetLocaleForDataTypes")]
        private void btnConfirm_Click(object sender, EventArgs e)
		{
            Microsoft.Samples.SqlServer.Message message = new
                    Microsoft.Samples.SqlServer.Message("Confirm", null);
			tran = conn.BeginTransaction();
            dialog.Send(message, conn, tran);
			tran.Commit();

			txtLabelShop.BackColor = System.Drawing.Color.LightSteelBlue;
			txtLabelFinish.BackColor = System.Drawing.Color.RoyalBlue;
			paneShop.Hide();
			paneFinish.Show();

			tran = conn.BeginTransaction();
			cartClient.GetConversation(dialog, conn, tran);
			message = dialog.Receive();
			LogMessage(message, false);
			if (message == null)
				return;

			XmlReader xreader = new XmlTextReader(message.Body);
			DataSet ds = new DataSet("Invoice");
			ds.ReadXml(xreader);
			dataGridView1.DataSource = ds;
			dataGridView1.DataMember = "LineItem";

			XmlDocument xdoc = new XmlDocument();
			message.Body.Seek(0, SeekOrigin.Begin);
			xdoc.Load(message.Body);
			XmlElement xmlNumberItems = (XmlElement)
				xdoc.DocumentElement.GetElementsByTagName("NumberItems")[0];
			XmlElement xmlTotalAmount = (XmlElement)
				xdoc.DocumentElement.GetElementsByTagName("TotalAmount")[0];
			txtNumberItems.Text = xmlNumberItems.InnerText;
			txtTotalAmount.Text = xmlTotalAmount.InnerText;

			dialog.End(conn, tran);
			tran.Commit();
		}

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.Windows.Forms.TextBoxBase.AppendText(System.String)")]
        private void LogMessage(Microsoft.Samples.SqlServer.Message message, bool sent)
        {
			if (sent)
			{
				txtLog.AppendText("Sent: [" + message.Type + "]\r\n");
			}
			else
			{
				txtLog.AppendText("Received: [" + message.Type + "]\r\n");
			}

			if (message.Body != null)
			{
				message.Body.Seek(0, SeekOrigin.Begin);
				StreamReader reader = new StreamReader(message.Body, Encoding.ASCII);
				txtLog.AppendText(reader.ReadToEnd() + "\r\n\r\n");
				txtLog.Select(txtLog.TextLength, 0);
				message.Body.Seek(0, SeekOrigin.Begin);
			}
			else
			{
				txtLog.AppendText("\r\n");
			}
		}
	}
}