/*******************************************************************************
 *  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.tools.imageconverter;

import cdac.medinfo.sdk.dcm30_04.baselibs.DataSet;
import cdac.medinfo.sdk.dcm30_04.baselibs.ImageElement;
import cdac.medinfo.sdk.dcm30_04.baselibs.OBImageObject;
import cdac.medinfo.sdk.dcm30_04.baselibs.OWImageObject;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;

public class DICOMImageInfoReader
{
	String strTSUID = null;
	short shSamplesPerPixel;
	String strPhotometricInterpretation = null;
	int iNumberOfFrames ;
	short shRows /* height */;
	short shColumns /* width */;
	short shBitsAllocated ;
	short shBitsStored ;
	short shHighBit ;
	short shPixelRepresentation ;
	String[] strWindowCenter = null;
	String[] strWindowWidth = null;
	String strBitsPerPixel;
	int iBitsPerPixel;
	ImageElement objImageElement;
	short shPlanarConfiguration;
	byte[] arrPlaetteRed;
	byte[] arrPlaetteGreen ;
	byte[] arrPlaetteBlue;


	public void readDICOMImageInfo(IDataSet objIDataSet)
	{
		strTSUID = objIDataSet.getTransferSyntax().getTransferSyntaxUID();
		if(strTSUID != null)
		{
			if(objIDataSet.isPresent(0x0028, 0x0002) && objIDataSet.getDataForTag(0x0028, 0x0002).getValue() != null)
				shSamplesPerPixel = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0002).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0004) && objIDataSet.getDataForTag(0x0028, 0x0004).getValue() != null)
				strPhotometricInterpretation = objIDataSet.getDataForTag(0x0028, 0x0004).getValue().toString();
			if(objIDataSet.isPresent(0x0028, 0x0008) && objIDataSet.getDataForTag(0x0028, 0x0008).getValue() != null)
				iNumberOfFrames = Integer.parseInt(objIDataSet.getDataForTag(0x0028, 0x0008).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0010) && objIDataSet.getDataForTag(0x0028, 0x0010).getValue() != null)
				shRows = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0010).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0011) && objIDataSet.getDataForTag(0x0028, 0x0011).getValue() != null)
				shColumns = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0011).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0100) && objIDataSet.getDataForTag(0x0028, 0x0100).getValue() != null)
				shBitsAllocated = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0100).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0101) && objIDataSet.getDataForTag(0x0028, 0x0101).getValue() != null)
				shBitsStored = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0101).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0102) && objIDataSet.getDataForTag(0x0028, 0x0102).getValue() != null)
				shHighBit = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0102).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0103) && objIDataSet.getDataForTag(0x0028, 0x0103).getValue() != null)
				shPixelRepresentation = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0103).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x0006) && objIDataSet.getDataForTag(0x0028, 0x0006).getValue() != null)
				shPlanarConfiguration = Short.parseShort(objIDataSet.getDataForTag(0x0028, 0x0006).getValue().toString());
			if(objIDataSet.isPresent(0x0028, 0x1050) && objIDataSet.getDataForTag(0x0028, 0x1050).getValue() != null)
			{
				if(objIDataSet.getDataForTag(0x0028, 0x1050).getValue() instanceof String)
				{
					strWindowCenter = new String[1];
					strWindowCenter[0] = objIDataSet.getDataForTag(0x0028, 0x1050).getValue().toString();
				}
				else
				{
					strWindowCenter = (String[])objIDataSet.getDataForTag(0x0028, 0x1050).getValue();
				}
			}
			if(objIDataSet.isPresent(0x0028, 0x1051) && objIDataSet.getDataForTag(0x0028, 0x1051).getValue() != null)
			{
				if(objIDataSet.getDataForTag(0x0028, 0x1051).getValue() instanceof String)
				{
					strWindowCenter = new String[1];
					strWindowCenter[0] = objIDataSet.getDataForTag(0x0028, 0x1051).getValue().toString();
				}
				else
				{
					strWindowCenter = (String[])objIDataSet.getDataForTag(0x0028, 0x1051).getValue();
				}
			}

			objImageElement =((DataSet) objIDataSet).getImageElement();
		}
	}


	public String getTSUID() 
	{
		return strTSUID;
	}


	public void setTSUID(String strTSUID)
	{
		this.strTSUID = strTSUID;
	}


	public short getSamplesPerPixel()
	{
		return shSamplesPerPixel;
	}


	public void setSamplesPerPixel(short strSamplesPerPixel)
	{
		this.shSamplesPerPixel = strSamplesPerPixel;
	}


	public String getPhotometricInterpretation() 
	{
		return strPhotometricInterpretation;
	}


	public void setPhotometricInterpretation(String strPhotometricInterpretation) 
	{
		this.strPhotometricInterpretation = strPhotometricInterpretation;
	}


	public int getNumberOfFrames() 
	{
		try
		{
			if(objImageElement.getDicomValue() instanceof OWImageObject)
			{
				OWImageObject objOWImageObject = (OWImageObject)objImageElement.getDicomValue();
				iNumberOfFrames = objOWImageObject.getNumberOfFrame();
			}
			else
			{
				OBImageObject objOWImageObject = (OBImageObject)objImageElement.getDicomValue();
				iNumberOfFrames = objOWImageObject.getNumberOfFrame();
			}
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return iNumberOfFrames;
	}


	public void setNumberOfFrames(int strNumberOfFrames) 
	{
		this.iNumberOfFrames = strNumberOfFrames;
	}


	public short getRows()
	{
		return shRows;
	}


	public void setRows(short shRows)
	{
		this.shRows = shRows;
	}


	public short getPlanarConfiguration()
	{
		return shPlanarConfiguration;
	}


	public void setPlanarConfiguration(short shPlanarConfiguration)
	{
		this.shPlanarConfiguration = shPlanarConfiguration;
	}

	public short getColumns()
	{
		return shColumns;
	}


	public void setColumns(short shColumns)
	{
		this.shColumns = shColumns;
	}

	public short getBitsAllocated() 
	{
		return shBitsAllocated;
	}


	public void setBitsAllocated(short shBitsAllocated)
	{
		this.shBitsAllocated = shBitsAllocated;
	}


	public short getBitsStored()
	{
		return shBitsStored;
	}


	public void setBitsStored(short shBitsStored)
	{
		this.shBitsStored = shBitsStored;
	}


	public short getHighBit() 
	{
		return shHighBit;
	}


	public void setHighBit(short shHighBit) 
	{
		this.shHighBit = shHighBit;
	}


	public short getPixelRepresentation() 
	{
		return shPixelRepresentation;
	}


	public void setPixelRepresentation(short strPixelRepresentation)
	{
		this.shPixelRepresentation = strPixelRepresentation;
	}


	public String[] getWindowCenter() 
	{
		return strWindowCenter;
	}


	public void setWindowCenter(String[] strWindowCenter)
	{
		this.strWindowCenter = strWindowCenter;
	}


	public String[] getWindowWidth() 
	{
		return strWindowWidth;
	}


	public void setWindowWidth(String[] strWindowWidth)
	{
		this.strWindowWidth = strWindowWidth;
	}

	public int getBitsPerPixel()
	{
		if(strPhotometricInterpretation != null)
		{
			if(strPhotometricInterpretation.trim().equals("MONOCHROME2") || strPhotometricInterpretation.trim().equals("MONOCHROME1"))
			{
				iBitsPerPixel = 8;
			}
			else if(strPhotometricInterpretation.equals("RGB"))
			{
				iBitsPerPixel = 24;
			}
			else if(strPhotometricInterpretation.equals("YBR_FULL_422"))
			{
				iBitsPerPixel = 24;
			}
			else if(strPhotometricInterpretation.equals("PALETTE COLOR"))
			{
				iBitsPerPixel = 24;
			}
		}
		else
		{
			strPhotometricInterpretation = "MONOCHROME2";
		}
		return iBitsPerPixel;
	}

	public ImageElement getImageData()
	{
		return objImageElement;
	}


	public void getPlaetteInfo(IDataSet objIDataSet)
	{
		if(strPhotometricInterpretation.equalsIgnoreCase("PALETTE COLOR"))
		{
			int LUTsize=0, LUToffset=0, Bits = 0;
			byte[] redLUT = new byte[256];
			byte[] greenLUT = new byte[256];
			byte[] blueLUT = new byte[256];
			Object objValue = objIDataSet.getDataForTag(0x28, 0x1101).getValue();

			//all the three values are identical for red green and blue PS -3 page no 282
			if(objValue!= null)
			{
				//256,0,16
				short[] shRedPalletDescrip = (short[])objValue;
				LUTsize = shRedPalletDescrip[0];//objDicomDataShort.getValue(); //de.getValueAsInt(0);
				LUToffset = shRedPalletDescrip[1];;//objDicomDataShort.getValue(); //de.getValueAsInt(1);
				Bits = 	 shRedPalletDescrip[2];;//objDicomDataShort.getValue(); //de.getValueAsInt(2);
			}

			byte[] data;

			ISingleCollection<byte[]> objByteArrayCollection = (ISingleCollection<byte[]>)objIDataSet.getDataForTag(0x28, 0x1201).getValue();
			arrPlaetteRed = new byte[256];
			data = objByteArrayCollection.get(0);
			if(null != data)
			{
				for(int i = LUToffset; i < LUTsize; i++)
				{
					redLUT[i] = (byte)(data[(i-LUToffset)*2+1]);
				}

				for(int i = LUTsize; i < 255; i++)
				{
					redLUT[i] = (byte)0;
				}
				for(int i = 0; i < LUToffset; i++) 
				{
					redLUT[i] = redLUT[0];
				}
			}

			objByteArrayCollection = (ISingleCollection<byte[]>)objIDataSet.getDataForTag(0x28, 0x1202).getValue();
			arrPlaetteGreen = new byte[256];
			data = (byte[])objByteArrayCollection.get(0);
			if(null != data)
			{
				for(int i = LUToffset; i < LUTsize; i++)
					greenLUT[i] = (byte)(data[(i-LUToffset)*2+1]);

				for(int i = LUTsize; i < 255; i++) 
					greenLUT[i] = (byte)0;

				for(int i = 0; i < LUToffset; i++) 
					greenLUT[i] = greenLUT[0];

			}

			objByteArrayCollection = (ISingleCollection<byte[]>)objIDataSet.getDataForTag(0x28, 0x1203).getValue();
			arrPlaetteBlue = new byte[256];
			data = (byte[])objByteArrayCollection.get(0);
			if( null != data)
			{
				for(int i = LUToffset; i < LUTsize; i++)
					blueLUT[i] = (byte)(data[(i-LUToffset)*2+1]);

				for(int i = LUTsize; i < 255; i++)
					blueLUT[i] = (byte)0;

				for(int i = 0; i < LUToffset; i++) 
					blueLUT[i] = blueLUT[0];
			}

			arrPlaetteRed = redLUT;
			arrPlaetteGreen = greenLUT;
			arrPlaetteBlue = blueLUT;

		}
	}

	public byte[] getRedPlaette()
	{
		return this.arrPlaetteRed;
	}

	public byte[] getBluePlaette()
	{
		return this.arrPlaetteBlue;
	}

	public byte[] getGreenPlaette()
	{
		return this.arrPlaetteGreen;
	}

	public byte[] getFrame(int iFrameNo)
	{
		try
		{
			if(objImageElement.getDicomValue() instanceof OWImageObject)
			{
				OWImageObject objOWImageObject = (OWImageObject)objImageElement.getDicomValue();
				return objOWImageObject.getFrame(iFrameNo);
			}
			else
			{
				OBImageObject objOWImageObject = (OBImageObject)objImageElement.getDicomValue();
				return objOWImageObject.getFrame(iFrameNo);
			}
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return null;
	}
	
	public int getImageDataLength()
	{
		try
		{
			if(objImageElement.getDicomValue() instanceof OWImageObject)
			{
				OWImageObject objOWImageObject = (OWImageObject)objImageElement.getDicomValue();
				return objOWImageObject.getImageDataLength();
			}
			else
			{
				OBImageObject objOWImageObject = (OBImageObject)objImageElement.getDicomValue();
				return objOWImageObject.getImageDataLength();
			}
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return 0;
	}
	
	
}
