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 System.Xml ;
using System.IO ;
using System.Xml.Serialization ;
using System.Text ;
using System.Configuration ;
//using Microsoft.Web.Services2.Security ;
//using Microsoft.Web.Services2.Security.Tokens ;
//using Microsoft.Web.Services2.Security.X509 ;
using Microsoft.RFIDLab.EPCISDemo.Common ;
using Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS ;

namespace Microsoft.RFIDLab.EPCISDemo
{
	/// <summary>
	/// Performs operations for receiving-agent.
	/// </summary>
	public class ReceivingAgent : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.Label Label2;
		protected System.Web.UI.WebControls.Button btnReceiveGoods;
		protected System.Web.UI.WebControls.HyperLink lnkPrint;
		protected System.Web.UI.WebControls.Button btnSendShipmentNotice;
		protected System.Web.UI.WebControls.Button btnShipGoods;
		protected System.Web.UI.WebControls.TextBox txtXml;
		protected System.Web.UI.WebControls.Xml Xml1;

		private ASNGenerationService.Pip3B2AdvanceShipmentNotification
			objPipNotification ;
		protected System.Web.UI.WebControls.Label lblMessage;
		protected System.Web.UI.WebControls.Button btnMoveToNextPage;
		protected System.Web.UI.WebControls.Label lblInformation;
		private static string ClientBase64KeyId =
			ConfigurationSettings.AppSettings["ClientBase64KeyId"] ;
	
		/// <summary>
		/// Invoked when the page-loads.
		/// </summary>
		/// <param name="sender">The source of the event. </param>
		/// <param name="e">The event-arguments. </param>
		private void Page_Load ( object sender, System.EventArgs e )
		{
			objPipNotification =
				( ASNGenerationService.Pip3B2AdvanceShipmentNotification )
				Session["ASN"] ; // get the ASN from the session

			if ( objPipNotification == null )
				Response.Redirect ( "OrderDetails.aspx?session_expired=true",
					true ) ; // end if

			if ( ! IsPostBack ) // if the page is loading for the first time
			{
				lblMessage.Text = "<b>Items delivered</b> by Shipping Agent to Receiving Agent. Accept Item delivery.</B>" ;
				lblInformation.Text = "Shipment Notification";

				// create a new XML-serializer
				XmlSerializer serializer = new XmlSerializer (
					objPipNotification.GetType () ) ;
				MemoryStream stream = new MemoryStream () ;
				// serialize the ASN into the memory-stream using the serializer
				serializer.Serialize ( stream, objPipNotification ) ;
				// get the XML string-form of the ASN
				string xml = Encoding.ASCII.GetString ( stream.ToArray () ) ;

				// if the request-mode is for printing
				if ( Request.QueryString["mode"] == "print" )
				{
					// create a new XML document and load it with the ASN
					XmlDocument doc = new XmlDocument () ;
					doc.LoadXml ( xml ) ;
					txtXml.Visible = false ; // hide the text-box
					Xml1.Visible = true ; // make the XML control visible
					Xml1.Document = doc ; // set the source-document for it
					// set the XSLT transform
					Xml1.TransformSource = "ASN.xslt" ;
					// set the properties for the print-link
					lnkPrint.Text = "Print ASN" ;
					lnkPrint.NavigateUrl = "javascript:window.print()" ;
					lnkPrint.ImageUrl = "images/printer.gif" ;

				} // end if

				else // the request-mode is not for printing
				{
					// set the properties for the print-link
					lnkPrint.Text = "Printer Friendly Version" ;
					lnkPrint.NavigateUrl = Request.Path + "?mode=print" ;
					lnkPrint.ImageUrl = "images/printer_friendly.gif" ;
					Xml1.Visible = false ; // hide the XML control
					txtXml.Visible = true ; // show the text-box
					// set the text for the text-box as the ASN
					txtXml.Text = xml ;
					txtXml.Height = 600 ; // set the height of the text-box

				} // end else

			} // end if

		} // end of Page_Load ()

		#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.btnReceiveGoods.Click += new System.EventHandler(this.btnReceiveGoods_Click);
			this.btnSendShipmentNotice.Click += new System.EventHandler(this.btnSendShipmentNotice_Click);
			this.btnShipGoods.Click += new System.EventHandler(this.btnShipGoods_Click);
			this.btnMoveToNextPage.Click += new System.EventHandler(this.btnMoveToNextPage_Click);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		/// <summary>
		/// Invoked when the 'Ship goods' button is clicked.
		/// </summary>
		/// <param name="sender">The source of the event. </param>
		/// <param name="e">The event-arguments. </param>
		private void btnShipGoods_Click ( object sender, System.EventArgs e )
		{
			if ( objPipNotification != null ) // if the ASN is not null
			{
				
				// check whether security is enabled or not
				string enableSecurity =
					ConfigurationSettings.AppSettings["EnableWSSecurity"] ;

				if ( enableSecurity != null && enableSecurity.ToLower ()
					== "true" ) // if security is enabled
				{
//					X509SecurityToken token = null ;
//					X509CertificateStore store =
//						X509CertificateStore.LocalMachineStore (
//						X509CertificateStore.MyStore ) ; // local machine store
//					// retrieve the token from the store
//					token = RetrieveTokenFromStore ( store, ClientBase64KeyId ) ;
//					proxy.RequestSoapContext.Security.Tokens.Add( token );
//					proxy.RequestSoapContext.Security.Elements.Add (
//						new MessageSignature ( token ) ) ;

				} // end if

				ReceiptAcknowledgement acknowledgement =
					( ReceiptAcknowledgement ) Session["ReceiptAcknowledgement"] ;

				Common.OrderInformation objOrder = CreateOrderInformationObject () ;

				// create an instance of the track and trace data-base manager
				TrackTraceDBManager manager = new TrackTraceDBManager (
					TrackTraceDBManager.Constants.ReceivingAgent ) ;
				DateTime current = DateTime.Now ; // current date-time
				ArrayList result = GetTagList () ; // get the list of EPCs
				object[] array = result.ToArray () ;// get the EPC-array
				
				////Send item delivered epc event to Receiver.
				ReceiverWS.ReceiverWebService recProxy = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.ReceiverWebService();
				
				ReceiverWS.EquipmentProductCodeInformation robjEPCEvent = new ReceiverWS.EquipmentProductCodeInformation();

				//Fillup Steward information. This is the person who 'owns' the EPC currently.
				robjEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value	= acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
				robjEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.EmailAddress					= acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress;
				robjEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber;
				robjEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber;

				robjEPCEvent.CreationTimeStamp.DateTimeStamp = System.DateTime.UtcNow.ToUniversalTime().ToString("yyyyMMddThhmmss.000Z");
				robjEPCEvent.BusinessTransactionIdentifier = objPipNotification.thisDocumentIdentifier.ProprietaryDocumentIdentifier;
			
				//fill up Agent information. this indicates who is sending this event.
				robjEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value = "Receiving Agent";
				robjEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = "425 653 2444";
				robjEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = "425 653 2333";
				robjEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress = "ReceivingAgent@ReceivingAgent.com";

				//add EPC information.				
				robjEPCEvent.EquipmentProductCodeEvent = new ReceiverWS.EquipmentProductCodeEvent[objOrder.PalletItemCollection.Count] ;
				int i = 0 ;

				foreach(Common.PalletItem pallet in objOrder.PalletItemCollection)
				{
					ReceiverWS.EquipmentProductCodeEvent objEPCEventPallet = new ReceiverWS.EquipmentProductCodeEvent();
					objEPCEventPallet.EquipmentProductCode.FreeFormText.Value = pallet.EpcTagId.FreeFormText.Value;
					objEPCEventPallet.EventType = Convert.ToString(TrackTraceDBManager.Constants.ItemDeliveredFromReceivingAgentToReceiver);
					objEPCEventPallet.AssociateEquipmentProductCode = new ReceiverWS.AssociateEquipmentProductCode[pallet.CaseItemCollection.Count] ;
					robjEPCEvent.EquipmentProductCodeEvent[i++] = objEPCEventPallet;					
					int j = 0 ;

					/*****
					 * Ramesh. Added default constructors into ReceiverWS proxy. however we can
					 * uncomment and use below constructors also if needed.
					 * 
					objEPCEventPallet.Agent = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.Agent();
					objEPCEventPallet.Agent.reportedBy = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.reportedBy();
					objEPCEventPallet.Agent.reportedBy.PartnerDescription = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.PartnerDescription2();
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.contactName2();
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.FreeFormText2();
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.facsimileNumber2();
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber = new Microsoft.RFIDLab.EPCISDemo.ReceiverWS.telephoneNumber2();
					*/

					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value = 
						objPipNotification.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
						objPipNotification.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress =
						objPipNotification.toRole.PartnerRoleDescription.ContactInformation.EmailAddress;
					
					objEPCEventPallet.EPCEventIdentifier = TrackTraceDBManager.Constants.ItemDeliveredFromReceivingAgentToReceiver.ToString () ;
					objEPCEventPallet.EventLocation.GlobalLocationIdentifier = "Receiving Agent Location" ;
					
					foreach(Common.CaseItem caseitem in pallet.CaseItemCollection)
					{
						ReceiverWS.AssociateEquipmentProductCode objEPCEventCase = new ReceiverWS.AssociateEquipmentProductCode();
						objEPCEventCase.FreeFormText.Value = caseitem.EpcTagId.FreeFormText.Value;
						objEPCEventPallet.AssociateEquipmentProductCode[j++] = objEPCEventCase;
					}
				}

				//call Receiver proxy.
				recProxy.ReceiveEPCEvent(robjEPCEvent);

				//If Above call fails, meaning, Receiver Web service is down, then we 
				//log the event in our local database and send the same to shipping agent.
				//other wise the same event cascades back to us.
				//for now we assume secure, reliable communication. So commenting following
				//code to avoid duplicate logging of events.
				
				/*
				// add the event to the local database
				manager.AddFullEpcStatusInfo ( array,
					TrackTraceDBManager.Constants.ItemDeliveredFromReceivingAgentToReceiver,
					current, "Receiving Agent", "Shipping Agent", "Receiving Agent Location" ) ;
					
				// create a Shipping Agent web-service proxy
				ShippingAgentWebService proxy = new ShippingAgentWebService () ;


				EquipmentProductCodeInformation objEPCEvent = new EquipmentProductCodeInformation();

				//Fillup Steward information. This is the person who 'owns' the EPC currently.
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value	= acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.EmailAddress					= acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber;

				objEPCEvent.CreationTimeStamp.DateTimeStamp = System.DateTime.UtcNow.ToUniversalTime().ToString("yyyyMMddThhmmss.000Z");
				objEPCEvent.BusinessTransactionIdentifier = objPipNotification.thisDocumentIdentifier.ProprietaryDocumentIdentifier;
			
				//fill up Agent information. this indicates who is sending this event.
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value = "Receiving Agent";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = "425 653 2444";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = "425 653 2333";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress = "ReceivingAgent@ReceivingAgent.com";

				//add EPC information.				
				objEPCEvent.EquipmentProductCodeEvent = new EquipmentProductCodeEvent[objOrder.PalletItemCollection.Count] ;
				int i = 0 ;

				foreach(Common.PalletItem pallet in objOrder.PalletItemCollection)
				{
					EquipmentProductCodeEvent objEPCEventPallet = new EquipmentProductCodeEvent();
					objEPCEventPallet.EquipmentProductCode.FreeFormText.Value = pallet.EpcTagId.FreeFormText.Value;
					objEPCEventPallet.EventType = Convert.ToString(TrackTraceDBManager.Constants.ItemDeliveredFromReceivingAgentToReceiver);
					objEPCEventPallet.AssociateEquipmentProductCode = new AssociateEquipmentProductCode[pallet.CaseItemCollection.Count] ;
					objEPCEvent.EquipmentProductCodeEvent[i++] = objEPCEventPallet;					
					int j = 0 ;

					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value =
						"Shipping Agent" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
						"425 779 5533" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
						"425 779 4433" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress =
						"ShippingAgent@ShippingAgent.com" ;
					objEPCEventPallet.EPCEventIdentifier = TrackTraceDBManager.Constants.ItemDeliveredFromReceivingAgentToReceiver.ToString () ;
					objEPCEventPallet.EventLocation.GlobalLocationIdentifier = "Receiving Agent Location" ;

					foreach(Common.CaseItem caseitem in pallet.CaseItemCollection)
					{
						AssociateEquipmentProductCode objEPCEventCase = new AssociateEquipmentProductCode();
						objEPCEventCase.FreeFormText.Value = caseitem.EpcTagId.FreeFormText.Value;
						objEPCEventPallet.AssociateEquipmentProductCode[j++] = objEPCEventCase;
					}
				}

				// invoke the web-service method to add the event
				 proxy.ReceiveEPCEvent ( objEPCEvent ) ;
				 */
			

				lblMessage.Text = "<B>Goods successfully shipped to receiver. </B>" ;
				// disable all buttons except move to next page
				btnReceiveGoods.Visible = false ;
				btnSendShipmentNotice.Visible = false ;
				btnShipGoods.Visible = false ;
				txtXml.Height = 600 ;
				lnkPrint.Visible = false ;
							
				//Move to Receiver Location.
				Response.Redirect ( "Receiver.aspx" ) ;

			} // end if			
		
		} // end of btnShipGoods_Click ()

		/// <summary>
		/// Invoked when the 'Receive goods' button is clicked.
		/// </summary>
		/// <param name="sender">The source of the event. </param>
		/// <param name="e">The event-arguments. </param>
		private void btnReceiveGoods_Click ( object sender, System.EventArgs e )
		{
			if ( objPipNotification != null ) // if the ASN is not null
			{
				// create a Shipping Agent web-service proxy
				ShippingAgentWebService proxy = new ShippingAgentWebService () ;
				// check whether security is enabled or not
				string enableSecurity =
					ConfigurationSettings.AppSettings["EnableWSSecurity"] ;

				if ( enableSecurity != null && enableSecurity.ToLower ()
					== "true" ) // if security is enabled
				{
//					X509SecurityToken token = null ;
//					X509CertificateStore store =
//						X509CertificateStore.LocalMachineStore (
//						X509CertificateStore.MyStore ) ; // local machine store
//					// retrieve the token from the store
//					token = RetrieveTokenFromStore ( store, ClientBase64KeyId ) ;
//					proxy.RequestSoapContext.Security.Tokens.Add( token );
//					proxy.RequestSoapContext.Security.Elements.Add (
//						new MessageSignature ( token ) ) ;

				} // end if

				// create an instance of the track and trace data-base manager
				TrackTraceDBManager manager = new TrackTraceDBManager (
					TrackTraceDBManager.Constants.ReceivingAgent ) ;
				ArrayList result = GetTagList () ; // get the list of EPCs
				object[] array = result.ToArray () ; // get the EPC-array
				DateTime current = DateTime.Now ; // current date-time
				
				// add the event to the local database
				manager.AddFullEpcStatusInfo ( array,
					TrackTraceDBManager.Constants.ItemReceivedFromReceivingAgent,
					current, "Receiving Agent", "Shipping Agent", "Receiving Agent Location" ) ;

				Common.OrderInformation objOrder = CreateOrderInformationObject () ;
				EquipmentProductCodeInformation objEPCEvent = new EquipmentProductCodeInformation();

				//Fillup Steward information. This is the person who 'owns' the EPC currently.
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value	= "Shipping Agent" ;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.EmailAddress					= "ShippingAgent@ShippingAgent.com" ;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = "425 779 4433" ;
				objEPCEvent.Steward.managedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = "425 779 5533" ;

				objEPCEvent.CreationTimeStamp.DateTimeStamp = System.DateTime.UtcNow.ToUniversalTime().ToString("yyyyMMddThhmmss.000Z");
				objEPCEvent.BusinessTransactionIdentifier = objPipNotification.thisDocumentIdentifier.ProprietaryDocumentIdentifier;
			
				//fill up Agent information. this indicates who is sending this event.
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value = "Receiving Agent";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber = "425 653 2444";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber = "425 653 2333";
				objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress = "ReceivingAgent@ReceivingAgent.com";

				//add EPC information.				
				objEPCEvent.EquipmentProductCodeEvent = new EquipmentProductCodeEvent[objOrder.PalletItemCollection.Count] ;
				int i = 0 ;

				foreach(Common.PalletItem pallet in objOrder.PalletItemCollection)
				{
					EquipmentProductCodeEvent objEPCEventPallet = new EquipmentProductCodeEvent();
					objEPCEventPallet.EquipmentProductCode.FreeFormText.Value = pallet.EpcTagId.FreeFormText.Value;
					objEPCEventPallet.EventType = Convert.ToString(TrackTraceDBManager.Constants.ItemReceivedFromReceivingAgent);
					objEPCEventPallet.AssociateEquipmentProductCode = new AssociateEquipmentProductCode[pallet.CaseItemCollection.Count] ;
					objEPCEvent.EquipmentProductCodeEvent[i++] = objEPCEventPallet;
					int j = 0 ;

					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value =
						"Shipping Agent" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
						"425 779 5533" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
						"425 779 4433" ;
					objEPCEventPallet.Agent.reportedBy.PartnerDescription.ContactInformation.EmailAddress =
						"ShippingAgent@ShippingAgent.com" ;
					objEPCEventPallet.EPCEventIdentifier = TrackTraceDBManager.Constants.ItemReceivedFromReceivingAgent.ToString () ;
					objEPCEventPallet.EventLocation.GlobalLocationIdentifier = "Receiving Agent Location" ;

					foreach(Common.CaseItem caseitem in pallet.CaseItemCollection)
					{
						AssociateEquipmentProductCode objEPCEventCase = new AssociateEquipmentProductCode();
						objEPCEventCase.FreeFormText.Value = caseitem.EpcTagId.FreeFormText.Value;
						objEPCEventPallet.AssociateEquipmentProductCode[j++] = objEPCEventCase;
					}
				}


				// invoke the web-service method to add the event

				proxy.ReceiveEPCEvent ( objEPCEvent ) ;

				lblMessage.Text = "Items successfully received from Shipping Agent.<br> Send <b>Shipment Receipt Notification</b>(PIP4B2) to Shipping Agent confirming receipt of all Items" ;
				btnReceiveGoods.Enabled = false ; // disable the receive-button
				// enable the send shipment-notice receipt button
				btnSendShipmentNotice.Visible = true ;
				Pip4B2ShipmentReceiptNotification objPip =
					CreatePIP4B2Notification () ; // create the Pip4B2 object				
				// get the acknowledgement
				ReceiptAcknowledgement acknowledgement = GetAcknowledgement () ;
				// put it into the session
				Session["ReceiptAcknowledgement"] = acknowledgement ;
				// create a new XML-serializer
				XmlSerializer serializer = new XmlSerializer (
					objPip.GetType () ) ;
				MemoryStream stream = new MemoryStream () ;
				/* serialize the acknowledgement into the memory-stream using
				 * the serializer */
				serializer.Serialize ( stream, objPip ) ;
				// get the XML string-form of the ASN
				string xml = Encoding.ASCII.GetString ( stream.ToArray () ) ;

				Xml1.Visible = false ; // hide the XML control
				txtXml.Visible = true ; // show the text-box
				// set the text for the text-box as the receipt
				lnkPrint.Visible = false ;
				txtXml.Text = xml ;
				txtXml.Height = 600 ; // set the height of the text-box
				lblInformation.Text = "Shipment Receipt Notification" ;
				btnMoveToNextPage.Visible = false ;
				btnReceiveGoods.Visible = false ;
				btnSendShipmentNotice.Visible = true ;
				btnShipGoods.Visible = false ;

			} // end if			
		
		} // end of btnReceiveGoods_Click ()

		/// <summary>
		/// Invoked when the 'Send Shipment notice' button is clicked.
		/// </summary>
		/// <param name="sender">The source of the event. </param>
		/// <param name="e">The event-arguments. </param>
		private void btnSendShipmentNotice_Click ( object sender,
			System.EventArgs e )
		{
			if ( objPipNotification != null )
			{
				// create a Shipping Agent web-service proxy
				ShippingAgentWebService proxy = new ShippingAgentWebService () ;
				// check whether security is enabled or not
				string enableSecurity =
					ConfigurationSettings.AppSettings["EnableWSSecurity"] ;

				if ( enableSecurity != null && enableSecurity.ToLower ()
					== "true" ) // if security is enabled
				{
//					X509SecurityToken token = null ;
//					X509CertificateStore store =
//						X509CertificateStore.LocalMachineStore (
//						X509CertificateStore.MyStore ) ; // local machine store
//					// retrieve the token from the store
//					token = RetrieveTokenFromStore ( store, ClientBase64KeyId ) ;
//					proxy.RequestSoapContext.Security.Tokens.Add( token );
//						proxy.RequestSoapContext.Security.Elements.Add (
//							new MessageSignature ( token ) ) ;

				} // end if

				// get the acknowledgement from the session
				ReceiptAcknowledgement acknowledgement =
					( ReceiptAcknowledgement ) Session["ReceiptAcknowledgement"] ;

				Common.OrderInformation order = CreateOrderInformationObject () ;

				// send it to the web-service
				BusinessResponse businessResponse = new BusinessResponse () ;
				businessResponse.GlobalProcessIndicatorCode = "4B2" ;
				Pip4B2ShipmentReceiptNotification objPip = CreatePIP4B2Notification();
				
				businessResponse.objAcknowledgement = acknowledgement ;
				businessResponse.objPip = objPip ;
				Session["Pip4B2Object"] = objPip ;

				bool response = proxy.ReceiveBusinessAcknowledgement (
					businessResponse ) ;

				if ( response == true ) // if the response is true
				{
					lblMessage.Text = "Shipment Receipt Notification sent to Shipping Agent. <b>Ship Items to Receiver.</b> <br> Move to Receiver Location." ;
					// make a new data-base manager
					TrackTraceDBManager manager = new TrackTraceDBManager (
						TrackTraceDBManager.Constants.ReceivingAgent ) ;
					ArrayList tagList = GetTagList () ; // get the list of tags
					// update the status in the local data-base

					manager.AddFullEpcStatusInfo ( tagList.ToArray (),
						TrackTraceDBManager.Constants.NotifyOfShipmentReceiptFromReceivingAgentToShippingAgent,
						DateTime.Now, "Receiving Agent", "Shipping Agent", "Receiving Agent Location" ) ;
					
					// disable the send shipment-notice receipt button
					btnSendShipmentNotice.Visible = false ;
					// disable the receive-goods button, in case it was enabled
					btnReceiveGoods.Visible = false ;
					btnMoveToNextPage.Visible = false ;
					btnShipGoods.Visible = true ; // show the ship-goods button
					txtXml.Height = 600 ;
					lblInformation.Text = "Shipment Receipt Notification" ;
					lnkPrint.Visible = false ;

				} // end if

			} // end if
		
		} // end of btnSendShipmentNotice_Click ()

		/// <summary>
		/// Creates an order-information object with all the EPC tags in the
		/// session.
		/// </summary>
		/// <returns>Order-information object containing all pallet and case
		/// EPCs. </returns>
		private Common.OrderInformation CreateOrderInformationObject()
		{
			Common.OrderInformation objOrder = new Common.OrderInformation () ;			
			objOrder.OrderNumber = objPipNotification.thisDocumentIdentifier.ProprietaryDocumentIdentifier ;
			objOrder.PalletItemCollection = new PalletItemCollection () ;

			// for each ASN shipping container in the ASN
			foreach ( ASNGenerationService.ShippingContainer container in 
				objPipNotification.AdvancedShipmentNotification.Shipment.ShippingContainer )
			{
				// get the proprietary serial-identifier
				string propriertarySerialIdentifer =
					container.shippingContainerIdentifier.ProprietarySerialIdentifier ;
				int index = propriertarySerialIdentifer.IndexOf ( ' ' ) ;
				string epc = null ;

				// set the EPC from the serial-identifier
				if ( index >= 0 )
					epc = propriertarySerialIdentifer.Substring ( 0,
						index  ) ; // end if

				else
					epc = propriertarySerialIdentifer ; // end else

				PalletItem pallet = new PalletItem () ;
				pallet.EpcTagId.FreeFormText.Value = epc ;
				objOrder.PalletItemCollection.Add ( pallet ) ;

				// for each shipping container-item in the container
				foreach ( ASNGenerationService.ShippingContainerItem item in
					container.ShippingContainerItem )
				{
					// get the proprietary serial-identifier
					propriertarySerialIdentifer =
						item.shippingContainerItemIdentifier.ProprietarySerialIdentifier ;
					index = propriertarySerialIdentifer.IndexOf ( ' ' ) ;
					epc = null ;

					// set the EPC from the serial-identifier
					if ( index >= 0 )
						epc = propriertarySerialIdentifer.Substring ( 0,
							index  ) ; // end if

					else
						epc = propriertarySerialIdentifer ; // end else

					CaseItem caseObj = new CaseItem () ;
					caseObj.EpcTagId.FreeFormText.Value = epc ;
					pallet.CaseItemCollection.Add ( caseObj ) ; // add it to the list

				} // end nested for					

			} // end outer for

			return objOrder ;

		}

		/// <summary>
		/// Returns a list of all EPCs in the shipment.
		/// </summary>
		/// <returns>Array-list containing all the tags. </returns>
		private ArrayList GetTagList ()
		{
			ArrayList result = new ArrayList () ;

			if ( objPipNotification != null ) // if the ASN is not null
			{
				// for each ASN shipping container in the ASN
				foreach ( ASNGenerationService.ShippingContainer container in 
					objPipNotification.AdvancedShipmentNotification.Shipment.ShippingContainer )
				{
					// get the proprietary serial-identifier
					string propriertarySerialIdentifer =
						container.shippingContainerIdentifier.ProprietarySerialIdentifier ;
					int index = propriertarySerialIdentifer.IndexOf ( ' ' ) ;
					string epc = null ;

					// set the EPC from the serial-identifier
					if ( index >= 0 )
						epc = propriertarySerialIdentifer.Substring ( 0,
							index  ) ; // end if

					else
						epc = propriertarySerialIdentifer ; // end else

					result.Add ( epc ) ; // add it to the list

					// for each shipping container-item in the container
					foreach ( ASNGenerationService.ShippingContainerItem item in
						container.ShippingContainerItem )
					{
						// get the proprietary serial-identifier
						propriertarySerialIdentifer =
							item.shippingContainerItemIdentifier.ProprietarySerialIdentifier ;
						index = propriertarySerialIdentifer.IndexOf ( ' ' ) ;
						epc = null ;

						// set the EPC from the serial-identifier
						if ( index >= 0 )
							epc = propriertarySerialIdentifer.Substring ( 0,
								index  ) ; // end if

						else
							epc = propriertarySerialIdentifer ; // end else

						result.Add ( epc ) ; // add it to the list

					} // end nested for					

				} // end outer for

			} // end if

			return result ; // return the result

		} // end of GetTagList ()

		/// <summary>
		/// Gets a receipt-acknowledgement.
		/// </summary>
		/// <returns>Acknowledgement. </returns>
		private ReceiptAcknowledgement GetAcknowledgement ()
		{
			// instantiate and populate the receipt-acknowledgement
			ReceiptAcknowledgement acknowledgement =
				new ReceiptAcknowledgement () ;

			if ( objPipNotification != null ) // if the ASN is not null
			{
				acknowledgement.fromRole = new fromRole1 () ;
				acknowledgement.fromRole.PartnerRoleDescription =
					new PartnerRoleDescription1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation =
					new ContactInformation1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName =
					new contactName1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
					new FreeFormText1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
					objPipNotification.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
					"Receiving Agent" ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress =
					"ReceivingAgent@ReceivingAgent.com" ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
					new facsimileNumber1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
					"748 985 5688" ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
					new telephoneNumber1 () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
					"748 485 5633" ;
				acknowledgement.fromRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode =
					"Receiving Agent Unique ID" ;
				acknowledgement.thisMessageDateTime =
					new thisMessageDateTime () ;
				acknowledgement.thisMessageDateTime.DateTimeStamp =
					DateTime.UtcNow.ToUniversalTime ().ToString ( "yyyyMMddThhmmss.000Z" ); ;
				acknowledgement.thisMessageIdentifier =
					new thisMessageIdentifier () ;
				acknowledgement.thisMessageIdentifier.ProprietaryMessageIdentifier =
					"Shipment receipt-notice. " ;
				acknowledgement.toRole = new toRole1 () ;
				acknowledgement.toRole.PartnerRoleDescription =
					new PartnerRoleDescription1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation =
					new ContactInformation1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName =
					new contactName1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
					new FreeFormText1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
					objPipNotification.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
					"Shipping Agent" ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.EmailAddress =
					"ShippingAgent@ShippingAgent.com" ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
					new facsimileNumber1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
					"425 779 5533" ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
					new telephoneNumber1 () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
					"425 779 4433" ;
				acknowledgement.toRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode =
					"Shipping Agent Unique ID" ;

			} // end if

			return acknowledgement ;

		} // end of GetAcknowledgement ()

//		/// <summary>
//		/// Gets an X-509 security-token.
//		/// </summary>
//		/// <param name="store">The store to get from. </param>
//		/// <param name="keyIdentifier">The key to identify. </param>
//		/// <returns>Instance of the security-token. </returns>
//		private static X509SecurityToken RetrieveTokenFromStore (
//			X509CertificateStore store, string keyIdentifier )
//		{
//			// if the store specified is null, throw an exception 
//			if ( store == null )
//				throw new ArgumentNullException ( "store" ) ; // end if
//            
//			X509SecurityToken token = null ;
//
//			try 
//			{
//				if ( store.OpenRead () ) // if the store gets opened for reading
//				{
//					/* Place the key-ID of the certificate in a byte-array.
//					 * This key-ID represents the Wse2Quickstart certificate
//					 * included with the WSE 2.0 Quickstarts.
//					 * ClientBase64KeyId is defined in the ClientBase.AppBase
//					 * class */
//					X509CertificateCollection certs =
//						store.FindCertificateByKeyIdentifier (
//						Convert.FromBase64String ( keyIdentifier ) ) ;
//
//					// if a certificate is found, get the first
//					if ( certs.Count > 0 )						
//						token = new X509SecurityToken ( (
//							( X509Certificate ) certs[0] ) ) ; // end if
//
//					else // no certificates found - throw an exception
//						throw new ApplicationException (
//							"X509-certificate not found in local store." ) ;
//							// end else
//
//				} // end if
//
//			} // end of try block
//
//			finally
//			{
//				if ( store != null ) // if the store is not null, close it
//					store.Close () ; // end if
//
//			} // end of finally block
//  
//			return token ; // return the token
//
//		} // end of RetrieveTokenFromStore ()

		/// <summary>
		/// Invoked when the 'Move to next page' button is clicked.
		/// </summary>
		/// <param name="sender">The source of the event. </param>
		/// <param name="e">The event-arguments. </param>
		private void btnMoveToNextPage_Click ( object sender,
			System.EventArgs e )
		{
			Response.Redirect ( "Receiver.aspx" ) ;

		} // end of btnMoveToNextPage_Click ()

		/// <summary>
		/// Creates a Pip4B2 notification to be sent.
		/// </summary>
		/// <returns>Pip4B2 shipment-receipt notification object. </returns>
		private Pip4B2ShipmentReceiptNotification CreatePIP4B2Notification ()
		{
			Pip4B2ShipmentReceiptNotification objPip =
				new Pip4B2ShipmentReceiptNotification () ;

			Common.OrderInformation order = CreateOrderInformationObject () ;
			
			objPip.fromRole = new fromRole2 () ;
			objPip.fromRole.PartnerRoleDescription =
				new PartnerRoleDescription2 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation =
				new ContactInformation3 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName =
				new contactName3 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
				new FreeFormText3 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
				objPipNotification.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
				"Receiving Agent" ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress =
				"ReceivingAgent@ReceivingAgent.com" ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
				new facsimileNumber3 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
				"748 985 5688" ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
				new telephoneNumber3 () ;
			objPip.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
				"748 485 5633" ;
			objPip.fromRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode =
				"Receiving Agent Unique ID" ;
			objPip.thisDocumentGenerationDateTime =
				new thisDocumentGenerationDateTime2 () ;
			objPip.thisDocumentGenerationDateTime.DateTimeStamp =
				DateTime.UtcNow.ToUniversalTime ().ToString ( "yyyyMMddThhmmss.000Z" ); ;
			objPip.thisDocumentIdentifier =
				new thisDocumentIdentifier2 () ;
			objPip.thisDocumentIdentifier.ProprietaryDocumentIdentifier =
				order.OrderNumber ;
			objPip.toRole = new toRole2 () ;
			objPip.toRole.PartnerRoleDescription =
				new PartnerRoleDescription2 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation =
				new ContactInformation3 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.contactName =
				new contactName3 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
				new FreeFormText3 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
				objPipNotification.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
				"Shipping Agent" ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.EmailAddress =
				"ShippingAgent@ShippingAgent.com" ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
				new facsimileNumber3 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
				"425 779 5533" ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
				new telephoneNumber3 () ;
			objPip.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
				"425 779 4433" ;
			objPip.toRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode =
				"Shipping Agent Unique ID" ;
			int i = 0 ;
			objPip.ShipmentReceiptInformationResource =
				new ShipmentReceiptInformationResource[order.PalletItemCollection.Count] ;

			foreach ( Common.PalletItem pallet in
				order.PalletItemCollection )
			{
				objPip.ShipmentReceiptInformationResource[i] = new ShipmentReceiptInformationResource () ;
				objPip.ShipmentReceiptInformationResource[i].shipmentIdentifier =
					new shipmentIdentifier () ;
				objPip.ShipmentReceiptInformationResource[i].shipmentIdentifier.ProprietaryReferenceIdentifier =
					pallet.EpcTagId.FreeFormText.Value ;
				objPip.ShipmentReceiptInformationResource[i].ShipmentReceiptNotificationLineItem =
					new ShipmentReceiptNotificationLineItem[pallet.CaseItemCollection.Count] ;

				int j = 0 ;

				foreach ( Common.CaseItem caseObj in
					pallet.CaseItemCollection )
				{
					objPip.ShipmentReceiptInformationResource[i].ShipmentReceiptNotificationLineItem[j] =
						new ShipmentReceiptNotificationLineItem () ;
					objPip.ShipmentReceiptInformationResource[i].ShipmentReceiptNotificationLineItem[j].ProprietarySerialIdentifier =
						new string[1] ;
					objPip.ShipmentReceiptInformationResource[i].ShipmentReceiptNotificationLineItem[j++].ProprietarySerialIdentifier[0] =
						caseObj.EpcTagId.FreeFormText.Value ;

				} // end nested for

				i ++ ;

			} // end for

			return objPip;
		}

	} // class definition over

} // end of namespace
