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

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

import de.uka.ipd.consensus.foundation.user.UserManager;
import de.uka.ipd.consensus.foundation.user.UserRole;

/**
 * This interface represents a user who is part of the ontology, but managed by the UserManager.
 * The user must be available within the ontology to enable associations between him and other elements of the ontology.
 * But the user's data need to be stored outside the ontology for security reasons.
 * @author Thomas Much
 * @version 2006-06-14
 * @see de.uka.ipd.consensus.foundation.user.UserManager
 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager
 */
public interface User extends Rateable,Commentatable,Serializable,Comparable {

	/**
	 * Returns the username that the user has given himself when creating his user account.
	 * This username must be unique within the user database.
	 * @return the username (never empty, never <code>null</code>)
	 * @see #getId()
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#createUser(String, String, Map)
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#getUserByUsername(String)
	 */
	public String getUsername();
	
	
	/**
	 * Returns the user's id that was computed automatically from the username when the user created his account.
	 * The user id must be unique within all elements of the ontology.
	 * @return the user's id (never empty, never <code>null</code>)
	 * @see #getUsername()
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#createUser(String, String, Map)
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#getUserById(String)
	 */
	public String getId();
	
	
	/**
	 * Returns the UserManager instance that manages this user account.
	 * @return the UserManager, never <code>null</code>
	 */
	public UserManager getUserManager();

	
	/**
	 * Checks if the user is in the given role.
	 * @param role the role to check
	 * @return <code>true</code> if the user is in the role, <code>false</code> otherwise
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#findRole(String)
	 */
	public boolean isInRole(UserRole role);
	
	
	/**
	 * Returns a collection of UserRole objects that this user is in.
	 * @return a possibly empty collection, never <code>null</code>
	 * @see de.uka.ipd.consensus.foundation.user.UserRole
	 */
	public Collection getRoles();
	
	
	/**
	 * Adds a UserRole to this user's roles.
	 * @param role the UserRole to add
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#findRole(String)
	 */
	public void addRole(UserRole role);
	
	
	/**
	 * Removes a UserRole from this user's roles.
	 * If the user isn't in the role, this call is ignored.
	 * @param role the UserRole to remove
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#findRole(String)
	 */
	public void removeRole(UserRole role);
	
	
	/**
	 * Checks if the user is in the admin role.
	 * @return <code>true</code> if the user is in the admin role, <code>false</code> otherwise
	 */
	public boolean isAdmin();
	
	
	/**
	 * Checks if the user is logged on.
	 * @return <code>true</code> if the user is logged on, <code>false</code> otherwise
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#login(String, String)
	 * @see de.uka.ipd.consensus.foundation.user.UserManager#logout(User)
	 */
	public boolean isLoggedOn();

	
	/**
	 * Returns this user's score.
	 * The IncentiveManager or a ScoringListener may change the user's score for his actions (e.g. create or rate elements).
	 * @return the user's score
	 * @see #setScore(double)
	 * @see de.uka.ipd.consensus.foundation.scoring.IncentiveManager#getInitialUserScore()
	 * @see de.uka.ipd.consensus.foundation.scoring.ScoringListener
	 */
	public double getScore();
	
	
	/**
	 * Changes this user's score.
	 * This method is usually called from a ScoringListener.
	 * @param score the new score (an absolute value, not a delta value!)
	 * @see #getScore()
	 * @see de.uka.ipd.consensus.foundation.scoring.ScoringListener
	 */
	public void setScore(double score);


	/**
	 * Returns a collection of all current Rating objects that this user has given to other elements of the ontology.
	 * This method exists just for convenience and delegates to a <code>RatingManager</code> method.
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Rating
	 * @see de.uka.ipd.consensus.foundation.rating.RatingManager#getUsersOwnRatings(User)
	 */
	public Collection getOwnRatings();
	
	
	/**
	 * Returns the number of ratings that this user has given to other elements of the ontology.
	 * Each element can have only one current rating by one user, i.e. historical ratings do not count.
	 * @return the number of ratings that this user has given to other elements of the ontology.
	 */
	public int getOwnRatingsCount();
	
	
	/**
	 * Returns the average value (the arithmetic mean) of all ratings that this user has given to other elements of the ontology.
	 * Each element can have only one current rating by one user, i.e. historical ratings do not count.
	 * @return the arithmetic mean of all ratings that this user has given to other elements of the ontology
	 */
	public double getAverageOwnRatingsValue();

}
