using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using Microsoft.RFIDLab.EPCISDemo.Common;
using Microsoft.RFIDLab.EPCISDemo.EPCEvent ;

namespace Microsoft.RFIDLab.EPCISDemo.ReceivingAgentWS
{
	/// <summary>
	/// Web-service for receiving-agent operations.
	/// </summary>	
	[System.Xml.Serialization.XmlInclude(typeof(PIP3B2.Pip3B2AdvanceShipmentNotification)),WebService(Namespace="http://www.microsoft.com/RFIDLab/TrackAndTraceDemo")]
	public class ReceivingAgentWebService : System.Web.Services.WebService
	{
		private TrackTraceDBManager dbManager = null ; // the data-base manager
 
		/// <summary>
		/// Default constructor.
		/// </summary>
		public ReceivingAgentWebService ()
		{
			//CODEGEN: This call is required by the ASP.NET Web Services Designer
			InitializeComponent () ;

			// initialize the data-base manager
			dbManager = new TrackTraceDBManager (
				TrackTraceDBManager.Constants.ReceivingAgent ) ;

		} // end of constructor ()

		#region Component Designer generated code
		
		//Required by the Web Services Designer 
		private IContainer components = null;
				
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if(disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);		
		}
		
		#endregion

		/// <summary>
		/// Receives and processes a business-request.
		/// </summary>
		/// <param name="objBusinessRequest"></param>
		/// <returns></returns>
		[System.Web.Services.WebMethod()]			
		public BusinessResponse ReceiveBusinessRequest (
			BusinessRequest objBusinessRequest )
		{
			// create a new business-response
			BusinessResponse objBusinessResponse = new BusinessResponse () ;

			if ( objBusinessRequest.GlobalProcessIndicatorCode.ToUpper ()
				== "3B2" ) //if the process-indicator is 3B2
			{
				// set the process-indicator code
				objBusinessResponse.GlobalProcessIndicatorCode =
					objBusinessRequest.GlobalProcessIndicatorCode ;
				// get the PIP object
				PIP3B2.Pip3B2AdvanceShipmentNotification objPip =
					( PIP3B2.Pip3B2AdvanceShipmentNotification )
					objBusinessRequest.objPip ;
				// create a new receipt-acknowledgement
				ReceiptAcknowledgement acknowledgement =
					new ReceiptAcknowledgement () ;
				// populate the fields in the acknowledgement
				acknowledgement.fromRole = new PIP3B2.fromRole () ;
				acknowledgement.fromRole.PartnerRoleDescription =
					new PIP3B2.PartnerRoleDescription () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation =
					new PIP3B2.ContactInformation () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName =
					new PIP3B2.contactName () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
					new PIP3B2.FreeFormText () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
					objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
					objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress =
					objPip.toRole.PartnerRoleDescription.ContactInformation.EmailAddress ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
					new PIP3B2.facsimileNumber () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
					objPip.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
					new PIP3B2.telephoneNumber () ;
				acknowledgement.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
					objPip.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber ;
				acknowledgement.fromRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode =
					objPip.toRole.PartnerRoleDescription.GlobalPartnerRoleClassificationCode ;
				acknowledgement.receivedDocumentDateTime =
					new receivedDocumentDateTime () ;
				acknowledgement.receivedDocumentDateTime.DateTimeStamp =
					DateTime.UtcNow.ToUniversalTime ().ToString ( "yyyyMMddThhmmss.000Z" ); ;
				acknowledgement.receivedDocumentIdentifier =
					new receivedDocumentIdentifier () ;
				acknowledgement.receivedDocumentIdentifier.ProprietaryDocumentIdentifier =
					objPip.thisDocumentIdentifier.ProprietaryDocumentIdentifier ;
				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 PIP3B2.toRole () ;
				acknowledgement.toRole.PartnerRoleDescription =
					new PIP3B2.PartnerRoleDescription () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation =
					new PIP3B2.ContactInformation () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName =
					new PIP3B2.contactName () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText =
					new PIP3B2.FreeFormText () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang =
					objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.lang ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value =
					objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.EmailAddress =
					objPip.fromRole.PartnerRoleDescription.ContactInformation.EmailAddress ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber =
					new PIP3B2.facsimileNumber () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber =
					objPip.fromRole.PartnerRoleDescription.ContactInformation.facsimileNumber.CommunicationsNumber ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber =
					new PIP3B2.telephoneNumber () ;
				acknowledgement.toRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber =
					objPip.fromRole.PartnerRoleDescription.ContactInformation.telephoneNumber.CommunicationsNumber ;
				
				// set the acknowledgement
				objBusinessResponse.objAcknowledgement = acknowledgement ;
				objBusinessResponse.objPip = objPip ; // set the PIP object

				// log the Receipt and Acknowledgment of the request for all EPC's in the database.
				LogEPCStatus ( objPip,
					TrackTraceDBManager.Constants.NotifyOfAsnFromShippingAgentToReceivingAgent ) ;

				LogEPCStatus ( objPip,
					TrackTraceDBManager.Constants.AcknowledgementFromReceivingAgentToShippingAgent ) ;

			} // end if

			return objBusinessResponse ; // return the response
						
		} // end of ReceiveBusinessRequest ()

		/// <summary>
		/// Receives and processes a business-acknowledgement.
		/// </summary>
		/// <param name="objResponse">A business-response object. </param>
		/// <returns>True or false, depending upon the business-response. </returns>
		[System.Web.Services.WebMethod()]			
		public bool ReceiveBusinessAcknowledgement (
			BusinessResponse objResponse )
		{
			// get the PIP object
			PIP3B2.Pip3B2AdvanceShipmentNotification objPip =
				( PIP3B2.Pip3B2AdvanceShipmentNotification ) objResponse.objPip ;

			if ( objPip != null ) // if the PIP is not null. log the event
				LogEPCStatus ( objPip,
					TrackTraceDBManager.Constants.ItemDeliveredFromShippingAgentToReceivingAgent ) ;
					// end if

			return true ;

		} // end of ReceiveBusinessAcknowledgement ()

		/// <summary>
		/// Receives an EPC event.
		/// </summary>
		/// <param name="objEPCEvent">Encapsultaed event-object, containing all
		/// pallet and case EPCs. </param>
		[WebMethod ()]
		public void ReceiveEPCEvent (
			EPCEvent.EquipmentProductCodeInformation objEPCEvent )
		{			
			// create a new Equipment product-code information object
			EPCEvent.EquipmentProductCodeInformation obj =
				new EquipmentProductCodeInformation () ;
			/* create a new equipment product-code information object for the
			 * shipping-agent web-service */
			ShippingAgentWS.EquipmentProductCodeInformation temp =
				new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.EquipmentProductCodeInformation () ;

			if ( objEPCEvent != null ) // if the EPC event object is not null
			{
				// get the order-number
				string ordernumber = objEPCEvent.BusinessTransactionIdentifier ;
				// set the order-number
				temp.BusinessTransactionIdentifier = ordernumber ;
				temp.EquipmentProductCodeEvent =
					new ShippingAgentWS.EquipmentProductCodeEvent[objEPCEvent.EquipmentProductCodeEventCollection.Count] ;
				string epctag ;
				int eventid ;
				System.DateTime datetime ;
				int i = 0 ;
				temp.CurrentAgent= new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.CurrentAgent () ;
				temp.CurrentAgent.Agent = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.Agent () ;
				temp.CurrentAgent.Agent.reportedBy = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.reportedBy () ;
				temp.CurrentAgent.Agent.reportedBy.PartnerDescription = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.PartnerDescription2 () ;
				temp.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.ContactInformation2 () ;
				temp.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.contactName2 () ;
				temp.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.FreeFormText2 () ;
				temp.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value =
					objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value ;

				// for each pallet
				foreach ( EPCEvent.EquipmentProductCodeEvent objPallet in
					objEPCEvent.EquipmentProductCodeEventCollection )
				{
					// get the EPC tag
					epctag = objPallet.EquipmentProductCode.FreeFormText.Value ;

					eventid = Convert.ToInt32 ( objPallet.EPCEventIdentifier ) ;
					datetime = System.DateTime.Now ;
					temp.EquipmentProductCodeEvent[i] =
						new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.EquipmentProductCodeEvent () ;
					temp.EquipmentProductCodeEvent[i].EventType = objPallet.EventType ;
					temp.EquipmentProductCodeEvent[i].EPCEventIdentifier = objPallet.EPCEventIdentifier ;
					temp.EquipmentProductCodeEvent[i].EventLocation = new ShippingAgentWS.EventLocation () ;
					temp.EquipmentProductCodeEvent[i].EventLocation.GlobalLocationIdentifier = objPallet.EventLocation.GlobalLocationIdentifier ;
					temp.EquipmentProductCodeEvent[i].EquipmentProductCode = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.EquipmentProductCode () ;
					temp.EquipmentProductCodeEvent[i].AssociateEquipmentProductCode = new ShippingAgentWS.AssociateEquipmentProductCode[objPallet.AssociateEquipmentProductCodeCollection.Count] ;
					temp.EquipmentProductCodeEvent[i].EquipmentProductCode.FreeFormText = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.FreeFormText2 () ;
					temp.EquipmentProductCodeEvent[i].EquipmentProductCode.FreeFormText.Value = objPallet.EquipmentProductCode.FreeFormText.Value ;
					temp.EquipmentProductCodeEvent[i].Agent = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.Agent () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.reportedBy () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy.PartnerDescription = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.PartnerDescription2 () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy.PartnerDescription.ContactInformation = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.ContactInformation2 () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy.PartnerDescription.ContactInformation.contactName = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.contactName2 () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.FreeFormText2 () ;
					temp.EquipmentProductCodeEvent[i].Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value =
						objPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value ;

					dbManager.AddFullEpcStatusInfo ( epctag, eventid, datetime,
						objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value,
						objPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value,
						objPallet.EventLocation.GlobalLocationIdentifier ) ;

					int j = 0 ;

					// for each case
					foreach ( EPCEvent.AssociateEquipmentProductCode objCase in
						objPallet.AssociateEquipmentProductCodeCollection )
					{
						// get the EPC tag
						epctag = objCase.FreeFormText.Value ;

						dbManager.AddFullEpcStatusInfo ( epctag, eventid, datetime,
							objEPCEvent.CurrentAgent.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value,
							objPallet.Agent.reportedBy.PartnerDescription.ContactInformation.contactName.FreeFormText.Value,
							objPallet.EventLocation.GlobalLocationIdentifier ) ;

						temp.EquipmentProductCodeEvent[i].AssociateEquipmentProductCode[j] = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.AssociateEquipmentProductCode () ;
						temp.EquipmentProductCodeEvent[i].AssociateEquipmentProductCode[j].FreeFormText = new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.FreeFormText2 () ;
						temp.EquipmentProductCodeEvent[i].AssociateEquipmentProductCode[j++].FreeFormText.Value = objCase.FreeFormText.Value ;

					} // end nested for

					i ++ ;

				} // end outer for

				// create an instance of the shipping-agent web-service proxy
				ShippingAgentWS.ShippingAgentWebService proxy =
					new Microsoft.RFIDLab.EPCISDemo.ShippingAgentWS.ShippingAgentWebService () ;
				// send the event to the shipping-agent web-service
				proxy.ReceiveEPCEvent ( temp ) ;

			} // end if
			
		} // end of ReceiveEPCEvent ()

		/// <summary>
		/// Logs the EPC status to the data-base.
		/// </summary>
		/// <param name="objPip">The PIP object. </param>
		/// <param name="eventType">The event-type. </param>
		private void LogEPCStatus (
			PIP3B2.Pip3B2AdvanceShipmentNotification objPip,
			int eventType )
		{
			if ( objPip == null ) // if the PIP object is not null
				return ; // end if

			string strFromRole = null;
			string strToRole = null;
			
			if(eventType == TrackTraceDBManager.Constants.NotifyOfAsnFromShippingAgentToReceivingAgent)
			{
				strFromRole = objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
				strToRole = objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
            }
			else if(eventType == TrackTraceDBManager.Constants.AcknowledgementFromReceivingAgentToShippingAgent)
			{
				strFromRole = objPip.toRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
				strToRole = objPip.fromRole.PartnerRoleDescription.ContactInformation.contactName.FreeFormText.Value;
			}


			// for each shipping container
			foreach ( PIP3B2.ShippingContainer container in
				objPip.AdvancedShipmentNotification.Shipment.ShippingContainerCollection )
			{
				// get the EPC
				string proprietarySerialIdentifier =
					container.shippingContainerIdentifier.ProprietarySerialIdentifier ;
				int index = proprietarySerialIdentifier.IndexOf ( ' ' ) ;
				string epc = null ;

				if ( index >= 0 )
					epc = proprietarySerialIdentifier.Substring ( 0, index ) ;
					// end if

				// add the event to the data-base
				dbManager.AddFullEpcStatusInfo ( epc, 
					eventType, 
					DateTime.Now,
					strFromRole,
					strToRole,
					"Receiving Agent Location" ) ;

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

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

					else
						epc = proprietarySerialIdentifier ; // end else

					// add the event to the data-base
					dbManager.AddFullEpcStatusInfo ( epc, 
						eventType, 
						DateTime.Now,
						strFromRole,
						strToRole,
						"Receiving Agent Location" ) ;

				} // end nested for

			} // end for

		} // end of LogEPCEvent ()

	} // class definition over

} // end of namespace
