/* -------------------------------------------------------------

   kdictapplet.h (part of The KDE Dictionary Client)

   Copyright (C) 2001 Christian Gebauer <gebauer@kde.org>

   The applet is loosely based on the "Run" applet included in KDE.
   Copyright (c) 2000 Matthias Elter <elter@kde.org> (Artistic License)

   This file is distributed under the Artistic License.
   See LICENSE for details.

    -------------------------------------------------------------

    PopupBox        helper class
    DictApplet      a small kicker-applet

 ------------------------------------------------------------- */

#include <tqlabel.h>
#include <tqpushbutton.h>
#include <tqtimer.h>
#include <tqlayout.h>
#include <tqtooltip.h>

#include <tdeconfig.h>
#include <kcombobox.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <dcopclient.h>
#include <tdeapplication.h>
#include <kprocess.h>

#include "kdictapplet.h"

//*********  PopupBox  ********************************************

PopupBox::PopupBox()
 : TQHBox(0, 0, WStyle_Customize | WType_Popup ), popupEnabled(true)
{
}


PopupBox::~PopupBox()
{}


bool PopupBox::showBox()
{
  if (!popupEnabled)    // prevents that the popup is shown again immediatly
    return false;
  else {
    show();
    return true;
  }
}


void PopupBox::hideEvent(TQHideEvent *)
{
  emit(hidden());
  popupEnabled = false;
  TQTimer::singleShot(100, this, TQT_SLOT(enablePopup()));
}


void PopupBox::enablePopup()
{
  popupEnabled = true;
}


//*********  DictApplet  ********************************************

extern "C"
{
  KDE_EXPORT KPanelApplet* init(TQWidget *parent, const TQString& configFile)
  {
    TDEGlobal::locale()->insertCatalogue("kdictapplet");
    return new DictApplet(configFile, KPanelApplet::Stretch, 0, parent, "kdictapplet");
  }
}


DictApplet::DictApplet(const TQString& configFile, Type type, int actions, TQWidget *parent, const char *name)
  : KPanelApplet(configFile, type, actions, parent, name), waiting(0)
{
  // first the widgets for a horizontal panel
  baseWidget = new TQWidget(this);
  TQGridLayout *baseLay = new TQGridLayout(baseWidget,2,6,0,1);

  textLabel = new TQLabel(i18n("Dictionary:"), baseWidget);
  textLabel->setBackgroundOrigin(AncestorOrigin);
  TQFont f(textLabel->font());
  f.setPixelSize(12);
  textLabel->setFont(f);
  baseLay->addWidget(textLabel,0,1);
  TQToolTip::add(textLabel,i18n("Look up a word or phrase with Kdict"));

  iconLabel = new TQLabel(baseWidget);
  iconLabel->setBackgroundOrigin(AncestorOrigin);
  TQPixmap pm = TDEGlobal::iconLoader()->loadIcon("kdict", TDEIcon::Panel, TDEIcon::SizeSmall, TDEIcon::DefaultState, 0L, true);
  iconLabel->setPixmap(pm);
  baseLay->addWidget(iconLabel,1,0);
  iconLabel->setAlignment(TQt::AlignCenter | TQt::AlignVCenter);
  iconLabel->setFixedWidth(pm.width()+4);
  TQToolTip::add(iconLabel,i18n("Look up a word or phrase with Kdict"));

  f.setPixelSize(10);
  clipboardBtn = new TQPushButton(i18n("C"),baseWidget);
  clipboardBtn->setBackgroundOrigin(AncestorOrigin);
  clipboardBtn->setFont(f);
  clipboardBtn->setFixedSize(16,16);
  connect(clipboardBtn, TQT_SIGNAL(clicked()), TQT_SLOT(queryClipboard()));
  baseLay->addWidget(clipboardBtn,0,3);
  TQToolTip::add(clipboardBtn,i18n("Define selected text"));

  defineBtn = new TQPushButton(i18n("D"),baseWidget);
  defineBtn->setBackgroundOrigin(AncestorOrigin);
  defineBtn->setFont(f);
  defineBtn->setFixedSize(16,16);
  defineBtn->setEnabled(false);
  connect(defineBtn, TQT_SIGNAL(clicked()), TQT_SLOT(startDefine()));
  baseLay->addWidget(defineBtn,0,4);
  TQToolTip::add(defineBtn,i18n("Define word/phrase"));

  matchBtn = new TQPushButton(i18n("M"),baseWidget);
  matchBtn->setBackgroundOrigin(AncestorOrigin);
  matchBtn->setFont(f);
  matchBtn->setFixedSize(16,16);
  matchBtn->setEnabled(false);
  connect(matchBtn, TQT_SIGNAL(clicked()), TQT_SLOT(startMatch()));
  baseLay->addWidget(matchBtn,0,5);
  TQToolTip::add(matchBtn,i18n("Find matching definitions"));

  completionObject = new TDECompletion();

  internalCombo = new KHistoryCombo(baseWidget);
  internalCombo->setBackgroundOrigin(AncestorOrigin);
  internalCombo->setCompletionObject(completionObject);
  internalCombo->setFocus();
  internalCombo->clearEdit();
  internalCombo->lineEdit()->installEventFilter( this );
  connect(internalCombo, TQT_SIGNAL(returnPressed(const TQString&)), TQT_SLOT(startQuery(const TQString&)));
  connect(internalCombo, TQT_SIGNAL(textChanged(const TQString&)), TQT_SLOT(comboTextChanged(const TQString&)));
  TQToolTip::add(internalCombo,i18n("Look up a word or phrase with Kdict"));

  baseLay->addMultiCellWidget(internalCombo,1,1,1,5);

  baseLay->setColStretch(2,1);
	
  // widgets for a vertical panel
  verticalBtn = new TQPushButton(this);
  connect(verticalBtn, TQT_SIGNAL(pressed()), TQT_SLOT(showExternalCombo()));	
  TQToolTip::add(verticalBtn,i18n("Look up a word or phrase with Kdict"));

  popupBox = new PopupBox();
  popupBox->setFixedSize(160, 22);
  connect(popupBox, TQT_SIGNAL(hidden()), TQT_SLOT(externalComboHidden()));
  externalCombo = new KHistoryCombo(popupBox);
  externalCombo->setCompletionObject(completionObject);  
  connect(externalCombo, TQT_SIGNAL(returnPressed(const TQString&)), TQT_SLOT(startQuery(const TQString&)));
  externalCombo->setFixedSize(160, externalCombo->sizeHint().height());
  
  connect(internalCombo, TQT_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
          this, TQT_SLOT(updateCompletionMode(TDEGlobalSettings::Completion)));
  connect(externalCombo, TQT_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
          this, TQT_SLOT(updateCompletionMode(TDEGlobalSettings::Completion)));

  // restore history and completion list
  TDEConfig *c = config();
  c->setGroup("General");

  TQStringList list = c->readListEntry("Completion list");
  completionObject->setItems(list);
  int mode = c->readNumEntry("Completion mode", 
                             TDEGlobalSettings::completionMode());
  internalCombo->setCompletionMode((TDEGlobalSettings::Completion)mode);  
  externalCombo->setCompletionMode((TDEGlobalSettings::Completion)mode);  

  list = c->readListEntry("History list");
  internalCombo->setHistoryItems(list);  
  externalCombo->setHistoryItems(list);
}


DictApplet::~DictApplet()
{
  // save history and completion list
  TDEConfig *c = config();
  c->setGroup("General");

  TQStringList list = completionObject->items();
  c->writeEntry("Completion list", list);
  c->writeEntry("Completion mode", (int) internalCombo->completionMode());
  
  list = internalCombo->historyItems();
  c->writeEntry("History list", list);  
  c->sync();
  
  delete completionObject;
}


int DictApplet::widthForHeight(int height) const
{
  if (height >= 38)
    return textLabel->sizeHint().width()+55;
  else
    return textLabel->sizeHint().width()+25;
}


int DictApplet::heightForWidth(int width) const
{
  return width;
}


void DictApplet::resizeEvent(TQResizeEvent*)
{
  if (orientation() ==Qt::Horizontal) {
    verticalBtn->hide();
    baseWidget->show();
    baseWidget->setFixedSize(width(),height());

    if (height() < internalCombo->sizeHint().height())
      internalCombo->setFixedHeight(height());
    else
      internalCombo->setFixedHeight(internalCombo->sizeHint().height());

    if (height() >= 38) {
      textLabel->show();
      clipboardBtn->show();
      defineBtn->show();
      matchBtn->show();
      iconLabel->hide();
      internalCombo->setFixedWidth(width());
    } else {
      textLabel->hide();
      clipboardBtn->hide();
      defineBtn->hide();
      matchBtn->hide();
      iconLabel->show();
      internalCombo->setFixedWidth(width()-iconLabel->width()-1);
    }

    baseWidget->updateGeometry();
	} else 	{     // orientation() ==Qt::Vertical
    verticalBtn->show();
    baseWidget->hide();
    verticalBtn->setFixedSize(width(),width());

    TDEIcon::StdSizes sz = 	width() < 32 ?	TDEIcon::SizeSmall : (width() < 48 ? TDEIcon::SizeMedium : TDEIcon::SizeLarge);
    TQPixmap pm = TDEGlobal::iconLoader()->loadIcon("kdict", TDEIcon::Panel, sz, TDEIcon::DefaultState, 0L, true);
    verticalBtn->setPixmap(pm);
	}
}


bool DictApplet::eventFilter( TQObject *o, TQEvent * e)
{
  if (e->type() == TQEvent::MouseButtonRelease)
  	emit requestFocus();

  return KPanelApplet::eventFilter(o, e);
}


void DictApplet::sendCommand(const TQCString &fun, const TQString &data)
{
  if (waiting > 0) {
    waiting = 1;
    delayedFunc = fun.copy();
    delayedData = data;
    return;
  }

  DCOPClient *client = kapp->dcopClient();
  if (!client->isApplicationRegistered("kdict")) {
    TDEApplication::startServiceByDesktopName("kdict");
    waiting = 1;
    delayedFunc = fun.copy();
    delayedData = data;
    TQTimer::singleShot(100, this, TQT_SLOT(sendDelayedCommand()));
    return;
  } else {
    QCStringList list = client->remoteObjects("kdict");
    if (list.findIndex("KDictIface")==-1) {
      waiting = 1;
      delayedFunc = fun.copy();
      delayedData = data;
      TQTimer::singleShot(100, this, TQT_SLOT(sendDelayedCommand()));
      return;
    }
  }

  client->send("kdict","default",fun,data);
}


void DictApplet::sendDelayedCommand()
{
  if (waiting > 100) {   // timeout after ten seconds
    waiting = 0;
    return;
  }

  DCOPClient *client = kapp->dcopClient();
  if (!client->isApplicationRegistered("kdict")) {
    waiting++;
    TQTimer::singleShot(100, this, TQT_SLOT(sendDelayedCommand()));
    return;
  } else {
    QCStringList list = client->remoteObjects("kdict");
    if (list.findIndex("KDictIface")==-1) {
      waiting++;
      TQTimer::singleShot(100, this, TQT_SLOT(sendDelayedCommand()));
      return;
    }
  }

  client->send("kdict","default",delayedFunc,delayedData);
  waiting = 0;
}


void DictApplet::startQuery(const TQString &s)
{
  TQString query = s.stripWhiteSpace();
  if (query.isEmpty())
    return;

  internalCombo->addToHistory(query);
  externalCombo->addToHistory(query);
  internalCombo->clearEdit();
  externalCombo->clearEdit();

  sendCommand("definePhrase(TQString)",query);

  if (orientation() ==Qt::Vertical)
    popupBox->hide();
}


void DictApplet::comboTextChanged(const TQString &s)
{
  defineBtn->setEnabled(!s.isEmpty());
  matchBtn->setEnabled(!s.isEmpty());
}


void DictApplet::queryClipboard()
{
  sendCommand("defineClipboardContent()",TQString());
}


void DictApplet::startDefine()
{
  startQuery(internalCombo->currentText());
}


void DictApplet::startMatch()
{
  TQString query = internalCombo->currentText().stripWhiteSpace();
  internalCombo->addToHistory(query);
  externalCombo->addToHistory(query);
  internalCombo->clearEdit();
  externalCombo->clearEdit();

  sendCommand("matchPhrase(TQString)",query);
}


void DictApplet::showExternalCombo()
{
  TQPoint p;
  if (position() == pLeft)
    p = mapToGlobal(TQPoint(-popupBox->width()-1, 0));
  else
    p = mapToGlobal(TQPoint(width()+1, 0));
  popupBox->move(p);
  if (popupBox->showBox())
    externalCombo->setFocus();
  else
    verticalBtn->setDown(false);
}


void DictApplet::externalComboHidden()
{
  verticalBtn->setDown(false);
}

void DictApplet::updateCompletionMode(TDEGlobalSettings::Completion mode)
{
  internalCombo->setCompletionMode(mode);
  externalCombo->setCompletionMode(mode);
}

//--------------------------------

#include "kdictapplet.moc"