/***************************************************************************
 *   Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com       *
 *   Portions Copyright (C) 2000-2005 Trolltech AS.                        * 
 *   Please do not use email address above for bug reports; see            *
 *   the README file                                                       *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#ifndef TQASSISTANTINDEX_H
#define TQASSISTANTINDEX_H

#include <tqstringlist.h>
#include <tqdict.h>
#include <tqdatastream.h>
#include <tqobject.h>

namespace QtAs
{

struct Document
{
	Document( int d, int f ) : docNumber( d ), frequency( f ) {}
	Document() : docNumber( -1 ), frequency( 0 ) {}
	bool operator==( const Document &doc ) const
	{
		return docNumber == doc.docNumber;
	}
	
	bool operator<( const Document &doc ) const
	{
		return frequency > doc.frequency;
	}
	
	bool operator<=( const Document &doc ) const
	{
		return frequency >= doc.frequency;
	}
	
	bool operator>( const Document &doc ) const
	{
		return frequency < doc.frequency;
	}
	
	TQ_INT16 docNumber;
	TQ_INT16 frequency;
};

TQDataStream &operator>>( TQDataStream &s, Document &l );
TQDataStream &operator<<( TQDataStream &s, const Document &l );

class Index : public TQObject
{
    TQ_OBJECT
  
	public:
		struct Entry
		{
			Entry( int d ) { documents.append( Document( d, 1 ) ); }
			Entry( TQValueList<Document> l ) : documents( l ) {}
			TQValueList<Document> documents;
		};
		
		struct PosEntry
		{
			PosEntry( int p ) { positions.append( p ); }
			TQValueList<uint> positions;
		};

		Index( const TQString &dp, const TQString &hp );
		Index( const TQStringList &dl, const TQString &hp );
		
		void 		writeDict();
		bool 		readDict();
		bool 		makeIndex();
		TQStringList query( const TQStringList&, const TQStringList&, const TQStringList& );
		
		void 		setDictionaryFile( const TQString& );
		void 		setDocListFile( const TQString& );
		void 		setDocList( const TQStringList & );
		TQString 	getCharsSplit() const { return m_charssplit; }
		TQString 	getCharsPartOfWord() const { return m_charsword; }

	signals:
		void indexingProgress( int );

	public slots:
		void setLastWinClosed();

	private:
		void	setupDocumentList();
		bool	parseDocumentToStringlist( const TQString& filename, TQStringList& tokenlist );
		void	parseDocument( const TQString& filename, int docnum );
		void	insertInDict( const TQString&, int );
		
		void	writeDocumentList();
		bool	readDocumentList();
		
		TQStringList				getWildcardTerms( const TQString& );
		TQStringList				split( const TQString& );
		TQValueList<Document> 	setupDummyTerm( const TQStringList& );
		bool 					searchForPhrases( const TQStringList &phrases, const TQStringList &words, const TQString &filename );
		
		TQStringList 		docList;
		TQDict<Entry> 		dict;
		TQDict<PosEntry>		miniDict;
		TQString 			docPath;
		TQString 			dictFile;
		TQString 			docListFile;
		bool 				lastWindowClosed;
	
		// Those characters are splitters (i.e. split the word), but added themselves into dictionary too.
		// This makes the dictionary MUCH larger, but ensure that for the piece of "window->print" both 
		// search for "print" and "->print" will find it.
		TQString m_charssplit;

		// Those characters are parts of word - for example, '_' is here, and search for _debug will find only _debug.
		TQString m_charsword;
};

struct Term
{
	Term( const TQString &t, int f, TQValueList<Document> l ) : term( t ), frequency( f ), documents( l ) {}
	
	TQString 				term;
	int 					frequency;
	TQValueList<Document>	documents;
};

class TermList : public TQPtrList<Term>
{
	public:
		TermList() : TQPtrList<Term>() {}
		int compareItems( TQPtrCollection::Item i1, TQPtrCollection::Item i2 );
};

};

#endif /* TQASSISTANTINDEX_H */
