/**********************************************************************
 *
 * recptproto.h -- 
 * Copyright (C) 1999  The New Zealand Digital Library Project
 *
 * A component of the Greenstone digital library software
 * from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *********************************************************************/


#ifndef RECPTPROTO_H
#define RECPTPROTO_H

#include "gsdlconf.h"
#include "text_t.h"
#include "comtypes.h"

#if defined(GSDL_USE_OBJECTSPACE)
#  include <ospace\std\vector>
#elif defined(GSDL_USE_STL_H)
#  include <vector.h>
#else
#  include <vector>
#endif

#if defined(GSDL_USE_OBJECTSPACE)
#  include <ospace\std\iostream>
#elif defined(GSDL_USE_IOS_H)
#  include <iostream.h>
#else
#  include <iostream>
#endif


// recptproto is a generalisation of a protocol for communicating
// with a collection server.
class recptproto {
public:

  recptproto() {};
  virtual ~recptproto() {};

  // add collection server to protocol
  virtual void add_collection (const text_t &collection, void *recpt, 
			       const text_t &gsdlhome, const text_t& collecthome,
			       const text_t &dbhome);

  virtual void remove_collection (const text_t &collection, ostream &logout);

  // configure should be called for each line in the configuration file
  virtual void configure (const text_t &key, const text_tarray &cfgline, comerror_t &err);

  // init should be called after the configuration but before any other
  // functions are called. If init returns false a message will be written
  // out to the log file and no other output should be produced.
  virtual bool init (comerror_t &err, ostream &logout);

  // get_site_name should return the name of the site used.
  // This is trivially empty in the case of a null protocol.  If a remote
  // connection to a site is being used then this should return the name
  // used to label a site
  virtual text_t get_site_name(comerror_t &err);

  // get_protocol_name should return the name of this protocol (e.g. recptproto)
  // that can be used to do run time type identification and display information
  // about the protocol.
  virtual text_t get_protocol_name (comerror_t &err);

  // get_collection_list returns the list of collections that
  // this protocol knows about
  virtual void get_collection_list (text_tarray &collist, comerror_t &err, 
				    ostream &logout);

  // has_collection sets 'hascollection' to be true if the protocol
  // can communicate with the collection (i.e. it is within its 
  // collection list). This function should be implemented in as
  // efficient time as possible as it will be called for each page
  // access and for each protocol.
  virtual void has_collection (const text_t &collection, bool &hascollection, 
			       comerror_t &err, ostream &logout);

  // sets 'wassuccess' to be true if a successful ping was done to
  // the given collection.
  virtual void ping (const text_t &collection, bool &wassuccess, 
		     comerror_t &err, ostream &logout);

  // obtains general information about the collection
  virtual void get_collectinfo (const text_t &collection, 
				ColInfoResponse_t &collectinfo,
				comerror_t &err, ostream &logout);

  // gets a list of all the filters
  virtual void get_filterinfo (const text_t &collection,
			       InfoFiltersResponse_t &response,
			       comerror_t &err, ostream &logout);

  // gets all the filter options for a particular filter
  virtual void get_filteroptions (const text_t &collection,
				  const InfoFilterOptionsRequest_t &request,
				  InfoFilterOptionsResponse_t &response, 
				  comerror_t &err, ostream &logout);

  // returns the contents of a collection's rss-items.rdf file (generated by BasePlugout)
  virtual void get_rss_items (const text_t &collection,
			      const text_t &gsdlhome,
			      text_t &rss_items,
			      comerror_t &err,
			      ostream &logout);

  // filters (search or browse) a result set and returns information
  // about the filtered set including term frequency information and 
  // metadata
  virtual void filter (const text_t &collection,
		       FilterRequest_t &request,
		       FilterResponse_t &response,
		       comerror_t &err, ostream &logout);

  // gets a document (duh!)
  virtual void get_document (const text_t &collection,
			     const DocumentRequest_t &request,
			     DocumentResponse_t &response,
			     comerror_t &err, ostream &logout);

  virtual void is_searchable (const text_t &collection, bool &issearchable, 
			      comerror_t &err, ostream &logout);

};


// The recptprotoptr function does not 'own' the recptproto. The 
// recptproto should be deleted by the code which created it.
class recptprotoptr {
public:
  recptproto *p;

  recptprotoptr () {p=NULL;}
  ~recptprotoptr () {}
};

typedef vector<recptprotoptr> recptprotoptrlist;


// contains a list of recptprotos
class recptprotolistclass {
protected:
  recptprotoptrlist recptprotoptrs;

public:
  // type support for recptprotolistclass
  typedef recptprotoptrlist::iterator iterator;
  typedef recptprotoptrlist::const_iterator const_iterator;
  typedef recptprotoptrlist::reference reference;
  typedef recptprotoptrlist::const_reference const_reference;
  typedef recptprotoptrlist::size_type size_type;

  typedef recptprotoptrlist::difference_type difference_type;
  typedef recptprotoptrlist::const_reverse_iterator const_reverse_iterator;
  typedef recptprotoptrlist::reverse_iterator reverse_iterator;
  
  // basic container support
  iterator begin () {return recptprotoptrs.begin();}
  const_iterator begin () const {return recptprotoptrs.begin();}
  iterator end () {return recptprotoptrs.end();}
  const_iterator end () const {return recptprotoptrs.end();}

  void erase(iterator pos) {recptprotoptrs.erase(pos);}
  void erase(iterator first, iterator last) {recptprotoptrs.erase(first, last);}
  recptprotolistclass &operator=(const recptprotolistclass &x) 
    {recptprotoptrs=x.recptprotoptrs;return *this;}

  bool empty () const {return recptprotoptrs.empty();}
  size_type size() const {return recptprotoptrs.size();}


  // added functionality
  void clear () {recptprotoptrs.erase(recptprotoptrs.begin(),recptprotoptrs.end());}

  // therecptproto remains the property of the calling code but
  // should not be deleted until it is removed from this list.
  void addrecptproto (recptproto *therecptproto);

  // getrecptproto will return NULL if a recptproto for the given collection
  // could not be found
  recptproto *getrecptproto (const text_t &collection, ostream &logout);
};


#endif
