/*******************************************************************************
 *  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.mediacreation.testcases.customizedscp;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;


import cdac.medinfo.sdk.dcm30_04.baselibs.ReferencedSOPSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ReferencedSOPSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.SQ;
import cdac.medinfo.sdk.dcm30_04.baselibs.TransferSyntax;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataElement;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITransferSyntax;
import cdac.medinfo.sdk.dcm30_04.dicommodel.mediacreationmanagement.MediaCreationManagementIOD;
import cdac.medinfo.sdk.dcm30_04.dicommodel.modules.MediaCreationManagementModule;
import cdac.medinfo.sdk.dcm30_04.dicommodel.modules.SOPCommonModule;
import cdac.medinfo.sdk.dcm30_04.enums.EnumAllowLossyCompression;
import cdac.medinfo.sdk.dcm30_04.enums.EnumAllowMediaSplitting;
import cdac.medinfo.sdk.dcm30_04.enums.EnumIncludeDisplayApplication;
import cdac.medinfo.sdk.dcm30_04.enums.EnumIncludeNonDICOMObjects;
import cdac.medinfo.sdk.dcm30_04.enums.EnumLabelUsingInformationExtractedFromInstances;
import cdac.medinfo.sdk.dcm30_04.enums.EnumLoggingLevel;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPreserveCompositeInstancesAfterMediaCreation;
import cdac.medinfo.sdk.dcm30_04.services.mediacreation.mediacreationsinkimpl.MediaCreation_SinkImpl;
import cdac.medinfo.sdk.dcm30_04.services.mediacreation.mediacreationsinkimpl.NCreateMediaCreationMang_QueryModel;
import cdac.medinfo.sdk.dcm30_04.services.mediacreation.mediacreationsourceimpl.EnumMediaCreationNGetAttributes;
import cdac.medinfo.sdk.dcm30_04.services.mediacreation.mediacreationsourceimpl.MediaCreation_SourceImpl;
import cdac.medinfo.sdk.dcm30_04.services.mediacreation.mediacreationsourceimpl.NGetMediaCreationMang_QueryModel;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.ICollectionIterator;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

public class MediaCreationQueryModel 
{
	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");

			/*
			 * Populating Database with data set on which find request will be processed.
			 */
			MediaCreationQueryModel objTest = new MediaCreationQueryModel();

			/*
			 * Create DataSourceImpl with ConnectionString and driver String.
			 * DataSourceImpl is default implementation of library which uses JavaDB to 
			 * fidn Data Elements.The user has to start javaDB server before connection
			 * if Client Server model in java DB is used.
			 * This DataSource should be set in CFind SCP.
			 * User can also provide its own implementation of IDataSource interface
			 * to find the attributes.
			 */
			String dataBasePath = "C:\\DataBase\\MediaDB";
			String ConnectionString = "jdbc:derby://localhost:1527/" + dataBasePath;
			String driverString = "org.apache.derby.jdbc.ClientDriver";

			MediaCreation_SinkImpl objDataSinkImpl = new MediaCreation_SinkImpl(ConnectionString, driverString);
			MediaCreation_SourceImpl objDataSourceImpl = new MediaCreation_SourceImpl(ConnectionString, driverString);

			// N-CREATE
			IDataSet objCreateDS = objTest.getDatasetForCreate();

			NCreateMediaCreationMang_QueryModel objCreateQM = new NCreateMediaCreationMang_QueryModel();
			objCreateQM.decode(objCreateDS);

			short shResultCreate = objDataSinkImpl.store(objCreateQM, "1.1.1.12.2.2.2.2.3");

			// display create DS of create
			NCreateMediaCreationMang_QueryModel objRsltQRYModel = (NCreateMediaCreationMang_QueryModel)objCreateQM;
			ISingleCollection<IDataSet> rstdatasetlist = new SingleCollection<IDataSet>();
			ITransferSyntax objITransferSyntax = new TransferSyntax();
			objRsltQRYModel.encode(objITransferSyntax, rstdatasetlist);

			IDataSet objRSLTDataCreate = rstdatasetlist.elementAt(0);
			objTest.display(objRSLTDataCreate);

			System.out.println("\n\n shResultCreate = " + shResultCreate);

			//---------------------

			// N-Get
			NGetMediaCreationMang_QueryModel objGetQM = new NGetMediaCreationMang_QueryModel("1.1.1.12.2.2.2.2.3");
			
			//First Level Attributes
			objGetQM.addNGetAttributes(EnumMediaCreationNGetAttributes.SPECIFIC_CHARACTER_SET_GROUP_NO, EnumMediaCreationNGetAttributes.SPECIFIC_CHARACTER_SET_ELEMENT_NO);
			
			{
				// Second level Attributes
//				objGetQM.addNGetAttributes(EnumMediaCreationNGetAttributes.ACCESSION_NUMBER_GROUP_NO, EnumMediaCreationNGetAttributes.ACCESSION_NUMBER_ELEMENT_NO);
//				objGetQM.addNGetAttributes(EnumMediaCreationNGetAttributes.REFERENCED_STUDY_SEQUENCE_GROUP_NO, EnumMediaCreationNGetAttributes.REFERENCED_STUDY_SEQUENCE_ELEMENT_NO);
			}
			NGetMediaCreationMang_QueryModel objRstQueryModel = new NGetMediaCreationMang_QueryModel("1.1.1.12.2.2.2.2.3");
			
			short shResultGet = objDataSourceImpl.retrieve(objGetQM, objRstQueryModel);
			
			ISingleCollection<IDataSet> rstdatasetlistGet = new SingleCollection<IDataSet>();
			ITransferSyntax objITransferSyntaxGet = new TransferSyntax();
			objRstQueryModel.encode(objITransferSyntaxGet, rstdatasetlistGet);
			
			IDataSet objRSLTDataSetGet = rstdatasetlistGet.elementAt(0);
			
			objTest.display(objRSLTDataSetGet);
			
			System.out.println("\n\n shResultGet = " + shResultGet);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

	}

	/*
	 * Displays the DataElements of Dataset
	 */
	private void display(IDataSet objIDataSet)
	{
		ICollectionIterator<IDataElement> objIDataSetIterator = objIDataSet.iterator();

		System.out.println("Tag     Value");
		while(objIDataSetIterator.hasNext())
		{
			IDataElement objDataElement = objIDataSetIterator.next();				

			if(!(objDataElement.getDicomValue() instanceof SQ))
			{

				System.out.println(objDataElement.getTag().getGroupNumber()+"    "+
						objDataElement.getTag().getElementNumber()+"    "+
						objDataElement.getDicomValue().toString());
			}
			else  
			{
				displaySequence((SQ)objDataElement.getDicomValue(),"> ");					
			}
		}

	}

	/*
	 * This method diaplays the SQ data type.
	 */
	private void displaySequence(SQ objSQDataElement,String ss)
	{
		ICollectionIterator<IItem> objSQItemIterator = objSQDataElement.iterator();
		int i = 1;
		while(objSQItemIterator.hasNext())
		{
			System.out.println("ITEM :"+ i++ );
			IItem objItem = objSQItemIterator.next();
			ICollectionIterator<IDataElement> objDataElementIterator = objItem.iterator();
			while(objDataElementIterator.hasNext())
			{
				IDataElement objDataElement = objDataElementIterator.next();

				if(!(objDataElement.getDicomValue() instanceof SQ))
				{
					System.out.println(ss +objDataElement.getTag().getGroupNumber()+"    "+
							objDataElement.getTag().getElementNumber()+"    "+
							objDataElement.getDicomValue().toString());						 

				}
				else
				{
					displaySequence((SQ)objDataElement.getDicomValue(),ss+ss);
				}	 
			}
		}
	}
	
	//Populates the Dataset with default values for Media Creation Management SOP Class.
	private IDataSet getDatasetForCreate()
	{
		MediaCreationManagementIOD objMediaCreationManagementIOD = new MediaCreationManagementIOD();

		//SOP Common Module
		SOPCommonModule objSOPCommonModule = objMediaCreationManagementIOD.getSOPCommonModule();
		String []arrStrSpecificCharacterSet = new String[2];
		arrStrSpecificCharacterSet[0] = "ISO-IR 100";
		arrStrSpecificCharacterSet[1] = "ISO-IR 100";
		objSOPCommonModule.setSpecificCharacterSet(arrStrSpecificCharacterSet);

		//Media Creation Management
		MediaCreationManagementModule objMediaCreationManagementModule = objMediaCreationManagementIOD.getMediaCreationManagementModule();
		objMediaCreationManagementModule.setStorageMediaFileSetID("3");
		objMediaCreationManagementModule.setStorageMediaFileSetUID("3");
		objMediaCreationManagementModule.setLabelUsingInformationExtractedFromInstances(EnumLabelUsingInformationExtractedFromInstances.YES);
		objMediaCreationManagementModule.setLabelText("LabelText");
		objMediaCreationManagementModule.setLabelStyleSelection("2");
		objMediaCreationManagementModule.setBarcodeValue("BarcodeValue");
		objMediaCreationManagementModule.setBarcodeSymbology("BarcodeSymbology");
		objMediaCreationManagementModule.setMediaDisposition("MediaDisposition");
		objMediaCreationManagementModule.setAllowMediaSplitting(EnumAllowMediaSplitting.YES);
		objMediaCreationManagementModule.setAllowLossyCompression(EnumAllowLossyCompression.YES);
		objMediaCreationManagementModule.setIncludeNonDICOMObjects(EnumIncludeNonDICOMObjects.FOR_PATIENT);
		objMediaCreationManagementModule.setIncludeDisplayApplication(EnumIncludeDisplayApplication.YES);
		objMediaCreationManagementModule.setPreserveCompositeInstancesAfterMediaCreation(EnumPreserveCompositeInstancesAfterMediaCreation.YES);

		{
			//adding our items containing values of referenced sop instance uids
			ReferencedSOPSequence objReferencedSOPSequence = objMediaCreationManagementModule.getReferencedSOPSequence();
			{
				ReferencedSOPSequenceItem  objReferencedSOPSequenceItem1 = objReferencedSOPSequence.getNewItem();

				objReferencedSOPSequenceItem1.getSOPInstanceReferenceMacro().setReferencedSOPClassUID("1.2.840.10008.5.1.4.1.1.12.1");
				objReferencedSOPSequenceItem1.getSOPInstanceReferenceMacro().setReferencedSOPInstanceUID("1.3.12.2.1107.5.4.3.284980.19951129.170916.9");
 
				objReferencedSOPSequence.addItem(objReferencedSOPSequenceItem1);
			}
			{
				ReferencedSOPSequenceItem  objReferencedSOPSequenceItem2 = objReferencedSOPSequence.getNewItem();

				objReferencedSOPSequenceItem2.getSOPInstanceReferenceMacro().setReferencedSOPClassUID("1.2.840.10008.5.1.4.1.1.12.1");
				objReferencedSOPSequenceItem2.getSOPInstanceReferenceMacro().setReferencedSOPInstanceUID("1.3.12.2.1107.5.4.3.284980.19951129.170916.9");

				objReferencedSOPSequence.addItem(objReferencedSOPSequenceItem2);
			}
			{
				ReferencedSOPSequenceItem  objReferencedSOPSequenceItem3 = objReferencedSOPSequence.getNewItem();

				objReferencedSOPSequenceItem3.getSOPInstanceReferenceMacro().setReferencedSOPClassUID("1.2.840.10008.5.1.4.1.1.12.1");
				objReferencedSOPSequenceItem3.getSOPInstanceReferenceMacro().setReferencedSOPInstanceUID("1.3.12.2.1107.5.4.3.284980.19951129.170916.9");

				objReferencedSOPSequence.addItem(objReferencedSOPSequenceItem3);
			}
			{
				ReferencedSOPSequenceItem  objReferencedSOPSequenceItem4 = objReferencedSOPSequence.getNewItem();

				objReferencedSOPSequenceItem4.getSOPInstanceReferenceMacro().setReferencedSOPClassUID("1.2.840.10008.5.1.4.1.1.12.1");
				objReferencedSOPSequenceItem4.getSOPInstanceReferenceMacro().setReferencedSOPInstanceUID("1.3.12.2.1107.5.4.3.284980.19951129.170916.9");

				objReferencedSOPSequence.addItem(objReferencedSOPSequenceItem4);
			}
		}

		return objMediaCreationManagementIOD.getDataSet();
	}
}
