/**********************************************************************
 *
 * comtypes.cpp -- 
 * 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.
 *
 *********************************************************************/

#include "comtypes.h"


text_t get_comerror_string (comerror_t err) {
  if (err == noError) return "no error";
  else if (err == authenticationFailure) return "authentication failure";
  else if (err == protocolError) return "protocol error";
  else if (err == configurationError) return "configuration error";
  else if (err == systemProblem) return "system problem";
  else if (err == syntaxError) return "query syntax error";
  return "unknown problem";
}


void ShortColInfo_t::clear() {
  name.clear();
  host.clear();
  port = 0;
}

/*
   isPublic now defaults to true  most values are default          
   similar to a constructor in a class to make some initializations
*/

void ColInfoResponse_t::clear () {
  shortInfo.clear();
  useBook=false;
  isPublic=true;
  isBeta=false;
  isSegmented=false;
  isCollectGroup=false;
  languages.erase(languages.begin(), languages.end());
  ccsCols.erase(ccsCols.begin(), ccsCols.end());
  ccsOptions = 0;
  stemIndexes = 3; // old default was both provided
  buildDate=0;
  buildType.clear();
  earliestDatestamp.clear();
  numDocs=0;
  numSections=0;
  numWords=0;
  numBytes=0;
  format.erase(format.begin(), format.end());
  building.erase(building.begin(), building.end());
  httpdomain.clear();
  httpprefix.clear();
  receptionist.clear();

  // Setting some authentication parameters use with
  // various parts of the code.
  
  authenticate.clear();         // turned off by default, individual collection authentication
  auth_group.clear();              // turned off by default, authentication by groups method
  public_documents.clear();          // turned off by default, allow access to these documents <list>
  private_documents.clear();           // turned off by default, disallow access to these documents <list>
    
}

text_t ColInfoResponse_t::get_collectionmeta(text_t name, text_t lang) {
  text_t value = collectionmeta[name][lang];
  if (value.empty()) {
    value = collectionmeta[name][g_EmptyText];
  }
  return value;

}

void InfoFiltersResponse_t::clear () {
  filterNames.erase(filterNames.begin(), filterNames.end());
}


void InfoFilterOptionsRequest_t::clear () {
  filterName.clear();
}


void FilterOption_t::clear () {
  name.clear();
  type = booleant;
  repeatable = onePerQuery;
  defaultValue.clear();
  validValues.erase(validValues.begin(), validValues.end());
}

void FilterOption_t::check_defaultValue () {
  text_tarray::iterator here, end;

  // how the default is interpreted depends on the option type
  switch (type) {
  case booleant: 
  case enumeratedt: // has to be one of the validValues
    here = validValues.begin ();
    end = validValues.end ();
    while (here != end) {
      if (*here == defaultValue) return;
      ++here;
    }
    
    break;

  case integert: // has to be in the validValues range
    if ((validValues.size() >= 2) &&
	(validValues[0].getint() <= defaultValue.getint()) &&
	(validValues[1].getint() >= defaultValue.getint()))
      return;
    break;

  case stringt: // any value is valid
    return; 
  }

  // did not find the defaultValue
  if (validValues.empty()) defaultValue.clear();
  else defaultValue = validValues[0];
}


bool operator==(const FilterOption_t &x, const FilterOption_t &y) {
  return ((x.name == y.name) &&
	  (x.type == y.type) &&
	  (x.repeatable == y.repeatable) &&
	  (x.defaultValue == y.defaultValue) &&
	  (x.validValues == y.validValues));
}

bool operator<(const FilterOption_t &x, const FilterOption_t &y) {
  return ((x.name < y.name) ||
	  ((x.name == y.name) &&
	   ((x.type < y.type) ||
	    ((x.type == y.type) &&
	     ((x.repeatable < y.repeatable) ||
	      ((x.repeatable == y.repeatable) &&
	       ((x.defaultValue < y.defaultValue) ||
		((x.defaultValue == y.defaultValue) &&
		 (x.validValues < y.validValues)))))))));
}



void InfoFilterOptionsResponse_t::clear () {
  filterOptions.erase(filterOptions.begin(), filterOptions.end());
}


void OptionValue_t::clear () {
  name.clear();
  value.clear();
}


void FilterRequest_t::clear () {
  filterName.clear();
  filterLang.clear();
  filterOptions.erase(filterOptions.begin(), filterOptions.end());
  docSet.erase(docSet.begin(), docSet.end());
  filterResultOptions = 0;
  requestParams.clear();
  refParams.clear();
  fields.erase(fields.begin(), fields.end());
  getParents = false;
}


void TermInfo_t::clear () {
  term.clear();
  freq = 0;
  matchTerms.erase (matchTerms.begin(), matchTerms.end());
}


void MetadataInfo_t::clear () {
  params.clear();
  isRef = false;
  values.erase(values.begin(), values.end());
  if (parent != NULL) {
    delete parent;
    parent = NULL;
  }
}

MetadataInfo_t::MetadataInfo_t () {parent=NULL;clear();}

// copy constructor
MetadataInfo_t::MetadataInfo_t (const MetadataInfo_t &x) {
  params = x.params;
  isRef = x.isRef;
  values = x.values;
  if (x.parent == NULL) parent = NULL;
  else {
    parent = new MetadataInfo_t ();
    *parent = *(x.parent);
  }
}

MetadataInfo_t::~MetadataInfo_t () {
  if (parent != NULL) {
    delete parent;
    parent = NULL;
  }
}

MetadataInfo_t &MetadataInfo_t::operator=(const MetadataInfo_t &x) {
  if (&x != this) {
    params = x.params;
    isRef = x.isRef;
    values = x.values;
    if (x.parent == NULL) parent = NULL;
    else {
      parent = new MetadataInfo_t ();
      *parent = *(x.parent);
    }
  }
  return *this;
}

void ResultDocInfo_t::clear () {
  OID.clear ();
  ranking = 0;
  result_num = 0;
  num_terms_matched = 0;
  num_phrase_match = 0;
  docFreq.erase(docFreq.begin(), docFreq.end());
  metadata.erase(metadata.begin(), metadata.end());
  classifier_metadata_type.erase(classifier_metadata_type.begin(), 
				 classifier_metadata_type.end());
  classifier_metadata_offset = 0;
  
}

ResultDocInfo_t &ResultDocInfo_t::operator=(const ResultDocInfo_t &x) {
  OID = x.OID; 
  ranking = x.ranking;
  result_num = x.result_num;
  num_terms_matched = x.num_terms_matched;
  num_phrase_match = x.num_phrase_match;
  docFreq = x.docFreq; 
  metadata = x.metadata;
  return *this;
}

void FilterResponse_t::clear () {
  error_message = g_EmptyText;
  numDocs = 0;
  isApprox = Exact;
  termInfo.erase (termInfo.begin(), termInfo.end());
  docInfo.erase (docInfo.begin(), docInfo.end());
  stopwords.clear();
}

FilterResponse_t &FilterResponse_t::operator=(const FilterResponse_t &x) {
  error_message = x.error_message;
  numDocs = x.numDocs;
  isApprox = x.isApprox;
  termInfo = x.termInfo;
  docInfo = x.docInfo;
  stopwords = x.stopwords;
  return *this;
}

void DocumentRequest_t::clear () {
  OID.clear();
  docType.clear();
  docFormat.clear();
}

void DocumentResponse_t::clear () {
  doc.clear();
}
