/******************************************************************************
 * MODULE     : QTMPrintDialog.cpp
 * DESCRIPTION: 
 * COPYRIGHT  : (C) 2010 Miguel de Benito Delgado
 *******************************************************************************
 * This software falls under the GNU general public license version 3 or later.
 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 ******************************************************************************/

#include "QTMPrintDialog.hpp"

/*!
 * Constructs a QTMPrintDialog and sets up the connections that allow for 
 * asynchronous loading of printer configuration:
 * QTMPrinterSettings will emit QTMPrinterSettings::doneReading() after a call to 
 * QTMPrinterSettings::readFromSystemConfig() terminates, that is, after the 
 * command executed is done.
 *
 * @see QTMPrinterSettings 
 *
 * @todo Read the current printer settings from TeXmacs.
 */
QTMPrintDialog::QTMPrintDialog(QTMPrinterSettings* s, QDialog* parent) 
  : QDialog(parent), _settings(s) {
    
  setupUi(this);
    
  QObject::connect(_settings, SIGNAL(doneReading()), 
                   this, SLOT(updatePrinterCapabilities()));
  QObject::connect(printerCombo, SIGNAL(currentIndexChanged(const QString)),
                   _settings, SLOT(startReadingSystemConfig(const QString&)));
    

}


/*!
 * Updates the controls which depend on the capabilities of the selected
 * printer, that is: available paper sizes, color printing, and duplex printing.
 * To this purpose we use QTMPrinterSettings::getChoices().
 *
 * @fixme How can we translate the output from the system config? Must we?
 */
void
QTMPrintDialog::updatePrinterCapabilities() {
  int idx = 0;
  
  paperSizeCombo->clear();
  paperSizeCombo->addItems(_settings->getChoices(QTMPrinterSettings::PageSize, idx));
  paperSizeCombo->setCurrentIndex(idx);
  paperSizeLabel->setEnabled(paperSizeCombo->count() > 1);
  paperSizeCombo->setEnabled(paperSizeCombo->count() > 1);

  resolutionCombo->clear();
  resolutionCombo->addItems(_settings->getChoices(QTMPrinterSettings::Resolution, idx));
  resolutionCombo->setCurrentIndex(idx);
  resolutionLabel->setEnabled(resolutionCombo->count() > 1);
  resolutionCombo->setEnabled(resolutionCombo->count() > 1);

  if (_settings->getChoices(QTMPrinterSettings::Duplex, idx).size() > 1) {
    duplexCheck->setEnabled(true);
  } else {
    duplexCheck->setEnabled(false);
    duplexCheck->setChecked(false);
  }
  
  blackWhiteCheck->setEnabled(_settings->getChoices(QTMPrinterSettings::ColorModel, 
                                                    idx).size() > 1);
}

/*!
 * @todo Translate strings?
 * @fixme QPrinterInfo::availablePrinters() does not return the spool names, but
 * the printer names, which are useless to print with lpr.
 */
void
QTMPrintDialog::setupUi(QDialog *dia) {

  Ui::QTMPrintDialog::setupUi(dia);
  typedef QPair<QString, QString> printerPair;
  foreach (printerPair printer, _settings->availablePrinters())
    printerCombo->addItem(printer.first, printer.second);
  
  if(printerCombo->count() == 0)
    printerCombo->addItem("No printers available"); // TODO hide everything else

  // We use the QVariant field to retrieve the correct value later.
  orientationCombo->addItem("Portrait", QTMPrinterSettings::Portrait);
  orientationCombo->addItem("Landscape", QTMPrinterSettings::Landscape);
  orientationCombo->addItem("Reverse portrait", QTMPrinterSettings::ReversePortrait);
  orientationCombo->addItem("Reverse landscape", QTMPrinterSettings::ReverseLandscape);
  
  // We use the QVariant field to retrieve the correct value later.
  orderPagesCombo->addItem("Left-Right, Top-Bottom", QTMPrinterSettings::LR_TB);
  orderPagesCombo->addItem("Right-Left, Top-Bottom", QTMPrinterSettings::RL_TB);
  orderPagesCombo->addItem("Top-Bottom, Left-Right", QTMPrinterSettings::TB_LR);
  orderPagesCombo->addItem("Top-Bottom, Right-Left", QTMPrinterSettings::TB_RL);  
  orderPagesCombo->addItem("Left-Right, Bottom-Top", QTMPrinterSettings::LR_BT);
  orderPagesCombo->addItem("Right-Left, Bottom-Top", QTMPrinterSettings::RL_BT);
  orderPagesCombo->addItem("Bottom-Top, Left-Right", QTMPrinterSettings::BT_LR);
  orderPagesCombo->addItem("Bottom-Top, Right-Left", QTMPrinterSettings::BT_RL);
  
  // Force reading the printer settings for the first printer in the list. 
  _settings->startReadingSystemConfig(printerCombo->currentText());
}


/*!
 * Stores the values from the dialog into the QTMPrinterSettings object after the
 * user presses the "Accept" button.
 */
void 
QTMPrintDialog::accept() {
  
  _settings->printerName   = printerCombo->currentText();
  _settings->copyCount     = copiesInput->text().toInt();
  _settings->collateCopies = collatedCheck->isChecked();
  
  if (allPagesRadio->isChecked())
    _settings->firstPage = _settings->lastPage = 0;
  else {
    _settings->firstPage   = fromPageInput->text().toInt();
    _settings->lastPage    = toPageInput->text().toInt();  
  }
  _settings->printOddPages  = oddPagesCheck->isChecked();
  _settings->printEvenPages = evenPagesCheck->isChecked();
  _settings->paperSize      = paperSizeCombo->currentText();
  _settings->orientation    = (QTMPrinterSettings::PageOrientation)
            orientationCombo->itemData(orderPagesCombo->currentIndex()).toInt();
  _settings->duplex         = duplexCheck->isChecked();
  _settings->blackWhite     = blackWhiteCheck->isChecked();
  _settings->pagesPerSide   = pagesPerSideCombo->currentText().toInt();
  _settings->pagesOrder     = (QTMPrinterSettings::PagePrintingOrder) 
             orderPagesCombo->itemData(orderPagesCombo->currentIndex()).toInt();
  _settings->fitToPage      = fitToPageCheck->isChecked();
  _settings->blackWhite     = blackWhiteCheck->isChecked();
  
  QDialog::accept();
}

/*!
 *
 */
void QTMPrintDialog::reject()
{
  QDialog::reject();
}


/////////////////// Some cosmetic stuff follows ///////////////////


/*!
 * Disable the From: and To: fields in the dialog.
 *
 * @note We use this signal because toggled() would be fired by our call to
 *       setChecked inside on_*PageInput_textChanged()
 */
void QTMPrintDialog::on_allPagesRadio_clicked(bool on)
{
  if(on) {
    fromPageInput->setText("");
    toPageInput->setText("");
  }
  allPagesRadio->setChecked(on);
}

/*!
 * Enable the From: and To: fields in the dialog.
 */
void QTMPrintDialog::on_rangePagesRadio_clicked(bool on)
{
  if (on) {
    int f = (_settings->firstPage < 1) ? 1 : _settings->firstPage;
    int l = (_settings->lastPage < 1) ? 1 : _settings->lastPage;
    fromPageInput->setText(QString("%1").arg(f));
    toPageInput->setText(QString("%1").arg(l));
  }
  rangePagesRadio->setChecked(on);
}

void QTMPrintDialog::on_copiesInput_textChanged(const QString& text)
{
  (void) text;
  collatedCheck->setEnabled(text.toInt() > 1);
}

void QTMPrintDialog::on_fromPageInput_textChanged(const QString& text)
{
  (void) text;
  if (allPagesRadio->isChecked())
    rangePagesRadio->setChecked(true);
}

void QTMPrintDialog::on_toPageInput_textChanged(const QString& text) {
  (void) text;
  if (allPagesRadio->isChecked())
    rangePagesRadio->setChecked(true);
}

void QTMPrintDialog::on_oddPagesCheck_stateChanged(int state) {
  evenPagesCheck->setEnabled(state == Qt::Checked);
}

void QTMPrintDialog::on_evenPagesCheck_stateChanged(int state) {
  oddPagesCheck->setEnabled(state == Qt::Checked);
}
