/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 */

package org.biojavax.bio.seq.io;

import org.biojava.bio.seq.io.ParseException;
import org.biojava.bio.seq.io.SeqIOListener;
import org.biojavax.Namespace;
import org.biojavax.RankedCrossRef;
import org.biojavax.RankedDocRef;
import org.biojavax.bio.BioEntryRelationship;
import org.biojavax.bio.seq.RichFeature;
import org.biojavax.bio.taxa.NCBITaxon;

/**
 * An interface for classes that listen to BioEntry or 
 * RichSequence I/O streams. The listener works as a call back interface.
 * The callback methods would be generated by an object that is, for example,
 * reading a sequence flat file. Guidelines on how many times the listener can
 * expect each callback to occur are given below.
 * Exactly what the Listener does with each call back is totally at the discretion
 * of the implementor. The listener may aggregate events and build objects.
 * The listener may selectively filter events and parse on others to another
 * listener. The listener may choose to modify events. The options are endless.
 * Although the name of the class and the name of some of the events suggest a
 * sequence centric design the class could be used to listen to a parser of a
 * bioentry style record that doesn't actually contain any sequence. In this
 * case no addSymbols() methods would be called. The listener may
 * be an implementation that only builds BioEntry objects and
 * ignores sequence information completely.
 * @author Mark Schreiber
 * @author Richard Holland
 * @since 1.5
 */
public interface RichSeqIOListener extends SeqIOListener {
    
    /**
     * Call back method so the event emitter can tell the listener
     * the accession of the record being read. It is possible that some
     * records have more than one accession. As a guide the first one
     * sent to the listener should be the primary one.
     * @param accession The accession of the record
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     *
     * @see #setName(String name)
     * @see #setURI(String uri)
     * @see #setIdentifier(String identifier)
     *
     */
    public void setAccession(String accession) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the identifier of the record being read. There should be
     * zero or one identifier per bioentry. If there is more
     * than one the Listener should consider throwing an exception.
     * For some formats like fasta the identifier may not exist. For others
     * like GenBank the identifier best maps to the GI.
     * @param identifier The identifier of the Bioentry.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     * @see #setName(String name)
     * @see #setAccession(String accession)
     * @see #setURI(String uri)
     */
    public void setIdentifier(String identifier) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the division of the record being read. If the source of the
     * calls back is a GenBank parser the division will be a Genbank division.
     * This method would typically be called 0 or 1 times. It should
     * not be called more than once per entry and an exception could be thrown
     * if it is.
     * @param division The division the entry belongs too.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setDivision(String division) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the description of the record being read. For example the description
     * line of a FASTA format file would be the description. This method
     * would typically be called 0 or 1 times and may cause an exception
     * if it is called more than once per entry.
     * @param description The description of the record
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setDescription(String description)throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the version of the record being read. This method would typically
     * be called 0 or 1 times per entry. If it is not called the
     * Listener should assume the version is 0. If it is called more
     * than once per entry an exception should be thrown.
     * @param version the version of the record
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setVersion(int version) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the version of the sequence of the record being read. This method would typically
     * be called 0 or 1 times per entry. If it is not called the
     * Listener should assume the version is 0. If it is called more
     * than once per entry an exception should be thrown.
     * @param version the version of the record
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setSeqVersion(String version) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * about a comment in the record being read. The comment is typically
     * one or more comment lines relevant to the record as a whole and
     * bundled in a Commment object.
     * This method may be called zero or one times per entry. It can be called zero or more times.
     * @param comment The comment
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setComment(String comment) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * about a literature reference in the record being read. This method
     * may be called zero or more times.
     * @param ref A literature reference contained in the entry.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setRankedDocRef(RankedDocRef ref) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the Taxon of the record being read. This method may be called
     * zero or one times. An exception may be thrown if it is called
     * more than once. As a design decision NCBI's taxon model was chosen as it
     * is commonly used and is supported by the BioSQL schema. The setting of
     * an NCBI taxon should be considered entirely optional.
     *
     * @param taxon The taxon information relevant to this entry.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setTaxon(NCBITaxon taxon) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * the namespace of the record being read. The method can be called
     * zero or one time. If it is called more than once an exception
     * may be thrown.<p>
     * The namespace is a concept from the BioSQL schema that enables
     * Bioentries to be disambiguated. It is possible in BioSQL and should be possible
     * in other collections of BioEntries to have records that have the same
     * name, accession and version but different namespaces. This method would be
     * expected to be called if you are reading a sequence from a biosql database or
     * if you are implementing a listener that knows how to write to a biosql database.
     * If you give a sequence a namespace and it is persited to biosql at somepoint in it's
     * life you could expect it to be persisted to that namespace (if possible).
     *
     * @param namespace The namespace of the entry.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setNamespace(Namespace namespace) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener
     * about a relationship between the bioentry or sequence in the
     * record being read and another bioentry. This may be called zero
     * or more times.
     * @param relationship The relationship
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setRelationship(BioEntryRelationship relationship) throws ParseException;
    
    /**
     * Call back method so the event emitter can tell the listener about a cross reference.
     * This could be called zero or more times per entry.
     * @param crossRef the cross reference
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     */
    public void setRankedCrossRef(RankedCrossRef crossRef) throws ParseException;
    
    /**
     * {@inheritDoc}
     * @deprecated There is no clear mapping between URI and BioSQL. This
     *  method is no longer used or supported in biojavax. Don't use it. Calling
     *  it may result in exceptions. Use instead setName(String name),
     *  setAccession(String accession), setVersion(int version) etc as
     *  appropriate.
     */
    public void setURI(String uri) throws ParseException;
    
    /**
     * Gets the feature currently being created.
     * @return the feature under construction.
     * @throws ParseException if a feature is not currently being created.
     */ 
    public RichFeature getCurrentFeature() throws ParseException;
    
    /**
     * Defined this sequence being parser as circular. It is best to call this
     * as early as possible during parsing. It should definitely be called
     * before doing anything with locations or features.
     * @throws org.biojava.bio.seq.io.ParseException If the Listener cannot understand the event, is unable
     * to deal with the event or is not expecting the event.
     * @param circular set this to true if you want it to be circular.
     */ 
    public void setCircular(boolean circular) throws ParseException;
    
}
