/***************************************************************************
    copyright            : (C) 2005-2006 by Robby Stephenson
    email                : robby@periapsis.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License as  *
 *   published by the Free Software Foundation;                            *
 *                                                                         *
 ***************************************************************************/

#include "onixexporter.h"
#include "xslthandler.h"
#include "tellicoxmlexporter.h"
#include "../collection.h"
#include "../filehandler.h"
#include "../tellico_utils.h"
#include "../imagefactory.h"
#include "../image.h"
#include "../tellico_debug.h"

#include <config.h>

#include <kstandarddirs.h>
#include <tdeapplication.h>
#include <kzip.h>
#include <tdeconfig.h>
#include <tdelocale.h>

#include <tqdom.h>
#include <tqfile.h>
#include <tqdatetime.h>
#include <tqbuffer.h>
#include <tqlayout.h>
#include <tqwhatsthis.h>
#include <tqcheckbox.h>
#include <tqgroupbox.h>

using Tellico::Export::ONIXExporter;

ONIXExporter::ONIXExporter() : Tellico::Export::Exporter(),
    m_handler(0),
    m_xsltFile(TQString::fromLatin1("tellico2onix.xsl")),
    m_includeImages(true),
    m_widget(0) {
}

ONIXExporter::ONIXExporter(Data::CollPtr coll_) : Tellico::Export::Exporter(coll_),
    m_handler(0),
    m_xsltFile(TQString::fromLatin1("tellico2onix.xsl")),
    m_includeImages(true),
    m_widget(0) {
}

ONIXExporter::~ONIXExporter() {
  delete m_handler;
  m_handler = 0;
}

TQString ONIXExporter::formatString() const {
  return i18n("ONIX Archive");
}

TQString ONIXExporter::fileFilter() const {
  return i18n("*.zip|Zip Files (*.zip)") + TQChar('\n') + i18n("*|All Files");
}

bool ONIXExporter::exec() {
  Data::CollPtr coll = collection();
  if(!coll) {
    return false;
  }

  TQCString xml = text().utf8(); // encoded in utf-8

  TQByteArray data;
  TQBuffer buf(data);

  KZip zip(TQT_TQIODEVICE(&buf));
  zip.open(IO_WriteOnly);
  zip.writeFile(TQString::fromLatin1("onix.xml"), TQString(), TQString(), xml.length(), xml);

  // use a dict for fast random access to keep track of which images were written to the file
  if(m_includeImages) { // for now, we're ignoring (options() & Export::ExportImages)
    const TQString cover = TQString::fromLatin1("cover");
    StringSet imageSet;
    for(Data::EntryVec::ConstIterator it = entries().begin(); it != entries().end(); ++it) {
      const Data::Image& img = ImageFactory::imageById(it->field(cover));
      if(!img.isNull() && !imageSet.has(img.id())
         && (img.format() == "JPEG" || img.format() == "JPG" || img.format() == "GIF")) { /// onix only understands jpeg and gif
        TQByteArray ba = img.byteArray();
        zip.writeFile(TQString::fromLatin1("images/") + it->field(cover),
                      TQString(), TQString(), ba.size(), ba);
        imageSet.add(img.id());
      }
    }
  }

  zip.close();
  return FileHandler::writeDataURL(url(), data, options() & Export::ExportForce);
//  return FileHandler::writeTextURL(url(), text(),  options() & Export::ExportUTF8, options() & Export::ExportForce);
}

TQString ONIXExporter::text() {
  TQString xsltfile = locate("appdata", m_xsltFile);
  if(xsltfile.isNull()) {
    myDebug() << "ONIXExporter::text() - no xslt file for " << m_xsltFile << endl;
    return TQString();
  }

  Data::CollPtr coll = collection();
  if(!coll) {
    myDebug() << "ONIXExporter::text() - no collection pointer!" << endl;
    return TQString();
  }

  // notes about utf-8 encoding:
  // all params should be passed to XSLTHandler in utf8
  // input string to XSLTHandler should be in utf-8, EVEN IF DOM STRING SAYS OTHERWISE

  KURL u;
  u.setPath(xsltfile);
  // do NOT do namespace processing, it messes up the XSL declaration since
  // TQDom thinks there are no elements in the Tellico namespace and as a result
  // removes the namespace declaration
  TQDomDocument dom = FileHandler::readXMLFile(u, false);
  if(dom.isNull()) {
    myDebug() << "ONIXExporter::text() - error loading xslt file: " << xsltfile << endl;
    return TQString();
  }

  // the stylesheet prints utf-8 by default, if using locale encoding, need
  // to change the encoding attribute on the xsl:output element
  if(!(options() & Export::ExportUTF8)) {
    XSLTHandler::setLocaleEncoding(dom);
  }

  delete m_handler;
  m_handler = new XSLTHandler(dom, TQFile::encodeName(xsltfile));

  TQDateTime now = TQDateTime::currentDateTime();
  m_handler->addStringParam("sentDate", now.toString(TQString::fromLatin1("yyyyMMddhhmm")).utf8());

  m_handler->addStringParam("version", VERSION);

  GUI::CursorSaver cs(TQt::waitCursor);

  // now grab the XML
  TellicoXMLExporter exporter(coll);
  exporter.setEntries(entries());
  exporter.setIncludeImages(false); // do not include images in XML
// yes, this should be in utf8, always
  exporter.setOptions(options() | Export::ExportUTF8);
  TQDomDocument output = exporter.exportXML();
#if 0
  TQFile f(TQString::fromLatin1("/tmp/test.xml"));
  if(f.open(IO_WriteOnly)) {
    TQTextStream t(&f);
    t << output.toString();
  }
  f.close();
#endif
  return m_handler->applyStylesheet(output.toString());
}

TQWidget* ONIXExporter::widget(TQWidget* parent_, const char* name_/*=0*/) {
  if(m_widget && TQT_BASE_OBJECT(m_widget->parent()) == TQT_BASE_OBJECT(parent_)) {
    return m_widget;
  }

  m_widget = new TQWidget(parent_, name_);
  TQVBoxLayout* l = new TQVBoxLayout(m_widget);

  TQGroupBox* box = new TQGroupBox(1, Qt::Horizontal, i18n("ONIX Archive Options"), m_widget);
  l->addWidget(box);

  m_checkIncludeImages = new TQCheckBox(i18n("Include images in archive"), box);
  m_checkIncludeImages->setChecked(m_includeImages);
  TQWhatsThis::add(m_checkIncludeImages, i18n("If checked, the images in the document will be included "
                                             "in the zipped ONIX archive."));

  return m_widget;
}

void ONIXExporter::readOptions(TDEConfig* config_) {
  TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
  m_includeImages = group.readBoolEntry("Include Images", m_includeImages);
}

void ONIXExporter::saveOptions(TDEConfig* config_) {
  m_includeImages = m_checkIncludeImages->isChecked();

  TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
  group.writeEntry("Include Images", m_includeImages);
}

#include "onixexporter.moc"