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

import java.io.IOException;
import java.io.Serializable;

import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidDataTypeException;
import cdac.medinfo.sdk.dcm30_04.exceptions.ValidationException;


/**
 * This interface needs to be implemented by all classes which implements functioning of DicomValue. 
 */
public interface IDicomValue extends Serializable
{
	/**
	 * Retrieves the value of DicomValue.
	 * @return Object - instance of object.
	 */
	Object getValue();

	/**
	 * Sets the value of DicomValue.
	 * @param objValue instance of object.
	 * @throws InvalidDataTypeException if DataType validation fails.
	 */
	void setValue(Object objValue) throws InvalidDataTypeException;

	/**
	 * Retrieves the VR type of an element.
	 * @return int - integer value shows VR type.
	 */
	int getIVRType();

	/**
	 * Sets the VR type of an element.
	 * @param iVRType integer value shows VR type.
	 */
	void setIVRType(int iVRType);

	/**
	 * Reads the DicomValue from DicomStream.
	 * @param objIDicomStream instance of DicomStream.
	 * @param iLength integer value of length.
	 * @return boolean - shows status as success or failure.
	 * @throws InvalidDataTypeException if DataType validation fails.
	 * @throws IOException if Input/Output operation fails.
	 */
	boolean read(IDicomStream objIDicomStream,int iLength) throws InvalidDataTypeException,IOException;

	/**
	 * Writes the DicomValue from DicomStream.
	 * @param objIDicomStream instance of DicomStream.
	 * @return boolean - shows status as success or failure.
	 * @throws IOException if Input/Output operation fails.
	 */
	int write(IDicomStream objIDicomStream) throws IOException;;

	/**
	 * Validates the DicomValue.
	 * @param objToValidate instance of object.
	 * @return boolean - shows status as success or failure.
	 * @throws ValidationException if DataType validation fails.
	 */
	boolean validate(Object objToValidate) throws ValidationException;

	/*
	 * This method should not be exposed in the interface
	 * This is because the value length if not set by the user should be
	 * calculated internally.
	 */
	//void setValueLength();

	/*
	 * The DicomValue value length should not be set from outside.
	 * This is because the user need not be calculating the length
	 * of the data he is going to set, we are going to internally
	 * calculate it anyways. Because if we allow the user to set it from outside,
	 * then we end up deciding whether it is set by the user or not. Again the
	 * length of the data in DataElement is different than actual length of 
	 * the data as padding issues are involved during parsing and serialization.
	 * So the DicomValue length and DataElement length should be different if padding
	 * issues is involved. The parser and serializer processes will take care of
	 * the issue. 
	 */
	//void setValueLength(int iLength);

	/**
	 * Retrieves the value length.
	 * @return int - integer value of length.
	 */
	int getValueLength();

	/**
	 * Retrieves the maximum allowed value length.
	 * @return long - long integer value of length.
	 */
	long getMaxLength();

	/**
	 * Retrieves the value multiplicity of the value in DicomValue
	 * @return integer - returns the actual value multiplicity of value in the DataElement
	 */
	public int getValueMultiplicity();

	/**
	 * Validates the DicomValue.
	 * @return boolean - shows status as success or failure.
	 * @throws ValidationException if DataType validation fails.
	 */
	boolean validate() throws ValidationException;
	
	/**
	 * Create similar object of this class.
	 * This does the deep copy and create a new instance of this class and return it.
	 * @return IDicomValue - object of IDicomValue.
	 */
	public Object clone();
	
	/**
	 * Dumps the DICOM Data in readable form to the specified stream.
	 * @param objIDicomStream - the Stream on which the Data is to be written.
	 * @throws IOException - Exception is thrown indicating runtime failure of writing operation.
	 */
	public void dumpDICOMInfo(IDicomStream objIDicomStream) throws IOException;
}