/***************************************************************************
                           datawidget.cpp  -  description
                             -------------------
    begin                : Tue Feb 12 2002
    copyright            : (C) 2002 by Scott Wheeler
    email                : wheeler@kde.org
***************************************************************************/

/***************************************************************************
 *   This program is free software; you can redistribute it and/or modify  *a
 *   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.                                   *
***************************************************************************/

#include <klocale.h>
#include <kpushbutton.h>
#include <kmessagebox.h>
#include <kdebug.h>

#include <qlayout.h>
#include <qlabel.h>

#include "datawidget.h"
#include "datawidget.moc"

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

DataWidget::DataWidget(QWidget *parent, const char *name ) : QWidget(parent, name)
{
  setupLayout();
}

DataWidget::~DataWidget()
{

}

CardList DataWidget::cardList() const
{
  QListViewItem *i = cardListView->firstChild();
  CardList list;

  while(i) {
    list.append(Card(i->text(0), i->text(1)));
    i = i->itemBelow();
  }

  return list;
}

void DataWidget::clear()
{
  cardListView->clear();
  frontBox->clear();
  backBox->clear();
}

void DataWidget::loadCards(const CardList &cards)
{
  for(CardList::ConstIterator it = cards.begin(); it != cards.end(); it++)
    cardListView->insertItem(new KListViewItem(cardListView, (*it).front(), (*it).back()));
}

void DataWidget::cut()
{
  if(frontBox && frontBox->hasSelectedText())
    frontBox->cut();
  else if(backBox && backBox->hasSelectedText())
    backBox->cut();
}

void DataWidget::copy()
{
  if(frontBox && frontBox->hasSelectedText())
    frontBox->copy();
  else if(backBox && backBox->hasSelectedText())
    backBox->copy();
}

bool DataWidget::hasSelectedText() const
{
  return frontBox && backBox && (frontBox->hasSelectedText() || backBox->hasSelectedText());
}

////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

void DataWidget::setupLayout()
{
  QVBoxLayout *layout = new QVBoxLayout(this, 0, 2 , "layout");

  cardListView = new KListView(this, "cardListView");
  cardListView->addColumn(i18n("Front"));
  cardListView->addColumn(i18n("Card backside", "Back"));

  cardListView->setFullWidth(true);
  cardListView->setAllColumnsShowFocus(true);

  layout->addWidget(cardListView);

  connect(cardListView, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(changeSelection(QListViewItem *)));

  QGridLayout *labelLayout = new QGridLayout(2, 2, 2, "labelLayout"); // rows, columns, spacing, name
  layout->addLayout(labelLayout);

  QLabel *frontLabel = new QLabel(i18n("Front"), this, "frontLabel");
  frontLabel->setAlignment(Qt::AlignHCenter);
  labelLayout->addWidget(frontLabel, 0, 0);

  QLabel *backLabel = new QLabel(i18n("Card backside", "Back"), this, "backLabel");
  backLabel->setAlignment(Qt::AlignHCenter);
  labelLayout->addWidget(backLabel , 0, 1);

  frontBox = new KLineEdit(this, "frontBox");
  labelLayout->addWidget(frontBox, 1, 0);

  backBox = new KLineEdit(this, "backBox");
  labelLayout->addWidget(backBox, 1, 1);

  connect(frontBox, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
  connect(frontBox, SIGNAL(returnPressed()), backBox, SLOT(setFocus()));

  connect(backBox, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
  connect(backBox, SIGNAL(returnPressed()), this, SLOT(addCard()));
  connect(backBox, SIGNAL(returnPressed()), frontBox, SLOT(setFocus()));

  frontBox->installEventFilter(this);
  backBox->installEventFilter(this);

  QHBoxLayout *buttonLayout = new QHBoxLayout(layout, 2);
  //  layout->addLayout(buttonLayout);

  KPushButton *addCardButton = new KPushButton(i18n("Add Card"), this, "addCardButton");
  buttonLayout->addWidget(addCardButton);
  KPushButton *deleteCardButton = new KPushButton(i18n("Delete Card"), this, "deleteCardButton");
  buttonLayout->addWidget(deleteCardButton);
  KPushButton *updateCardButton = new KPushButton(i18n("Update Card"), this, "updateCardButton");
  buttonLayout->addWidget(updateCardButton);

  connect(addCardButton, SIGNAL(clicked()), this, SLOT(addCard()));
  connect(deleteCardButton, SIGNAL(clicked()), this, SLOT(deleteCard()));
  connect(updateCardButton, SIGNAL(clicked()), this, SLOT(updateCard()));
}

// This should be the same as QuizWidget::eventFilter() -- I'm just too lazy at the 
// moment to create a base class for QuizWidget and DataWidget that has just this.

bool DataWidget::eventFilter(QObject *object, QEvent *event)
{
  if(event && event->type() == QEvent::FocusIn) {
    if(KLineEdit *lineEdit = dynamic_cast<KLineEdit *>(object))
      emit(lineEditFocusIn(lineEdit));
  }
  if(event && event->type() == QEvent::FocusOut) {
    QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
    if(dynamic_cast<KLineEdit *>(object) && focusEvent->reason() != QFocusEvent::Popup)
      emit(lineEditFocusOut());
  }
  return QWidget::eventFilter(object, event);
}

////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////

void DataWidget::changeSelection(QListViewItem *item)
{
  frontBox->setText(item->text(0));
  backBox->setText(item->text(1));
}

void DataWidget::addCard()
{
  if(frontBox->text().stripWhiteSpace().isEmpty() || backBox->text().stripWhiteSpace().isEmpty()) {
    // KMessageBox::sorry(this, i18n("You must enter text for both the front and back of the card."));
  }
  else {
    cardListView->insertItem(new KListViewItem(cardListView, frontBox->text(), backBox->text()));
    frontBox->clear();
    backBox->clear();
    frontBox->setFocus();
    emit(dataChanged());
  }
}

void DataWidget::deleteCard()
{
  delete(cardListView->currentItem());
  frontBox->clear();
  backBox->clear();
  frontBox->setFocus();
  emit(dataChanged());
}

void DataWidget::updateCard()
{
  if (cardListView->currentItem()) {
    cardListView->currentItem()->setText(0, frontBox->text());
    cardListView->currentItem()->setText(1, backBox->text());
    frontBox->setFocus();
    emit(dataChanged());
  }
}
