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 Palletization.
	/// </summary>
	public class Palletization : System.Web.UI.Page
	{
		protected OpenDoubleListBox.DoubleListBox DoubleListBox1;
		private DataTable dtCasesEPCList;
		protected System.Web.UI.WebControls.DataGrid palletEPCDatagrid;
		protected System.Web.UI.WebControls.Button btnCreatePallet;
		protected System.Web.UI.WebControls.Button btnGenerateASN;
		protected System.Web.UI.WebControls.Literal Literal1;
		protected System.Web.UI.WebControls.Label lblCasesToPalletize;
		private String orderNumber;
		protected System.Web.UI.HtmlControls.HtmlTable tblDoubleListBox;
		private int colIndex;
	
		private void Page_Load(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"];
			orderNumber = (String)Session["OrderNumber"];
            
			BindPalletDataGrid();

			int intRowCount = dtCasesEPCList.Rows.Count;
			//if there are no cases left to palletize, hide the list box
			if( intRowCount == 0)
			{
				tblDoubleListBox.Visible = false;
				DoubleListBox1.Visible = false;
				btnCreatePallet.Visible = false;
				btnGenerateASN.Visible = true;
			}
			
			lblCasesToPalletize.Text = "Number of cases left to palletize: " + intRowCount.ToString();
			if (!Page.IsPostBack & intRowCount > 0)
			{
				DoubleListBox1.ListBox1DataTextField = "Description-EPC";
				DoubleListBox1.ListBox1DataValueField = "EPC";
				DoubleListBox1.ListBox1DataSource = dtCasesEPCList;
				DoubleListBox1.DataBind();
			}
			
			Session["OrderNumber"] = orderNumber;
		}

		#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.btnCreatePallet.Click += new System.EventHandler(this.btnCreatePallet_Click);
			this.btnGenerateASN.Click += new System.EventHandler(this.btnGenerateASN_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		public DataTable GetAssociatedCasesEPCInformation(string palletEPC)
		{
			DatabaseManager dm = new DatabaseManager(System.Configuration.ConfigurationSettings.AppSettings["ManufacturerString"]);
			orderNumber = (String)Session["OrderNumber"];
			
			DataSet dsAssociatedCasesForPallet = dm.GetAssociatedCasesEPCInformation(Convert.ToInt32(orderNumber),palletEPC);			

			dtCasesEPCList=(DataTable) Session["CasesEPCList"];
			DataTable dtAssociatedCasesEPCList = dsAssociatedCasesForPallet.Tables[0];
			//Add the URI column to the datatable
			dtAssociatedCasesEPCList.Columns.Add("TagIdURI");

			ArrayList rowsToRemove = new ArrayList();			
			foreach (DataRow dr in dtAssociatedCasesEPCList.Rows)
			{
				colIndex = dtAssociatedCasesEPCList.Columns.IndexOf("TagId");
				string tagID = Convert.ToString(dr.ItemArray.GetValue(colIndex));

				string errorMessage = null;
				string tagIDURI = EPC.GetURIforEPCIS(tagID, out errorMessage);
				if (errorMessage != null)
				{
					throw new ApplicationException(errorMessage);
				}
				
				dr["TagIdURI"] = tagIDURI;

				//Remove the rows from the case EPC list that have already been palletized
				foreach (DataRow dr1 in dtCasesEPCList.Rows)
				{
					int index1 = dtCasesEPCList.Columns.IndexOf("EPC");
					string strUPC = Convert.ToString(dr1.ItemArray.GetValue(index1));
					if (tagID == strUPC)
					{
						rowsToRemove.Add(dr1);
					}
				}				
			}
			for (int counter=0; counter<rowsToRemove.Count;counter++)
			{
				dtCasesEPCList.Rows.Remove((DataRow)rowsToRemove[counter]);
			}
			Session["CasesEPCList"]=dtCasesEPCList;
			return dtAssociatedCasesEPCList;
		}

		private void btnCreatePallet_Click(object sender, System.EventArgs e)
		{
            if (DoubleListBox1.SelectedItems.Count == 0)
			{
				lblCasesToPalletize.Text = "No cases were selected for adding to the pallet. <BR>The Pallet EPC was not generated.";
				return;
			}

			DatabaseManager dm = new DatabaseManager(System.Configuration.ConfigurationSettings.AppSettings["ManufacturerString"]);
			int nextCompanySerialNumber = dm.GetNextCompanySerialNumber();
			string errorMessage;
			
			//Generate Pallet EPC
			// Filter value for Pallet is 4
			string palletId = EPC.Encode(Constants.CompanyPrefix , EPCEncoding.SSCC64, 6, 4, nextCompanySerialNumber, out errorMessage);
			if (errorMessage != null)
			{
				throw new ApplicationException(errorMessage);
			}
			
			dm.UpdateCompanyNextSerialNumber();

			//Get the URI for the pallet EPC
			string palletIdURI = EPC.GetURIforEPCIS(palletId, out errorMessage);
			if (errorMessage != null)
			{
				throw new ApplicationException(errorMessage);
			}
			
			lblCasesToPalletize.Text = "Pallet created with EPC " + palletId + " " + palletIdURI + "<BR>";
			lblCasesToPalletize.Text += "The following cases were added to the pallet - ";
			
			//Remove the cases from the list of cases left to palletize
			ArrayList childTags = new ArrayList();
			ArrayList rowsToRemove = new ArrayList();
			foreach (ListItem item in DoubleListBox1.SelectedItems)
			{
				string tagID = item.Value.ToString();
				lblCasesToPalletize.Text += tagID + " ";
				childTags.Add(tagID);
				
				foreach (DataRow dr in dtCasesEPCList.Rows)
				{
					colIndex = dtCasesEPCList.Columns.IndexOf("EPC");
					string strUPC = Convert.ToString(dr.ItemArray.GetValue(colIndex));
					if (tagID == strUPC)
					{
						rowsToRemove.Add(dr);
					}
				}				
			}

			for (int counter=0; counter<rowsToRemove.Count;counter++)
			{
				dtCasesEPCList.Rows.Remove((DataRow)rowsToRemove[counter]);
			}
            
			//Save the pallet EPC to the database
			//The product id used for pallets is -1
			dm.AddPalletEpc(palletId, null, Convert.ToInt32(orderNumber), -1, childTags);

			Session["CasesEPCList"]=dtCasesEPCList;

			//Save pallet containment details to EPCIS
			SaveToEPCISContainmentProfile(palletId, childTags);

			DoubleListBox1.SelectedItems.Clear();
			DoubleListBox1.ListBox1DataTextField = "Description-EPC";
			DoubleListBox1.ListBox1DataValueField = "EPC";
			DoubleListBox1.ListBox1DataSource = dtCasesEPCList;
			DoubleListBox1.DataBind();

			if( dtCasesEPCList.Rows.Count == 0)
			{
				tblDoubleListBox.Visible = false;
				DoubleListBox1.Visible = false;
				btnCreatePallet.Visible = false;
				btnGenerateASN.Visible = true;
			}

			//Bind data to the pallet datagrid
			BindPalletDataGrid();		
		}

		private void btnGenerateASN_Click(object sender, System.EventArgs e)
		{			
			Response.Redirect("DisplayASN.aspx", true);			
		}

		private void SaveToEPCISContainmentProfile(string palletId, ArrayList childTags)
		{
			string errorMessage;
			string palletTagIDURI = EPC.GetURIforEPCIS(palletId, out errorMessage);
			if (errorMessage != null)
			{
				throw new ApplicationException(errorMessage);
			}

			ContainmentProfileService wsContainmentProfileService = new ContainmentProfileService();
			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;				
			wsContainmentProfileService.AuthInfo = objAuthInfoType;

			EPCArrayIn objEPCArray = new EPCArrayIn();
			//Set the Pallet EPC URI
			objEPCArray.epc = palletTagIDURI;
			objEPCArray.time = System.DateTime.Now;

			string[] objCaseEPCList = new string[childTags.Count];
			
			for (int counter=0; counter<childTags.Count;counter++)
			{
				string caseTagIDURI = EPC.GetURIforEPCIS((string)childTags[counter], out errorMessage);
				if (errorMessage != null)
				{
					throw new ApplicationException(errorMessage);
				}
				objCaseEPCList[counter] = caseTagIDURI;
			}

			objEPCArray.epcList = objCaseEPCList;				
			//wsContainmentProfileService.setContents(objEPCArray);
		}

		//This function retrieves data and binds it to the pallet data grid.
		private void BindPalletDataGrid()
		{
			DatabaseManager dm = new DatabaseManager(System.Configuration.ConfigurationSettings.AppSettings["ManufacturerString"]);
			DataSet dsPalletEPCDetailsForOrder = dm.GetPalletEPCInformationForOrder(Convert.ToInt32(orderNumber));

			DataTable dtPalletEPCDetailsForOrder = dsPalletEPCDetailsForOrder.Tables[0];
			
			DataTable dtPalletEPCList = new DataTable("PalletEPCList");
			dtPalletEPCList.Columns.Add("PalletEPC");
			dtPalletEPCList.Columns.Add("PalletEPCURI");
			
			if (dtPalletEPCDetailsForOrder.Rows.Count > 0)
			{
				//Pallet details present in database
				foreach (DataRow dr in dtPalletEPCDetailsForOrder.Rows)	
				{
					colIndex = dtPalletEPCDetailsForOrder.Columns.IndexOf("TagId");
					string palletEpc = Convert.ToString(dr.ItemArray.GetValue(colIndex));
					object[] rowData = new object[2];

					string errorMessage;
					string palletEpcURI = EPC.GetURIforEPCIS(palletEpc, out errorMessage);
					if (errorMessage != null)
					{
						throw new ApplicationException(errorMessage);
					}

					rowData[0] = palletEpc;
					rowData[1] = palletEpcURI;

					dtPalletEPCList.Rows.Add(rowData);
				}
				palletEPCDatagrid.DataSource = dtPalletEPCList;
				palletEPCDatagrid.DataBind();
			}
			Session["PalletEPCList"] = dtPalletEPCList;
		}
	}
}
