/*
 *    AbstractGS2AudioSearch.java
 *    Copyright (C) 2011 New Zealand Digital Library, http://www.nzdl.org
 *
 *    This program is free software; you can redistribute it and/or modify
 *   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.
 */
package org.greenstone.gsdl3.service;


// Greenstone classes
import org.greenstone.gsdl3.util.OID;
import org.greenstone.gsdl3.util.DBInfo;
import org.greenstone.gsdl3.util.GSXML;
import org.greenstone.gsdl3.util.BasicDocumentDatabase;
import org.greenstone.gsdl3.util.GSFile;

// XML classes
import org.w3c.dom.Document;
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList;

// java
import java.util.Vector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import java.io.File;

import org.apache.log4j.*;

public abstract class AbstractGS2AudioSearch 
    extends AbstractAudioSearch 
{

    protected static final String EQUIV_TERM_ELEM = "equivTerm";

    protected static final String STEM_ATT = "stem";
    protected static final String NUM_DOCS_MATCH_ATT = "numDocsMatch";
    protected static final String FREQ_ATT = "freq";

    // Elements used in the config file that are specific to this class
    protected static final String DEFAULT_INDEX_ELEM = "defaultIndex";
    protected static final String INDEX_STEM_ELEM = "indexStem";
    protected static final String INDEX_ELEM = "index";
    protected static final String DEFAULT_INDEX_SUBCOLLECTION_ELEM = "defaultIndexSubcollection";
    protected static final String DEFAULT_INDEX_LANGUAGE_ELEM = "defaultIndexLanguage";
    protected static final String INDEX_SUBCOLLECTION_ELEM = "indexSubcollection";
    protected static final String INDEX_LANGUAGE_ELEM = "indexLanguage";
   

    // Some indexing options
    protected static final String STEMINDEX_OPTION = "stemIndexes";
    protected static final String MAXNUMERIC_OPTION = "maxnumeric";

    /** the stem used for the index files */
    protected String index_stem = null;

    // stem indexes available
    protected boolean does_case=true;
    protected boolean does_stem=true;
    protected boolean does_accent=false;

    // maxnumeric - 
    protected int maxnumeric = 4;

    BasicDocumentDatabase gs_doc_db = null;

    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractGS2AudioSearch.class.getName());


    /** constructor */
    public AbstractGS2AudioSearch()
    {
	
    }

    public void cleanUp() {
	super.cleanUp();
	this.gs_doc_db.cleanUp();
    }

    /** configure this service */
    public boolean configure(Element info, Element extra_info)
    {
	if (!super.configure(info,extra_info)) {
	    return false;
	}

	// find out what kind of database we have
	Element database_type_elem = (Element) GSXML.getChildByTagName(info, GSXML.DATABASE_TYPE_ELEM);
	String database_type = null;
	if (database_type_elem != null) {
	  database_type = database_type_elem.getAttribute(GSXML.NAME_ATT);
	}
	if (database_type == null || database_type.equals("")) {
	  database_type = "gdbm"; // the default
	}
	
	// the index stem is either the collection name or is specified in the config file
	Element index_stem_elem = (Element) GSXML.getChildByTagName(info, INDEX_STEM_ELEM);
	if (index_stem_elem != null) {
	    this.index_stem = index_stem_elem.getAttribute(GSXML.NAME_ATT);
	}
	if (this.index_stem == null || this.index_stem.equals("")) {
	    logger.warn("indexStem element not found, stem will default to collection name");
	    this.index_stem = this.cluster_name;
	}

	// replaces default AbstractSearch version with one tied to database
	gs_doc_db = new BasicDocumentDatabase(database_type,this.site_home,
					      this.cluster_name,
					      this.index_stem);
	if (!gs_doc_db.isValid()) {
	    logger.error("Failed to open Document Database.");
	    return false;
	}
	this.gs_doc = gs_doc_db; 

	// do we support any of the extended features?
	does_chunking = true;

	// Get the default index out of <defaultIndex> (buildConfig.xml)
	Element def = (Element) GSXML.getChildByTagName(info, DEFAULT_INDEX_ELEM);
	if (def != null) {
	    this.default_index = def.getAttribute(GSXML.SHORTNAME_ATT);
	} // otherwise will be "", and the first one will be the default
        

	// Get index options ... 
	// ... but there are currently no index options supported for audio
	// so nothing to do

	// Similarly the following will not currently do anything, but leave
	// in for the time we do start supporting different indexes
	// 
	// *** Also, it is identical to that in AbstractGS2TextSearch, so
	// consider putting into supporting routine and sharing 
	// (realted in 'info' object

	// get display info from extra info
	if (extra_info !=null) {
	    Document owner = info.getOwnerDocument();
	    // so far we have index specific display elements, and global format elements 
	    NodeList indexes = info.getElementsByTagName(GSXML.INDEX_ELEM);
	    Element config_search = (Element)GSXML.getChildByTagName(extra_info, GSXML.SEARCH_ELEM);
	    
	    for (int i=0; i<indexes.getLength();i++) {
		Element ind = (Element)indexes.item(i);
		String name = ind.getAttribute(GSXML.NAME_ATT);
		Element node_extra = GSXML.getNamedElement(config_search,
							   GSXML.INDEX_ELEM,
							   GSXML.NAME_ATT,
							   name);
		if (node_extra == null) {
		    logger.error("haven't found extra info for index named "+name);
		    continue;
		}
		
		// get the display elements if any - displayName
		NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
		if (display_names !=null) {
		    for (int j=0; j<display_names.getLength(); j++) {
			Element e = (Element)display_names.item(j);
			ind.appendChild(owner.importNode(e, true));
		    }
		}
	    } // for each index
	}

	return true;
    }

    protected void getIndexData(ArrayList index_ids, ArrayList index_names, String lang) 
    {
	logger.info("Trivial index support for audio for now.  Adding hardwired 'audioDB' to index");
	index_names.add("audioDB");
    }
}


