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

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

import de.uka.ipd.consensus.foundation.rating.RatingManagerException;
import de.uka.ipd.consensus.foundation.rights.DynamicRightsManagerException;

/**
 * This is a mixin interface for rateable elements.
 * @author Thomas Much
 * @version 2006-06-14
 * @see Rating
 */
public interface Rateable extends Serializable {

	/**
	 * Returns the id of the element that is unique within the ontology.
	 * This is used to distinguish concepts and users.
	 * @return the id (never empty, never <code>null</code>)
	 */
	public String getId();


	/**
	 * Adds a rating for the given user to this element.
	 * If the user has rated the element already, only the rating's value is changed.
	 * Otherwise, this method creates and adds a new rating using suitable <code>RatingManager</code> methods.
	 * @param rater the user who wants to add or change the rating
	 * @param value the new value
	 * @return the newly created or the existing but changed rating
	 * @throws RatingManagerException if the rating could not be created/changed
	 * @throws DynamicRightsManagerException if the user is not allowed to rate this element
	 * @see de.uka.ipd.consensus.foundation.rating.RatingManager
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayAddRating(Rating, Rateable)
	 */
	public Rating addRating(User rater, double value) throws RatingManagerException,DynamicRightsManagerException;


	/**
	 * Returns a collection of all current Rating objects (from different users) for this element.
	 * This method exists just for convenience and delegates to one of the <code>getRatings()</code> methods of <code>RatingManager</code>.
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Rating
	 * @see de.uka.ipd.consensus.foundation.rating.RatingManager
	 */
	public Collection getRatings();

	
	/**
	 * Returns the number of ratings for this element.
	 * Each user can have only one current rating for each element, i.e. historical ratings do not count.
	 * @return the number of ratings for this element.
	 */
	public int getRatingsCount();


	/**
	 * Returns the rating of the given user for this element.
	 * This method exists just for convenience and delegates to one of the <code>getRatings()</code> methods of <code>RatingManager</code>.
	 * @param rater the user who's rating shall be returned
	 * @return the rating of the user or <code>null</code> if the user hasn't rated this element yet
	 * @see de.uka.ipd.consensus.foundation.rating.RatingManager
	 */
	public Rating getRating(User rater);

	
	/**
	 * Returns the average value (the arithmetic mean) of all current ratings for this element.
	 * @return the arithmetic mean of all ratings for this element
	 */
	public double getAverageRatingValue();

}
