using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.RFIDLab.EPCISDemo.Common;
using Microsoft.RFIDLab.EPCISDemo.VerisignEPCIS;

namespace Microsoft.RFIDLab.EPCISDemo
{
	/// <summary>
	/// Summary description for CaseEPCGeneration.
	/// </summary>
	public class CaseEPCGeneration : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.Button btnPrint;
		protected System.Web.UI.WebControls.Label lblOrderNumber;
		public DataTable dtCasesEPCList;
		protected System.Web.UI.WebControls.CheckBox chkEnablePrint;
		protected System.Web.UI.WebControls.Label lblStatus;
		protected System.Web.UI.WebControls.DataGrid dgCaseEPCDetails;
		protected System.Web.UI.WebControls.Button btnSaveToEPCIS;
		protected System.Web.UI.WebControls.Button btnStartPalletization;
		private Boolean blnPalletizationStarted = false;
		private int colIndex;
		private string errorMessage;
		private string caseEpc;
		private string caseURI;

		private void Page_Load(object sender, System.EventArgs e)
		{
			string strOrderNumber;

			dtCasesEPCList = new DataTable("CaseEPCList");
			dtCasesEPCList.Columns.Add("EPC");
			dtCasesEPCList.Columns.Add("Description-EPC");
			dtCasesEPCList.Columns.Add("EPCURI");
			dtCasesEPCList.Columns.Add("UPC");
			dtCasesEPCList.Columns.Add("Description");
			dtCasesEPCList.Columns.Add("Product ID");
			
			btnSaveToEPCIS.Visible=false;

			if (!Page.IsPostBack)
			{
				strOrderNumber= Request.Form["txtOrderNumber"];
				Session["OrderNumber"] = strOrderNumber;

				DatabaseManager dm = new DatabaseManager(System.Configuration.ConfigurationSettings.AppSettings["ManufacturerString"]);
				DataSet dsOrderDetails = dm.GetPurchaseOrderDetails(Convert.ToInt32(strOrderNumber));
				
				lblOrderNumber.Text = "Details for Order Number " + strOrderNumber;
				
				dgCaseEPCDetails.DataSource = dsOrderDetails;
				dgCaseEPCDetails.DataBind();
				
				if (System.Configuration.ConfigurationSettings.AppSettings["EnableCaseLabelPrinting"].Equals("false"))
				{
					btnPrint.Enabled = false;
					chkEnablePrint.Visible = true;
					chkEnablePrint.Text = "Enable Printing of labels";
				}
				else
					chkEnablePrint.Visible = false;
			}
			
			//Save EPC Information to EPCIS repository
			SaveCaseEPCToEPCIS(dtCasesEPCList);			
		}


		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);
			this.btnStartPalletization.Click += new System.EventHandler(this.btnStartPalletization_Click);
			this.chkEnablePrint.CheckedChanged += new System.EventHandler(this.chkEnablePrint_CheckedChanged);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		
		public DataTable GetEPCInformation(string orderNumber, string productId, string strUPC, string strDescription, int countOfCases)
		{
			int counter, serialNumber=0;

			DataTable dtEPCInformation = new DataTable("EPCInformation");
			dtEPCInformation.Columns.Add("EPC");
			dtEPCInformation.Columns.Add("Description-EPC");
			dtEPCInformation.Columns.Add("EPCURI");
			dtEPCInformation.Columns.Add("UPC");
			dtEPCInformation.Columns.Add("Description");
			dtEPCInformation.Columns.Add("Product ID");

			if (!blnPalletizationStarted)
			{			
				DatabaseManager dm = new DatabaseManager(System.Configuration.ConfigurationSettings.AppSettings["ManufacturerString"]);

				DataSet dsEPCDetailsForOrder = dm.GetPurchaseOrderCaseEPCDetails(Convert.ToInt32(orderNumber), Convert.ToInt32(productId));
				DataTable dtEPCDetailsForOrder = dsEPCDetailsForOrder.Tables[0];
			
				if (dtEPCDetailsForOrder.Rows.Count > 0)
				{
					lblOrderNumber.Text+= " Details retrieved from database for Product ID " + productId + ".";
					foreach (DataRow drEPCDetailsForOrder in dtEPCDetailsForOrder.Rows)	
					{
						colIndex = dtEPCDetailsForOrder.Columns.IndexOf("TagId");
						caseEpc = Convert.ToString(drEPCDetailsForOrder.ItemArray.GetValue(colIndex));
					
						caseURI = EPC.GetURIforEPCIS(caseEpc, out errorMessage);
						if (errorMessage != null)
						{
							throw new ApplicationException(errorMessage);
						}

						object[] rowData = new object[6];

						rowData[0] = caseEpc;
						rowData[1] = strDescription + " - Case EPC# " + caseEpc;
						rowData[2] = caseURI;
						rowData[3] = strUPC;
						rowData[4] = strDescription;
						rowData[5] = productId;

						dtEPCInformation.Rows.Add(rowData);
						dtCasesEPCList.Rows.Add(rowData);
					}
				}
				else
				{
					for (counter=0;counter<countOfCases;counter++)	
					{
						serialNumber = dm.GetNextSerialNumber(strUPC);
												
						caseEpc = EPC.Encode(strUPC, EPCEncoding.SGTIN64, 6, 3, serialNumber, out errorMessage);
						if (errorMessage != null)
						{
							throw new ApplicationException(errorMessage);
						}
						
						dm.UpdateProductNextSerialNumber(strUPC);

						caseURI = EPC.GetURIforEPCIS(caseEpc, out errorMessage);
						if (errorMessage != null)
						{
							throw new ApplicationException(errorMessage);
						}

						object[] rowData = new object[6];
				
						rowData[0] = caseEpc;
						rowData[1] = strDescription + " - Case EPC# " + caseEpc;
						rowData[2] = caseURI;
						rowData[3] = strUPC;
						rowData[4] = strDescription;
						rowData[5] = productId;
				
						dtEPCInformation.Rows.Add(rowData);
						dtCasesEPCList.Rows.Add(rowData);

						//Save the EPC information to the database
						//Parameters - Product UPC, Case EPC, Tag Type, Order Number, Product Number 
						dm.AddProductEpc(strUPC, caseEpc, 3, null, Convert.ToInt32(orderNumber), Convert.ToInt32(productId),  null);					
					}
				}
			}
			Session["CasesEPCList"] = dtCasesEPCList;
			Session["OrderNumber"] = orderNumber;

			return dtEPCInformation;
		}

		private void btnStartPalletization_Click(object sender, System.EventArgs e)
		{
			blnPalletizationStarted = true;
			Server.Transfer("Palletization.aspx", true);
		}

		private void btnPrint_Click(object sender, System.EventArgs e)
		{
			//Check if the session is still alive
			if (Session["CasesEPCList"] == null)
			{
				Response.Redirect("OrderDetails.aspx?session_expired=true", true);
			}
			
			dtCasesEPCList=(DataTable)Session["CasesEPCList"] ;
						
			if (dtCasesEPCList != null)
			{
				foreach (DataRow dr in dtCasesEPCList.Rows)	
				{
					//Print Case EPC
					string[][] caseArrayVariables = new string[][]
					{
						new string[] {"PRODUCT_NAME", Convert.ToString(dr["Description"])},
						new string[] {"PRODUCT_UPC",Convert.ToString(dr["UPC"])},
						new string[] {"CASE_EPC",Convert.ToString(dr["EPC"])}
					};

					RFIDTagPrintService.ServiceRFIDPrinting printWS = new Microsoft.RFIDLab.EPCISDemo.RFIDTagPrintService.ServiceRFIDPrinting();
					try
					{
						printWS.printRFIDTag("labelEPCISDemoCase.lwl","EPCISCasePrint", 1, caseArrayVariables);
					}
					catch (Exception ex)
					{
						throw ex;
					}
					break;
				}
			}
		}

		private void chkEnablePrint_CheckedChanged(object sender, System.EventArgs e)
		{
			btnPrint.Enabled = true;
			chkEnablePrint.Visible = false;
		
		}

		private void SaveCaseEPCToEPCIS(DataTable dtCasesEPCList)
		{
			bool eventsLogged = false;
			ObservationDataProfile wsObservationDataProfile = new ObservationDataProfile();
			
			UserTokenType objUserTokenType = new UserTokenType();
			objUserTokenType.UserName = System.Configuration.ConfigurationSettings.AppSettings["VerisignEPCISUserName"];
			objUserTokenType.Password = System.Configuration.ConfigurationSettings.AppSettings["VerisignEPCISPassword"];

			AuthInfoType objAuthInfoType = new AuthInfoType();
			objAuthInfoType.UserToken = objUserTokenType;				
			wsObservationDataProfile.AuthInfo = objAuthInfoType;

			logEvent[] epcEvents = new logEvent[1];

			epcEvents[0] = new logEvent();
			epcEvents[0].location = new IdentifierType();
			epcEvents[0].location.schemeAgencyID = "EAN.UCC";
			epcEvents[0].location.schemeID = "GLN";
			epcEvents[0].location.schemeURI = "urn:epc:id:gln";
			epcEvents[0].location.schemeVersionID = "1.0";
			epcEvents[0].location.Value = "urn:epc:id:gln:0124578.07296.9";
				
			epcEvents[0].observation = new ObservationType();
			epcEvents[0].observation.Command = "Shipping";
			epcEvents[0].observation.DateTime = System.DateTime.Now;

			int rowCount = dtCasesEPCList.Rows.Count;
			TagType[] objIndividualTag = new TagType[1];
						
			foreach (DataRow drCasesEPCList in dtCasesEPCList.Rows)	
			{
					
				//Print Case EPC
				string[][] caseArrayVariables = new string[][]
					{
						new string[] {"PRODUCT_NAME", Convert.ToString(drCasesEPCList["Description"])},
						new string[] {"PRODUCT_UPC",Convert.ToString(drCasesEPCList["UPC"])},
						new string[] {"CASE_EPC",Convert.ToString(drCasesEPCList["EPC"])}
					};

				//Logging for each individual tag as well
				objIndividualTag[0] = new TagType();

				//Tags in the EPC Network are identified by an identifier code. 
				//The universal structure ID element is reused to capture tag identification information.
				objIndividualTag[0].ID = new IdentifierType();
				objIndividualTag[0].ID.schemeID = "EPC";
				objIndividualTag[0].ID.schemeAgencyID = "EAN";			
				objIndividualTag[0].ID.schemeVersionID = "1.0";
				objIndividualTag[0].ID.schemeURI = Convert.ToString(drCasesEPCList["EPCURI"]).Substring(1,Convert.ToString(drCasesEPCList["EPCURI"]).LastIndexOf(":"));
				objIndividualTag[0].ID.Value = Convert.ToString(drCasesEPCList["EPCURI"]);					
				
				epcEvents[0].observation.Tag = objIndividualTag;
				//eventsLogged = wsObservationDataProfile.logEvents(epcEvents);	
				eventsLogged = true;
			}

			if (eventsLogged)
			{
				lblStatus.Text = "Event(s) logged successfully" + @" to <a href=""http://microsoft.verisignepctest.com/"">Microsoft EPC IS</a>";
				lblStatus.ForeColor= System.Drawing.Color.Green;
			}
			else
			{
				lblStatus.Text = "Failed to log event(s)" + @" to <a href=""http://microsoft.verisignepctest.com/"">Microsoft EPC IS</a>";
				lblStatus.ForeColor=System.Drawing.Color.Red;
			}
		}
	}
}