/***************************************************************************
 *   Copyright (C) 2005 Cédric Brun                                        *
 *   cedric.brun$free.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 <qdir.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qmap.h>
#include <qpixmap.h>
#include <qregexp.h>
#include <qxml.h>

#include <kglobal.h>
#include <kio/job.h>
#include <kio/netaccess.h>
#include <kzip.h>
#include <kurl.h>
#include <klocale.h>
#include <kdebug.h>
#include <ktempdir.h>
#include <kgenericfactory.h>

#include "aux.h"
#include "DItem.h"
#include "DDataControl.h"
#include "DDataItem.h"

#include "kdissdocbook.h"

class richtext2docbook : public QXmlDefaultHandler
{
	public:
		richtext2docbook() : QXmlDefaultHandler() {}
		~richtext2docbook() {}

		bool startDocument();
		bool startElement( const QString&, const QString&, const QString& , const QXmlAttributes& );
		bool endElement( const QString&, const QString&, const QString& );
		bool characters( const QString& s);
		const QString& stringRead() { return m_result; }


	private:

		QString m_result;
		bool m_inparagraph;
		bool m_inbullet;
		bool m_inspan;

		bool m_isbold;
		bool m_isitalic;
		bool m_isunderline;

		QString m_str;
};

bool richtext2docbook::startDocument()
{
	m_inbullet = false;
	m_inparagraph = false;
	m_inspan = false;
	return true;
}

bool richtext2docbook::startElement( const QString&, const QString&, const QString& qName, const QXmlAttributes& atts )
{
	if (qName == "ul")
	{
		m_result += "<itemizedlist>\n";
		m_inbullet = true;
	}
	else if (qName == "p")
	{
		m_result += "<para>";
		m_str = QString::null;
		m_inparagraph = true;
	}
	else if (qName == "li")
	{
		m_result += "<listitem><para>\n";
		m_str = QString::null;
	}
	else if (qName == "span")
	{
		QString style = atts.value("style");

		m_isbold=false;
		m_isitalic=false;
		m_isunderline=false;

		QStringList styleatts = QStringList::split(";", style);

		if (m_inparagraph)
		{
			m_result += DDataItem::protectXML(m_str);
			m_str = QString::null;
			//       m_result += "<text:span text:style-name=\"T"+QString::number(styleCode())+"\">";
		}
		else if (m_inbullet)
		{
			m_result += DDataItem::protectXML(m_str);
			m_str = QString::null;
			//	m_result += "<text:span text:style-name=\"T"+QString::number(styleCode())+"\">";
		}
		m_inspan = true;
	}
	return true;
}

bool richtext2docbook::endElement( const QString&, const QString&, const QString& qName )
{
	if (qName == "ul")
	{
		m_result += "</itemizedlist>\n";
		m_inbullet = false;
	}
	else if (qName == "li")
	{
		m_result += DDataItem::protectXML( m_str );
		m_result += "</para></listitem>\n";
		m_str = QString::null;
	}
	else if (qName == "p")
	{
		m_inparagraph = false;
		m_result += DDataItem::protectXML( m_str );
		m_str = QString::null;
		m_result += "</para>\n";
	}
	else if (qName == "span")
	{
		m_inspan = false;
		if (m_inparagraph)
		{
			m_result += DDataItem::protectXML( m_str );
			m_str=QString::null;
		}
		else if (m_inbullet)
		{
			m_result += DDataItem::protectXML( m_str );
			m_str=QString::null;
		}
	}
	else if (qName == "br")
	{
		//m_result += "</text:p>\n";
		if (m_inparagraph)
		{
			if (m_inspan)
			{
				m_result += DDataItem::protectXML(m_str);
				m_str=QString::null;
				//m_result += "</text:p>\n";
				//m_result += "<text:p text:style-name=\"Standard\">";
				//m_result += "<text:span text:style-name=\"T"+QString::number(styleCode())+"\">";
			}
			else
			{
				m_result += DDataItem::protectXML(m_str);
				//m_result += "</text:p>\n";
				//m_result += "<text:p text:style-name=\"Standard\">";
				m_str=QString::null;
			}
		}
		else if (m_inbullet)
		{
			// TODO : nothing to do here ?
			/*m_result += DDataItem::protectXML(m_str);
			  m_str=QString::null;
			  m_result += "</text:span>";
			  m_result += "</text:p>\n";
			  m_result += "<text:p text:style-name=\"Standard\">";
			  m_result += "<text:span text:style-name=\"T"+QString::number(styleCode())+"\">";*/
		}
	}

	return true;
}

bool richtext2docbook::characters( const QString& s)
{
	m_str += s;
	return true;
}


K_EXPORT_COMPONENT_FACTORY(libkdissdocbook, kdissdocbookFactory) 
	QObject *kdissdocbookFactory::createObject(QObject *, const char *, const char *, const QStringList &) { return new kdissdocbook; }

	static const int maxpicsize = 700;

const QString kdissdocbook::identifikation()
{
	return "kdissdocbook";
}

const QString kdissdocbook::fullName()
{
	return i18n("Docbook document writer");
}

const QString kdissdocbook::group()
{
	return i18n("DocBook");
}

const QString kdissdocbook::description()
{
	return i18n("This template generates a simple DocBook - book document. Author : Cédric Brun, based on the work of Thomas Nagy for the OpenOffice.org document generators.");
}

const QString kdissdocbook::quickstart()
{
	return i18n("Go into the directory created and launch db2pdf or any other db* command.\n");
}

void kdissdocbook::outputData(DDataItem* item, QTextStream & s, int level)
{
	// links
	for (unsigned int i=0; i<item->m_urllist.count(); i++)
	{
		QString url = item->m_urllist[i].m_url;
		QString caption = item->m_urllist[i].m_caption;
		if (!caption.length()) caption = url;
		s << "<ulink url=\"" << url <<"\">" << caption << "</ulink>";
	}

	// print the comment
	if (item->m_comment.length()>0)
	{
		s<<"<!--";
		s<<DDataItem::protectXML(item->m_comment);
		s<<"-->\n";
	}

	// process the picture
	if (!item->m_pix.isNull())
	{

		s<<"<figure>\n";
		s<<"<title>"<<DDataItem::protectXML(item->m_piccaption)<<"</title>\n";
		s<<"<mediaobject><imageobject><imagedata ";
		s<<"format=\"PNG\" fileref=\"pics/"<<item->m_picfilename<<"\"/>\n";
		s<<"<!--"<<item->m_picurl<<"-->\n";
		s<<"<!--"<<item->m_picfilename<<"-->\n";
		s<<"</imageobject></mediaobject> ";
		s<<"</figure>\n";
	}	
}

QString convertToOOOdoc(const QString & str)
{
	QString thing = str;

	richtext2docbook handler;
	QXmlInputSource source;
	source.setData( str );
	QXmlSimpleReader reader;
	reader.setContentHandler( &handler );
	bool result = reader.parse( source );

	if (result) return handler.stringRead();
	else return QString::null;
}



void kdissdocbook::writeItem(DDataItem* item, QTextStream & s, int level)
{
	DGenerator::writeItem(item, s, level);

	// printitem ?
	if (level == 0)
	{
		if (item->countChildren() > 0)
		{
			for (int i = 0; i<item->countChildren(); i++)
				writeItem((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
		}
	}
	else if (level == 1)
	{
		// The title
		for (int i=0; i<level; i++)
		{
			//s<<"<text:ordered-list text:style-name=\"L1\" text:continue-numbering=\"true\">";
			//s<<"<text:list-item>\n";
		}

		s << "<chapter><title>\n";
		//s<<"<text:h text:style-name=\"P"<<level+100<<"\" text:level=\""<<level<<"\">";
		s<<DDataItem::protectXML(item->m_summary);
		s<<"</title>\n";


		// The text
		s<<convertToOOOdoc( item->m_text );

		// The data
		outputData(item, s, level);

		// And now the children
		if (item->countChildren() > 0)
		{
			for (int i = 0; i<item->countChildren(); i++)
				writeItem((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
		}
		s<<"</chapter>\n";
	}
	else if (level <= 10)
	{
		// The title
		for (int i=0; i<level; i++)
		{
			//s<<"<text:ordered-list text:style-name=\"L1\" text:continue-numbering=\"true\">";
			//s<<"<text:list-item>\n";
		}

		s << "<section><title>";
		//s<<"<text:h text:style-name=\"P"<<level+100<<"\" text:level=\""<<level<<"\">";
		s<<DDataItem::protectXML(item->m_summary);
		s<<"</title>\n";


		// The text
		s<<convertToOOOdoc( item->m_text );

		// The data
		outputData(item, s, level);

		// And now the children
		if (item->countChildren() > 0)
		{
			for (int i = 0; i<item->countChildren(); i++)
				writeItem((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
		}
		s<<"\n</section>\n\n";
	}
	else
	{
		// insane, a document shouldn't grow *that* big
		s<<DDataItem::protectXML(item->m_summary);

		//s<<"<text:p text:style-name=\"Standard\">";
		s<<convertToOOOdoc( item->m_text );

		outputData(item, s, level);
	}
}

bool kdissdocbook::writeMaindoc(DDataItem *root, const QString & path)
{

	QFile textfile(path+"/main.docbook");
	if (!textfile.open(IO_WriteOnly | IO_Append) )
	{
		kdWarning()<<"could not open docbook file for append :-/"<<endl;
		return false;
	}

	QTextStream u(&textfile);
	u.setEncoding(QTextStream::UnicodeUTF8);

	// print the headers and footers
	u << "<?xml version='1.0' encoding='utf-8'?>\n<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook V4.1//EN\" \"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\" >\n "; 
	u << "<book lang=\"" << Settings::countrycode() << "\">\n";
	u << "<bookinfo><title>\n";
	u<<DDataItem::protectXML(root->m_summary)<<"\n";
	u << "</title>\n<authorgroup>\n<author>\n<firstname>";
	u<<DDataItem::protectXML(m_data->m_fname)<<"\n";
	u << "</firstname>\n<surname>\n";
	u <<DDataItem::protectXML(m_data->m_sname)<<"\n";
	u << "</surname>\n</author>\n</authorgroup>\n</bookinfo>\n\n<toc></toc>";


	// standard headers
	u<<"\n";

	// now the central part, with text, pictures, etc ..
	writeItem(root, u, 0);

	// central part is finished
	u<<"</book>\n";
	textfile.close();

	notifyDocGenerated( path+"/main.docbook" );

	return true;
}

#include "kdissdocbook.moc"
