//
// C++ Implementation: klshistorycombo
//
// Description:
//
//
// Author: Paulo Moura Guedes <moura@kdewebdev.org>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "klshistorycombo.h"
#include "klsconfig.h"

#include <tdeapplication.h>
#include <tdeconfig.h>
#include <tdecompletionbox.h>
#include <kdebug.h>
#include <tdestdaccel.h>
#include <kurldrag.h>
#include <tdeglobalsettings.h>


bool KLSHistoryCombo::items_saved_ = false;


KLSHistoryCombo::KLSHistoryCombo(TQWidget *parent, const char *name)
        : KHistoryCombo(parent, name)
{
    setMaxCount(KLSConfig::maxCountComboUrl());
    
    setDuplicatesEnabled(false);
    setAutoCompletion(false);

    connect(this, TQ_SIGNAL(activated(const TQString& )),
            this, TQ_SLOT(addToHistory(const TQString& )));
}

KLSHistoryCombo::~KLSHistoryCombo()
{}

void KLSHistoryCombo::init()
{
    loadItems();
}

void KLSHistoryCombo::saveItems()
{
    if(items_saved_)
        return;

    TQStringList items = historyItems();

    KLSConfig::setComboUrlHistory(items);
    KLSConfig::writeConfig();
    
    items_saved_ = true;
}

void KLSHistoryCombo::loadItems()
{
    clear();
    
    TQStringList items = KLSConfig::comboUrlHistory();

    bool block = signalsBlocked();
    blockSignals( true );

    setHistoryItems(items);
    blockSignals(block);

    completionObject()->setItems(items);

    setCompletionMode(TDEGlobalSettings::completionMode());
}

bool KLSHistoryCombo::eventFilter( TQObject *o, TQEvent *ev )
{
    // Handle Ctrl+Del/Backspace etc better than the TQt widget, which always
    // jumps to the next whitespace.
    TQLineEdit *edit = lineEdit();
    if ( o == edit )
    {
        int type = ev->type();
        if ( type == TQEvent::KeyPress )
        {
            TQKeyEvent *e = static_cast<TQKeyEvent*>( ev );

            if ( e->key() == Key_Return || e->key() == Key_Enter )
            {
                //m_modifier = e->state();
                return false;
            }

            int delete_word_back = TDEStdAccel::deleteWordBack().keyCodeQt();
            int delete_word_forward = TDEStdAccel::deleteWordForward().keyCodeQt();

            if ( KKey( e ) == KKey(delete_word_back) ||
                    KKey( e ) == KKey(delete_word_forward) ||
                    ((e->state() & ControlButton) &&
                     (e->key() == Key_Left || e->key() == Key_Right) ) )
            {
                selectWord(e);
                e->accept();
                return true;
            }
        }

        else if ( type == TQEvent::MouseButtonDblClick )
        {
            edit->selectAll();
            return true;
        }
    }
    return KComboBox::eventFilter( o, ev );
}

/*
   Handle Ctrl+Cursor etc better than the TQt widget, which always
   jumps to the next whitespace. This code additionally jumps to
   the next [/#?:], which makes more sense for URLs. The list of 
   chars that will stop the cursor are '/', '.', '?', '#', ':'.
*/
void KLSHistoryCombo::selectWord(TQKeyEvent *e)
{
    TQLineEdit* edit = lineEdit();
    TQString text = edit->text();
    int pos = edit->cursorPosition();
    int pos_old = pos;
    int count = 0;

    // TODO: make these a parameter when in tdelibs/tdeui...
    TQValueList<TQChar> chars;
    chars << TQChar('/') << TQChar('.') << TQChar('?') << TQChar('#') << TQChar(':');
    bool allow_space_break = true;

    if( e->key() == Key_Left || e->key() == Key_Backspace )
    {
        do
        {
            pos--;
            count++;
            if( allow_space_break && text[pos].isSpace() && count > 1 )
                break;
        }
        while( pos >= 0 && (chars.findIndex(text[pos]) == -1 || count <= 1) );

        if( e->state() & ShiftButton )
        {
            edit->cursorForward(true, 1-count);
        }
        else if(  e->key() == Key_Backspace )
        {
            edit->cursorForward(false, 1-count);
            TQString text = edit->text();
            int pos_to_right = edit->text().length() - pos_old;
            TQString cut = text.left(edit->cursorPosition()) + text.right(pos_to_right);
            edit->setText(cut);
            edit->setCursorPosition(pos_old-count+1);
        }
        else
        {
            edit->cursorForward(false, 1-count);
        }
    }
    else if( e->key() == Key_Right || e->key() == Key_Delete )
    {
        do
        {
            pos++;
            count++;
            if( allow_space_break && text[pos].isSpace() )
                break;
        }
        while( pos < (int) text.length() && chars.findIndex(text[pos]) == -1 );

        if( e->state() & ShiftButton )
        {
            edit->cursorForward(true, count+1);
        }
        else if(  e->key() == Key_Delete )
        {
            edit->cursorForward(false, -count-1);
            TQString text = edit->text();
            int pos_to_right = text.length() - pos - 1;
            TQString cut = text.left(pos_old) +
                          (pos_to_right > 0 ? text.right(pos_to_right) : TQString() );
            edit->setText(cut);
            edit->setCursorPosition(pos_old);
        }
        else
        {
            edit->cursorForward(false, count+1);
        }
    }
}

#include "klshistorycombo.moc"
