/*******************************************************************************
 *  Copyright 2017 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *******************************************************************************/
package cdac.medinfo.sdk.hl7282.hl7model.messages.patientadministration;

import cdac.medinfo.sdk.hl7282.baselibs.messagedictionary.MessageMapReader;
import cdac.medinfo.sdk.hl7282.baselibs.messages.ACK;
import cdac.medinfo.sdk.hl7282.baselibs.messages.IMessageFactory;
import cdac.medinfo.sdk.hl7282.baselibs.messages.Message;
import cdac.medinfo.sdk.hl7282.exceptions.MessageNotSupportedException;
import cdac.medinfo.sdk.hl7282.utils.EnumHL7System;
import cdac.medinfo.sdk.hl7282.utils.EnumMessageCode;
import cdac.medinfo.sdk.hl7282.utils.EnumMessageStructure;
import cdac.medinfo.sdk.hl7282.utils.EnumTriggerEvent;
import cdac.medinfo.sdk.hl7282.utils.IMap;
import cdac.medinfo.sdk.hl7282.utils.IMessageMapReader;

class ADTMessageFactory implements IMessageFactory
{
	private static ADTMessageFactory objADTMessageFactory = null;
	private static IMessageMapReader objMessamapReader = null;
	
	private ADTMessageFactory()
	{}

	/**
	 * Creates Object of ADTMessageFactory.
	 * @return ADTMessageFactory object of ADTMessageFactory
	 */
	public static ADTMessageFactory createInstance()
	{
		if(objADTMessageFactory == null)
		{
			objMessamapReader = MessageMapReader.createInstance(EnumHL7System.HL7_SYSTEM_PATIENTADMINISTRATION);
			objADTMessageFactory = new ADTMessageFactory();
		}
		return objADTMessageFactory;
	}

	/**
	 * Creates Message with specified enumerations of Trigger Event & Message Structure
	 * @param enumMessageCode enumerated value of Message Code
	 * @param enumTriggerEvent enumerated value of Trigger Event
	 * @return Message instance of Message
	 */
	public Message createMessage(EnumMessageCode enumMessageCode,EnumTriggerEvent enumTriggerEvent)
	{
		Message objMessage = null;
		
		IMap objMessageMap = getMessageMap(enumMessageCode, enumTriggerEvent);
		
		if(enumMessageCode == EnumMessageCode.ACK)
		{
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode, null);
			if(isEventSupported(enumTriggerEvent))
				objMessage = new ACK(enumTriggerEvent, objMessageMap);
			else
				throw new MessageNotSupportedException(enumTriggerEvent.getValue());
		}
		else
		{
			switch(enumTriggerEvent)
			{
			case A01:
				objMessage = new ADT_A01(objMessageMap);
				break;
			case A02:
				objMessage = new ADT_A02(objMessageMap);
				break;
			case A03:
				objMessage = new ADT_A03(objMessageMap);
				break;
			case A04 : 
				objMessage = new ADT_A04(objMessageMap);
				break;
			case A05 : 
				objMessage = new ADT_A05(objMessageMap);
				break;
			case A06 : 
				objMessage = new ADT_A06(objMessageMap);
				break;
			case A07 : 
				objMessage = new ADT_A07(objMessageMap);
				break;
			case A08 : 
				objMessage = new ADT_A08(objMessageMap);
				break;
			case A09 : 
				objMessage = new ADT_A09(objMessageMap);
				break;
			case A10 : 
				objMessage = new ADT_A10(objMessageMap);
				break;
			case A11 :
				objMessage = new ADT_A11(objMessageMap); 
				break;
			case A12 :
				objMessage = new ADT_A12(objMessageMap); 
				break;
			case A13 : 
				objMessage = new ADT_A13(objMessageMap); 
				break;
			case A14 : 
				objMessage = new ADT_A14(objMessageMap); 
				break;
			case A15 :
				objMessage = new ADT_A15(objMessageMap); 
				break;
			case A16 :
				objMessage = new ADT_A16(objMessageMap); 
				break;
			case A17 :
				objMessage = new ADT_A17(objMessageMap); 
				break;
		
		
			case A20:
				objMessage = new ADT_A20(objMessageMap);
				break;
			case A21 :
				objMessage = new ADT_A21(objMessageMap); 
				break;
			case A22 :
				objMessage = new ADT_A22(objMessageMap); 
				break;
			case A23 :
				objMessage = new ADT_A23(objMessageMap); 
				break;
			case A24 :
				objMessage = new ADT_A24(objMessageMap); 
				break;
			case A25 :
				objMessage = new ADT_A25(objMessageMap); 
				break;
			case A26 :
				objMessage = new ADT_A26(objMessageMap); 
				break;
			case A27 :
				objMessage = new ADT_A27(objMessageMap); 
				break;
			case A28 :
				objMessage = new ADT_A28(objMessageMap); 
				break;
			case A29 :
				objMessage = new ADT_A29(objMessageMap); 
				break;

			case A31 :
				objMessage = new ADT_A31(objMessageMap); 
				break;
			case A32 :
				objMessage = new ADT_A32(objMessageMap); 
				break;
			case A33 :
				objMessage = new ADT_A33(objMessageMap); 
				break;

			case A37 :
				objMessage = new ADT_A37(objMessageMap); 
				break;
			case A38 :
				objMessage = new ADT_A38(objMessageMap); 
				break;
			case A40 :
				objMessage = new ADT_A40(objMessageMap); 
				break;
			case A41 :
				objMessage = new ADT_A41(objMessageMap); 
				break;
			case A42 :
				objMessage = new ADT_A42(objMessageMap); 
				break;
			case A43 :
				objMessage = new ADT_A43(objMessageMap); 
				break;
			case A44 :
				objMessage = new ADT_A44(objMessageMap); 
				break;
			case A45 :
				objMessage = new ADT_A45(objMessageMap); 
				break;

			case A47 :
				objMessage = new ADT_A47(objMessageMap); 
				break;

			case A49 :
				objMessage = new ADT_A49(objMessageMap); 
				break;
			case A50 :
				objMessage = new ADT_A50(objMessageMap); 
				break;
			case A51 :
				objMessage = new ADT_A51(objMessageMap); 
				break;
			case A52 :
				objMessage = new ADT_A52(objMessageMap); 
				break;
			case A53 :
				objMessage = new ADT_A53(objMessageMap); 
				break;
			case A54 :
				objMessage = new ADT_A54(objMessageMap); 
				break;
			case A55 :
				objMessage = new ADT_A55(objMessageMap); 
				break;
			case A60 :
				objMessage = new ADT_A60(objMessageMap); 
				break;
			case A61 :
				objMessage = new ADT_A61(objMessageMap); 
				break;
			case A62 :
				objMessage = new ADT_A62(objMessageMap); 
				break;
			case Q21 : 
				objMessage = new QBP_Q21(objMessageMap);
				break;
			case Q22 : 
				objMessage = new QBP_Q22(objMessageMap);
				break;
			case Q23 : 
				objMessage = new QBP_Q23(objMessageMap);
				break;
			case Q24 : 
				objMessage = new QBP_Q24(objMessageMap);
				break;
			case Q32 : 
				objMessage = new QBP_Q32(objMessageMap);
				break;
			case K21 : 
				objMessage = new RSP_K21(objMessageMap);
				break;
			case K22 :
				objMessage = new RSP_K22(objMessageMap);
				break;
			case K23 : 
				objMessage = new RSP_K23(objMessageMap);
				break;
			case K24 : 
				objMessage = new RSP_K24(objMessageMap);
				break;
			case K32 : 
				objMessage = new RSP_K32(objMessageMap);
				break;
			}
		}
		return objMessage;
	}

	/**
	 * 
	 * @param enumMessageCode
	 * @param enumTriggerEvent
	 */
	private IMap getMessageMap(EnumMessageCode enumMessageCode, EnumTriggerEvent enumTriggerEvent)
	{
		IMap objMessageMap = null;
		
		switch(enumTriggerEvent)
		{
		case A01:
		case A04 :
		case A08 :
		case A13 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A01);
			break;
		case A02:
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A02);
			break;
		case A03:
			objMessageMap =objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A03);
			break;
		case A05 : 
		case A14 :
		case A28 :
		case A31 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A05);
			break;
		case A06 :
		case A07 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A06);
			break;
		case A09 : 
		case A10 :
		case A11 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A09);
			break;
		case A12 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A12); 
			break;
		case A15 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A15); 
			break;
		case A16 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A16);
			break;
		case A17 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A17);
			break;

		case A20:
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A20);
			break;
		case A21 :
		case A22 :
		case A23 :
		case A25 :
		case A26 :
		case A27 :
		case A29 :
		case A32 :
		case A33 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A21); 
			break;
		case A24 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A24); 
			break;
	
		case A37 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A37);
			break;
		case A38 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A38);
			break;
		
		case A40 :
		case A41 :
		case A42 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,enumTriggerEvent); 

			break;
		case A43 :
		case A49 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A43);
			break;
		case A44 :
		case A47 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A44);
			break;
		case A45 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A45); 
			break;
		case A50 :
		case A51 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A50); 
			break;
		case A52 :
		case A53 :
		case A55 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A52); 
			break;
		case A54 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A54); 
			break;
		case A60 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A60);
			break;
		case A61 :
		case A62 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.A61); 
			break;
		case Q21 :
		case Q22 :
		case Q23 :
		case Q24 :
		case Q32 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.Q21); 
			break;
		case K32 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.K32); 
			break;
		case K21 :
		case K22 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.K21); 
			break;
		case K23 :
		case K24 :
			objMessageMap = objMessamapReader.getMessageMap(enumMessageCode,EnumTriggerEvent.K23);
			break;
		}
		return objMessageMap;
	}

	/**
	 * Checks whether Trigger Event specified in Enumeration is Supported.
	 * @param enumTriggerEvent enumerated value of Trigger Event
	 * @return boolean shows status as success or failure
	 */
	public boolean isEventSupported(EnumTriggerEvent enumTriggerEvent) 
	{
		if(enumTriggerEvent.equals(EnumTriggerEvent.A01)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A02)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A03)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A04)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A05)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A06)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A07)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A08)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A09)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A10)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A11)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A12)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A13)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A14)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A15)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A16)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A17)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A20)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A21)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A22)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A23)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A24)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A25)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A26)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A27)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A28)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A29)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A31)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A32)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A33)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A37)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A38)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A39)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A40)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A41)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A42)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A43)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A44)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A45)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A47)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A49)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A50)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A51)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A52)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A53)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A54)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A55)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A60)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A61)
				|| enumTriggerEvent.equals(EnumTriggerEvent.A62)
				|| enumTriggerEvent.equals(EnumTriggerEvent.Q21)
				|| enumTriggerEvent.equals(EnumTriggerEvent.Q22)
				|| enumTriggerEvent.equals(EnumTriggerEvent.Q23)
				|| enumTriggerEvent.equals(EnumTriggerEvent.Q24)
				|| enumTriggerEvent.equals(EnumTriggerEvent.Q32)
				|| enumTriggerEvent.equals(EnumTriggerEvent.K21)
				|| enumTriggerEvent.equals(EnumTriggerEvent.K22)
				|| enumTriggerEvent.equals(EnumTriggerEvent.K23)
				|| enumTriggerEvent.equals(EnumTriggerEvent.K24)
				|| enumTriggerEvent.equals(EnumTriggerEvent.K32)
		)
			return true;
		else 
			return false;
	}
	
	/*
	 * Checks whether Message Code specified in Enumeration is Supported.
	 */
	boolean isCodeSupported(EnumMessageCode enumMessageCode)
	{
		if(enumMessageCode == EnumMessageCode.ADR || enumMessageCode == EnumMessageCode.ACK ||
				enumMessageCode == EnumMessageCode.RSP || enumMessageCode == EnumMessageCode.ADT ||
				enumMessageCode == EnumMessageCode.QRY || enumMessageCode == EnumMessageCode.QBP)
			return true;
		
		return false;
	}
}
