//
// C++ Implementation: fieldtextedit
//
// Description: 
//
//
// Author: Thach Nguyen <thach.nguyen@rmit.edu.au>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
// Based on KLineEdit
//

#include "fieldtextedit.h"
#include <iostream>

namespace GUI {

FieldTextEdit::FieldTextEdit(QWidget *parent, const char *name)
 : KTextEdit(parent, name)
{
	completionBox = 0L;
}

FieldTextEdit::~FieldTextEdit()
{
}

void FieldTextEdit::keyPressEvent ( QKeyEvent * e ){
	KTextEdit::keyPressEvent( e );
	int para, index;
	getCursorPosition (&para, &index );
	QString txt = (this->text(para));
	txt = txt.left(txt.length()-1);
	makeCompletion(txt);
}

void FieldTextEdit::makeCompletion( const QString& text ) { 
	KCompletion *comp = compObj();
	KGlobalSettings::Completion mode = completionMode();

	if ( !comp || mode == KGlobalSettings::CompletionNone )
		return;  // No completion object...

	QString match = comp->makeCompletion( text );
	if ( mode == KGlobalSettings::CompletionPopup || mode == KGlobalSettings::CompletionPopupAuto )
	{
		if ( match.isNull() )
		{
			if ( completionBox )
			{
				completionBox->hide();
				completionBox->clear();
			}
		}
		else
			setCompletedItems( comp->allMatches() );
	}
	else // Auto,  ShortAuto (Man) and Shell
	{
		// all other completion modes
		// If no match or the same match, simply return without completing.
		if ( match.isNull() || match == text )
			return;

//		if ( mode != KGlobalSettings::CompletionShell )
//			setUserSelection(false);
//		if ( d->autoSuggest )
//			setCompletedText( match );
	}
	
}


KCompletionBox * FieldTextEdit::getCompletionBox( bool create ){
	if ( create && !completionBox ) {
		completionBox = new KCompletionBox( this, "completion box" ) ;
		completionBox->setFont(font());
		connect( completionBox, SIGNAL(highlighted( const QString& )), SLOT(setTextWorkaround( const QString& )) );
		connect( completionBox, SIGNAL(userCancelled( const QString& )), SLOT(userCancelled( const QString& )) );
		
		connect(completionBox, SIGNAL( activated( const QString& )), SLOT(completionSelect( const QString& ) ) );
	}

	return completionBox;	
}

void FieldTextEdit::setCompletedItems( const QStringList& items ){
	QString txt;
//	if ( completionBox && completionBox->isVisible() ) {
		// The popup is visible already - do the matching on the initial string,
		// not on the currently selected one.
//		txt = completionBox->cancelledText();
//	} else {
		int para, index;
		getCursorPosition (&para, &index );
		txt = text(para);
		txt = txt.stripWhiteSpace();
//	}
	if ( !items.isEmpty() && !(items.count() == 1 && txt == items.first()) )
	{
		// create completion box if non-existent
		getCompletionBox();

		if ( completionBox->isVisible() )
		{
			bool wasSelected = completionBox->isSelected( completionBox->currentItem() );
			const QString currentSelection = completionBox->currentText();
			completionBox->setItems( items );
			QListBoxItem* item = completionBox->findItem( currentSelection, Qt::ExactMatch );
			// If no item is selected, that means the listbox hasn't been manipulated by the user yet,
			// because it's not possible otherwise to have no selected item. In such case make
			// always the first item current and unselected, so that the current item doesn't jump.
			if( !item || !wasSelected )
			{
				wasSelected = false;
				item = completionBox->item( 0 );
			}
			if ( item )
			{
				completionBox->blockSignals( true );
				completionBox->setCurrentItem( item );
				completionBox->setSelected( item, wasSelected );
				completionBox->blockSignals( false );
			}
			if ( !txt.isEmpty() )
				completionBox->setCancelledText( txt );
		}
		else // completion box not visible yet -> show it
		{
			if ( !txt.isEmpty() )
				completionBox->setCancelledText( txt );
			completionBox->setItems( items );
			completionBox->popup();
		}

/*		if ( d->autoSuggest && autoSuggest )
		{
			int index = items.first().find( txt );
			QString newText = items.first().mid( index );
			setUserSelection(false);
			setCompletedText(newText,true);
		}
*/
	}
	else
	{
		if ( completionBox && completionBox->isVisible() )
			completionBox->hide();
	}
	
}

void FieldTextEdit::setTextWorkaround( const QString& txt){
	int para, index;
	getCursorPosition (&para, &index );	
	removeParagraph (para );
	insertParagraph (txt, para);	
	setCursorPosition(para,txt.length());
}

void FieldTextEdit::userCancelled( const QString& txt){
	if ( completionMode() != KGlobalSettings::CompletionPopupAuto )
	{
		int para, index;
		getCursorPosition (&para, &index );	
		removeParagraph (para );
		insertParagraph (txt, para);
		setCursorPosition(para,txt.length());
	}
}

void FieldTextEdit::completionSelect(const QString & txt){
	int para, index;
	getCursorPosition (&para, &index );	
	removeParagraph (para );
	insertParagraph (txt, para);
	setCursorPosition(para,txt.length());
}

void  FieldTextEdit::setCompletedText (const QString &txt){
	int para, index;
	getCursorPosition (&para, &index );	
	removeParagraph (para );
	insertParagraph (txt, para);
	setCursorPosition(para,txt.length());
}

}
#include "fieldtextedit.moc"
