/***************************************************************************
 *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>                  *
 *   Copyright (C) 2007 by Pino Toscano <pino@kde.org>                     *
 *                                                                         *
 *   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 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "searchlineedit.h"

// local includes
#include "core/document.h"

// qt/kde includes
#include <qapplication.h>
#include <qtimer.h>
#include <kcolorscheme.h>

SearchLineEdit::SearchLineEdit( QWidget * parent, Okular::Document * document )
    : KLineEdit( parent ), m_document( document ), m_minLength( 0 ),
      m_caseSensitivity( Qt::CaseInsensitive ),
      m_searchType( Okular::Document::AllDocument ), m_id( -1 ),
      m_moveViewport( false ), m_changed( false ), m_fromStart( true )
{
    setObjectName( "SearchLineEdit" );
    setClearButtonShown( true );

    // a timer to ensure that we don't flood the document with requests to search
    m_inputDelayTimer = new QTimer(this);
    m_inputDelayTimer->setSingleShot(true);
    connect( m_inputDelayTimer, SIGNAL( timeout() ),
             this, SLOT( startSearch() ) );

    connect(this, SIGNAL( textChanged(const QString &) ), this, SLOT( slotTextChanged(const QString &) ));
    connect(document, SIGNAL( searchFinished(int, Okular::Document::SearchStatus) ), this, SLOT( searchFinished(int, Okular::Document::SearchStatus) ));
}

void SearchLineEdit::clearText()
{
    clear();
}

void SearchLineEdit::setSearchCaseSensitivity( Qt::CaseSensitivity cs )
{
    m_caseSensitivity = cs;
    m_changed = true;
}

void SearchLineEdit::setSearchMinimumLength( int length )
{
    m_minLength = length;
    m_changed = true;
}

void SearchLineEdit::setSearchType( Okular::Document::SearchType type )
{
    if ( type == m_searchType )
        return;

    m_searchType = type;
    m_changed = ( m_searchType != Okular::Document::NextMatch && m_searchType != Okular::Document::PreviousMatch );
}

void SearchLineEdit::setSearchId( int id )
{
    m_id = id;
    m_changed = true;
}

void SearchLineEdit::setSearchColor( const QColor &color )
{
    m_color = color;
    m_changed = true;
}

void SearchLineEdit::setSearchMoveViewport( bool move )
{
    m_moveViewport = move;
}

void SearchLineEdit::setSearchFromStart( bool fromStart )
{
    m_fromStart = fromStart;
}

void SearchLineEdit::restartSearch()
{
    m_inputDelayTimer->stop();
    m_inputDelayTimer->start( 500 );
    m_changed = true;
}

void SearchLineEdit::findNext()
{
    if ( m_id == -1 || m_searchType != Okular::Document::NextMatch )
        return;

    if ( !m_changed )
        m_document->continueSearch( m_id, m_searchType );
    else
        startSearch();
}

void SearchLineEdit::findPrev()
{
    if ( m_id == -1 || m_searchType != Okular::Document::PreviousMatch )
        return;

    if ( !m_changed )
        m_document->continueSearch( m_id, m_searchType );
    else
        startSearch();
}

void SearchLineEdit::slotTextChanged( const QString & text )
{
    QPalette pal = palette();
    const int textLength = text.length();
    if ( textLength > 0 && textLength < m_minLength )
    {
        const KColorScheme scheme( QPalette::Active, KColorScheme::View );
        pal.setBrush( QPalette::Base, scheme.background( KColorScheme::NegativeBackground ) );
        pal.setBrush( QPalette::Text, scheme.foreground( KColorScheme::NegativeText ) );
    }
    else
    {
        const QPalette qAppPalette = QApplication::palette();
        pal.setColor( QPalette::Base, qAppPalette.color( QPalette::Base ) );
        pal.setColor( QPalette::Text, qAppPalette.color( QPalette::Text ) );
    }
    setPalette( pal );
    restartSearch();
}

void SearchLineEdit::startSearch()
{
    if ( m_id == -1 || !m_color.isValid() )
        return;

    if ( m_changed && ( m_searchType == Okular::Document::NextMatch || m_searchType == Okular::Document::PreviousMatch ) )
    {
        m_document->resetSearch( m_id );
    }
    m_changed = false;
    // search text if have more than 3 chars or else clear search
    QString thistext = text();
    if ( thistext.length() >= qMax( m_minLength, 1 ) )
    {
        m_document->searchText( m_id, thistext, m_fromStart, m_caseSensitivity,
                                m_searchType, m_moveViewport, m_color );
    }
    else
        m_document->resetSearch( m_id );
}

void SearchLineEdit::searchFinished( int id, Okular::Document::SearchStatus endStatus )
{
    // ignore the searches not started by this search edit
    if ( id != m_id )
        return;

    // if not found, use warning colors
    if ( endStatus == Okular::Document::NoMatchFound )
    {
        QPalette pal = palette();
        const KColorScheme scheme( QPalette::Active, KColorScheme::View );
        pal.setBrush( QPalette::Base, scheme.background( KColorScheme::NegativeBackground ) );
        pal.setBrush( QPalette::Text, scheme.foreground( KColorScheme::NegativeText ) );
        setPalette( pal );
    }
    else
    {
        QPalette pal = palette();
        const QPalette qAppPalette = QApplication::palette();
        pal.setColor( QPalette::Base, qAppPalette.color( QPalette::Base ) );
        pal.setColor( QPalette::Text, qAppPalette.color( QPalette::Text ) );
        setPalette( pal );
    }
}

#include "searchlineedit.moc"
