/***************************************************************************
    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 "lineedit.h"

#include <kstdaction.h>
#include <kactioncollection.h>
#include <kspell.h>

#include <tqapplication.h>
#include <tqpainter.h>
#include <tqpopupmenu.h>

using Tellico::GUI::LineEdit;

LineEdit::LineEdit(TQWidget* parent_, const char* name_) : KLineEdit(parent_, name_)
    , m_drawHint(false)
    , m_allowSpellCheck(false)
    , m_enableSpellCheck(true)
    , m_spell(0) {
  m_spellAction = KStdAction::spelling(TQT_TQOBJECT(this), TQT_SLOT(slotCheckSpelling()), new KActionCollection(this));
}

void LineEdit::clear() {
  KLineEdit::clear();
  m_drawHint = true;
  tqrepaint();
}

void LineEdit::setText(const TQString& text_) {
  m_drawHint = text_.isEmpty();
  tqrepaint();
  KLineEdit::setText(text_);
}

void LineEdit::setHint(const TQString& hint_) {
  m_hint = hint_;
  m_drawHint = text().isEmpty();
  tqrepaint();
}

void LineEdit::focusInEvent(TQFocusEvent* event_) {
  if(m_drawHint) {
    m_drawHint = false;
    tqrepaint();
  }
  KLineEdit::focusInEvent(event_);
}

void LineEdit::focusOutEvent(TQFocusEvent* event_) {
  if(text().isEmpty()) {
    m_drawHint = true;
    tqrepaint();
  }
  KLineEdit::focusOutEvent(event_);
}

void LineEdit::drawContents(TQPainter* painter_) {
  // draw the regular line edit first
  KLineEdit::drawContents(painter_);

  // no need to draw anything else if in focus or no hint
  if(hasFocus() || !m_drawHint || m_hint.isEmpty() || !text().isEmpty()) {
    return;
  }

  // save current pen
  TQPen oldPen = painter_->pen();

  // follow lead of tdepim and amarok, use disabled text color
  painter_->setPen(palette().color(TQPalette::Disabled, TQColorGroup::Text));

  TQRect rect = contentsRect();
  // again, follow tdepim and amarok lead, and pad by 2 pixels
  rect.rLeft() += 2;
  painter_->drawText(rect, AlignAuto | AlignVCenter, m_hint);

  // reset pen
  painter_->setPen(oldPen);
}

TQPopupMenu* LineEdit::createPopupMenu() {
  TQPopupMenu* popup = KLineEdit::createPopupMenu();

  if(!popup) {
    return popup;
  }

  if(m_allowSpellCheck && echoMode() == TQLineEdit::Normal && !isReadOnly()) {
    popup->insertSeparator();

    m_spellAction->plug(popup);
    m_spellAction->setEnabled(m_enableSpellCheck && !text().isEmpty());
  }

  return popup;
}

void LineEdit::slotCheckSpelling() {
  delete m_spell;
  // re-use the action string to get translations
  m_spell = new KSpell(this, m_spellAction->text(),
                       TQT_TQOBJECT(this), TQT_SLOT(slotSpellCheckReady(KSpell*)), 0, true, true);

  connect(m_spell, TQT_SIGNAL(death()),
          TQT_SLOT(spellCheckerFinished()));
  connect(m_spell, TQT_SIGNAL(misspelling( const TQString &, const TQStringList &, unsigned int)),
          TQT_SLOT(spellCheckerMisspelling( const TQString &, const TQStringList &, unsigned int)));
  connect(m_spell, TQT_SIGNAL(corrected(const TQString &, const TQString &, unsigned int)),
          TQT_SLOT(spellCheckerCorrected(const TQString &, const TQString &, unsigned int)));
}

void LineEdit::slotSpellCheckReady(KSpell* spell) {
  spell->check(text());
  connect(spell, TQT_SIGNAL(done(const TQString&)), TQT_SLOT(slotSpellCheckDone(const TQString&)));
}

void LineEdit::slotSpellCheckDone(const TQString& newText) {
  if(newText != text()) {
    setText(newText);
  }
}

void LineEdit::spellCheckerFinished() {
  delete m_spell;
  m_spell = 0;
}

void LineEdit::spellCheckerMisspelling(const TQString &text, const TQStringList&, unsigned int pos) {
  setSelection(pos, pos + text.length());
}

void LineEdit::spellCheckerCorrected(const TQString& oldWord, const TQString& newWord, unsigned int pos) {
  if(oldWord != newWord) {
    setSelection(pos, pos + oldWord.length());
    insert(newWord);
  }
}

#include "lineedit.moc"
