/*------------------------------------------------------------------------------
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
* 
* Distributable under the terms of either the Apache License (Version 2.0) or 
* the GNU Lesser General Public License, as specified in the COPYING file.
------------------------------------------------------------------------------*/
#include "CLucene/StdHeader.h"
#include "WildcardQuery.h"
#include "CLucene/util/BitSet.h"

CL_NS_USE(index)
CL_NS_USE(util)
CL_NS_DEF(search)


  WildcardQuery::WildcardQuery(Term* term): 
	MultiTermQuery( term ){
  //Func - Constructor
  //Pre  - term != NULL
  //Post - Instance has been created

  }

  WildcardQuery::~WildcardQuery(){
  //Func - Destructor
  //Pre  - true
  //Post - true

  }

  const TCHAR* WildcardQuery::getQueryName() const{
  //Func - Returns the string "WildcardQuery"
  //Pre  - true
  //Post - The string "WildcardQuery" has been returned
	return getClassName();
  }

  const TCHAR* WildcardQuery::getClassName(){
      return _T("WildcardQuery");
  }


  FilteredTermEnum* WildcardQuery::getEnum(IndexReader* reader) {
    return _CLNEW WildcardTermEnum(reader, getTerm(false));
  }

	WildcardQuery::WildcardQuery(const WildcardQuery& clone):
		MultiTermQuery(clone)
	{
	}

	Query* WildcardQuery::clone() const{
		return _CLNEW WildcardQuery(*this);
	}
	size_t WildcardQuery::hashCode() const{
		//todo: we should give the query a seeding value... but
		//need to do it for all hascode functions
		return Similarity::floatToByte(getBoost()) ^ getTerm()->hashCode();
	}
	bool WildcardQuery::equals(Query* other) const{
		if (!(other->instanceOf(WildcardQuery::getClassName())))
			return false;

		WildcardQuery* tq = (WildcardQuery*)other;
		return (this->getBoost() == tq->getBoost())
			&& getTerm()->equals(tq->getTerm());
	}










	

WildcardFilter::WildcardFilter( Term* term )
{
	this->term = _CL_POINTER(term);
}

WildcardFilter::~WildcardFilter()
{
	_CLDECDELETE(term);
}

WildcardFilter::WildcardFilter( const WildcardFilter& copy ) : 
	term( _CL_POINTER(copy.term) )
{
}

Filter* WildcardFilter::clone() const {
	return _CLNEW WildcardFilter(*this );
}


TCHAR* WildcardFilter::toString()
{
	//Instantiate a stringbuffer buffer to store the readable version temporarily
    CL_NS(util)::StringBuffer buffer;
    //check if field equal to the field of prefix
    if( term->field() != NULL ) {
	  //Append the field of prefix to the buffer
      buffer.append(term->field());
	  //Append a colon
      buffer.append(_T(":") );
    }
    //Append the text of the prefix
    buffer.append(term->text());

	//Convert StringBuffer buffer to TCHAR block and return it
    return buffer.toString();
}


/** Returns a BitSet with true for documents which should be permitted in
search results, and false for those that should not. */
BitSet* WildcardFilter::bits( IndexReader* reader )
{
	BitSet* bts = _CLNEW BitSet( reader->maxDoc() );
	
	WildcardTermEnum termEnum (reader, term);
    if (termEnum.term(false) == NULL)
      return bts;

	TermDocs* termDocs = reader->termDocs();
	try{
		do{
			termDocs->seek(&termEnum);

			while (termDocs->next()) {
			  bts->set(termDocs->doc());
			}
		}while(termEnum.next());
	} _CLFINALLY(
      termDocs->close();
      _CLDELETE(termDocs);
      termEnum.close();
    )

	return bts;
}

CL_NS_END
