/* ============================================================
 *
 * This file is a part of digiKam project
 * http://www.digikam.org
 *
 * Date        : 2007-11-25
 * Description : a bar used to search a string.
 * 
 * Copyright (C) 2007-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation;
 * either version 2, or (at your option)
 * any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * ============================================================ */

// TQt includes.

#include <tqcolor.h>
#include <tqpalette.h>
#include <tqpainter.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqtoolbutton.h>

// KDE includes.

#include <kapplication.h>
#include <kiconloader.h>
#include <kdialogbase.h>
#include <kconfig.h>

// Local includes.

#include "searchtextbar.h"
#include "searchtextbar.moc"

namespace Digikam
{

class DLineEditPriv
{
public:

    DLineEditPriv()
    {
        drawMsg = true;
    }

    bool    drawMsg;

    TQString message;
};

DLineEdit::DLineEdit(const TQString &msg, TQWidget *parent)
         : KLineEdit(parent)
{
    d = new DLineEditPriv;
    setMessage(msg);
}

DLineEdit::~DLineEdit()
{
    delete d;
}

TQString DLineEdit::message() const
{
    return d->message;
}

void DLineEdit::setMessage(const TQString &msg)
{
    d->message = msg;
    tqrepaint();
}

void DLineEdit::setText(const TQString &txt)
{
    d->drawMsg = txt.isEmpty();
    tqrepaint();
    KLineEdit::setText(txt);
}

void DLineEdit::drawContents(TQPainter *p)
{
    KLineEdit::drawContents(p);

    if (d->drawMsg && !hasFocus())
    {
        TQPen tmp = p->pen();
        p->setPen(palette().color(TQPalette::Disabled, TQColorGroup::Text));
        TQRect cr = contentsRect();

        // Add two pixel margin on the left side
        cr.rLeft() += 3;
        p->drawText(cr, AlignAuto | AlignVCenter, d->message);
        p->setPen( tmp );
    }
}

void DLineEdit::dropEvent(TQDropEvent *e)
{
    d->drawMsg = false;
    KLineEdit::dropEvent(e);
}

void DLineEdit::focusInEvent(TQFocusEvent *e)
{
    if (d->drawMsg)
    {
        d->drawMsg = false;
        tqrepaint();
    }
    TQLineEdit::focusInEvent(e);
}

void DLineEdit::focusOutEvent(TQFocusEvent *e)
{
    if (text().isEmpty())
    {
        d->drawMsg = true;
        tqrepaint();
    }
    TQLineEdit::focusOutEvent(e);
}

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

class SearchTextBarPriv
{
public:

    SearchTextBarPriv()
    {
        textQueryCompletion = false;
        searchEdit          = 0;
        clearButton         = 0;
    }

    bool         textQueryCompletion;

    TQToolButton *clearButton;

    DLineEdit   *searchEdit;
};

SearchTextBar::SearchTextBar(TQWidget *parent, const char* name, const TQString &msg)
             : TQWidget(parent, 0, TQt::WDestructiveClose)
{
    d = new SearchTextBarPriv;
    setFocusPolicy(TQ_NoFocus);
    setName(name);

    TQHBoxLayout *hlay = new TQHBoxLayout(this);

    d->clearButton = new TQToolButton(this);
    d->clearButton->setEnabled(false);
    d->clearButton->setAutoRaise(true);
    d->clearButton->setIconSet(kapp->iconLoader()->loadIcon("clear_left",
                               KIcon::Toolbar, KIcon::SizeSmall));

    d->searchEdit     = new DLineEdit(msg, this);
    KCompletion *kcom = new KCompletion;
    kcom->setOrder(KCompletion::Sorted);
    d->searchEdit->setCompletionObject(kcom, true);
    d->searchEdit->setAutoDeleteCompletionObject(true);
    d->searchEdit->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Minimum));

    hlay->setSpacing(0);
    hlay->setMargin(0);
    hlay->addWidget(d->searchEdit);
    hlay->addWidget(d->clearButton);

    connect(d->clearButton, TQT_SIGNAL(clicked()),
            d->searchEdit, TQT_SLOT(clear()));

    connect(d->searchEdit, TQT_SIGNAL(textChanged(const TQString&)),
            this, TQT_SLOT(slotTextChanged(const TQString&)));

    KConfig *config = kapp->config();
    config->setGroup(name + TQString(" Search Text Tool"));
    d->searchEdit->setCompletionMode((KGlobalSettings::Completion)config->readNumEntry("AutoCompletionMode", 
                                      (int)KGlobalSettings::CompletionAuto));
}

SearchTextBar::~SearchTextBar()
{
    KConfig *config = kapp->config();
    config->setGroup(name() + TQString(" Search Text Tool"));
    config->writeEntry("AutoCompletionMode", (int)d->searchEdit->completionMode());
    config->sync();

    delete d;
}

void SearchTextBar::setEnableTextQueryCompletion(bool b)
{
    d->textQueryCompletion = b;
}

bool SearchTextBar::textQueryCompletion() const
{
    return d->textQueryCompletion;
}

void SearchTextBar::setText(const TQString& text)
{
    d->searchEdit->setText(text);
}

TQString SearchTextBar::text() const
{
    return d->searchEdit->text();
}

DLineEdit *SearchTextBar::lineEdit() const
{
    return d->searchEdit;
}

void SearchTextBar::slotTextChanged(const TQString& text)
{
    if (d->searchEdit->text().isEmpty())
        d->searchEdit->unsetPalette();

    d->clearButton->setEnabled(text.isEmpty() ? false : true);

    emit signalTextChanged(text);
}

void SearchTextBar::slotSearchResult(bool match)
{
    if (d->searchEdit->text().isEmpty())
    {
        d->searchEdit->unsetPalette();
        return;
    }

    TQPalette pal = d->searchEdit->palette();
    pal.setColor(TQPalette::Active, TQColorGroup::Base,
                 match ? TQColor(200, 255, 200) :
                 TQColor(255, 200, 200));
    pal.setColor(TQPalette::Active, TQColorGroup::Text, TQt::black);
    d->searchEdit->setPalette(pal);

    // If search result match the text query, we put the text 
    // in auto-completion history.
    if (d->textQueryCompletion && match)
        d->searchEdit->completionObject()->addItem(d->searchEdit->text());
}

}  // namespace Digikam
