package in.cdac.medinfo.csnotk.csnolib.model;
/*******************************************************************************
 * Copyright 2014 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.
 ******************************************************************************/
import in.cdac.medinfo.csnotk.csnolib.commons.EnumCharacteristicType;
import in.cdac.medinfo.csnotk.csnolib.commons.EnumModifier;
import in.cdac.medinfo.csnotk.csnolib.commons.EnumRelationshipType;

import java.util.Date;

/**
 * 	Concrete Relationship represents an association between concept and concrete domain.
 */

public class ConcreteRelationship extends Component{
	/**
	 * Source concept id of the concrete  relationship.
	 */
	private Concept sourceConcept;
	/**
	 * Destination value of the concrete relationship.
	 */
	private String  destinationValue;
	
	/**
	 * Destination value of the concrete relationship.
	 */
	private String destinationValueWithPrefix;
	/**
	 * Integer value that groups together the relationships that are logically associated.
	 */
	private int relationshipGroup;
	/**
	 * Type of relationship.
	 */
	private Concept type;
	/**
	 * Characteristic Type of the relationship.
	 */
	private EnumCharacteristicType characteristicTypeId;
	/**
	 * Id that refers to the modifier type (possible values for modifier- SOME, ALL).
	 */
	private EnumModifier modifierId;
	/**
	 * Default constructor.
	 */
	protected ConcreteRelationship()
	{
		
	}
	/**
	 * Parameterized constructor.
	 * @param id
	 * 			 Id of the particular SNOMED CT relationship.
	 * @param effTime
	 * 			 Effective time associated with the Relationship.
	 * @param status
	 * 			 Active status of the relationship (0 or 1).
	 * @param modId
	 * 			 represents module Id.
	 * @param sourceId
	 * 			 Id of the source concept.
	 * @param destinationValue
	 * 			 Id of the destination Value.
	 * @param relationshipGroup
	 * 			 Integer value that groups together the relationships that are logically associated.
	 * @param typeId
	 * 			 represents type of relationship.
	 * @param characteristicTypeId
	 * 			 specifies the characteristic type.
	 * @param modifierId
	 * 			specifies the modifier Id.
	 */
	protected ConcreteRelationship(String id,Date effTime,Byte status,String modId,
			Concept sourceConcept,String destinationValue,int relationshipGroup,
			Concept type,EnumCharacteristicType 
			characteristicTypeId,EnumModifier modifierId,String prefixvalue)
	{
		super(id,effTime,status,modId);
		this.sourceConcept=sourceConcept;
		this.destinationValue=destinationValue;
		this.setRelationshipGroup(relationshipGroup);
		this.type=type;
		this.setCharacteristicTypeId(characteristicTypeId);
		this.setModifierId(modifierId);
		this.setDestinationValueWithPrefix(prefixvalue);
	}
	public String getDestinationValueWithPrefix() {
		return destinationValueWithPrefix;
	}
	public void setDestinationValueWithPrefix(String prefixvalue) {
		this.destinationValueWithPrefix=prefixvalue;
	}
	/**
	 * 
	 * @return a unique identifier for this relationship.
	 */
	public String getId() {
		return super.getId();
	}
	/**
	 * sets the Id of the relationship.
	 */
	public void setId(String id) {
		super.setId(id);
	}
	/**
	 * Retrieves the status of the Relationship.
	 */
	public Byte getActiveStatus()
	{
		return super.getActiveStatus();
	}
	/**
	 * sets the Relationship status.
	 */
	public void setActiveStatus(Byte activeStatus)
	{
		super.setActiveStatus(activeStatus);
	}
	/**
	 * returns the module Id of the Relationship.
	 */
	public String getModuleId()
	 {
		 return super.getModuleId();
	 }
	/**
	 * sets the module Id of the Relationship.
	 */
	 public void setModuleId(String modId)
	 {
		 super.setModuleId(modId);
	 }
	 /**
	  * returns the effective time of the Relationship.
	  */
	 public Date getTime()
	 {
		 return super.getTime();
	 }
	 /**
	  * sets the effective time.
	  */
	 public void setTime(Date date)
	 {
		 super.setTime(date);
	 }
	/**
	 * Returns the source Concept Id.
	 * @return the identifier of the source {@link Concept} of this relationship.
	 */
	public Concept getSourceConcept() {
		return sourceConcept;
	}
	/**
	 * Sets the source Concept Id.
	 * @param sourceConcept
	 * 						 Id of the source concept.
	 */
	public void setSourceConcept(Concept sourceConcept) {
		this.sourceConcept = sourceConcept;
	}

	/**
	 * Returns the destination Concept Id.
	 * @return the destination concept of this relationship.
	 */
	public String getDestinationValue() {
		return destinationValue;
	}
	/**
	 * Sets the destination Concept Id.
	 * @param destinationConcept
	 * 					 destination Concept.
	 */
	public void setDestinationValue(String destinationValue) {
		this.destinationValue = destinationValue;
	}
	/**
	 * Sets the type of the {@link Relationship}.
	 * @param type
	 * 			 represents the Relationship type.
	 */
	public void setType(Concept type) {
		this.type = type;
	}

	/**
	 * 
	 * @return {@link EnumRelationshipType} the type of this relationship.
	 */
	public Concept getType() {
		return type;
	}
	
/*	@Override
	public String toString(){
		return this.getType().getValue()+
	}*/

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());//(int) (id ^ (id >>> 32));
		result = prime * result
				+ ((sourceConcept.getId()== null) ? 0 : sourceConcept.getId().hashCode()); //(int) (sourceConceptId ^ (sourceConceptId >>> 32));
		//result = prime * result
			//	+ ((destination.getId() == null) ? 0 : destinationConcept.getId().hashCode());//(int) (targetConceptId ^ (targetConceptId >>> 32));
		result = prime * result + ((type.getId() == null) ? 0 : type.getId().hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ConcreteRelationship other = (ConcreteRelationship) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		
		if (sourceConcept.getId() == null) {
			if (other.sourceConcept.getId() != null)
				return false;
		} else if (!sourceConcept.getId().equals(other.sourceConcept.getId()))
			return false;
		
		//if (destinationConcept.getId() == null) {
			//if (other.destinationConcept.getId() != null)
				//return false;
		//} else if (!destinationConcept.getId().equals(other.destinationConcept.getId()))
			//return false;

		if (type.getId() != other.type.getId())
			return false;
		return true;
	}
	/**
	 * Returns the relationship group.
	 * @return relationship group to which the particular {@link Relationship} belongs.
	 */
	public int getRelationshipGroup() {
		return relationshipGroup;
	}
	/**
	 * Sets the relationship group.
	 * @param relationshipGroup
	 * 						 integer value that represents a group of 
	 * relationships logically associated with one another.
	 */
	public void setRelationshipGroup(int relationshipGroup) {
		this.relationshipGroup = relationshipGroup;
	}
	/**
	 * Returns the characteristic type.
	 * @return characteristic type Id associated with the {@link Relationship}.
	 */
	public String getCharacteristicTypeId() {
		return characteristicTypeId.getValue();
	}
	/**
	 * Sets the characteristic type.
	 * @param characteristicTypeId
	 * 							specifies the characteristic type.
	 */
	public void setCharacteristicTypeId(EnumCharacteristicType characteristicTypeId) {
		this.characteristicTypeId = characteristicTypeId;
	}
	/**
	 * Returns the modifier Id.
	 * @return modifier Id.
	 */
	public String getModifierId() {
		return modifierId.getValue();
	}
	/**
	 * Sets the modifier Id.
	 * @param modifierId
	 * 					the modifier Id.
	 */
	public void setModifierId(EnumModifier modifierId) {
		this.modifierId = modifierId;
	}
	
}
