/* This file is part of the KDE project
   Copyright (c) 2004 Kevin Ottens <ervin ipsquad net>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "cluceneimpl.h"

#include <kdebug.h>
#include <kglobalsettings.h>
#include <kstandarddirs.h>
#include <kdesktopfile.h>
#include <kservice.h>
#include <klocale.h>

#include <qdir.h>
#include <qfile.h>

#include <sys/stat.h>
#include <kio/slavebase.h>
#include <kio/netaccess.h>

#include <qstringlist.h>

#include <kclucene_search_daemon_dcopiface_stub.h>

#include <kuser.h>
#include <qfile.h>

#include <qcstring.h>
#include <qsocket.h>
#include <qdatetime.h>
#include <qbitarray.h>

#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <kmessagebox.h>
//#include <kinstance.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kurl.h>
#include <ksock.h>
#include <kconfig.h>
#include <dcopclient.h>
#include <kapplication.h>

#include <stdlib.h>

#include <kprocess.h>


#include <algorithm>
#include <stdlib.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>

#include <kdesktopfile.h>
#include <kstandarddirs.h>

CLuceneImpl::CLuceneImpl() 
		: 
		m_cleanHits(TRUE), 
		m_query(""), 
		m_request(0), 
		m_kprocess(""), 
		m_queryName(""),
		m_configItem(
				KURL::fromPathOrURL(
					locateLocal("config","kclucene_index_settings_rc")
					  	   ),
				"text/plain",S_IFREG
			    ), 
		m_oldConfigFileModTime(0),
		m_cfg("kclucene_index_settings_rc" , 
		      TRUE,
		      FALSE, //kde global toggled off
		      "config" 
		     )
{
	//init path where to store raw-queries
	QString path = locateLocal("appdata","stored_queries");
	QDir dir = path;
	if (!dir.exists())
	{
		dir.cdUp();
		dir.mkdir("stored_queries");
	}
	
	connect(&m_request, SIGNAL(AllHitsAreHere()),this, SLOT(processAllHitsAreHere()));
	connect(&m_request, SIGNAL(HitsAreHere()),   this, SLOT(processCLuceneHits()));
}

//TODO: check what to delete here
CLuceneImpl::~CLuceneImpl()
{
// 	delete proc;
}

//function imported from ???
static void addAtom(KIO::UDSEntry &entry, unsigned int ID, long l,
		    const QString &s = QString::null)
{
	KIO::UDSAtom atom;
	atom.m_uds = ID;
	atom.m_long = l;
	atom.m_str = s;
	entry.append(atom);
}

static KURL findServiceRealURL(QString wizardService)
{
	KURL url;
	kdDebug() << "CLuceneImpl::findServiceRealURL SEARCHING FOR!"  << wizardService << endl;

	KService::Ptr service = KService::serviceByDesktopName(wizardService);

	if (service && service->isValid())
	{
		url.setPath( locate("apps",
			     service->desktopEntryPath())
			   );
	}

	return url;
}

//creates the top level entry of the ioslave
void CLuceneImpl::createTopLevelEntry(KIO::UDSEntry &entry) const
{
	entry.clear();
	addAtom(entry, KIO::UDS_NAME, 0, ".");
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_ACCESS, 0777);
	addAtom(entry, KIO::UDS_MIME_TYPE, 0, "inode/directory");
}

// should behave like a link to the toplevel entry
//it must work with KDIALOG and konqueror => sofar, it is implemented as directory with a redirection
bool CLuceneImpl::createGoHomeEntry(KIO::UDSEntry &entry) const
{
	entry.clear();
	addAtom(entry, KIO::UDS_NAME,0, "KCLucene Home");
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_MIME_TYPE,0, "inode/directory");
	addAtom(entry, KIO::UDS_ICON_NAME,0, "folder_home");
	addAtom(entry, KIO::UDS_URL,0, GO_HOME_URL );
// 	app_entry(entry, KIO::UDS_FILE_TYPE, S_IFLNK);
// 	app_entry(entry, KIO::UDS_LINK_DEST, "../" );
	return TRUE;
}

//creates an entry for each Query
//it must behave like a directory so as to display results, even inside KDIALOG.
//the name of the entry is the NAME of the query, the URL points to the real query string
void CLuceneImpl::createQueryEntry(KIO::UDSEntry& entry , const KURL & url , const QString & name ,const QString & iconName)
{
	entry.clear();
	addAtom(entry, KIO::UDS_NAME,0, QFile::decodeName(name.local8Bit()));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_ACCESS, 0400);
// 	addAtom(entry, KIO::UDS_MIME_TYPE,0, "inode/directory");
	addAtom(entry, KIO::UDS_ICON_NAME,0, iconName);
	//PURE HACK:make some queries don't work and it is ugly
	//it relies on the truncated query being redirected as queryy
	//i need it because I get problems with my hacky mkdir/symlink Kacke
	//but it breaks the query recognition
	QString str = url.url();
	str = str.remove(0,13+9);
	str = "clucene:/" + str +"/";
	addAtom(entry, KIO::UDS_URL, 0,str );
}

//creates the toplevel entry used to save raw-queries
void CLuceneImpl::createBackup(KIO::UDSEntry& entry)
{
	entry.clear();
	addAtom(entry, KIO::UDS_NAME,0, "Saved Queries");
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	//app_entry(entry, KIO::UDS_FILE_TYPE, S_IFLINK);
	addAtom(entry, KIO::UDS_ACCESS, 0400);
	addAtom(entry, KIO::UDS_MIME_TYPE,0, "inode/directory");
	addAtom(entry, KIO::UDS_ICON_NAME,0, "folder");
	//app_entry(entry, KIO::UDS_LINK_DEST, BACKUP_LOCATION );
	addAtom(entry, KIO::UDS_URL,0, BACKUP_URL );
}

//creates the entry for the kclucene-search-dialog
//it is a directory to allow use inside KDIALOG, but it must not be in principle
bool CLuceneImpl::createGUISearchEntry(KIO::UDSEntry &entry) const
{
	entry.clear();
	KURL url = findServiceRealURL(GUI_SEARCH_SERVICE );
	if (!url.isValid())
	{
		kdDebug() << "CLuceneImpl::createGUISearchEntry APP DESKTOP FILE NOT FOUND!"  << endl;
		return false;
	}
	//must be of type dir to work within kfiledialog
	addAtom(entry, KIO::UDS_NAME, 0, i18n("Start search dialog"));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_URL, 0, GUI_SEARCH_URL);  //path in the slave
	addAtom(entry, KIO::UDS_ICON_NAME, 0, "wizard");
	addAtom(entry, KIO::UDS_MIME_TYPE,0, "inode/directory");
	return true;
}

//creates the entry for the kclucene-indexer-config, opened at the ioslave index-selection page
//it is a directory to allow use inside KDIALOG, but it must not be in principle
bool CLuceneImpl::createConfigIndexesEntry(KIO::UDSEntry &entry) const
{
	entry.clear();
	KURL url = findServiceRealURL( CONFIG_INDEXES_SERVICE );

	if (!url.isValid())
	{
		kdDebug() << "CLuceneImpl::createConfigIndexesEntry NOT FOUND!"  << endl;
		return false;
	}
	addAtom(entry, KIO::UDS_NAME, 0, i18n("Setup indexes"));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_URL, 0, CONFIG_INDEXES_URL);  //path in the slave
	addAtom(entry, KIO::UDS_ICON_NAME, 0, "configure");
	addAtom(entry, KIO::UDS_MIME_TYPE,0, "inode/directory");
	return true;
}

//useless but I use it. SearchForm corresponds to the string used in the HTML-queryy-form "search"
bool CLuceneImpl::createHTMLSearchFormEntry(KIO::UDSEntry &entry) const
{
	entry.clear();
	addAtom(entry, KIO::UDS_NAME, 0, i18n("Search Form Link"));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFDIR);
	addAtom(entry, KIO::UDS_ACCESS, 0500);
// 	addAtom(entry, KIO::UDS_LINK_DEST, 0,"clucene:/" );
	addAtom(entry, KIO::UDS_URL, 0, SEARCH_FORM_URL);
// 	addAtom(entry, KIO::UDS_MIME_TYPE, 0, "inode/directory");
	return TRUE;
}

//creates a link to a search-webform
//TODO: a local webform will be search first.
bool CLuceneImpl::createHTMLSearchEntry(KIO::UDSEntry &entry) const
{
	QString webForm = KGlobal::dirs()
			->findResource("data","kio_clucene/html_search/kio_clucene_webformA.html");
	kdDebug() << "CLuceneImpl::createHTMLSearchEntry webForm:" << webForm<<endl;
	
	entry.clear();
	addAtom(entry, KIO::UDS_NAME, 0, i18n("Start HTML search"));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFLNK);
	addAtom(entry, KIO::UDS_ACCESS, 0500);
	addAtom(entry, KIO::UDS_LINK_DEST, 0,"file:" + webForm );
	addAtom(entry, KIO::UDS_URL, 0, webForm);
	addAtom(entry, KIO::UDS_MIME_TYPE, 0, "text/html");
	if (webForm.isEmpty() )
		   return FALSE;
	else
		return TRUE;
}

//TODO: full report
bool CLuceneImpl::createHTMLReportEntry(KIO::UDSEntry &entry) const
{
	addAtom(entry, KIO::UDS_NAME, 0, i18n("Query Stats"));
	addAtom(entry, KIO::UDS_FILE_TYPE, S_IFREG);
	QString str = "clucene:/" + m_query + "/" + HTML_RESULTS_URL;
	QString str2 = "clucene:/gui_search/results";
	addAtom(entry, KIO::UDS_ACCESS, 0500);
	addAtom(entry, KIO::UDS_MIME_TYPE, 0, "html");
	addAtom(entry, KIO::UDS_ICON_NAME, 0, "html");
	return TRUE;	//Last Query
}

//small helper function: compares a string and a url
bool CLuceneImpl::isWantedURL(const KURL &url , QString wizardUrl) const
{
	KURL testUrl(wizardUrl);
	
	kdDebug() << "CLuceneImpl::isWantedURL: url:" << url << "  | " << wizardUrl  << endl;
	kdDebug() << "CLuceneImpl::isWantedURL: Test result is :" << QString::number(url==testUrl) << endl;
	return url==testUrl;
}

//set Query
void CLuceneImpl::setQuery(QString query)
{
	
	m_query = query;
}

//TODO
int CLuceneImpl::displayHTMLResults()
{
	if (m_html == 0)
	{
		//FIXME: should use an error message instead and block the access to the file
		m_display = "<HTML> <BODY>No results yet</BODY></HTML>";
	}
	return 1;	
}

//list entries at TOPLEVEL: loast queries and co
void CLuceneImpl::listRoot(QValueList<KIO::UDSEntry> &list) 
{
	kdDebug() << "CLuceneImpl::listRoot: query"  << m_queryList << endl;
	kdDebug() << "CLuceneImpl::listRoot: urls"  <<  m_query_urlList<< endl;

	//list the query lists
// 	bool update(TRUE);
	QStringList::ConstIterator queryItemString = m_queryList.begin();
	QStringList::ConstIterator end = m_queryList.end();
	QStringList::ConstIterator queryItemURLString = m_query_urlList.begin();
	QStringList::ConstIterator URLend = m_query_urlList.end();
	
	for(; queryItemString !=end; ++queryItemString )
	{
		KIO::UDSEntry entry;
		entry.clear();
		QString name;
		QString iconName="folder";
		if (queryItemString ==  m_queryList.fromLast())
		{
			name = "Last query:  " + *queryItemString;
			//TODO:make it green
			iconName = "kfind";
		}
		else
		{
			name = "Old query: " + *queryItemString;
			iconName = "kfind";
		}
		KURL myUrl(*queryItemURLString);
		createQueryEntry( entry , myUrl  , name , iconName);
		list.append(entry);
		++queryItemURLString;
	}
	
	m_query = "";
	m_queryName = "";
}

KURL CLuceneImpl::query_url()
{
	return m_query_url;
}

void CLuceneImpl::setQuery_url( KURL& url)
{
	m_query_url= url;
	return;
}

QString CLuceneImpl::query()
{
	return m_query;
}

void CLuceneImpl::addQueryToList()
{
	//check if the query is know already
// 	if ( m_queryList.find(m_query_url)!=m_queryList.end())
	kdDebug() << "CLuceneImpl::addQueryToList() list: : " << m_query_urlList <<endl;
	kdDebug() << "CLuceneImpl::addQueryToList() m_queryURL: : " << m_query_url.url() <<endl;
	kdDebug() << "CLuceneImpl::addQueryToList() m_query: : " << m_query <<endl;

		if ( m_query_urlList.find(m_query_url.url())!=m_query_urlList.end())

	{
		kdDebug() << "CLuceneImpl::addQueryToList() QUERY EXISTS, not added : " << endl;
		kdDebug() << "CLuceneImpl::addQueryToList() egal if names are different or not : " << endl;

		return;
	}
	//if it is known, then do nothing
	
	if (this->m_queryName.isEmpty())
	{
		//remove the query fields here, or
		m_queryList.append(m_query);
	}
	else
	{
		//TODO: check if name already exists
		m_queryList.append(m_queryName);
	}
	m_query_urlList.append(m_query_url.url());
	
	kdDebug() << "CLuceneImpl::addQueryToList() QUERY LIST ADDED IN : " << endl;
	kdDebug() << "CLuceneImpl::addQueryToList() QUERY LIST ADDED IN : " << endl;

}

void CLuceneImpl::startQuery()
{
	//reread the index paths if changed
	this->hasConfigFileChanged();

	//FIXME: not implemented
	kdDebug() << "QUERY PROCESS HAS BEEN STARTED" << m_request.indexesPathList.join(" , ") << endl;
	
	m_request.setQuery(m_query);
	m_request.start();
	kdDebug() << "QUERY PROCESS HAS ENDED" << endl;
}

//TODO:rewrite all this cahos
void CLuceneImpl::urlToPattern(const KURL& url)
{
	// Reset old patterns here 
	setQuery     (QString::null );
	KURL m5 = KURL(QString::null);
	setQuery_url (m5);
	//setDirRoot   (FALSE);
	
	QString pattern = url.decode_string(url.url());
	
	kdDebug() << "CLuceneImpl::urlToPattern: URL: " << url.url() << endl;
	
	//url must start with /. set it
	if (!(pattern.startsWith("clucene:/", false)) && (pattern.startsWith("clucene:", false))) 
	{
		pattern = pattern.mid(8);
		pattern = "clucene:/" + pattern;
	}
	
        // Strip off protocol part.
	if (pattern.startsWith("clucene:", false)) 
	{
		pattern = pattern.mid(8);
	}
	
	if (pattern == "/")
	{
		return;
		//we are in ROOT and listDir OR STAT will be called if completion is ON or OFF
		//setDirRoot(TRUE);
	}	
	
	
	
	// When konqueror tries to do autocompletion, the URL ends in "/".
        // Likewise if an URL is entered by the user any trailing slashes are
        // removed by KDE. So we can detect autocompletion.
	int n = pattern.length();
	
	//xavier says : what about ROOT
	m_isAutoCompletion = (n > 0) && (pattern[n-1] == '/');
	
	if (pattern.startsWith("/ ")) {
		pattern = pattern.mid(2);
	}
	
	if (pattern.startsWith("/")) 
	{
		pattern = pattern.mid(1);
	}
	
	//?????????????
	m_query = pattern.replace("§" ,"*");
// 	m_query = pattern;
	
	//FIXME:TODO very bad all those bad hacks

	QString protocol("clucene:");
	
	if (!(url.path().startsWith("/")))
		protocol= "clucene:/";
		
// 		m_query_url = url.url() + "/";
	m_query_url = url.url();
	
	
	
	kdDebug() << "CLuceneImpl::urlToPattern: UQUERY: " << m_query << endl;
	kdDebug() << "CLuceneImpl::urlToPattern: UQUERY: " <<  m_query_url<< endl;


}

bool CLuceneImpl::startGuiConfig()
{
	//init buffer
	
	proc = new KProcess;
	connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)),
		this, SLOT(getOutput(KProcess *, char *, int)));
	connect(proc, SIGNAL(processExited(KProcess*)),
		this, SLOT(slotProcessExited(KProcess*)));
	
	m_buf = QString::null;

	m_kprocess = CONFIG_INDEXES_EXEC;
	kdDebug() << "GETXH. YOU HAVE STARTED THE CONFIG CONFIG" << m_kprocess <<endl;

	*proc <<  m_kprocess;
	*proc << "--displayIOSlaveconfigOnly";
	proc->start(KProcess::Block , KProcess::Stdout);
	return TRUE;
}	


bool CLuceneImpl::startGuiSearch()
{
	//init buffer
	m_buf = QString::null;
	m_kprocess = GUI_SEARCH_EXEC;
	kdDebug() << "GETXH. YOU HAVE STARTED THE GUI QUERY proc" << m_kprocess <<endl;

	proc = new KProcess;
	connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)),
		this, SLOT(getOutput(KProcess *, char *, int)));
	connect(proc, SIGNAL(processExited(KProcess*)),
		this, SLOT(slotProcessExited(KProcess*)));

	
	*proc <<  m_kprocess;
	*proc << "--onrequest";
	proc->start(KProcess::Block , KProcess::Stdout);
	//FIXME: HELP I can't get it run async
// 	proc->start(KProcess::NotifyOnExit , KProcess::Stdout);
	//results will be temporaray saved in m_buf. Set the query to the buffer content
	return TRUE;
}	
	
void CLuceneImpl::getOutput(KProcess * /*proc*/, char *buffer, int buflen)
{
	//API sagt : copy buffer data to private ... so we do it here, end the calling
	//calling functions will decide what to do with the buffer string
	
	//TODO: cannot use search dialog and config zusammen FIXME: if search dialog is async, one should separate the buffers
	//so far, no problems, because we don't expect something from anybody else
	m_buf.append(QString::fromLatin1(buffer, buflen));  //FIXME:latin
	kdDebug() << "GETOUTPUT CALLED:   " <<  m_buf << endl;
	//tutorial http://www.pro-linux.de/work/kde/kdews_4.html
	
	//test of async
// 	if (m_kprocess == GUI_SEARCH_EXEC)	
	{
// // 		m_kprocess = QString::null;
// 		emit OutPutToGUI();
// 		kdDebug() << "CLuceneImpl::slotProcessExited  SIGNAL EMITTED FROM GUI  " << endl;
	}
}
		
void CLuceneImpl::processCLuceneHits()
{
	kdDebug() << "CLuceneImpl::processCLuceneHits : " << endl;
	emit HitsAreHere();
}
		
void CLuceneImpl::processCLuceneHighlightings()
{
	emit HighLightingsAreHere();
}

void CLuceneImpl::processAllHitsAreHere()
{
	kdDebug() << "CLuceneImpl::processAllHitsAreHere EMIT  AllHitsAreHere: " << m_query << endl;

	emit AllHitsAreHere();
}

void CLuceneImpl::getResultsList(QStringList& list)
{
	list = m_request.resultsList;
}

//FIXME code directly imported FROM ????
const UDSEntry CLuceneImpl::pathToUDSEntry(const QString& path, const QString& display,
			const QString& mime, const QString modTime, const QString& mode_T,
			const QString & size, const QString & pathToPixmap)
/*			      const QString& url = QString::null, 
			      const QString& icon = QString::null)*/
{
	
	UDSEntry entry;
	addAtom(entry, KIO::UDS_MIME_TYPE, 0, mime);
	addAtom(entry, KIO::UDS_NAME,0, display);
	if ( ! (pathToPixmap.isEmpty() || pathToPixmap == "empty") )
	{
		kdDebug() << "CLuceneImpl::pathToUDSEntry WANTED: " << pathToPixmap << endl;

		if ( KIO::NetAccess::exists(pathToPixmap,TRUE,0) )
		{
			kdDebug() << "CLuceneImpl::pathToUDSEntry EXISTS: " << pathToPixmap << endl;

			addAtom(entry, KIO::UDS_ICON_NAME,0, pathToPixmap);
		}
	}

	addAtom(entry, KIO::UDS_SIZE, size.toUInt());
// 	addAtom(entry, KIO::UDS_ACCESS, info.st_mode);
	addAtom(entry, KIO::UDS_MODIFICATION_TIME, modTime.toUInt() );
// 	addAtom(entry, KIO::UDS_ACCESS_TIME, info.st_atime);
// 	addAtom(entry, KIO::UDS_CREATION_TIME, info.st_ctime);

// 	struct passwd * user = getpwuid(info.st_uid);
// 	struct group * group = getgrgid(info.st_gid);
// 	addAtom(entry, KIO::UDS_USER,0, ((user != NULL) ? user->pw_name : "???" ));
// 	addAtom(entry, KIO::UDS_GROUP,0, ((group != NULL) ? group->gr_name : "???" ));
	addAtom(entry, KIO::UDS_URL,0, path);

		mode_t type = mode_T.toUInt();
		if (S_ISLNK(type)) {
			QString slink = "";
			char buff[1000];
			int n = readlink(path, buff, 1000);
			if (n != -1) {
				buff[n] = 0;
				slink = buff;
			}
			addAtom(entry, KIO::UDS_LINK_DEST,0 , slink);
		} else {
			type &= S_IFMT;
		}
		addAtom(entry, KIO::UDS_FILE_TYPE , type);
	return entry;






/*	UDSEntry entry;
	addAtom(entry, KIO::UDS_NAME,0, display);

	struct stat info;
	lstat(path, &info);

	addAtom(entry, KIO::UDS_SIZE, info.st_size);
	addAtom(entry, KIO::UDS_ACCESS, info.st_mode);
	addAtom(entry, KIO::UDS_MODIFICATION_TIME, info.st_mtime);
	addAtom(entry, KIO::UDS_ACCESS_TIME, info.st_atime);
	addAtom(entry, KIO::UDS_CREATION_TIME, info.st_ctime);

	struct passwd * user = getpwuid(info.st_uid);
	struct group * group = getgrgid(info.st_gid);
	addAtom(entry, KIO::UDS_USER,0, ((user != NULL) ? user->pw_name : "???" ));
	addAtom(entry, KIO::UDS_GROUP,0, ((group != NULL) ? group->gr_name : "???" ));
	addAtom(entry, KIO::UDS_URL,0, path);

		mode_t type = info.st_mode;
		if (S_ISLNK(type)) {
			QString slink = "";
			char buff[1000];
			int n = readlink(path, buff, 1000);
			if (n != -1) {
				buff[n] = 0;
				slink = buff;
			}
			addAtom(entry, KIO::UDS_LINK_DEST,0 , slink);
		} else {
			type &= S_IFMT;
		}
		addAtom(entry, KIO::UDS_FILE_TYPE , type);
	return entry;
	*/
}

	
void CLuceneImpl::setIndexesPaths(QStringList list)
{
	m_request.indexesPathList = list;
}

//TODO: does not work so far. Always true
bool CLuceneImpl::hasConfigFileChanged()
{
	m_configItem.refresh();
	uint actualModTime = m_configItem.time(KIO::UDS_MODIFICATION_TIME);
	if (actualModTime != m_oldConfigFileModTime )
	{
		m_oldConfigFileModTime = actualModTime;
		m_cfg.reparseConfiguration();
		m_cfg.setGroup("IOSlaveConfig");
		QStringList indexesPathList = m_cfg.readListEntry("selected");
		setIndexesPaths(indexesPathList);
		kdDebug() << "CLuceneImpl::hasConfigFileChanged CHANGED  " << indexesPathList.join(",") << endl;
		return TRUE;
	}
	else
	{
		kdDebug() << "CLuceneImpl::hasConfigFileChanged NOT CHANGED  " <<  endl;
		return FALSE;
	}
}

void CLuceneImpl::readConfig()
{
	m_cfg.setGroup("IOSlaveConfig");
	QStringList indexesPathList = m_cfg.readListEntry("selected");
	setIndexesPaths(indexesPathList);
	m_oldConfigFileModTime =  m_configItem.time(KIO::UDS_MODIFICATION_TIME);
	kdDebug() << "CLuceneImpl::readConfig read  " << indexesPathList.join(",") << endl;
}

 void CLuceneImpl::slotProcessExited(KProcess* /*process*/)
{
	kdDebug() << "CLuceneImpl::slotProcessExited CALLED  " << m_buf << endl;
	delete proc;
	if (m_kprocess == GUI_SEARCH_EXEC)	
	{
		m_kprocess = QString::null;
		emit OutPutToGUI();
		kdDebug() << "CLuceneImpl::slotProcessExited  SIGNAL EMITTED FROM GUI  " << endl;
	}
	else if (m_kprocess == CONFIG_INDEXES_EXEC)	
	{
		m_kprocess = QString::null;
		emit OutPutToConfig();
		kdDebug() << "CLuceneImpl::slotProcessExited SIGNAL EMITTED FROM CONFIG  " << endl;
		
	}
}

#include "cluceneimpl.moc"
