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

#include "kdissOOOimpress.h"

K_EXPORT_COMPONENT_FACTORY(libkdissOOOimpress, kdissOOOimpressFactory) 
	QObject *kdissOOOimpressFactory::createObject(QObject *, const char *, const char *, const QStringList &) { return new kdissOOOimpress; }

	static const int maxpicsize = 700;
	int kdissOOOimpress::m_slidecount = 0;
	int kdissOOOimpress::m_piclocation = 0;

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

const QString kdissOOOimpress::fullName()
{
	return i18n("Presentation");
}

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

const QString kdissOOOimpress::description()
{
	return i18n("This template generates a simple OpenOffice.org presentation that can be viewed using any OpenOffice.org file format reader like OpenOffice.org impress or kpresenter\n"
		"Nice and interesting presentations can be obtained quickly from mindmaps containing lots of pictures and illustrations\n"
		"The text in the items is not exported to the final documents."
		   );
}

const QString kdissOOOimpress::quickstart()
{
	return i18n("Go into the directory created and open the .sxi file generated with ooimpress or kpresenter\n"
			"The picture positioning heuristic is not perfect, so you may have to move some of them\n"
		   );
}

void outputPix(DDataItem* item, QTextStream & s)
{
	if (item->m_pix.isNull())
		return;

	int width = item->m_pix.width();
	int height = item->m_pix.height();

	int newwidth = width;
	int newheight = height;

	if (width > maxpicsize)
	{
		newwidth = maxpicsize;
		newheight = height*newwidth/width;
	}
	else if (height > maxpicsize)
	{
		newheight = maxpicsize;
		newwidth = width*newheight/height;
	}

	// TODO: there is no cation for the picture
	s<<"<draw:image draw:style-name=\"gr1\" draw:text-style-name=\"P5\" draw:layer=\"layout\" svg:width=\""<<newwidth<<"pt\" svg:height=\""<<newheight<<"pt\" svg:x=\"22.512cm\" svg:y=\""<<kdissOOOimpress::m_piclocation<<"cm\" xlink:href=\"#Pictures/"<<item->m_picfilename<<"\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>\n";

	// FIXME do not put all pictures at the same location .. 
	kdissOOOimpress::m_piclocation += 1;
}

void outputURL(DDataItem* item, QTextStream & s)
{
	// FIXME: url goes nowhere .. information loss
	for (unsigned int i=0; i<item->m_urllist.count(); i++)
	{
		QString url = DDataItem::protectXML(item->m_urllist[i].m_url);
		QString caption = DDataItem::protectXML(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";
	}
}

void outputComment(DDataItem* item, QTextStream & s)
{
	if (item->m_comment.length()>0)
		s<<"<!--"<<item->m_comment<<"-->\n";
}

void printItem(DDataItem* item, QTextStream & s)
{
	s<<"<p>\n";
	s<<DDataItem::protectXML( wipeTags(item->m_text) );
	s<<"\n</p>\n";

	outputPix(item, s);
	outputURL(item, s);
	outputComment(item, s);
}

void kdissOOOimpress::writeDownPics(DDataItem* item, QTextStream & s)
{
	outputPix(item, s);
	if (item->countChildren() > 0)
	{
		for (unsigned int i = 0; i<item->countChildren(); i++)
			writeDownPics((DDataItem*) m_data->Item(item->childNum(i)), s);
	}
}

void kdissOOOimpress::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=\"P67\">";
		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<<"<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";
	}	
}

void kdissOOOimpress::writeCompleteSlide(DDataItem* item, QTextStream & s)
{
	m_slidecount++;
	m_piclocation = 1;
	s<<"<draw:page draw:name=\""<<i18n("slide %1").arg(m_slidecount)<<"\" draw:style-name=\"dp1\" draw:id=\"2\" draw:master-page-name=\"lyt-cool\" presentation:presentation-page-layout-name=\"AL2T1\">\n";
	s<<"<draw:text-box presentation:style-name=\"pr4\" draw:text-style-name=\"P4\" draw:layer=\"layout\" svg:width=\"23.912cm\" svg:height=\"3.508cm\" svg:x=\"2.058cm\" svg:y=\"1.543cm\" draw:corner-radius=\"0.032cm\" presentation:class=\"title\">\n";
	s<<"<text:p text:style-name=\"P4\">"<<DDataItem::protectXML(item->m_summary)<<"</text:p>\n";
	s<<"</draw:text-box><draw:text-box presentation:style-name=\"pr5\" draw:text-style-name=\"P6\" draw:layer=\"layout\" svg:width=\"23.549cm\" svg:height=\"13.232cm\" svg:x=\"3.023cm\" svg:y=\"6.178cm\" draw:corner-radius=\"0.032cm\" presentation:class=\"outline\" presentation:user-transformed=\"true\">\n";

	if (item->countChildren() > 0)
	{
		for (unsigned int i = 0; i<item->countChildren(); i++)
			writeBullet((DDataItem*) m_data->Item(item->childNum(i)), s, 1);
	}

	s<<"</draw:text-box><presentation:notes>\n";
	s<<"<draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" draw:page-number=\"2\"/>\n";
	s<<"<draw:text-box presentation:style-name=\"pr3\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"14.518cm\" svg:height=\"11.411cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" draw:corner-radius=\"0.002cm\" presentation:class=\"notes\" presentation:placeholder=\"true\"/>\n";
	s<<"</presentation:notes>\n";
	writeDownPics(item, s);
	s<<"</draw:page>\n";
}

void kdissOOOimpress::writeBullet(DDataItem* item, QTextStream & s, int level)
{
	int val=0;
	if (level > 9)
	{
		kdWarning()<<"insanity detector found something wrong .. kdissOOOimpress::writeBullet"<<endl;
		return;
	}

	s<<"<text:unordered-list text:style-name=\"L4\">\n";
	val = level;
	while (val > 0)
	{
		val--;
		s<<"<text:list-item>\n";
		s<<"<text:unordered-list>\n";
	}
	s<<"<text:list-item>\n";
	s<<"<text:p text:style-name=\"P"<<QString::number(level+4)<<"\">"<<DDataItem::protectXML(item->m_summary)<<"</text:p>\n";
	s<<"</text:list-item>\n";
	val = level;
	while (val > 0)
	{
		val--;
		s<<"</text:unordered-list>\n";
		s<<"</text:list-item>\n";
	}
	s<<"</text:unordered-list>\n";

	if (item->countChildren() > 0)
	{
		for (unsigned int i = 0; i<item->countChildren(); i++)
			writeBullet((DDataItem*) m_data->Item(item->childNum(i)), s, level+1);
	}
}

void kdissOOOimpress::writeItem(DDataItem* item, QTextStream & s, int level)
{
	DGenerator::writeItem(item, s, level);
	if (item->countFamily() > 8)
	{
		m_slidecount++;
		m_piclocation = 1;

		s<<"<draw:page draw:name=\""<<i18n("slide %1").arg(m_slidecount)<<"\" draw:style-name=\"dp1\" draw:id=\"2\" draw:master-page-name=\"lyt-cool\" presentation:presentation-page-layout-name=\"AL2T1\">\n";
		s<<"<draw:text-box presentation:style-name=\"pr4\" draw:text-style-name=\"P4\" draw:layer=\"layout\" svg:width=\"23.912cm\" svg:height=\"3.508cm\" svg:x=\"2.058cm\" svg:y=\"1.543cm\" draw:corner-radius=\"0.032cm\" presentation:class=\"title\">\n";
		s<<"<text:p text:style-name=\"P5\">"<<DDataItem::protectXML(item->m_summary)<<"</text:p>\n";
		s<<"</draw:text-box><draw:text-box presentation:style-name=\"pr5\" draw:text-style-name=\"P6\" draw:layer=\"layout\" svg:width=\"23.549cm\" svg:height=\"13.232cm\" svg:x=\"3.023cm\" svg:y=\"6.178cm\" draw:corner-radius=\"0.032cm\" presentation:class=\"outline\" presentation:user-transformed=\"true\">\n";
		//s<<"<text:unordered-list text:style-name=\"L4\">\n";
		s<<"<text:p text:style-name=\"P"<<QString::number(7)<<"\">"<<DDataItem::protectXML( wipeTags(item->m_text))<<"</text:p>\n";
		//s<<"</text:unordered-list>\n";
		s<<"</draw:text-box><presentation:notes>\n";

		outputPix(item, s);

		s<<"<draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" draw:page-number=\"2\"/>\n";
		s<<"<draw:text-box presentation:style-name=\"pr3\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"14.518cm\" svg:height=\"11.411cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" draw:corner-radius=\"0.002cm\" presentation:class=\"notes\" presentation:placeholder=\"true\"/>\n";
		s<<"</presentation:notes>\n";
		s<<"</draw:page>\n";

		for (unsigned int i = 0; i<item->countChildren(); i++)
		{
			writeCompleteSlide((DDataItem*) m_data->Item(item->childNum(i)), s);
		}
	}
	else
	{
		writeCompleteSlide(item, s);
	}
}

void kdissOOOimpress::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 (unsigned int i=0; i<item->countChildren(); i++)
	{
		writeItemPic( data, (DDataItem*) data->Item(item->childNum(i)), m );
	}
}

void kdissOOOimpress::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 kdissOOOimpress::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);

	m_piclocation = 1;
	// now the central part, with text, pictures, etc ..
	u<<"<draw:page draw:name=\"Title\" draw:style-name=\"dp1\" draw:id=\"1\" draw:master-page-name=\"lyt-cool\" presentation:presentation-page-layout-name=\"AL1T0\">\n";
	u<<"<draw:text-box presentation:style-name=\"pr1\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"23.912cm\" svg:height=\"3.508cm\" svg:x=\"2.058cm\" svg:y=\"1.543cm\" draw:corner-radius=\"0.048cm\" presentation:class=\"title\">\n";
	u<<"<text:p text:style-name=\"P1\">"<<DDataItem::protectXML(root->m_summary)<<"</text:p>";
	u<<"</draw:text-box>\n";
	u<<"<draw:text-box presentation:style-name=\"pr2\" draw:text-style-name=\"P3\" draw:layer=\"layout\" svg:width=\"23.549cm\" svg:height=\"13.232cm\" svg:x=\"3.023cm\" svg:y=\"6.178cm\" draw:corner-radius=\"0.048cm\" presentation:class=\"subtitle\" presentation:user-transformed=\"true\">\n";
	u<<"<text:p text:style-name=\"P6\">"<<DDataItem::protectXML( wipeTags(root->m_text) )<<"</text:p><text:p text:style-name=\"P2\"/>\n";
	u<<"</draw:text-box>\n";

	outputPix(root, u);

	u<<"<presentation:notes>\n";
	u<<"<draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" draw:page-number=\"1\"/>\n";
	u<<"<draw:text-box presentation:style-name=\"pr3\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"14.518cm\" svg:height=\"11.411cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" presentation:class=\"notes \" presentation:placeholder=\"true\"/>\n";
	u<<"</presentation:notes>\n";
	u<<"</draw:page>\n";

	//outputData(item, s, level);
	//s<<"<text:ordered-list text:style-name=\"L1\">";
	if (root->countChildren() > 0)
	{
		for (unsigned int i = 0; i<root->countChildren(); i++)
			writeItem((DDataItem*) m_data->Item(root->childNum(i)), u, 0);
	}

	// write the end of document
	u<<"<presentation:settings presentation:stay-on-top=\"true\"/>\n";
	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<<"<draw:text-box draw:style-name=\"gr2\" draw:text-style-name=\"P3\" draw:layer=\"backgroundobjects\" svg:width=\"16.93cm\" svg:height=\"1.259cm\" svg:x=\"5.76cm\" svg:y=\"19.298cm\">";
	v<<"<text:p text:style-name=\"P3\">";
	v<<DDataItem::protectXML(m_data->m_fname)<<" "<<DDataItem::protectXML(m_data->m_sname);
	v<<"</text:p>";
	v<<"</draw:text-box>";
        if (!m_data->m_company.isEmpty())
        {
          v<<"<style:style style:name=\"company\" style:family=\"paragraph\">";
          v<<"<style:properties fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:text-align=\"end\" fo:text-indent=\"0cm\"/>";
          v<<"</style:style>";
          v<<"<draw:text-box draw:style-name=\"gr2\" draw:text-style-name=\"company\" draw:layer=\"backgroundobjects\" svg:width=\"16.93cm\" svg:height=\"1.259cm\" svg:x=\"0cm\" svg:y=\"0cm\">";
          v<<"<text:p text:style-name=\"company\">";
          v<<DDataItem::protectXML(m_data->m_company);
          v<<"</text:p>";
          v<<"</draw:text-box>";
        }
	v<<"<presentation:notes style:page-master-name=\"PM2\">";
	v<<"<draw:page-thumbnail presentation:style-name=\"lyt-cool-title\" draw:layer=\"backgroundobjects\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" presentation:class=\"page\"/>";
	v<<"<draw:text-box presentation:style-name=\"lyt-cool-notes\" draw:layer=\"backgroundobjects\" svg:width=\"14.518cm\" svg:height=\"11.41cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" presentation:class=\"notes\" presentation:placeholder=\"true\"/>";
	v<<"</presentation:notes> </style:master-page> </office:master-styles> </office:document-styles>";

	stylefile.close();

	// process the meta-data section
	// store the author name, title and time creation

	// title: DDataItem::protectXML(root->m_summary)
	// author: protectTex(m_data->m_fname)<<" "<<protectTex(m_data->m_sname)

	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>";
	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.sxi");
	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();

        if (cli)
        {
                KIO::del(KURL(path+"/META-INF"), false, true );
                KIO::del(KURL(path+"/Pictures"), false, true );
		QFile(path+"/mimetype").remove();
                QFile(path+"/content.xml").remove();
                QFile(path+"/meta.xml").remove();
                QFile(path+"/settings.xml").remove();
                QFile(path+"/styles.xml").remove();
        }
        else
        {
	// 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.sxi" );
	
	return true;
}

#include "kdissOOOimpress.moc"
