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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import cdac.medinfo.sdk.dcm30_04.baselibs.DicomFileHeader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomFileHeader;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomFileWriter;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDicomStream;
import cdac.medinfo.sdk.dcm30_04.dicomstreams.DicomFileStream;

/**
 * This class will be used as a file writer capable of writing part-10 complaint dicom file
 */
public class DicomFileWriter implements IDicomFileWriter 
{


	private IDicomStream objIDicomStream;
	private static final int DCM_FILE_PREAMBLE_LENGTH = 128;
	private static final byte[] DCM_FILE_HEADER_PREFIX = {'D','I','C','M'};
	IDicomFileHeader objIDicomFileHeader = null;

	/**
	 * This constructor creates a DicomFileReader by accepting file name with  complete path.
	 * @param strFileNameWithPath The file name with complete path.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public DicomFileWriter(String strFileNameWithPath) throws IOException
	{
		File objFile = new File(strFileNameWithPath);

		FileOutputStream objFileOutputStream = new FileOutputStream(objFile);
		DicomFileStream objDicomFileStream = new DicomFileStream();
		objDicomFileStream.setOutputStream(objFileOutputStream);
		objIDicomStream = objDicomFileStream;
	}

	/**
	 * This constructor accepts DicomStream in which file is already set .
	 * @param objIDicomStream_  The DicomStream in which file is already set.
	 */
	public DicomFileWriter(IDicomStream objIDicomStream_)
	{
		objIDicomStream = objIDicomStream_;	
	}


	/**
	 * This method writes 128 byte preamble in the dicom file before DICM suffix and header details .
	 * @return int - returns 1 on success.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public int writePreamble() throws IOException
	{
		byte[] bytePreAmble = new byte[128];
		for(int i=0;i<128;i++)
			bytePreAmble[i] = 0;
		objIDicomStream.writeBuffer(bytePreAmble, 0, 128);
		return 1;
	}
	/**
	 * This method writes the 128 byte preamble in the dicom file before DICM suffix and header details .
	 * @param preamble preamble of dicom file as byte array.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 * @return int - returns 1 on success.
	 */
	public int writePreamble(byte[] preamble) throws IOException
	{
		if(preamble.length < DCM_FILE_PREAMBLE_LENGTH)
			return 0;
		objIDicomStream.writeBuffer(preamble,0,preamble.length);
		return 1;
	}

	/**
	 * This method writes the 4 byte Dicom Header prefix which determines whether the header is present or not
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 * @return  int - returns 1 on success.
	 */
	public int writeHeaderPrefix() throws IOException
	{
		objIDicomStream.writeBuffer(DCM_FILE_HEADER_PREFIX, 0, 4);
		return 1;
	}
	/**
	 * This method writes the header in the file which is stored in the DicomFileHeader class.
	 * @param header DicomFileHeader as byte array.
	 * @return int - returns 1 on success.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public int writeHeader(byte[] header) throws IOException
	{
		objIDicomStream.writeBuffer(header, 0, header.length);
		return 1;
	}

	/**
	 * This method writes the DicomFileHeader into the file.
	 * @param objDicomFileHeader Object of DicomFileHeader.
	 * @return int - returns 1 on success.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public int writeHeader(IDicomFileHeader objDicomFileHeader) throws IOException
	{
		objDicomFileHeader.serialize(objIDicomStream);
		return 1;
	}

	/**
	 * This method writes the default DicomFileHeader into the file.
	 * @return int - returns 1 on success.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public int writeDefaultHeader() throws IOException
	{
		objIDicomFileHeader = new DicomFileHeader();
		objIDicomFileHeader.createDefaultHeader();
		writePreamble();
		writeHeaderPrefix();
		writeHeader(objIDicomFileHeader.getHeader());
		return 1;
	}

	/**
	 * This method sets the Dicom File Header to be written into the DicomFileWriter.
	 * @param objDicomFileHeader_ Object of DicomFileHeader.
	 * @return int - returns 1 on success.
	 */
	public int setHeader(IDicomFileHeader objDicomFileHeader_)
	{
		objIDicomFileHeader = objDicomFileHeader_;
		return 1;
	}
	/**
	 * This method writes data contents in the file which is actually content of DataSet.
	 * @param dataContents byte array of data to be written.
	 * @return int - returns 1 on success.
	 * @throws IOException Signals that an I/O exception of some sort has occurred.
	 */
	public int writeDataContents(byte[] dataContents) throws IOException
	{
		objIDicomStream.writeBuffer(dataContents, 0, dataContents.length);
		return 1;
	}
}
