/**********************************************************************
 *
 * browseaction.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 "gsdl_modules_cfg.h"
#ifdef GSDL_USE_BROWSE_ACTION

#include "browseaction.h"
#include "querytools.h"
#include "browseactiontools.h"
#include "recptprototools.h"

browseaction::browseaction(){

 

  cgiarginfo arg_ainfo;
  arg_ainfo.shortname = "a";
  arg_ainfo.longname = "action";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "br";
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);

  //the first browsing criterion -- collection metadata types
  arg_ainfo.shortname = "b1";
  arg_ainfo.longname = "browse criterion 1";
  arg_ainfo.multiplechar = false;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "0";
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);
 
  //the second browsing criterion -- collection metadata types + none - meaning
  //only one browsing criterion.  None is the default.
  arg_ainfo.shortname = "b2";
  arg_ainfo.longname = "browse criterion 2";
  arg_ainfo.multiplechar = false;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "0";
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);
  
  //the number of documents to show per page -- if the box is empty then
  //only the most basic divisions are made (so, first letter for A-Z, year 
  //for date).
  arg_ainfo.shortname = "bnu";
  arg_ainfo.longname = "browse docs per page";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::good;
  arg_ainfo.argdefault = g_EmptyText;
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);

  //The text to filter documents for browsing (only documents containing these 
  //words will be browsed).
  arg_ainfo.shortname = "bft";
  arg_ainfo.longname = "browse filter text";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::none;
  arg_ainfo.argdefault = g_EmptyText;
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);


  //Whether all or just some of the words in the filter box have to be present
  //0 - any 1- all
  arg_ainfo.shortname = "bt";
  arg_ainfo.longname = "browse all or any";
  arg_ainfo.multiplechar = false;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "0";
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo); 
  
}

browseaction::~browseaction(){}

bool browseaction::init (ostream &logout){
  return true;
}

void browseaction::configure (const text_t &key, const text_tarray &cfgline){
  action::configure(key, cfgline);
}



bool browseaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/, 
				  recptprotolistclass * /*protos*/, ostream &/*logout*/) {
  // don't want to check anything yet.
  
  return true;
}

  
void browseaction::get_cgihead_info (cgiargsclass &args, 
				     recptprotolistclass *protos,
				     response_t &response, 
				     text_t &response_data, 
				     ostream &logout){
  response = content;
  response_data = "text/html";

  
}

void browseaction::define_internal_macros (displayclass &disp, 
					   cgiargsclass &args, 
					   recptprotolistclass *protos, 
					   ostream &logout){
 
}

void browseaction::define_external_macros (displayclass &disp, 
					   cgiargsclass &args, 
					   recptprotolistclass *protos, 
					   ostream &logout){
  
}

bool browseaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
			      browsermapclass *browsers, displayclass &disp, 
			      outconvertclass &outconvert, ostream &textout, 
			      ostream &logout){
 
  if(args["c"].empty()) return false;
  else if(get_document_list(args, protos, browsers, disp, outconvert, textout,
			    logout)) return true;
  else return false;
}

bool browseaction::get_document_list(cgiargsclass &args, 
		recptprotolistclass *protos, browsermapclass *browsers, 
		displayclass &disp, outconvertclass &outconvert, 
		ostream &textout, ostream &logout){ 
  
  text_t collection = args["c"];
  comerror_t err;
  text_t list_type = "VList";  //result display type

  //check that the protocol is alive
  recptproto* colproto = protos->getrecptproto (collection, logout);
  if(colproto == NULL) {
    logout << outconvert << "ERROR: Null collection protocol trying to browse "
	   << collection << "\n";
    return false;
  }
  
  //check the collection is responding/in place
  ColInfoResponse_t *colinfo = recpt->get_collectinfo_ptr(colproto, collection,
							  logout);
  if(colinfo == NULL){
    logout << outconvert << "ERROR: Null returned for get_collectinfo_ptr on "
	   << collection << "in browseaction\n";
    return false;
  }

  browserclass* br_ptr = browsers->getbrowser(list_type);

  FilterRequest_t request;
  FilterResponse_t response;

  //set up browser structure 
  br_ptr->set_filter_options(request, args);
  request.filterLang = args["l"];
  br_ptr->load_metadata_defaults(request.fields);

  //set up format information
  format_t* formatptr = new format_t();
  parse_formatstring(br_ptr->get_default_formatstring(), formatptr, 
		     request.fields, request.getParents);

  request.filterResultOptions = FROID | FRmetadata;
  
  text_t bf_string = g_EmptyText;
  format_browsestring(args["bft"],bf_string,args.getintarg("bt"));
  
  set_browsefilter_options(request, bf_string, args);
  
  //set up browse filter string;
  if(!args["bft"].empty()){

    colproto->filter (collection, request, response, err, logout);
    if (err != noError) {
      outconvertclass text_t2ascii;
      logout << text_t2ascii
	     << "browseaction::get_document_list QueryFilter failed "
	     << "for " << collection << " collection (" 
	     << get_comerror_string (err) << ")\n";
      return false;
    }// if (err != noError) 

  }// end if(!args["bft"].empty())
  else {
    text_tset metadata_items;
    text_t temp = "Title";
    metadata_items.insert(temp);
    temp = "browselist";
    if (!get_children(temp, args["c"], args["l"], metadata_items, false, colproto,
		     response,logout)) return false;
  }

  //get rid of documents that do not have the metadata element classified on
  if(!remove_no_meta_results("Title",response, outconvert)) {
    return false;
    logout<<"ERROR: browseactiontools::remove_no_meta_results failed"<<endl;
  }

  textout << outconvert << disp << "_browse:header_\n" <<"_browse:content_";

  
  bool use_table = is_table_content (formatptr);
  br_ptr->output_section_group (response, args, collection, 0, formatptr, 
			      use_table, request.fields, request.getParents, 
			      colproto, disp, outconvert, textout, logout);

  textout << outconvert << disp << "_browse:footer_";
    
  
  
  return true;
}

#endif //GSDL_USE_BROWSE_ACTION
