package de.uka.ipd.consensus.foundation.schema;

import java.io.Serializable;
import java.util.Collection;

/**
 * This interface represents one rating given by a user to a rateable element.
 * @author Thomas Much
 * @version 2006-06-14
 * @see User
 * @see Rateable
 * @see de.uka.ipd.consensus.foundation.rating.RatingManager
 */
public interface Rating extends Versionable,Createable,Commentatable,Serializable,Comparable {

	/**
	 * The proposed minimum value for ratings (disagreement).
	 */
	public static final double NO      = -1.0;
	
	
	/**
	 * The proposed maximum value for ratings (agreement).
	 */
	public static final double YES     =  1.0;
	
	
	/**
	 * The proposed neutral value for ratings.
	 */
	public static final double NEUTRAL =  0.0;

	
	/**
	 * Returns the rating's value from -1.0 to 1.0 (including both values).
	 * @return the rating's value
	 * @see #setValue(double)
	 */
	public double getValue();
	
	
	/**
	 * Changes the rating's value and adds the old values to the history.
	 * If this is a historic rating, changing its value has no effect.
	 * @param value the new value from -1.0 to 1.0 (including both values) 
	 * @see #getValue()
	 * @see #getHistory()
	 * @see #isHistorical()
	 */
	public void setValue(double value);

	
	/**
	 * Returns the rated element. This can be only a concept (topic, association, attribute) or a user.
	 * However, if you want to retrieve an association wrapper like <code>Synonym</code>, <code>SuperSubclass</code> or <code>TypeInstance</code> (which are Rateable, too), 
	 * use <code>OntologyManager.checkInternalRateable()</code> to convert the returned association into one of these wrappers.
	 * @return the rated element
	 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager#checkInternalRateable(Rateable)
	 */
	public Rateable getRateable();

	/**
	 * Returns the version of the rated element.
	 * This is the element's version at the time when the rating was assigned to the element, not necessarily the element's current version.
	 * @return the version of the rated element, may be <code>null</code> if no version information is available
	 */
	public Version getRatedVersion();

	
	/**
	 * Checks if this rating is historic, i.e. if it contains older values than the element's current rating.
	 * Historic ratings are read-only.
	 * @return <code>true</code> if this rating belongs to the rating history, <code>false</code> if it is a current rating
	 * @see #getHistory()
	 * @see #setValue(double)
	 * @see Commentatable#setComment(User, String)
	 */
	public boolean isHistorical();

	
	/**
	 * Returns a collection of Rating objects that contain all older values for this rating (i.e. the rating for this element from the creator of the rating).
	 * If this rating is a historical rating itself or if the RatingManager does not support rating histories, an empty collection is returned.
	 * @return a possibly empty collection, never <code>null</code>
	 * @see #isHistorical()
	 */
	public Collection getHistory();
}
