#ifndef _TEXTINDEX_H_INCLUDED_
#define _TEXTINDEX_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// TextIndex.h
// -----------
// TextIndex class definition
//                                                         
// Design and Implementation by Bjoern Lemke               
//                                                         
// (C)opyright 2000-2016 Bjoern Lemke                        
//                                                         
// INTERFACE MODULE
//
// Class: TextIndex
// 
// Description: Full text index utility class
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// INCLUDES
#include "Chain.h"
#include "SetT.h"
#include "AVLTreeT.h"
#include "Matcher.h"

#define MAXDEPTH 10

class TextIndex {

public:

    class IndexFilter {
	
    public:

	IndexFilter()
	{
	    _pMatch = 0;
	}

	IndexFilter(const Chain& pattern, const Chain& token)
	{
	    _pMatch = new Matcher(pattern);
	    _pMatch->prepare();
	    _token = token;
	}
	
	~IndexFilter()
	{
	    if ( _pMatch)
		delete _pMatch;	    
	}
	
	bool match(const Chain& token) const
	{
	    return _pMatch->match(token);
	}

	Chain getPattern() const
	{
	    if ( _pMatch )
		return _pMatch->getExpr();
	    return Chain();
	}
	Chain getToken() const
	{
	    return _token;
	}
	
	IndexFilter& operator = ( const IndexFilter& f)
	{
	    if ( _pMatch)
	    {
		delete _pMatch;
		_pMatch = 0;
	    }
	    if ( f.getPattern() != Chain() )
	    {
		_pMatch = new Matcher(f.getPattern());
		_pMatch->prepare();
	    }
	    _token = f._token;
	    return (*this);
	}
	
	bool operator == ( const IndexFilter& f) const
	{
	    return ( getPattern() == f.getPattern() );	      
	}

    private:
	
	Matcher *_pMatch;
	Chain _token;
		
    };
    
    TextIndex(const Chain& text, const SetT<IndexFilter>& filter, unsigned int depth, const Chain& sep, char esc = '\\');
    ~TextIndex();
    
    bool nextKey(Chain& key);
    
 private:

    void tokenizeText();
    bool nextPos(unsigned int d);
    
    unsigned int _depth;
    Chain _text;
    SetT<IndexFilter> _filter;
    Chain _sep;
    char _esc;

    AVLTreeT<Chain> _tokenSet;
    Chain** _tokenArray;
    unsigned int _depPos[MAXDEPTH];
};
#endif
