#ifndef _RAALIST_H_
#define _RAALIST_H_
#include <string>

namespace bpp {

class RAA;

/**
 * @brief List of sequences, keywords, or species returned by a database query.
 *
 * Instances of this class are created by database queries. Each instance contains
 * one or several elements that are often sequences, but can also be species or keywords.
 * Iteration through all elements of the list is possible.
 */
class RaaList {
	friend class RAA;
	RAA *myraa;
	int rank;
	std::string name;
	const std::string *type;
	int from;
	std::string elementname;
	int elementlength;
public:
	
	/**
	 * @brief Refers to a sequence list.
	 */
	static const std::string LIST_SEQUENCES;
	
	/**
	 * @brief Refers to a keyword list.
	 */
	static const std::string LIST_KEYWORDS;
	
	/**
	 * @brief Refers to a species list.
	 */
	static const std::string LIST_SPECIES;
	
	/**
	 * @brief Gives the number of elements (often sequences) in the list.
	 */
	int getCount();
	
	/**
	 * @brief   Gives the database rank of the first element of the list.
	 */
	int firstElement();
	
	/**
	 * @brief   Gives the database rank of the list element following the last considered element.
	 */
	int nextElement();
	
	/**
	 * @brief   Sets an element of the list from which nextElement() will start.
	 *
	 * @param  element_rank   The database rank of an element of the list, typically returned by 
	 * a previous nextElement() call.
	 */
	void setFrom(int element_rank);
	
	/**
	 * @brief   Gives the name of the last considered list element.
	 */
	std::string elementName() {return elementname; };
	
	/**
	 * @brief   Gives the length of the last considered list element (meaningful only for sequence lists).
	 */
	int elementLength() {return elementlength; };
	
	/**
	 * @brief   Returns the total # of residues in all sequences of list (meaningful only for sequence lists).
	 *
	 * Because this count can exceed a long integer, it is returned as a string.
	 */
	std::string residueCount();
	
	/**
	 * @brief   Adds an element identified by its database rank to the list.
	 */
	void addElement(int rank);
	
	/**
	 * @brief   Removes an element identified by its database rank from the list.
	 */
	void removeElement(int rank);
	
	/**
	 * @brief   Tests whether an element identified by its database rank belongs to the list.
	 */
	bool isInList(int rank);
	
	/**
	 * @brief   Removes all elements from the list.
	 */
	void zeroList();
	
	/**
	 * @brief Gives the rank of the list.
	 */
	int getRank() {return rank; };
	
	/**
	 * @brief true means that list contains only parent sequences (does not contain any subsequence).
	 */
	bool parentsOnly();
	
	/**
	 * @brief Indicates whether the list contains sequences, species or keywords.
	 *
	 * @return  can be "sequence list", "species list", or "keyword list"
	 */
	std::string getType() {return *type; };
	
	/**
	 * @brief   Gives the list name.
	 */
	std::string getName() {return name; };
	
	/**
	 * @brief   Modifies a sequence list by a length criterion.
	 *
	 * @param criterion		Length criterion such as "> 1000" or "<5000".
	 * @param listname		Name to be given to created list of sequences matching the length criterion.
	 * @return				A new list of sequences matching the length criterion, or NULL if error.
	 */
	RaaList *modifyByLength(const std::string &criterion, const std::string &listname);
	
	/**
	 * @brief   Modifies a sequence list by a database insertion date criterion.
	 *
	 * The database insertion date of each sequence is that of the last DT record for the embl/swissprot format, 
	 * or that of the LOCUS record for the GenBank format.
	 *
	 * @param criterion		Date criterion such as "> 1/jun/98" or "<10/DEC/2004". Year can be expressed with 2 or 4 digits.
	 * Case is not significant.
	 * @param listname		Name to be given to the created list of sequences matching the date criterion.
	 * @return				A new list of sequences matching the date criterion, or NULL if error.
	 */
	RaaList *modifyByDate(const std::string &criterion, const std::string &listname);
private:
	RaaList();
};

} //end of namespace bpp.

#endif  //_RAALIST_H_

