/*******************************************************************************
 *  Copyright 2017-2018 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.dcm30_04.services.ianservice.testcases.scu;

import java.io.IOException;
import java.net.InetSocketAddress;


import cdac.medinfo.sdk.dcm30_04.baselibs.DataSet;
import cdac.medinfo.sdk.dcm30_04.baselibs.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImplicitDE;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataTypeSQ;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDictionaryReader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITransferSyntax;
import cdac.medinfo.sdk.dcm30_04.enums.EnumLoggingLevel;

import cdac.medinfo.sdk.dcm30_04.services.ian.scu.IAN_SCU;
import cdac.medinfo.sdk.dcm30_04.services.ncreate.commons.NCreateRSP;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;

/**
 * This class tests a Stand Alone IAN SCU.
 * "Stand Alone" means that the User is required to write a minimal set of code to actually send a 
 * NCreate Request. Once the required parameters are given to the IAN SCU object it is 
 * capable of making a connection to the SCP, establishing association, sending the NCreate Request and receiving the 
 * DIMSE Response for the same. If User wants to handle the request sending scenarios by his/her code 
 * then please refer to sample code "TestIANSCU.java". 
 */
public class IAN_SCU_Stanalone 
{
	public static void main(String[] args)
	{
		try
		{
			DicomConfig objDicomConfig = DicomConfig.createInstance();

			//enable logging,specify the path of the directory where log files are created.
			//User can specify any directory in place of 'c:\DCM_Logs'.
			//If no directory is defined by user to create logs then it is created in User Temp DIR.
			objDicomConfig.enableLogging(EnumLoggingLevel.INFO, "C:\\DCM_Logs");
			/*
			 * Creates IAN_SCU_Stanalone.
			 */
			IAN_SCU_Stanalone objTestStanaloneIAN_SCU = new IAN_SCU_Stanalone();
			objTestStanaloneIAN_SCU.doIAN();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	/*
	 * This function starts thre IAN operation,
	 */
	public void doIAN()throws IOException
	{
		/* 
		 * Creates SCU with specified destination .
		 */
		InetSocketAddress addr = new InetSocketAddress("192.168.8.94",9000);
		IAN_SCU objIAN_SCU = new IAN_SCU(addr);

		objIAN_SCU.send("SDK","SDK","1.3.12.2.1107.5.1.4.36085.4.0.11",getIANForCreate());

		if(objIAN_SCU.getDIMSEResponse().size() >0)
		{
			System.out.println("IAN instance creation operation performed");
			NCreateRSP objNCreateRSP = new NCreateRSP(objIAN_SCU.getDIMSEResponse().get(0));
			System.out.println("N-Create Response Status :" + objNCreateRSP.getStatus());
		}
		else
		{
			System.out.println("IAN instance creation operation failed");
		}
	}

	/*
	 * Populates the DataSet with modified values for IAN.
	 * It populates the Dataset manually using some default values of Dataelements for IAN.
	 * This Dataset can be generated using some file also.
	 * @return objIDataSet instance of IDataSet.
	 */
	private IDataSet getIANForCreate()
	{
		IDataSet objIDataSet = new DataSet();
		IDictionaryReader objDictionaryReader = objIDataSet.getDictionaryReader();
		ITransferSyntax objTS = objIDataSet.getTransferSyntax();

		String []arrstrSpecificCharSet = new String[2];
		arrstrSpecificCharSet[0] = "ian1";
		arrstrSpecificCharSet[1] = "ian2";

		objIDataSet.addDataElement(getDataElement(0x0008,0x0005,arrstrSpecificCharSet, objDictionaryReader));
		{
			IDataTypeSQ objReferencedPerformedProcedureStepSQ = getSQ(0x0008,0x1111, objTS);
			IItem objReferencedPerformedProcedureStepItem = objReferencedPerformedProcedureStepSQ.getNewItem();

			objReferencedPerformedProcedureStepItem.addDataElement(getDataElement(0x0008,0x1150, "1.2.840.10008.5.1.4.1.1.12.1", objDictionaryReader));
			objReferencedPerformedProcedureStepItem.addDataElement(getDataElement(0x0008,0x1155, "1.3.12.2.1107.5.4.3.284980.19951129.170916.11", objDictionaryReader));
			{
				IDataTypeSQ objPerformedWorkitemCodeSQ = getSQ(0x0040,0x4019, objTS);
				IItem objPerformedWorkitemCodeItem = objPerformedWorkitemCodeSQ.getNewItem();
				objPerformedWorkitemCodeItem.addDataElement(getDataElement(0x0008,0x0100,"Code", objDictionaryReader));
				objPerformedWorkitemCodeItem.addDataElement(getDataElement(0x0008,0x0102,"Coding", objDictionaryReader));
				objPerformedWorkitemCodeItem.addDataElement(getDataElement(0x0008,0x0104,"Code", objDictionaryReader));

				objPerformedWorkitemCodeSQ.addItem(objPerformedWorkitemCodeItem);
				objReferencedPerformedProcedureStepItem.addDataElement(getDataElement(0x0040,0x4019,objPerformedWorkitemCodeSQ.getValue(), objDictionaryReader));
			}
			objReferencedPerformedProcedureStepSQ.addItem(objReferencedPerformedProcedureStepItem);
			objIDataSet.addDataElement(getDataElement(0x0008,0x1111,objReferencedPerformedProcedureStepSQ.getValue(), objDictionaryReader));
			objIDataSet.addDataElement(getDataElement(0x0020,0x000D,"1.3.12.2.1107.5.4.3.4975316777216.19951114.94101.16", objDictionaryReader));

			{
				IDataTypeSQ objReferencedSeriesSQ = getSQ(0x0008,0x1115, objTS);
				IItem objReferencedSeriesItem = objReferencedSeriesSQ.getNewItem();
				objReferencedSeriesItem.addDataElement(getDataElement(0x0020,0x000E,"1.3.12.2.1107.5.4.3.4975316777216.19951114.94101.17", objDictionaryReader));
				{
					IDataTypeSQ objReferencedSOPSQ = getSQ(0x0008,0x1199, objTS);
					IItem objReferencedSOPItem = objReferencedSOPSQ.getNewItem();
					objReferencedSOPItem.addDataElement(getDataElement(0x0008,0x1150,"1.2.840.10008.5.1.4.1.1.12.1", objDictionaryReader));
					objReferencedSOPItem.addDataElement(getDataElement(0x0008,0x1155,"1.3.12.2.1107.5.4.3.284980.19951129.170916.11", objDictionaryReader));
					objReferencedSOPItem.addDataElement(getDataElement(0x0008,0x0056,"123", objDictionaryReader));
					objReferencedSOPItem.addDataElement(getDataElement(0x0008,0x0054,"SDK", objDictionaryReader));
					objReferencedSOPItem.addDataElement(getDataElement(0x0088,0x0130,"3", objDictionaryReader));
					objReferencedSOPItem.addDataElement(getDataElement(0x0088,0x0140,"3", objDictionaryReader));

					objReferencedSOPSQ.addItem(objReferencedSOPItem);
					objReferencedSeriesItem.addDataElement(getDataElement(0x0008,0x1199,objReferencedSOPSQ.getValue(), objDictionaryReader));
				}
				objReferencedSeriesSQ.addItem(objReferencedSeriesItem);
				objIDataSet.addDataElement(getDataElement(0x0008,0x1115,objReferencedSeriesSQ.getValue(), objDictionaryReader));
			}
		}

		return objIDataSet;
	}

	/*
	 * Creates DataElement for given Group and Element Number
	 */
	private IDataElement getDataElement(int GroupNo,int ElementNo,Object objVal,IDictionaryReader objDictionaryReader)
	{
		IDataElement objIDataElement = new ImplicitDE(GroupNo, ElementNo,objVal,objDictionaryReader);
		return objIDataElement;
	}

	/*
	 * Creates SQ for given Group and Element Number
	 */
	private IDataTypeSQ getSQ(int GroupNo,int ElementNo , ITransferSyntax objTS)
	{
		return DicomV3Factory.createInstance().createSequence(GroupNo, ElementNo, objTS);
	}
}
