#include "CLucene/StdHeader.h"
#include "CLucene/util/Reader.h"
#include "Field.h"
#include "CLucene/util/Misc.h"
#include "CLucene/util/StringIntern.h"
CL_NS_USE(util)
CL_NS_DEF(document) 

	Field::Field(const TCHAR* Name, const TCHAR* String, bool store, bool index, bool token, const bool storeTermVector)
	{
	//Func - Constructor
	//Pre  - Name != NULL and contains the name of the field
	//       String != NULL and contains the value of the field
	//       store indicates if the field must be stored
	//       index indicates if the field must be indexed
	//       token indicates if the field must be tokenized
	//Post - The instance has been created

		CND_PRECONDITION(Name != NULL, "Name is NULL");
		CND_PRECONDITION(String != NULL,"String is NULL");
		CND_PRECONDITION(!(!index && storeTermVector),"cannot store a term vector for fields that are not indexed.");

		_name        = CLStringIntern::intern( Name CL_FILELINE);
		_stringValue = stringDuplicate( String );
#ifdef _UCS2
		_utf8Value = NULL;
#endif
		_readerValue = NULL;

		_isStored = store;
		_isIndexed = index;
		_isTokenized = token;
      this->storeTermVector = storeTermVector;
      boost=1.0f;

	}

	Field::Field(const TCHAR* Name, Reader* reader, const bool storeTermVector){
	//Func - Constructor
	//Pre  - Name != NULL and contains the name of the field
	//       reader != NULL and contains a Reader
	//Post - The instance has been created with:
	//       isStored    = false
	//       isIndexed   = true
	//       isTokenized = true     
	//       meaning that the field only is indexed and tokenized

		CND_PRECONDITION(Name != NULL, "Name is NULL");
		CND_PRECONDITION(reader != NULL, "reader is NULL");

		_name        = CLStringIntern::intern( Name  CL_FILELINE);
		_stringValue = NULL;
#ifdef _UCS2
		_utf8Value = NULL;
#endif
		_readerValue = reader;

		_isStored = false;
		_isIndexed = true;
		_isTokenized = true;
      this->storeTermVector = storeTermVector;
      boost=1.0f;
	}

	Field::Field(const TCHAR* Name, Reader* reader, bool store, bool index, bool token, const bool storeTermVector)
	{
	//Func - Constructor
	//Pre  - Name != NULL and contains the name of the field
	//       reader != NULL and contains a Reader
	//       store indicates if the field must be stored
	//       index indicates if the field must be indexed
	//       token indicates if the field must be tokenized
	//Post - The instance has been created

		CND_PRECONDITION(Name != NULL, "Name is NULL");
		CND_PRECONDITION(reader != NULL, "reader is NULL");
		CND_PRECONDITION(!(!index && storeTermVector),"cannot store a term vector for fields that are not indexed.");

		_name        = CLStringIntern::intern( Name  CL_FILELINE);
		_stringValue = NULL;
#ifdef _UCS2
		_utf8Value = NULL;
#endif
		_readerValue = reader;

		_isStored = store;
		_isIndexed = index;
		_isTokenized = token;
      this->storeTermVector = storeTermVector;
      boost=1.0f;
	}

	Field* Field::Keyword(const TCHAR* Name, const TCHAR* Value) {
		return _CLNEW Field(Name, Value, true, true, false,false);
	}
#ifdef _UCS2
	Field* Field::Keyword(const char* Name, const char* Value) {
		TCHAR* wName = Misc::_utf8ToWide(Name);
		TCHAR* wValue = Misc::_utf8ToWide(Value);
		Field* ret = Keyword(wName, wValue);
		_CLDELETE_CARRAY(wName);
		_CLDELETE_CARRAY(wValue);
		return ret;
	}
#endif

	Field* Field::UnIndexed(const TCHAR* Name, const TCHAR* Value) {
		return _CLNEW Field(Name, Value, true, false, false,false);
	}
#ifdef _UCS2
	Field* Field::UnIndexed(const char* Name, const char* Value) {
		TCHAR* wName = Misc::_utf8ToWide(Name);
		TCHAR* wValue = Misc::_utf8ToWide(Value);
		Field* ret = UnIndexed(wName, wValue);
		_CLDELETE_CARRAY(wName);
		_CLDELETE_CARRAY(wValue);
		return ret;
	}
#endif

	Field* Field::Text(const TCHAR* Name, const TCHAR* Value, const bool storeTermVector) {
		return _CLNEW Field(Name, Value, true, true, true,storeTermVector);
	}
#ifdef _UCS2
	Field* Field::Text(const char* Name, const char* Value, const bool storeTermVector) {
		TCHAR* wName = Misc::_utf8ToWide(Name);
		TCHAR* wValue = Misc::_utf8ToWide(Value);
		Field* ret = Text(wName, wValue, storeTermVector);
		_CLDELETE_CARRAY(wName);
		_CLDELETE_CARRAY(wValue);
		return ret;
	}
#endif

	Field* Field::UnStored(const TCHAR* Name, const TCHAR* Value, const bool storeTermVector) {
		return _CLNEW Field(Name, Value, false, true, true,storeTermVector);
	}
#ifdef _UCS2
	Field* Field::UnStored(const char* Name, const char* Value, const bool storeTermVector) {
		TCHAR* wName = Misc::_utf8ToWide(Name);
		TCHAR* wValue = Misc::_utf8ToWide(Value);
		Field* ret = UnStored(wName, wValue, storeTermVector);
		_CLDELETE_CARRAY(wName);
		_CLDELETE_CARRAY(wValue);
		return ret;
	}
#endif

	Field* Field::Text(const TCHAR* Name, Reader* Value, const bool storeTermVector) {
		return _CLNEW Field(Name, Value,storeTermVector);
	}
#ifdef _UCS2
	Field* Field::Text(const char* Name, Reader* Value, const bool storeTermVector) {
		TCHAR* wName = Misc::_utf8ToWide(Name);
		Field* ret = Text(wName, Value, storeTermVector);
		_CLDELETE_CARRAY(wName);
		return ret;
	}
#endif

	Field::~Field(){
	//Func - Destructor
	//Pre  - true
	//Post - Instance has been destroyed

		CLStringIntern::unintern(_name);
		_CLDELETE_CARRAY(_stringValue);
#ifdef _UCS2
		_CLDELETE_CARRAY(_utf8Value);
#endif
		_CLDELETE(_readerValue);
	}


	/*===============FIELDS=======================*/
	const TCHAR* Field::name() 		{ return _name; } ///<returns reference
	TCHAR* Field::stringValue()		{ return _stringValue; } ///<returns reference
	Reader* Field::readerValue()	{ return _readerValue; }

	bool	Field::isStored() 	{ return _isStored; }
	bool 	Field::isIndexed() 	{ return _isIndexed; }
	bool 	Field::isTokenized() 	{ return _isTokenized; }
   bool  Field::isTermVectorStored() { return storeTermVector; }

   void Field::setBoost(float_t boost) {
    this->boost = boost;
  }

  float_t Field::getBoost() {
    return boost;
  }

        char* Field::utf8Value() {
		if (_utf8Value == NULL && _stringValue != NULL)
			_utf8Value = Misc::_wideToUtf8(_stringValue);
		return _utf8Value;
	}

	TCHAR* Field::toString() {
		if (_isStored && _isIndexed && !_isTokenized)
			return Misc::join(_T("Keyword<"), _name, _T(":"), (_stringValue==NULL?_T("Reader"):_stringValue), _T(">"));
		else if (_isStored && !_isIndexed && !_isTokenized)
			return Misc::join(_T("Unindexed<"), _name, _T(":"), (_stringValue==NULL?_T("Reader"):_stringValue), _T(">"));
		else if (_isStored && _isIndexed && _isTokenized )
			return Misc::join(_T("Text<"), _name, _T(":"), (_stringValue==NULL?_T("Reader"):_stringValue), _T(">"));
      else if (!_isStored && _isIndexed && _isTokenized)
         return Misc::join(_T("UnStored<"), _name, _T(">"));
		else
			return Misc::join(_T("Field Object ("), _name, _T(")") );
	}

CL_NS_END
