/***************************************************************************
 *   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 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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <qdir.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qmap.h>
#include <qpixmap.h>
#include <qregexp.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 "datastruct/aux.h"
#include "datastruct/DItem.h"
#include "datastruct/DDataControl.h"
#include "datastruct/DDataItem.h"

#include "kdissOOOdoc.h"

K_EXPORT_COMPONENT_FACTORY(libkdissOOOdoc, kdissOOOdocFactory) 
	QObject *kdissOOOdocFactory::createObject(QObject *, const char *, const char *, const QStringList &) { return new kdissOOOdoc; }

	static const int maxpicsize = 700;

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

const QString kdissOOOdoc::fullName()
{
	return i18n("OpenOffice.org Writer");
}

const QString kdissOOOdoc::group()
{
	return "OpenOffice.org";
}

const QString kdissOOOdoc::description()
{
	return i18n("This template generates a simple OpenOffice.org document that can be viewed using any OpenOffice.org file format reader like OpenOffice.org writer or kword");
}

const QString kdissOOOdoc::quickstart()
{
	return i18n("Go into the directory created and open the .sxw file generated with oowriter or kword\n");
}

void kdissOOOdoc::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<<"<text:p text:style-name=\"Standard\">";
		s<<"<text:a xlink:type=\"simple\" xlink:href=\"";
		s<<url;
		s<<"\">"<<caption<<"</text:a>\n";
		s<<"</text:p>\n";
	}

	// print the comment
	if (item->m_comment.length()>0)
	{
		s<<"<text:p text:style-name=\"P11\">";
		s<<DDataItem::protectXML(item->m_comment);
		s<<"</text:p>\n";
	}

	// process the picture
	if (!item->m_pix.isNull())
	{
		//s<<"<text:p text:style-name=\"P"<<level<<"\">\n";
		s<<"<text:p text:style-name=\"P8\">\n";
		s<<"<draw:text-box draw:style-name=\"fr1\" draw:name=\"Cadre1\" text:anchor-type=\"paragraph\" svg:x=\"1.48cm\" svg:y=\"0.226cm\" svg:width=\"5.606cm\" fo:min-height=\"3.605cm\" draw:z-index=\"0\">\n";

		s<<"<text:p text:style-name=\"Illustration\">\n";

		// TODO : set the size of the picture ..
		s<<"<draw:image draw:style-name=\"fr2\" draw:name=\"Image1\" text:anchor-type=\"paragraph\" svg:x=\"0.004cm\" svg:y=\"0.002cm\" svg:width=\"5.606cm\" style:rel-width=\"100%\" svg:height=\"3.605cm\" style:rel-height=\"scale\" draw:z-index=\"1\" xlink:href=\""<<"#Pictures/"<<item->m_picfilename<<"\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>Illustration <text:sequence text:ref-name=\"refIllustration0\" text:name=\"Illustration\" text:formula=\"Illustration+1\" style:num-format=\"1\">1</text:sequence>: "<<DDataItem::protectXML(item->m_piccaption)<<"</text:p>";

		s<<"</draw:text-box>\n";
		s<<"</text:p>\n";
	}	
}

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

	thing.replace("</span>", "SPAN");
	thing.replace("<span", "SPAN<span");
	QStringList lst = QStringList::split("SPAN", thing);

	QString ret;
	QRegExp boldrx("font-weight:600.*>");
	QRegExp italicrx("italic.*>");
	QRegExp underlinerx("underline.*>");
	QRegExp toremove("<span.*>");

	for (int i=0; i<lst.size(); i++)
	{
		QString txt = lst[i];

		if (txt.startsWith("<span"))
		{
			bool bold = false;
			bool italic = false;
			bool underline = false;
			int style = 0;

			if (txt.contains(boldrx))
				bold = true;
			if (txt.contains(italicrx))
				italic = true;
			if (txt.contains(underlinerx))
				underline = true;

			if (bold)
			{
				if (italic)
				{
					if (underline)
						style = 8;
					else
						style = 5;
				}
				else if (underline)
				{
					style = 6;
				}
				else
				{
					style = 2;
				}
			}
			else if (italic)
			{
				if (underline)
					style = 7;
				else
					style = 3;
			}
			else if (underline)
			{
				style = 4;
			}

			ret += "<text:span text:style-name=\"T"+QString::number(style)+"\">";

			txt.remove(toremove);
			ret += DDataItem::protectXML( txt );

			ret += "</text:span>";
		}
		else
		{
			ret += DDataItem::protectXML( wipeTags(txt) );
		}
	}
	return ret;
}

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

	// printitem ?

	if (level == 0)
	{
		s<<"<text:p text:style-name=\"P1\">";
		s<<DDataItem::protectXML(item->m_summary);
		s<<"</text:p>\n";

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

		s<<"<text:p text:style-name=\"Standard\"/>\n";
		outputData(item, s, level);
		s<<"<text:p text:style-name=\"Standard\"/>\n";

		//s<<"<text:table-of-content text:style-name=\"Sect1\" text:protected=\"true\" text:name=\"";
		//s<<i18n("Table of contents")<<"1\">\n";
		/*s<<"<text:table-of-content-source text:outline-level=\"10\">\n";
		  s<<"<text:index-title-template text:style-name=\"Contents Heading\">";
		  s<<i18n("Table of contents")<<"</text:index-title-template>\n";
		  s<<"</text:table-of-content>\n";
		  */

		s<<"<text:p text:style-name=\"Standard\"/>\n";
		s<<"<text:ordered-list text:style-name=\"L1\">";
		if (item->countChildren() > 0)
		{
			for (int i = 0; i<item->countChildren(); i++)
				writeItem((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
		}
		s<<"</text:ordered-list>\n";
	}
	else if (level <= 10)
	{
		s<<"<text:list-item>\n";

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

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

		outputData(item, s, level);

		if (item->countChildren() > 0)
		{
			s<<"<text:ordered-list>\n";
			for (int i = 0; i<item->countChildren(); i++)
				writeItem((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
			s<<"</text:ordered-list>\n";
		}

		s<<"</text:list-item>\n";
	}
	else
	{
		// insane, a document shouldn't grow *that* big

		s<<"<text:p text:style-name=\"Standard\">";
		s<<DDataItem::protectXML(item->m_summary);
		s<<"</text:p>\n";

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

		outputData(item, s, level);
	}
}

void kdissOOOdoc::writeItemPic(DDataControl * data, DDataItem *item, QTextStream &m)
{
	if (!item)
		return;

	if (! item->m_pix.isNull())
	{
		if (item->m_picfilename.endsWith(".png", false))
		{
			m<<"<manifest:file-entry manifest:media-type=\"image/png\" manifest:full-path=\"";
			m<<"Pictures/"+item->m_picfilename;
			m<<"\"/>\n";
		}
		else if (item->m_picfilename.endsWith(".jpeg", false) || item->m_picfilename.endsWith(".jpg", false))
		{
			m<<"<manifest:file-entry manifest:media-type=\"image/jpeg\" manifest:full-path=\"";
			m<<"Pictures/"+item->m_picfilename;
			m<<"\"/>\n";
		}
		// FIXME : can't remember why ?
		//item->m_pix.save(path+"/Pictures/"+"pic-"+QString::number(data->idNum(i))+".png", "PNG");
	}

	for (int i=0; i<item->countChildren(); i++)
	{
		writeItemPic( data, (DDataItem*) data->Item(item->childNum(i)), m );
	}
}

void kdissOOOdoc::writePics(DDataControl * data, QString path)
{
	// ----------------------------------------------------
	// write the pics and process the META-INF directory

	DDataItem *root = (DDataItem*) data->Item( data->rootID() );

	// copy the pictures
	KIO::NetAccess::dircopy( KURL(data->getTmpDir()->absPath()), KURL(path+"/Pictures"), NULL );

	// proces the manifest file
	QFile manifestfile(path+"/META-INF/manifest.xml");
	if (!manifestfile.open(IO_WriteOnly | IO_Append) )
	{
		kdError()<<"could not open the manifest xml file for append :-/"<<endl;
		return;
	}

	QTextStream m(&manifestfile);
	m.setEncoding(QTextStream::UnicodeUTF8);

	// write the pictures contained in the subtree considered
	writeItemPic( data, root, m );

	// close the manifest file
	m<<"</manifest:manifest>";
	manifestfile.close();
}

bool kdissOOOdoc::writeMaindoc(DDataItem *root, const QString & path)
{
	// ----------------------------------------------------
	// process the content

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

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

	// test
	//u<<"<text:p text:style-name=\"Standard\">";
	//u<<DDataItem::protectXML(root->m_summary);
	//u<<"</text:p>\n";

	/*outputPixParagraph(root, u);
	  outputURL(root, u);
	  outputComment(root, u);*/

	u<<"<office:body>\n";

	u<<"<text:sequence-decls>\n";
	u<<"<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Illustration\"/>\n";
	u<<"<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Table\"/>\n";
	u<<"<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Text\"/>\n";
	u<<"<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Drawing\"/>\n";
	u<<"</text:sequence-decls>\n";

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

	// write the end of document
	u<<"</office:body>\n";
	u<<"</office:document-content>";

	// close the content document
	textfile.close();

	// ----------------------------
	// styles

	QFile stylefile(path+"/styles.xml");
	if (!stylefile.open(IO_WriteOnly | IO_Append) )
	{
		kdWarning()<<"could not open the styles xml file for append :-/"<<endl;
		return false;
	}
	QTextStream v(&stylefile);

	//v<<"<text:author-name text:fixed=\"false\">";
	v<<DDataItem::protectXML(m_data->m_fname)<<" "<<DDataItem::protectXML(m_data->m_sname);
	//v<<"</text:author-name>";
	v<<"</text:p></style:header><style:footer><text:p text:style-name=\"Footer\"><text:date style:data-style-name=\"N37\" text:date-value=\"\" text:fixed=\"false\"></text:date><text:tab-stop/><text:page-number text:select-page=\"current\">1</text:page-number>/<text:page-count>3</text:page-count></text:p></style:footer></style:master-page></office:master-styles></office:document-styles>";
	stylefile.close();

	// ----------------------------------
	// TODO process the meta-data section

	// title : DDataItem::protectXML(root->m_summary)
	QFile metafile(path+"/meta.xml");
	if (!metafile.open(IO_WriteOnly | IO_Append) )
	{
		kdWarning()<<"could not open the main xml file for append :-/"<<endl;
		return false;
	}

	QTextStream m(&metafile);
	m.setEncoding(QTextStream::UnicodeUTF8);

	m<<"<meta:initial-creator>"<<DDataItem::protectXML(m_data->m_fname)<<" "<<DDataItem::protectXML(m_data->m_sname)<<"</meta:initial-creator>\n";
	m<<"<dc:creator>"<<DDataItem::protectXML(m_data->m_fname)<<" "<<DDataItem::protectXML(m_data->m_sname)<<"</dc:creator>\n";

	m<<"<dc:language>";
	//KLocale *loc = KGlobal::locale();
	//if (loc) m<<loc->country();
	//m<<KLocale::defaultLanguage().replace('_', '-');
	//m<<"fr-FR";
	m<<Settings::countrycode();
	m<<"</dc:language>\n";

	m<<"<meta:editing-cycles>3</meta:editing-cycles>\n";
	m<<"<meta:editing-duration>PT8S</meta:editing-duration>\n";

	m<<"<meta:user-defined meta:name=\"Info 1\"/>";
	m<<"<meta:user-defined meta:name=\"Info 2\"/>";
	m<<"<meta:user-defined meta:name=\"Info 3\"/>";
	m<<"<meta:user-defined meta:name=\"Info 4\"/>";
	m<<"<meta:document-statistic meta:table-count=\"0\" meta:image-count=\"0\" meta:object-count=\"0\" meta:page-count=\"1\" meta:paragraph-count=\"1\" meta:word-count=\"1\" meta:character-count=\"0\"/>\n";
	m<<"</office:meta>\n</office:document-meta>";

	metafile.close();

	// ----------------------------------------------------
	// create the archive

	KZip zip(path+"/newdoc.sxw");
	zip.setCompression( KZip::DeflateCompression );
	zip.open( IO_WriteOnly );

	zip.addLocalFile(path+"/content.xml", "content.xml");
	zip.addLocalFile(path+"/meta.xml", "meta.xml");
	zip.addLocalFile(path+"/mimetype", "mimetype");
	zip.addLocalFile(path+"/settings.xml", "settings.xml");
	zip.addLocalFile(path+"/styles.xml", "styles.xml");
	zip.addLocalDirectory(path+"/Pictures", "Pictures");
	zip.addLocalDirectory(path+"/META-INF", "META-INF");

	zip.close();

	// ----------------------------------------------------
	// remove the (now useless) temporary files

	// do not show the progressdialog
	KIO::del(KURL(path+"/content.xml"), false, false );
	KIO::del(KURL(path+"/meta.xml"), false, false );
	KIO::del(KURL(path+"/mimetype"), false, false );
	KIO::del(KURL(path+"/settings.xml"), false, false );
	KIO::del(KURL(path+"/styles.xml"), false, false );
	KIO::del(KURL(path+"/META-INF"), false, false );
	KIO::del(KURL(path+"/Pictures"), false, false );

	notifyDocGenerated( path+"/newdoc.sxw" );
	
	return true;
}

#include "kdissOOOdoc.moc"
