/***************************************************************************
    copyright            : (C) 2003-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 "csvexporter.h"
#include "../document.h"
#include "../collection.h"
#include "../filehandler.h"

#include <tdelocale.h>
#include <kdebug.h>
#include <klineedit.h>
#include <tdeconfig.h>

#include <tqgroupbox.h>
#include <tqcheckbox.h>
#include <tqlayout.h>
#include <tqbuttongroup.h>
#include <tqradiobutton.h>
#include <tqwhatsthis.h>

using Tellico::Export::CSVExporter;

CSVExporter::CSVExporter() : Tellico::Export::Exporter(),
    m_includeTitles(true),
    m_delimiter(TQChar(',')),
    m_widget(0) {
}

TQString CSVExporter::formatString() const {
  return i18n("CSV");
}

TQString CSVExporter::fileFilter() const {
  return i18n("*.csv|CSV Files (*.csv)") + TQChar('\n') + i18n("*|All Files");
}

TQString& CSVExporter::escapeText(TQString& text_) {
  bool quotes = false;
  if(text_.find('"') != -1) {
    quotes = true;
    // quotation marks will be escaped by using a double pair
    text_.replace('"', TQString::fromLatin1("\"\""));
  }
  // if the text contains quotes or the delimiter, it needs to be surrounded by quotes
  if(quotes || text_.find(m_delimiter) != -1) {
    text_.prepend('"');
    text_.append('"');
  }
  return text_;
}

bool CSVExporter::exec() {
  if(!collection()) {
    return false;
  }

  TQString text;

  Data::FieldVec fields = collection()->fields();
  Data::FieldVec::Iterator fIt;

  if(m_includeTitles) {
    for(fIt = fields.begin(); fIt != fields.end(); ++fIt) {
      TQString title = fIt->title();
      text += escapeText(title);
      if(!fIt.nextEnd()) {
        text += m_delimiter;
      }
    }
    text += '\n';
  }

  bool format = options() & Export::ExportFormatted;

  TQString tmp;
  for(Data::EntryVec::ConstIterator entryIt = entries().begin(); entryIt != entries().end(); ++entryIt) {
    for(fIt = fields.begin(); fIt != fields.end(); ++fIt) {
      tmp = entryIt->field(fIt->name(), format);
      text += escapeText(tmp);
      if(!fIt.nextEnd()) {
        text += m_delimiter;
      }
    }
    fIt = fields.begin();
    text += '\n';
  }

  return FileHandler::writeTextURL(url(), text, options() & ExportUTF8, options() & Export::ExportForce);
}

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

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

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

  m_checkIncludeTitles = new TQCheckBox(i18n("Include field titles as column headers"), box);
  m_checkIncludeTitles->setChecked(m_includeTitles);
  TQWhatsThis::add(m_checkIncludeTitles, i18n("If checked, a header row will be added with the "
                                             "field titles."));

  TQButtonGroup* delimiterGroup = new TQButtonGroup(0, TQt::Vertical, i18n("Delimiter"), box);
  TQGridLayout* m_delimiterGroupLayout = new TQGridLayout(delimiterGroup->layout());
  m_delimiterGroupLayout->setAlignment(TQt::AlignTop);
  TQWhatsThis::add(delimiterGroup, i18n("In addition to a comma, other characters may be used as "
                                       "a delimiter, separating each value in the file."));

  m_radioComma = new TQRadioButton(delimiterGroup);
  m_radioComma->setText(i18n("Comma"));
  m_radioComma->setChecked(true);
  TQWhatsThis::add(m_radioComma, i18n("Use a comma as the delimiter."));
  m_delimiterGroupLayout->addWidget(m_radioComma, 0, 0);

  m_radioSemicolon = new TQRadioButton( delimiterGroup);
  m_radioSemicolon->setText(i18n("Semicolon"));
  TQWhatsThis::add(m_radioSemicolon, i18n("Use a semi-colon as the delimiter."));
  m_delimiterGroupLayout->addWidget(m_radioSemicolon, 0, 1);

  m_radioTab = new TQRadioButton(delimiterGroup);
  m_radioTab->setText(i18n("Tab"));
  TQWhatsThis::add(m_radioTab, i18n("Use a tab as the delimiter."));
  m_delimiterGroupLayout->addWidget(m_radioTab, 1, 0);

  m_radioOther = new TQRadioButton(delimiterGroup);
  m_radioOther->setText(i18n("Other"));
  TQWhatsThis::add(m_radioOther, i18n("Use a custom string as the delimiter."));
  m_delimiterGroupLayout->addWidget(m_radioOther, 1, 1);

  m_editOther = new KLineEdit(delimiterGroup);
  m_editOther->setEnabled(m_radioOther->isChecked());
  TQWhatsThis::add(m_editOther, i18n("A custom string, such as a colon, may be used as a delimiter."));
  m_delimiterGroupLayout->addWidget(m_editOther, 1, 2);
  TQObject::connect(m_radioOther, TQ_SIGNAL(toggled(bool)),
                   m_editOther, TQ_SLOT(setEnabled(bool)));

  if(m_delimiter == TQChar(',')) {
    m_radioComma->setChecked(true);
  } else if(m_delimiter == TQChar(';')) {
    m_radioSemicolon->setChecked(true);
  } else if(m_delimiter == TQChar('\t')) {
    m_radioTab->setChecked(true);
  } else if(!m_delimiter.isEmpty()) {
    m_radioOther->setChecked(true);
    m_editOther->setEnabled(true);
    m_editOther->setText(m_delimiter);
  }

  l->addStretch(1);
  return m_widget;
}

void CSVExporter::readOptions(TDEConfig* config_) {
  TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
  m_includeTitles = group.readBoolEntry("Include Titles", m_includeTitles);
  m_delimiter = group.readEntry("Delimiter", m_delimiter);
}

void CSVExporter::saveOptions(TDEConfig* config_) {
  m_includeTitles = m_checkIncludeTitles->isChecked();
  if(m_radioComma->isChecked()) {
    m_delimiter = TQChar(',');
  } else if(m_radioSemicolon->isChecked()) {
    m_delimiter = TQChar(';');
  } else if(m_radioTab->isChecked()) {
    m_delimiter = TQChar('\t');
  } else {
    m_delimiter = m_editOther->text();
  }

  TDEConfigGroup group(config_, TQString::fromLatin1("ExportOptions - %1").arg(formatString()));
  group.writeEntry("Include Titles", m_includeTitles);
  group.writeEntry("Delimiter", m_delimiter);
}

#include "csvexporter.moc"
