/***************************************************************************
 *   Copyright (C) 2004, 2005 Thomas Nagy                                  *
 *   tnagy2^8@yahoo.fr                                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation (see COPYING)            *
 *                                                                         *
 *   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.                          *
 ***************************************************************************/

#include <qregexp.h>
#include <qvaluelist.h>

#include <kdebug.h>
#include <kspell.h>
#include <klocale.h>
#include <kmessagebox.h>

#include "DDataItem.h"
#include "DDataControl.h"
#include "DSpell.h"

DSpell::DSpell(DDataControl *ctrl): QObject(ctrl)
{
	m_datacontrol = ctrl;
	m_spell = NULL;
}

DSpell::~DSpell()
{
	delete m_spell;
}

void DSpell::spell()
{
	//kdWarning()<<"DSpell::spell"<<endl;
	if (m_spell)
	{
		//kdWarning()<<"spell wasn't deleted before!"<<endl;
		delete m_spell;
	}

	m_spell = new KSpell(NULL, i18n("Spellcheck"), this, SLOT( spell_started(KSpell *)),
			0, true, true, KSpell::HTML);
	connect(m_spell, SIGNAL(done(const QString&)), this, SLOT(spell_done(const QString&)));
	connect(m_spell, SIGNAL(death()), this, SLOT( spell_death()));
	connect(m_spell, SIGNAL(corrected(const QString&, const QString&, unsigned int)), 
			this, SLOT(corrected(const QString&, const QString&, unsigned int)));
}

void DSpell::corrected(const QString&, const QString&, unsigned int)
{
	//kdWarning()<<"DSpell::corrected"<<endl;
	QStringList lst = QStringList::split(QString("<item />"), m_spell->intermediateBuffer());

	QRegExp rx("\\d+");    

	QValueList<QString>::iterator it;
	QValueList<QString>::iterator end = lst.end();
	for (it=lst.begin(); it!=end; ++it)
	{
		QString str = *it;

		QStringList itemlst = QStringList::split(QString("<field />"), str, true);
		if (! rx.exactMatch(itemlst[0]))
			continue;

		DDataItem *item = m_datacontrol->dataItem( itemlst[0].toInt() );
		if (!item)
		{
			kdWarning()<<"BUG : no item found of id "<<itemlst[0].toInt()<<endl;
			itemlst.join(" @@@@ ");
		}

		if (itemlst.count() != 5)
		{
			//kdWarning()<<"bad count : "<<itemlst.count()<<endl;
			continue;
		}

		// check if the item has changed
		bool changed = false;
		if (changed || item->m_summary != itemlst[1])
			changed = true;
		if (changed || item->m_text != itemlst[2])
			changed = true;
		if (changed || item->m_comment != itemlst[3])
			changed = true;
		if (changed || item->m_piccaption != itemlst[4])
			changed = true;

		if (changed)
		{
			//kdWarning()<<"item changed ! "<<item->Id()<<endl;

			item->m_summary = itemlst[1];
			item->m_text = itemlst[2];
			item->m_comment = itemlst[3];
			item->m_piccaption = itemlst[4];

			m_datacontrol->itemChanged(item->Id());
			m_datacontrol->docChanged();
		}
	}
}

void DSpell::spell_started(KSpell *)
{
	m_localtext = QString::null;

	QString smallsep = QString("<field />");

	QValueList<int>::iterator it;
	QValueList<int> allitems = m_datacontrol->m_map.keys();

	for ( it = allitems.begin(); it != allitems.end(); ++it )
	{
		DDataItem *item = m_datacontrol->dataItem( *it );

		m_localtext += QString::number(item->Id());
		m_localtext += smallsep;
		m_localtext += item->m_summary;
		m_localtext += smallsep;
		m_localtext += item->m_text;
		m_localtext += smallsep;
		m_localtext += item->m_comment;
		m_localtext += smallsep;
		m_localtext += item->m_piccaption;

		m_localtext += QString("<item />");
	}

	m_spell->check(m_localtext);
}

void DSpell::spell_done(const QString&)
{
	//kdWarning()<<"DSpell::spell_done"<<endl;
	m_spell->cleanUp();
}

void DSpell::spell_death()
{
	//kdWarning()<<"DSpell::spell_finished"<<endl;
	KSpell::spellStatus status = m_spell->status();

	delete m_spell;
	m_spell = 0;

	if (status == KSpell::Error) KMessageBox::sorry(NULL, i18n("Spell checker could not be started."));
	else if (status == KSpell::Crashed) KMessageBox::sorry(NULL, i18n("Spell checker seems to have crashed."));
}

#include "DSpell.moc"
