#pragma once

/**
* @mainpage The Xairo API
*
* The Xairo API is the common low level entry point to the Xairo server. It is used by
* the various Xaira clients to accept queries and return solutions; it is also used by
* the SOAP server, which in turn exposes a higher level interface suitable to transfer
* of data by HTTP. Many users will not need to use the low level API and will use a client
* to solve queries. This documentation is for those wishing to use the C++ API. Some
* general programming considerations are discussed \ref prog "here" and these should be consulted
* before the detailed API document pages.
* 
* There is also a Java API with Javadoc documentation almost identical to this in docs/api/java. The SOAP
* web service API is formally defined by the file Xaira.wsdl and informally in the docs/api/webserver
* directory.
*
*/

#define XAIRO_API_VERSION 1203


#ifndef _WIN32
typedef unsigned short xairo_uchar;
#else
typedef unsigned short xairo_uchar;
#endif

/**
 * All Xairo objects are in the XAIRO namespace
 */
namespace XAIRO_NAMESPACE {


/**
 * Interface to the grammar.
 *
 * The Xaira grammar is a set of tables that record the XML usage of a corpus. The
 * grammar is compiled by the indexer: it differs from a DTD or set of schemata in
 * that it records what actually occurs rather than what may legally occur.
 *
 * The various objects used by the grammar are represented by classes nested inside
 * Grammar. These are doocumented separately.
 *
 * There is only one grammar and it does not vary in the course of a session. The 
 * programmer is advised to cache information from the grammar to save repeatedly
 * accessing the interface. Objects returned by calls to the grammar are nevertheless
 * copies and the progammer is reponsible for their deletion.
 */
class CXairoIGrammar
{
public:

	virtual int getNamespaceCount() const =0;
	
	class Namespace
	{
	public: 
		virtual const xairo_uchar* getUrl() const=0;
	};
	virtual const Namespace* getNamespace(int) const=0;

	class Codebook
	{
	public:
		virtual const xairo_uchar* lookup(const xairo_uchar*) const =0;
		virtual int getCount() const=0;
		virtual void getPair(int i,const xairo_uchar**,const xairo_uchar**) const=0;
	};

	virtual int getAddkeyCount() const =0;

	class Addkey
	{
	public:
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getGloss() const =0;
		virtual bool isLemmaScheme() const =0;
		virtual const Codebook* getCodebook() const =0;
		virtual const xairo_uchar* getAttribute() const =0;
	};
	virtual const Addkey* getAddkey(int i) const =0;

	virtual int getLemmaSchemeCount() const =0;

	class LemmaScheme
	{
	public:
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getGloss() const =0;
		virtual int getFacetCount() const=0;
		virtual const xairo_uchar* getFacet(int) const=0;
	};
	virtual const LemmaScheme* getLemmaScheme(int) const =0;

	virtual int getRegionCount() const =0;

	class Region
	{
	public:
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getGloss() const =0;
		virtual int getValueCount() const=0;
		virtual const xairo_uchar* getValue(int) const=0;
		virtual const Addkey* getAddkey() const=0;
	};
	virtual const Region* getRegion(int) const =0;

	class Attribute
	{
	public:
		enum ip {ip_cdata,ip_none,ip_tax,ip_idref,ip_id,ip_content,ip_lemma,ip_contenta};
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getGloss() const =0;
		virtual const Namespace* getNamespace() const =0;
		virtual const Codebook* getCodebook() const =0;
		virtual const xairo_uchar* getElt() const =0;
		virtual ip getIP() const =0;
		virtual const xairo_uchar* getTarget() const =0;
		virtual bool inBib() const =0;

	};
	virtual int getElementCount() const =0;

	class Element
	{
	public:
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getGloss()const =0;
		virtual int getAttributeCount() const =0;
		virtual const Attribute* getAttribute(int) const =0;
		virtual const Namespace* getNamespace() const =0;
		virtual bool inBib() const =0;

	};
	virtual const Element* getElement(int) const =0;

	virtual int getGlobalAttributeCount() const=0;
	virtual const Attribute* getGlobalAttribute(int) const =0;

	class Partition
	{
	public:
		virtual const xairo_uchar* getName() const =0;
		virtual const xairo_uchar* getDescription() const =0;
		virtual int getCount()const =0;
		virtual const Partition* getDivision(int) const =0;
		virtual bool hasClasses() const =0;
		virtual int getWordCount() const =0;
		virtual int getIndex() const =0;
	};
	virtual const Partition* getRootPartition() const =0;

	class Label
	{
	public:
		virtual const xairo_uchar* getElement() const =0;
		virtual const xairo_uchar* getAttribute() const =0;
	};
	virtual int getLabelCount() const =0;
	virtual const Label* getLabel(int) const=0;

	virtual int getCodePageCount() const =0;
	virtual const xairo_uchar* getCodePage(int) const =0;

	virtual int getCharacterEntityCount() const =0;
	virtual void getCharacterEntity(int,const xairo_uchar**,int*) const =0; 

	virtual int getWTagCount() const=0;
	virtual const xairo_uchar* getWTag(int) const=0;

	virtual const char* getDSC() const=0;
};

class CXairoIGrammar;
class CXairoIInterruptHandler;
class CXairoIExtendedForm;
class CXairoICorpusTextFilter;
class CXairoIAddkeyFilter;

/**
 * Top level interface to the Xairo server
 *
 * Use the static members of the CXairoImplementation class to obtain a CXairoInterface
 * object. All other objects are acquired by calls to the members of this class.
 */
class CXairoInterface
{
public:
/**
 * Gets a list of dictionary entries matching a pattern. No
 * assumptions should be made about the list is sorted.
 *
 * @param n Number of patterns supplied (should equal number of facets in lemma scheme)
 * @param patterns Array of regular expressions controlling the words to be included.
 * @param scheme Name of the lemma scheme whose dictionary is to be used. Empty for the null scheme.
 * @return CXairoIWordList object with an entry for each matching word.
 */
	virtual class CXairoIWordList* getWordList(int n,const xairo_uchar** patterns,const xairo_uchar* scheme)=0;
/**
 * Gets a list of dictionary words sorted by frequency.
 *
 * @param n Number of patterns supplied (should equal number of facets in lemma scheme)
 * @param patterns Array of regular expressions controlling the words to be included.
 * @param scheme Name of the lemma scheme whose dictionary is to be used. Empty for the null scheme.
 * @param maxn Maximum number of words to be included in list - the least frequent will be omitted.
 * @param minf Minimum frequency below which words will be excluded
 * @param maxf Maximum frequency above which words will be excluded.
 * @return CXairoIWordList object with an entry for each matching word.
 */
	virtual class CXairoIWordList* getFrequencyList(int n,const xairo_uchar** patterns,int maxn,int minf,int maxf,const xairo_uchar* scheme)=0;
/**
 * Gets a list of dictionary words sorted by frequency.
 *
 * @param n Number of patterns supplied (should equal number of facets in lemma scheme)
 * @param patterns Array of regular expressions controlling the words to be included.
 * @param scheme Name of the lemma scheme whose dictionary is to be used. Empty for the null scheme.
 * @param maxn Maximum number of words to be included in list - the least frequent will be omitted.
 * @param minf Minimum frequency below which words will be excluded
 * @param maxf Maximum frequency above which words will be excluded.
 * @return CXairoIWordList object with an entry for each matching word.
 */
	virtual class CXairoIWordList* getFilteredFrequencyList(int n,const xairo_uchar** patterns,int maxn,int minf,int maxf,const xairo_uchar* scheme,const CXairoICorpusTextFilter* f,const CXairoIAddkeyFilter* ff)=0;
/**
 * Get a list of values that occur for an attribute. The programmer might expect
 * to find this information in CXairoIGrammar but because of its potential size
 * it is in fact not assembled until requested. Codebook information is stored in
 * the grammar and is automatically retrieved when an attribute value is fetched from 
 * the list.
 *
 * @param att CXairoIGrammar::Attribute to be queried.
 * @return CXairoIAttributeValueList object
 */
	virtual class CXairoIAttributeValueList* getAttributeValueList(const CXairoIGrammar::Attribute* att)=0;
/**
 * Get a list of values that occur for an addkey. The programmer might expect
 * to find this information in CXairoIGrammar but because of its potential size
 * it is in fact not assembled until requested. 
 *
 * @param ak CXairoIGrammar::Addkey to be queried.
 * @return CXairoIAddkeyValueList object
 */
	virtual class CXairoIAddkeyValueList* getAddkeyValueList(const CXairoIGrammar::Addkey* ak)=0;
/**
 * Solve a CQL query. 
 *
 * @param query The query
 * @return CXairoISolution object with an entry for each hit,
 */
 virtual class CXairoISolution* solve(const xairo_uchar* query)=0;
/**
* Get the list of all corpus texts of type CXairoICorpusTextList. 
*
* @return A pointer to a copy of the corpus text list object. 
*/
	virtual class CXairoICorpusTextList* getCorpusTextList()=0;
/**
 * Get the grammar associated with the corpus in use.
 *
 * @return CXairoIGrammar object
 */
	virtual const CXairoIGrammar* getGrammar()=0;
/**
 * Get the total number of word usages in the corpus.
 *
 * @return Number of usages
 */
	virtual int getWordCount()=0;
/**
 * Get the name of the corpus in use.
 * @return The name, s set in the .xcorpus file.
 */
	virtual const xairo_uchar* getCorpusName()=0;
/**
 * Get the default language of the corpus. 
 * @return The language identifier. 
 */
	virtual const xairo_uchar* getDefaultLanguage()=0;
/**
 * Get a usage by serial number. A usage means any item indexed by the 
 * xaira indexer - a word of content, an XML tag or anything else at
 * all. Conceptually a corpus is a sequence of usages. Just as each 
 * word of content corresponds to some CXairoIForm, so each usage 
 * corresponds to a CXairoIExtendedForm. This function returns the extended 
 * form of the usage with given sequence number. In practice the only way
 * to get a sequence number is by using CXairoIHit::getCursorStart or 
 * CXairoIHit::getCursorEnd and then adding or subtracting to or from
 * the result as required.
 * 
 * @param k The sequence number
 * @return The extended form. 
 */
	virtual CXairoIExtendedForm* getUsage(unsigned int k)=0;
/**
 * Get a CXairoIAddkeyFilter object that can be used to thin CXairoISolution objects 
 * (see CXairoISolution::thinAddkeyFilter).  
 * An addkey filter restricts searches to words whose addkey value for
 * the specified addkey is in the specified list. Regions as defined
 * in the corpus header can be used to define an addkey filter, but it
 * is also possible for the programmer to construct a filter for a 
 * set of values that is not a region.
 * 
 * @param key The name of the addkey to be used (should be an addkey object)
 * @param nvals The number of values in the vals array
 * @param vals Array of values determining inclusion when filtered.
 * @return An addkeyfiler. 
 */
	virtual CXairoIAddkeyFilter* getAddkeyFilter(const xairo_uchar* key,int nvals,const xairo_uchar** vals)=0;
//	virtual CXairoIAddkeyFilter* getAddkeyFilter(CXairoIGrammar::Region* r)=0;
	virtual void* deserialize(const xairo_uchar*)=0;
	virtual ~CXairoInterface(){}
};



class CXairoIWord;

/**
 * Interface to a list of headwords.
 *
 * Headword lists may be obtained using CXairoInterface::getWordList and 
 * CXairoInterfaceServer::getFrequencyList. 
 *
 */
class CXairoIWordList
{
public:
/**
 * Get the number of words in the list. 
 *
 * @return The count. 
 */
	virtual int getCount()=0;
/**
 * Get the nth word in the list.
 *
 * @param n The index of the required word.
 * @return The count. 
 */
	virtual CXairoIWord* getWord(int n)=0;
};


class CXairoIForm;

/**
 * Interface to a single headword.
 *
 * A headword is a word that occurs as the headword of a word in a specified lemma 
 * scheme. Its forms are all words with the given headword together with each
 * combination of additional keys that occurs with one of those words. In the null 
 * lemma scheme each word is its own headword.
 *
 * The same word may have several different headwords. 
 *
 */
class CXairoIWord
{
public:
/**
 * Returns a component of the headword as a string. getNorm is a stupid name.
 *
 * @param n Desired component of the headword. This is usually 0.
 * @return Headword
 */	
	virtual const xairo_uchar* getNorm(int n)=0;
/**
 * Returns the frequency of the headword, that is, the number of words in the corpus
 * that are its forms.
 *
 * @return Frequency
 */	
	virtual int getFrequency()=0;
/**
 * Returns the frequency of the headword in the subcorpus, that is, the number of words in the corpus
 * that are its forms. 
 * This information is not in the index and takes longer to compute
 * than the zero argument form.
 * It is also possible to specify filtering by an addkey filter.
 *
 * \deprecated This is no faster than solving a lemma query then thinning to subcorpus
 * and in general where there is a solution using cql that is preferred.
 *
 * @param f Pointer to the CXairoICorpusTextFilter to be used
 * @param ff Pointer to the CXairoIAddkeyFilter to be used
 * @return Frequency
 */	
	virtual int getFilteredFrequency(const CXairoICorpusTextFilter* f,const CXairoIAddkeyFilter* ff)=0;
/**
 * Returns the number of forms of the headword. 
 *
 * @return Number of forms
 */	
	virtual int getFormCount()=0;
/**
 * Returns the CXairoIForm with the given index
 *
 * @param i Index
 * @return Pointer to CXairoIForm
 */	
	virtual CXairoIForm* getForm(int i)=0;
};


/**
 * Interface to a form.
 *
 * A form is a word together with a value for each additional key. The word in the
 * form is normalised: although the index records variant capitalisations of forms
 * they are not available through this call, though they can be extracted using
 * a suitable xql query.
 
 */
class CXairoIForm
{
public:
/**
 * Returns the frequency of the form in the corpus, that is, the number of times that
 * the combination occurs. 
 *
 * @return Frequency
 */	
	virtual int getFrequency()=0;
/**
 * Returns the frequency of the form in the subcorpus, that is, the number of times that
 * the combination occurs. This information is not in the index and takes longer to compute
 * than the zero argument form.
 *
 * \deprecated This is no faster than solving a lemma query then thinning to subcorpus
 * and in general where there is a solution using cql that is preferred.
 *
 * @param f Pointer to the CXairoICorpusTextFilter to be used
 * @return Frequency
 */	
	virtual int getFilteredFrequency(const CXairoICorpusTextFilter* f)=0;

/**
 * Returns the value of the named additional key. 
 *
 * @param key Key name
 * @return Key value.
 */	
	virtual const xairo_uchar* getAdditionalKey(const xairo_uchar* key)=0;
/**
 * Returns the normalised form. 
 *
 * @return Normalised string.
 */	
	virtual const xairo_uchar* getNorm()=0;
/**
 * Returns the unnormalised form. 
 *
 * @return String without normalisation.
 */	
	virtual const xairo_uchar* getText()=0;
/**
 * Tests whether a particular form of a word is included by a given addkey filter.
 *
 * @param f The addket filterkey Key name
 * @return true if included.
 */	
	virtual bool included(const CXairoIAddkeyFilter* f)=0;

};

/**
 * Interface to an extended form.
 *
 * An extended form corresponds to a single entry in the Xaira dictionary.
 * The entry may be for anything that is indexed, usually either a word
 * or XML markup. 
 *
 * At the moment only the interface to words has been developed.
 
 */
class CXairoIExtendedForm 
{
public:
	enum type {TY_WORD};
/**
 * Returns the value of the named additional key. 
 *
 * @param key Key name
 * @return Key value.
 */	
	virtual const xairo_uchar* getAdditionalKey(const xairo_uchar* key)=0;
/**
 * Returns the normalised form. 
 *
 */	
	virtual const xairo_uchar* getNorm()=0;
/**
 * Returns the unnormalised form. 
 *
 */	
	virtual const xairo_uchar* getText()=0;
/**
 * Returns the type. 
 *
 */	
	virtual type getType()=0;
	virtual ~CXairoIExtendedForm() {}
};

/**
 * Interface to a single attribute value.
 *
 * An attribute value is one of the possible values for an attribute. Possible values are
 * values that actually occur; no notice is taken of DTD or schemata declaration.
 *
 */
class CXairoIAttributeValue
{
public:
/**
 * Returns the value as a string.
 *
 * @return Value
 */	
	virtual const xairo_uchar* getValue()=0;
/**
 * Returns the number of times this value occurs.
 *
 * @return Frequency
 */	
	virtual int getFrequency()=0;
/**
 * Returns the number of times this value occurs in the selected texts of
 * a corpus text filter.
 *
 * \deprecated This is no faster than solving a lemma query then thinning to subcorpus
 * and in general where there is a solution using cql that is preferred.
 *
 * @param f Pointer to the CXairoICorpusTextFilter to be used
 * @return Frequency
 */	
	virtual int getFilteredFrequency(const CXairoICorpusTextFilter* f)=0;
/**
 * Returns the value's gloss as a string. The gloss is taken from the codebook if one exists.
 *
 * @return Gloss
 */	
	virtual const xairo_uchar* getGloss()=0;
};


/**
 * Interface to a single addkey value.
 *
 * An addkey value is one of the possible values for an addkey. Possible values are
 * values that actually occur; no notice is taken of DTD or schemata declaration.
 *
 */
class CXairoIAddkeyValue
{
public:
/**
 * Returns the value as a string.
 *
 * @return Value
 */	
	virtual const xairo_uchar* getValue()=0;
/**
 * Returns the number of words whose value is this addkey value.
 *
 * @return Frequency
 */	
	virtual int getFrequency()=0;
};


/**
 * Interface to an attribute value list.
 *
 * An attribute value list is the list of all values that a specified attribute takes
 * in a corpus. 
 *
 * Note that this is not a CXairoIGrammar subclass. The resource is created for the caller
 * and so the caller takes responsibility for its deletion. An attribute value list
 * embeds a CXairoIGrammar::Codebook if one is available.
 */
class CXairoIAttributeValueList
{
public:
/**
 * Returns the number of values in the list.
 *
 * @return Number of attributes.
 */	
	virtual int getCount()=0;
/**
 * Returns a CXairoIAttributeValue from the list.
 *
 * @param i Index
 * @return Pointer to CXairoIAttributeValue
 */	
	virtual CXairoIAttributeValue* getAttributeValue(int i)=0;

};

/**
 * Interface to an addkey value list.
 *
 * An addkey value list is the list of all values that a specified attribute takes
 * in a corpus. 
 *
 * Note that this is not a CXairoIGrammar subclass. The resource is created for the caller
 * and so the caller takes responsibility for its deletion. 
 */
class CXairoIAddkeyValueList
{
public:
/**
 * Returns the number of values in the list.
 *
 * @return Number of attributes.
 */	
	virtual int getCount()=0;
/**
 * Returns a CXairoIAttributeValue from the list.
 *
 * @param i Index
 * @return Pointer to CXairoIAttributeValue
 */	
	virtual CXairoIAddkeyValue* getAddkeyValue(int i)=0;

};



class CXairoIHit;
class CXairoICollocate;

/**
 * Interface to a collocation table.
 *
 * See CXairoISolution::makeCollocationTable.
 */
class CXairoICollocationTable
{
public:
/**
 * @enum cmeth
 * Enumeration of scoring algorithms used in CXairoISolution::makeCollocationTable.
 * A score is computed from the following variables:
 *	- @a h, the hit count of the collocate
 *	- @a f, the frequency of the collocate
 *	- @a m, the total number of words in the collocation window
 *	- @a n, the total number of words in the corpus
 *
 * See Statistics for Corpus Linguistics, Oakes, Edinburgh (1998) especially Chapter 4.
 */
/**
 * @var CM_Z
 * Z-score
 *
 * @a (h-f*m/n)/sqrt(m*(f/n)*(1-f/n))
 * 
 */
/**
 * @var CM_MI
 * MI-score (MI stands for Mutual Information)
 *
 * @a (log(h)-log(f*m/n))/log(2)
 *
 */
	enum cmeth {CM_Z,CM_MI,CM_MAX};
/**
 * struct that defines a collocation window. Convenience constructors are supplied.
 * The window specifies a span on either side of a hit that is its collocation 
 * window. A window may be specified as:
 *	- a number of words on each side
 *	- an XML element
 *
 * However it is specified, words within the hit are @em never in the window.
 */
	struct _cwin {
/**
 * @c true if the window is an XML element, @c false if it is a word count.
 */
		bool bX;
/**
 * Left window - specify an integer. Ignored if @a bX is @c true.
 */
		int wl;
/**
 * Right window - specify an integer. Ignored if @a bX is @c true.
 */
		int wr;
/** 
 * XML tag that defines window. The window will start at the start tag before the 
 * start of the hit and end at the first end tag after that start tag. If there is no
 * such start tag or if the start of the hit occurs after the end of the window then
 * the window is empty. Ignored if @a bX is @c false.
 */
		const xairo_uchar* s;
/** 
 * XML namespace qualifying @a s. Ignored if @a bX is @c false.
 */
		const xairo_uchar* ns;
		_cwin() {}
/** 
* Constructor for number of words window.
*/
		_cwin(int l,int r):wl(l),wr(r),bX(false) {}
/** 
* Constructor for XML window.
*/
		_cwin(const xairo_uchar* sc,const xairo_uchar* scn):s(sc),ns(scn),bX(true) {}
	};

/**
 * Returns the number of collocates in the table.
 *
 * @return Number of collocates.
 */	
	virtual int getCount()=0;
/**
 * Returns the CXairoICollocate with index @a i in the table.
 *
 * @param i Index
 * @return Pointer to CXairoICollocate
 */	
	virtual CXairoICollocate* getCollocate(int i)=0;
};


#define XAIRO_MIN_ELLIPSIS 100

/**
 * Interface to the solution to a xql query.
 *
 * A solution is a collection of hits. The prime use of CXairoISolution objects is for
 * the extraction of individual hits, but collocation and analysis functions make
 * possible statistical analysis of solutions.
 */
class CXairoISolution
{
public:
/**
 * Returns the number of hits in the solution.
 *
 * @return Number of hits.
 */	
	virtual int getCount()=0;
/**
 * Returns the number of corpus texts that contain hits in the solution. This is a convenience
 * function but is substantially faster than counting the document labels of the hits
 * because extracting individual hits requires reading of texts.
 *
 * @return Number of texts.
 */	
	virtual int getCorpusTextCount()=0;
/**
 * Returns a pointer to the CXairoIHit with index @a i. The specified number of scopes are returned 
 * as well. To be precise:
 * - the start of the hit occurs at the (s+1) th scope start tag before the start of the hit or at the start of the text entity if later
 * - the end of the hit occurs at the (s+1) th scope end tag after the end of the hit or at the end of the text entity if earlier.
 *
 * @param i Index of hit
 * @return Hit.
 */	
	virtual CXairoIHit* getHit(int i)=0;
/**
 * Returns a solution with only the first @a n hits of this solution.
 *
 * @param n Number of hits in required solution.
 * @return Thinned solution.
 */	
	virtual CXairoISolution* thinInit(int n)=0;
/**
 * Returns a solution with @a n randonly selected hits from this solution. The second
 * argument is the seed to be used for generating random numbers; this is passed to the 
 * C library @a srand function. Set @a s to 1 for the default behaviour.
 *
 * @param n Number of hits in required solution.
 * @param s Seed for random number generation.
 * @return Thinned solution.
 */	
	virtual CXairoISolution* thinRand(int n,int s)=0;
/**
 * Returns a solution with only the first hit for each corpus text that has hits
 * in the solution.
 *
 * @return Thinned solution.
 */	
	virtual CXairoISolution* thinOnePerText()=0;
/**
 * Returns a solution with specified hits from the solution. The caller must pass an
 * @c int[] array containing the indexes of the required hits. The array remains the
 * property of the caller.
 *
 * 
 * @param n The number of elements in the array s
 * @param s Array of indexes
 * @return Thinned solution.
 */	
	virtual CXairoISolution* thinSelection(int n,int *s)=0;
/**
 * Returns a solution with only the hits that match specified collocates. More precisely,
 * the caller supplies an array of words; usually these will have been selected from a 
 * collocation table and the key and w parameters will be those supplied when the table
 * was built. A hit in the solution is included in the returned
 * solution if and only if one of the collocates specified occurs in the collocation window 
 * of that hit.
 *
 * @param key Name of addkey used to find headword or empty to use word as headword.
 * @param w Collocation window
 * @param n Size of array s
 * @param s Array of words
 * @return Thinned solution.
 */	
	virtual CXairoISolution* thinCollocation(const xairo_uchar* key,CXairoICollocationTable::_cwin w,int n,const xairo_uchar** s)=0;
/**
 * Returns a collocation table for a specifed solution. solution with only the hits that match specified collocates. 
 * A collocation table is made as follows.
 *	- each hit of the solution is examined in turn.
 *	- the collocation window (see CXairoICollocationTable::_cwin) is constructed
 *	- for each word in the collocation window in turn
 *		- the word is mapped to its headword in addkey @a key
 *		- if the headword does not match @a pattern it is ignored
 *		- the hit count for that headword is incremented
 *	- headwords whose hit count is smaller than @a lowf are discarded
 *	- headwords whose score is less than @a mins are discarded
 *	- headwords whose score is greater than @a maxs are discarded
 *	- the headwords are sorted by score
 *	- all but the first @a maxn headwords are discarded
 * 
 * Normally @a key will be empty (denoting the null lemma scheme) or will name a lemma
 * scheme. If @a key names an addkey that is not a lemma scheme then the term 
 * @em colligation rather then @em collocation is used.
 *
 * Note that there is no mechanism for provision of a partition for a collocation.
 * If the solution was restricted to a division of a partition then the collocation
 * table will be restricted in the same way.
 *
 * @param pattern Regular expression that headwords must match. Use @c ".*" as default, do not leave blank.
 * @param key Name of addkey used to find headword or empty to use word as headword.
 * @param m Scoring algorithm
 * @param w Collocation window
 * @param maxn Maximum number of collocates in table. 
 * @param mins Minimum score
 * @param maxs Maximum score
 * @param lowf Frequency below which headwords are to be discarded
 * @return Pointer to CXairoICollocationTable object.
 */	
	virtual CXairoICollocationTable* makeCollocationTable(const xairo_uchar* pattern,const xairo_uchar* key,CXairoICollocationTable::cmeth m,CXairoICollocationTable::_cwin w,int maxn,double mins,double maxs,int lowf)=0;
/**
 * Returns a solution with hits from the solution that occur in corpus text filter.
 *
 * @param f CXairoICorpusTextFilter object
 * @return Thinned solution
 */
	virtual CXairoISolution* thinCorpusTextFilter(const CXairoICorpusTextFilter* f)=0;
/**
 * Returns a solution with hits from the solution that occur in addkey filter.
 *
 * @param f CXairoIAddkeyFilter object
 * @return Thinned solution
 */
	virtual CXairoISolution* thinAddkeyFilter(const CXairoIAddkeyFilter* f)=0;
	virtual const xairo_uchar* serialize()=0;
/**
 * Fills an array with the number of hits in each division of a user-defined partition, that
 * is, an array of integers, one for each text, showing which division of the partition
 * the text is in. The caller must
 * supply the output array and pass in its size, which should be the number of divisions of the
 * partition. The nth element of the array will be set to the number of hits for the
 * solution that occur in corpus texts in the nth division of the partition.
 *
 * @param np size of p, must be equal to the number of corpus texts
 * @param p array representing partition
 * @param n Size of arrays a and b
 * @param a @c int array to receive hit counts
 * @param b @c int array to receive text counts
 */	
	virtual void getAnalysis(int np,int* p,int n,int* a,int* b)=0;
/**
 * Fills an array with the size of hits in each division of a user-defined partition, that
 * is, an array of integers, one for each text, showing which division of the partition
 * the text is in. The caller must
 * supply the output array and pass in its size, which should be the number of divisions of the
 * partition. The nth element of the array will be set to the size of hits for the
 * solution that occur in corpus texts in the nth division of the partition. The size of a hit
 * is determined by finding the smallest occurrence of e that contains the
 * hit and counting the number of words in it. If there is no such element
 * ten no words are counted for that hit.
 *
 * @param np size of p, must be equal to the number of corpus texts
 * @param p array representing partition
 * @param n Size of arrays a and b
 * @param a @c int array to receive hit counts
 * @param b @c int array to receive text counts
 * @param e element determining extent to be measured
 */	
	virtual void getAnalysisScope(int np,int* p,int n,int* a,int* b,const xairo_uchar* e)=0;
	virtual CXairoISolution* copy()=0;
	virtual ~CXairoISolution(){}
};

/**
* @page hitformat The format of hits
* An arbitrary sequence of characters drawn from a corpus text will not in general constitute
* well-formed XML. The CXairoISolution::getHit interface never extracts a completely arbitrary sequence
* because a selection will never start or end in the middle of a content item nor in the middle of
* an XML tag. However, there is no guarantee that a selection will contain the right balance of 
* markup to make it well formed. For example if a corpus text contains the text:
* 
* \verbatim <u sp="Mar"><s>Holla!</s><s>Bernardo!</s></u><u sp="Ber"><s>Say.</s><s>What, is Horatio there?</s></u>\endverbatim
*
* then a search for the element <CODE>u</CODE> with <CODE>spkr</CODE> attribute <CODE>Ber</CODE> will return <I>inter alia</I> the selection 
*
* \verbatim <s>Bernardo!</s></u><u sp="Ber"><s>Say.</s>\endverbatim
* 
* which is not well-formed XML.
*
* The Xairo hit markup is designed to address this problem. It also addresses three related problems:
* <UL>
* <LI>how to represent character entities in the hit, assuming that we do <I>not</I> want to
* prepend the DTD to each hit;</LI>
* <LI>how to restrict the amount of text returned for very large hits;</LI>
* <LI>how to identify the part of the returned text that is the hit.</LI>
* </UL>
*
* Terminology: The location that satisfies the query is called the <I>hit</I>. The extracted text
* that is returned by CXairoISolution::getHit containing the hit is called the <I>selection</I>.
*
* \section ex An example
* 
* The selection returned for the above query would be
*
* \verbatim<hns:hit xmlns:hns="http://xaira.org/ns/hit/1.0">
<u hns:added="start"><s>Bernardo!</s></u>
<hns:hit_start/>
<u sp="Ber" hns:added="end">
<hns:hit-end/>
<s>Say.</s></u>
</hns:hit>\endverbatim 
*
* As well as wrapping the selection in hit tags we have added markup to balance the missing u tags
* and mark the start and end of the hit.
*
* All hit markup is in the Xaira hit namespace http://xaira.org/ns/hit/1.0. Programmers should try to
* avoid reference to the <CODE>hns</CODE> prefix and check instead for the namespace.
*
* \section ref Tag reference
*
* \subsection hit hit tag
*
* This is the wrapper tag: it has no attributes. If a language other than the default is in use at the 
* start of the selection then this tag may have an <CODE>xml:lang</CODE> attribute.
*
* \subsection hit-start hit-start tag
*
* This marks the start of the hit proper. Although it may seem at first sight that the hit
* start and end tags ought to be paired, if this were the case any markup within the hit would
* have to be balanced. Empty tags can be placed anywhere.
*
* Programming note: In practice it is safe to search for <CODE><hns:hit_start/></CODE>
* in the returned text but it is better style to parse the hit and look for a node with name
* <CODE>hit_start</CODE> and the right namespace.
*
* \subsection hit-end hit-end tag
*
* This marks the end of the hit proper. See remarks about <CODE>hit-start</CODE> above.
*
* \subsection omitted-characters omitted-characters tag
*
* \verbatim <hns:omitted-characters n="100"/> \endverbatim
*
* This represents a span of n characters omitted to reduce the size of the hit to within
* the limit specified by CXairoISolution::getHit.
*
* \subsection entity entity tag
* 
* \verbatim <hns:entity original-name="mdash">&#x2014;</hns:entity> \endverbatim
*
* Any named character entity that is not predefined is replaced by a numeric character
* entity and its original name is given in the <CODE>original-name</CODE> attribute.
* This makes the XML returned by CXairoISolution::getHit standalone.
*
* A character entity whose replacement value cannot be found (this would imply that
* the corpus text was not valid XML) is denoted by the character <CODE>?</CODE>.
*
* In attribute values character entities are replaced as described but the <CODE><hns:entity></CODE>
* markup is not added.
*
* \subsection added added attribute
*
* This attribute is added to a tag to show that it was supplied by tag balancing rather
* than found in the text. Unfortunately it is impossible to add an attribute to an end tag
* so when an end tag is added in this way the attribute is added to the corresponding start tag.
* The value of the attribute (<CODE>start</CODE> or <CODE>end</CODE>) shows which tag is
* added (it is easy to see that they will never both be added).
*/

/**
 * An object representing an exception in Xaira execution.
 */ 
class CXairoIError
{
public:
	enum code {ERR_UNKNOWN,ERR_INT,ERR_CQL,ERR_XMLRPC,ERR_MEMORY,ERR_NOKEY,
		ERR_FILTER,ERR_REGEXP,ERR_NULLKEY,ERR_GRAMMARID,ERR_NOTEXT,
		ERR_ENCODING,ERR_COMMS,ERR_LIMIT};
	enum sev {SEV_WARN,SEV_ERROR,SEV_FATAL};
/**
 * Returns the message associated with the error. 
 * NB: We ought to add a list of error throws for each call.
 *
 * @return Text message.
 */
	virtual const xairo_uchar* getMessage()=0;
	virtual code getCode()=0;
	virtual sev getSeverity()=0;
};


class CXairoITextEntity;
class CXairoICorpusText;

/**
 * A single hit that satisfies a CQL query.
 *
 * A solution is a set of hits and a CXairoISolution object is obtained by calling
 * CXairoInterface::solve, or by thinning an existing solution. Individual hits may
 * then be obtained by CXairoISolution::getHit. 
 *
 * The programmer should note that the operation of extracting a hit is quite costly,
 * certainly much more costly than obtaining the location and size of the hit. The text 
 * must be opened and, unless it is in UCS-2, already transcoded. The hit is extracted
 * when CXairoISolution::getHit is first called, and not when CXairoIHit::getText is called.
 * It is then cached on the server until the solution is freed.
 */ 
class CXairoIHit 
{
public:
/**
 * Returns the text of a query. 
 *
 * The specified number of scopes are returned 
 * as well. To be precise:
 * - the start of the hit occurs at the (s+1) th scope start tag before the start of the hit or at the start of the text entity if later
 * - the end of the hit occurs at the (s+1) th scope end tag after the end of the hit or at the end of the text entity if earlier.
 *
 * Extra markup (\ref hitformat "details")
 * is added to ensure that the returned text is well-formed XML.
 *
 * @param s Number of scopes
 * @param max Maximum length
 * @return Text string.
 */
	virtual const xairo_uchar* getText(int s,int max)=0;
/**
 * Returns the corpus text of this hit. This is determined by the unit labelling rules
 * in the corpus header. To get the document label use CXairoICorpusText::getTitle.
 *
 * @return Corpus text.
 */
	virtual CXairoICorpusText* getCorpusText()=0;
/**
 * Returns the unit label of this hit. This is determined by the unit labelling rules
 * in the corpus header.
 *
 * @return Unit label.
 */
	virtual  const xairo_uchar* getUnit()=0;
/**
 * Returns the CXairoITextEntity that contains the hit. This allows a transfer from display
 * of hits to browsing in an HTTP browser.
 *
 * @return Pointer to text entity.
 */
	virtual CXairoITextEntity* getTextEntity()=0;
/**
 * Obtain a cursor for the start of the hit. A cursor can be used with CXairoInterface::getUsage	
 * to inspect the full dictionary entry for a usage; this is useful for applications 
 * that use Xaira for statistical analysis beyond the simple features provided
 * by this interface.
 */
	virtual unsigned int getCursorStart()=0;
/**
 * Obtain a cursor for the end of the hit. A cursor can be used with CXairoInterface::getUsage	
 * to inspect the full dictionary entry for a usage; this is useful for applications 
 * that use Xaira for statistical analysis beyond the simple features provided
 * by this interface.
 */
	virtual unsigned int getCursorEnd()=0;
	virtual ~CXairoIHit() {}
};


/**
 * Interface to a single text entity.
 *
 * A text entity is an XML entity containing a corpus text, a number of corpus texts or a 
 * part of a corpus text. Generally text entities are manipulated directly by the server,
 * but this interface is exposed to allow applications to browse text entities. 
 */
class CXairoITextEntity
{
public:
/**
 * Returns a URL that may be used to browse this text entity. A local server 
 * will return a url of type file: but a remote one will typically use an http: type.
 * The Xairo server does not contain an HTTP server; the system manager must make sure
 * that a suitable server is available at the advertsied URL. There is no requirement
 * that this should resolve to the same machine that runs the Xairo server.
 *
 * @return URL for text. An empty string means that the text is not available.
 */
	virtual const xairo_uchar* getURL()=0;
};


class CXairoICorpusText;

/**
 * Interface for the corpus text list.
 *
 * An object of this class denotes the list of texts in the corpus. Its only use is for
 * the extraction of individual CXairoICorpusText objects. Note that although this list
 * is a constant for a given corpus the class follows the normal Xairo memory conventions,
 * so that the caller is responsible for deletion of the object. 
 */
class CXairoICorpusTextList
{
public:
/**
 * Return the number of corpus texts in the list.
 *
 * @return Number of texts
 */
	virtual int getCount()=0;
/**
 * Return an individual corpus text. Note that text 0 will be the header and 1 the 
 * bibliography.
 *
 * @param i Index of required text
 * @return Pointer to the corpus text selected.
 */
	virtual CXairoICorpusText* getCorpusText(int i)=0;
/**
 * Return a corpus text filter object. A filter is simply a sequence of values, either
 * 0 or 1, so that the ith text in the corpus text list is selected by the filter
 * if the ith member of the sequence is 1. It follows that if there are fewer members
 * than texts then the extra texts are excluded; if there are more then the
 * extra 0/1 values are ignored.
 *
 * Note that this API replaces the older one where the array was passed direct
 * to the thinner to reduce bandwidth when the same list is used several times;
 * this is of no concern on a local connection but avoids a lot of
 * processing when xml-rpc is used.
 *
 * @param n Size of sequence.
 * @param t Array of 0 or 1 values with n members.
 * @return Pointer to the filter created.
 */
	virtual CXairoICorpusTextFilter* getCorpusTextFilter(int n,int* t)=0;
/**
 * Return a corpus text filter object. This version returns a filter that
 * includes every text in a given division of a partition.
 *
 * @param p The partitionSize of sequence.
 * @param n The number of the division to be used.
 * @return Pointer to the filter created.
 */
	virtual CXairoICorpusTextFilter* getCorpusTextFilter(CXairoIGrammar::Partition* p,int n)=0;
};

/**
 * Interface for a corpus text filter.
 *
 * A corpus text filter is a list of corpus texts. Its primary use is to thin
 * solutions where solutions in certain corpus texts are not required. This operation 
 * is performed by CXairoISolution::thinCorpusTextFilter. To make a corpus text filter
 * pass a vector of ones and zeroes (one for required) to CXairoICorpusTextList::getCorpusTextFilter.
 */
class CXairoICorpusTextFilter
{
public:
	virtual const xairo_uchar* serialize()=0;
};


/**
 * Interface for a single collocate.
 *
 * A collocate of a CXairoISolution is a headword in a given additional key with a measured
 * score for the frequency with which it occurs near to the hits of the solution. To get
 * collocates, it is necessary to build a CXairoICollocationTable for the CXairoISolution
 * object. 
 */
class CXairoICollocate
{
public:
/**
* Get the headword. This will be a headword in the dictionary for the additional key
* for which the collocation table was built (and so, if the additional key was not a 
* lemma scheme, it may be what is called a 'pos tag'): in this case the term colligation
* rather than collocation is used in the literature, but we always use the term collocation
* here.
*
* @return The word
*/
	virtual CXairoIWord* getWord()=0;
/**
* Get the hit count. This is the number of times that the collocate occurs in the 
* collocation window of the solution. The term hit count is misleading because this is not
* the same as the number of hits whose collocation window contains the collocate. Check this.
*
* @return The hit count
*/
	virtual int getHits()=0;
/**
* Get the score in the scoring system of the collocation of the collocate. See CXairoICollocationTable::cmeth for
* definitions of scoring systems.
*
* @return The score.
*/
	virtual double getScore()=0;
};


/**
 * Interface for the value of a Xairo xpath expression, usually a node set.
 */
class CXairoIXpathValue
{
public:
/**
 * Return the value of an Xpath expression coerced to a string. This is the string value
 * of the first node in the set.
 *
 * There are no facilities in the server for the manipulation of a node set other then
 * by coercion to another type. We should probably allow coercion to boolean too.
 *
 * @return The string value.
 */
		virtual const xairo_uchar* getText()=0;
};



/**
 * Interface for manipulating a single corpus text.
 *
 * A corpus text is a single document of a corpus. A text has a title which can be used to label
 * hits. The corpus text object supports the Xairo simplified xpath search operation. A special case of 
 * this is the extraction of bibliographic data from a text.
 *
 * There are two ways to get a corpus text object. The server call CXairoInterface::getCorpusTextList() gets a list of all corpus 
 * texts. Also from a hit the CXairoIHit::getCorpusText() method obtains the document that contains that hit.
 *
 * A corpus text is not necessarily a file. To get file system information use the text entity object.
 * Using xinclude, a corpus text may reside in several text entities: or several corpus texts may
 * occur in one entity.
 *
 * @see CXairoICorpusTextList
 */
class CXairoICorpusText
{
public:
/**
* Get the title of the text. The title is assigned by the indexer based on the labelling
* rules in force.
*
* @return title of text
*/
	virtual const xairo_uchar* getTitle()=0;
/**
* Evaluate an xpath expression. The context is the root node of the document. The result
* will be of type CXairoIXpathValue * and will typically be a nodeset. There is, however,
* no mechanism for manipulating it as a nodeset other than to coerce it to a string.
*
* There is not space here to give the rules for xpath expressions. The exact details of
* the xpath features available is in Xairo TN1. Not many of the standard functions are
* implemented but one additional function is available: its name is cql, it takes a single
* argument which it treats as a string, and it expects the string to evaluate to a cql
* query including the start and end tag. It is designed for use as a node test and succeeds
* when the node in question contains a solution to the query. The syntax of the Xaira
* query language is given in Xairo TN2.
*
* @param path The xpath expression.
* @return The expression value. This call returns NULL only when there is an error in
* the expression. If the nodeset defined is empty then the result will be a representation
* of the empty node set. A node set may be tested for emptiness by coercing it to boolean.
*/
	virtual CXairoIXpathValue* evalXpath(const xairo_uchar* path)=0;

/**
* Find which division of a partition the text belongs to. If the text is a member of
* a division of @a part then that division is returned. Otherwise NULL is returned.
*
* Note that this is subject to revision. At the moment the code only works with a 
* partition all of whose children are leaves. To extend to nested partitions it would
* be necessary to determine what should happen if the text is a member of two (non-leaf) 
* divisions of the same partition, as happens in BNC, for example.
*
* @param part The partition.
* @return The index of the division to which the text belongs, or -1 if it does not belong to any
* division.
*/
	virtual int classify(const CXairoIGrammar::Partition* part)=0;
/**
* Return a count of the number of words in the texts of this partition.
*
* @return The number of words.
*/
	virtual int getWordCount()=0;
/**
* Test whether this text is selected in the filter.
*
* @param f Pointer to CXairoICorpusTextFilter object. 
* @return true if selected.
*/
	virtual bool isSelected(CXairoICorpusTextFilter* f)=0;/**
/**
* Get the text entity in which this document is contained. 
* This will always be a top-level text entity even if the 
* top lelvel entity is a simple driver file and the document is
* wholly contained in one of the included entitities. This guarantees
* that the returned entity is a valis xml text entity.
*
* @return Containing CXairoITextEntity.
*/
	virtual CXairoITextEntity* getTextEntity()=0;
/*
* Gets the position of this text in the corpus. 
*
^ @return Integer position.
*/
	virtual int getIndex()=0;
};

/**
 * Interface for manipulating an addkey filter.
 *
 * An addkey filter is a collection of values for a specified addkey.
 * It may be used to restrict forms found by CXairoIWord::getForm to
 * those with one of a set of addkey values, and also to restrict solutions
 * of queries in the same way.
 *
 * An addkey filter is created by supplying the addkey and a list
 * of values to CXairoInterface::getXairoAddkeyFilter; it is used
 * as an argument to CXairoIWord::getFilteredFrequency and to 
 * CXairoISolution::thinAddkeyFilter.
 */
class CXairoIAddkeyFilter
{
public:
};


// callbacks

// the next is not part of the Xairo interface

class CXairoIBootMonitor
{
public:
	virtual void Log(const xairo_uchar*)=0;
};

class CXairoIInterruptHandler
{
public:
	virtual bool testInterrupt()=0;
};

// end of interface definition

#if 0
// Is this ever used?


class CXairoGrammar : public CXairoIGrammar
{
public:

	XAIRO_API int getNamespaceCount();
	
	class Namespace : public CXairoIGrammar::Namespace
	{
	public: 
		XAIRO_API const xairo_uchar* getUrl();
	};
	XAIRO_API Namespace* getNamespace(int);

	XAIRO_API int getAddkeyCount();

	class Addkey : public CXairoIGrammar::Addkey
	{
	public:
		XAIRO_API const xairo_uchar* getName();
		XAIRO_API const xairo_uchar* getGloss();
		XAIRO_API bool isLemmaScheme();
	};
	XAIRO_API Addkey* getAddkey(int i);

	class Codebook : public CXairoIGrammar::Codebook
	{
	public:
		XAIRO_API const xairo_uchar* lookup(const xairo_uchar*);

	};

	class Attribute : public CXairoIGrammar::Attribute
	{
	public:
		XAIRO_API const xairo_uchar* getName();
		XAIRO_API const xairo_uchar* getGloss();
		XAIRO_API Namespace* getNamespace();
		XAIRO_API Codebook* getCodebook();
		XAIRO_API const xairo_uchar* getElt();

	};

	XAIRO_API int getElementCount();

	class Element : public CXairoIGrammar::Element
	{
	public:
		XAIRO_API const xairo_uchar* getName();
		XAIRO_API const xairo_uchar* getGloss();
		XAIRO_API int getAttributeCount();
		XAIRO_API Attribute* getAttribute(int);
		XAIRO_API Namespace* getNamespace();

	};

	XAIRO_API Element* getElement(int);

	XAIRO_API int getGlobalAttributeCount();
	XAIRO_API Attribute* getGlobalAttribute(int);

	class Partition : public CXairoIGrammar::Partition
	{
	public:
		XAIRO_API const xairo_uchar* getName();
		XAIRO_API const xairo_uchar* getDescription();
		XAIRO_API int getCount();
		XAIRO_API Partition* getDivision(int);
		XAIRO_API bool hasClasses();
		XAIRO_API int getWordCount();
	};
	XAIRO_API Partition* getRootPartition();

};
class CXairoServer : public CXairoInterface
{
public:
	XAIRO_API class CXairoIWordList* getWordList(const xairo_uchar*,const xairo_uchar*);
	XAIRO_API bool Init(const char*,CXairoIBootMonitor*);
	XAIRO_API static CXairoServer* getServer();
	XAIRO_API class CXairoIWordList* getFrequencyList(const xairo_uchar*,int,int,int,const xairo_uchar*);
	XAIRO_API class CXairoIAttributeValueList* getAttributeValueList(CXairoIGrammar::Attribute*);
	XAIRO_API class CXairoISolution* solve(const xairo_uchar*);
	XAIRO_API class CXairoISolution* solveInDivision(const xairo_uchar*,CXairoIGrammar::Partition*);
	/**
	* Get the list of all corpus texts of type CXairoICorpusTextList. 
	*
	* @return A pointer to a copy of the corpus text list object. 
	*/
	XAIRO_API class CXairoICorpusTextList* getCorpusTextList();
	XAIRO_API CXairoIGrammar* getGrammar();
	XAIRO_API int getWordCount();

};

class CXairoWord: public CXairoIWord
{
public:
	XAIRO_API const xairo_uchar* getNorm();
	XAIRO_API int getFrequency();
	XAIRO_API int getFrequencyInDivision(CXairoIGrammar::Partition* part);
	XAIRO_API int getFormCount();
	XAIRO_API CXairoIForm* getForm(int i);
};

class CXairoForm : public CXairoIForm
{
public:
	XAIRO_API int getFrequency();
	XAIRO_API int getFrequencyInDivision(CXairoIGrammar::Partition* part);
	XAIRO_API const xairo_uchar* getAdditionalKey(const xairo_uchar* key);
	XAIRO_API const xairo_uchar* getNorm();
};

class CXairoAttributeValue : public CXairoIAttributeValue
{
public:
	XAIRO_API const xairo_uchar* getValue();
	XAIRO_API int getFrequency();
	XAIRO_API const xairo_uchar* getGloss();
};

class CXairoWordList: public CXairoIWordList
{
public:
	XAIRO_API int getCount();
	XAIRO_API CXairoIWord* getWord(int);
};

class CXairoAttributeValueList: public CXairoIAttributeValueList
{
public:
	XAIRO_API int getCount();
	XAIRO_API CXairoIAttributeValue* getAttributeValue(int i);
};

class CXairoCollocationTable:public CXairoICollocationTable
{
public:
	XAIRO_API int getCount();
	XAIRO_API CXairoICollocate* getCollocate(int i);
};

class CXairoSolution : public CXairoISolution
{
public:
	XAIRO_API int getCount();
	XAIRO_API int getCorpusTextCount();
	XAIRO_API CXairoIHit* getHit(int i,int s);
	XAIRO_API CXairoISolution* thinInit(int n);
	XAIRO_API CXairoISolution* thinRand(int n,int s);
	XAIRO_API CXairoISolution* thinOnePerText();
	XAIRO_API CXairoISolution* thinSelection(int n,int *s);
	XAIRO_API CXairoISolution* thinCollocation(const xairo_uchar* key,CXairoICollocationTable::_cwin w,int n,const xairo_uchar** s);
	XAIRO_API CXairoICollocationTable* makeCollocationTable(const xairo_uchar* pattern,const xairo_uchar* key,CXairoCollocationTable::cmeth m,CXairoCollocationTable::_cwin w,int maxn,double mins,double maxs,int lowf);
	XAIRO_API void getAnalysis(CXairoIGrammar::Partition* p,int n,int* a);

};
class CXairoError: public CXairoIError
{
public:
	XAIRO_API const xairo_uchar* getMessage();
};

class CXairoCorpusText : public CXairoICorpusText
{
public:
	XAIRO_API const xairo_uchar* getTitle();
	XAIRO_API CXairoIXpathValue* evalXpath(const xairo_uchar* path);
	XAIRO_API CXairoIGrammar::Partition* classify(CXairoIGrammar::Partition* part);
	XAIRO_API int getWordCount();
};



class CXairoHit : public CXairoIHit
{
public:
	XAIRO_API const xairo_uchar* getText();
	XAIRO_API CXairoICorpusText* getCorpusText();
	XAIRO_API const xairo_uchar* getUnit();
	XAIRO_API int getOffset();
	XAIRO_API int getLength();
	XAIRO_API CXairoITextEntity* getTextEntity();
};

class CXairoCorpusTextList : public CXairoICorpusTextList
{
public:
	XAIRO_API int getCount();
	XAIRO_API CXairoICorpusText* getCorpusText(int i);
};
class CXairoCollocate:public CXairoICollocate
{
public:
	XAIRO_API const xairo_uchar* getWord();
	XAIRO_API int getHits();
	XAIRO_API int getFreq();
	XAIRO_API double getScore();
};

class CXairoXpathValue : public CXairoIXpathValue
{
public:
		XAIRO_API const xairo_uchar* getText();
};


class CXairoTextEntity
{
public:
	XAIRO_API const xairo_uchar* getURL();
};

#endif

#ifndef _WIN32
#define XAIRO_API
#else
#ifdef XAIRO_SERVER_API
#define XAIRO_API __declspec(dllexport)
#else
#define XAIRO_API __declspec(dllimport)
#endif
#endif

// The stub server mechanism is exposed solely for export to the proxy library

class CXairoIStubServer
{
public:
	virtual char* Transport(const char*)=0;
};

struct CXairoIParameters {
	const char* parameter_file;
	CXairoIBootMonitor* bm;
	CXairoIInterruptHandler* inth;
	const char* temppath;
	const char* datapath;
};

class CXairoImplementation {
public:
	XAIRO_API static CXairoInterface* getServer(const CXairoIParameters*);
	XAIRO_API static CXairoIStubServer* getStubServer();
	XAIRO_API static CXairoIStubServer* getStubServer(CXairoInterface*);
	XAIRO_API static unsigned getAPIVersion() {return XAIRO_API_VERSION;}
};


#ifndef _WIN32
#define XAIRO_PROXY_API
#else
#ifdef XAIRA_PROXY_DLL
#define XAIRO_PROXY_API __declspec(dllexport)
#else
#define XAIRO_PROXY_API __declspec(dllimport)
#endif
#endif

class CXairoTransport
{
public:
	virtual void Start()=0;
	virtual void End()=0;
	virtual char* DoTransport(const char*)=0;
	virtual void Interrupt()=0;
	virtual void Message(const char*) {}
};


class CXairoProxyImplementation {
public:
	XAIRO_PROXY_API static XAIRO_NAMESPACE::CXairoInterface* getLocalServer(XAIRO_NAMESPACE::CXairoInterface*);
	XAIRO_PROXY_API static XAIRO_NAMESPACE::CXairoInterface* getRemoteServer(const char*,int,XAIRO_NAMESPACE::CXairoIBootMonitor*);
	XAIRO_PROXY_API static XAIRO_NAMESPACE::CXairoInterface* getCustomServer(XAIRO_NAMESPACE::CXairoTransport*,XAIRO_NAMESPACE::CXairoIBootMonitor*);
	XAIRO_PROXY_API static unsigned getAPIVersion() {return XAIRO_API_VERSION;}
};

} // end of Xairo namespace

/**
* \page prog Programming considerations
*
* \section unicode Wide characters
*
* There are substantial difficulties associated with writing portable C++ programs using 
* Unicode characters. Originally it was intended that Unicode should be a 16-bit character
* set so that the appropriate unit for a character on 32 bit hardware would be a short
* unsigned. However, the introduction by the Unicode consortium of surrogate pairs, allowing
* Unicode characters to occupy 17 times the original 16-bit space, makes it desirable in some
* circumstances to have a 32-bit Unicode character. Unfortunately instead of providing 
* two types for 16 and 32 bit Unicode different compilers assign different basic types to
* the wide character type <CODE>wchar_t</CODE>. On many platforms the GNU compilers make this
* a 32 bit <CODE>unsigned</CODE> though the majority of implementations make it <CODE>short
* unsigned</CODE>. 
*
* The Xairo interface uses a typedef called <CODE>xairo_ucode</CODE> as a synonym for 
* <CODE>unsigned short</CODE>. If you are developing for a platform such as Windows where
* <CODE>wchar_t</CODE> is a 16-bit type the simplest way to use Xaira is to use the built-in
* support for wide characters. Functions such as <CODE>wcslen</CODE> in the C library provide
* the same functionality as <CODE>strlen</CODE> for wide characters; and long strings of the form
* <CODE>L"foo"</CODE> may be used when a literal wide string is required.
*
* If on the other hand you are concerned to produce a portable solution we advise you to use
* the freely available ICU libraries. If you have built Xaira on a Unix platform you will 
* already have these available. In ICU the type <CODE>UnicodeString</CODE> denotes a Unicode 
* string and although there are functions that address it as string of 32-bit characters
* it may easily be treated as 16-bit by use of the <CODE>getTerminatedBuffer</CODE> member.
* This may be used wherever a Xairo function requires a <CODE>const xairo_uchar*</CODE> parameter,
* as in
* \verbatim	UnicodeString query("<cql><lemma>banbury</lemma></cql>");
	sol=corpus->solve(query.getTerminatedBuffer());\endverbatim
* We have two reservations about this approach:
* <UL><LI>The ICU UnicodeString API has been developed with no requirement that it should 
* resemble the standard C library string functions and if you are used to the latter, or indeed
* to the C++ <CODE>&lt;string&gt;</CODE> functions, you will have to learn a new and often rather
* clumsy API.</LI>
* <LI>It is extraordinarily difficult to allocate a literal wide string in a portable way. 
* If the string happens to be ASCII you can sometimes use the 8-bit constructor to UnicodeString
* as in the example just given. The official ICU system for allocating wide strings is only
* endurable in the smallest examples.</LI></UL>
*
* \section hdr The Xairo header and the Xairo namespace
*
* \subsection resrc	Resource usage
*
* \section hdr Accessing a corpus
*
* \section ex A simple example
*
*/

