/***************************************************************************
                          console.cpp  -  description
                             -------------------
    begin                : Sun May 27 2001
    copyright            : (C) 2003 by Troy Corbin Jr.
    email                : tcorbin@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "console.moc"
#include "knightstextview.h"
#include "accel.h"
#include "tabmanager.h"

/* KDE */
#include <klineedit.h>
#include <kiconloader.h>
#include <tqregexp.h>
#include <tqstyle.h>

Console::Console(TQWidget *parent,
                 const char *name,
                 resource *Rsrc ) : TQVBox(parent,name)
{
  myResource = Rsrc;
  SelfMoving = false;
  TQStyle& Style = TQApplication::style();

  margin = Style.defaultFrameWidth();
  myTextView = new KnightsTextView( this, myResource );
  myLineEdit = new KLineEdit( this, "console_edit" );
	/* Configure misc */
	setBG();
	myTextView->setStaticBackground( false );

	connect( myLineEdit, TQ_SIGNAL( returnPressed( const TQString& ) ), this, TQ_SLOT( getText( const TQString& ) ) );
	connect( myResource->myAccel, TQ_SIGNAL( history_prev() ), this, TQ_SLOT( historyBackward() ) );
	connect( myResource->myAccel, TQ_SIGNAL( history_next() ), this, TQ_SLOT( historyForward() ) );
	connect( myResource->myAccel, TQ_SIGNAL( page_up() ), this, TQ_SLOT( pageUp() ) );
	connect( myResource->myAccel, TQ_SIGNAL( page_down() ), this, TQ_SLOT( pageDown() ) );
	connect( myResource->myAccel, TQ_SIGNAL( kibitz() ), this, TQ_SLOT( kibitz() ) );
	connect( myResource->myAccel, TQ_SIGNAL( whisper() ), this, TQ_SLOT( whisper() ) );
	connect( myResource->myAccel, TQ_SIGNAL( reply_tell() ), this, TQ_SLOT( replyPrivate() ) );
	connect( myResource->myAccel, TQ_SIGNAL( reply_channel() ), this, TQ_SLOT( replyChannel() ) );
	connect( myResource->myAccel, TQ_SIGNAL( focus() ), this, TQ_SLOT( getFocus() ) );
	connect( myResource->myAccel, TQ_SIGNAL( focus( const TQChar& ) ), this, TQ_SLOT( getFocus( const TQChar& ) ) );

	myTextView->show();
	myLineEdit->show();
	show();
}
Console::~Console()
{
	delete myLineEdit;
	delete myTextView;
}
///////////////////////////////////////
//
//	Console::pageDown
//
///////////////////////////////////////
void Console::pageDown( void )
{
	myTextView->pageMove( TQt::Key_PageDown );
}
///////////////////////////////////////
//
//	Console::pageUp
//
///////////////////////////////////////
void Console::pageUp( void )
{
	myTextView->pageMove();
}
///////////////////////////////////////
//
//	Console::recvCMD
//
///////////////////////////////////////
void Console::recvCMD( const Command& command )
{
	TQString modText; /* this will hold the text to append after it has been modified with anchors */

	switch(((Command)command).getCommand())
	{
		case CMD_Append_To_Console:
			if( myTextView->contentsY() >= ( myTextView->contentsHeight() - myTextView->visibleHeight() - 12 ) )
			{
				modText = insertTags(((Command)command).getData());
				myTextView->append(modText);
				myTextView->scrollToBottom();
			}
			else
			{
				modText = insertTags(((Command)command).getData());
				myTextView->append(modText);
			}
			break;
		case CMD_Set_Input:
			myLineEdit->setText( ((Command)command).getData() );
			if( !myLineEdit->hasFocus() )
				getFocus();
			break;
		case CMD_Set_Src_Tell:
			lastPrivateSource = ((Command)command).getData();
			break;
		case CMD_Set_Src_Channel:
			lastChannelSource = ((Command)command).getData();
			break;
		default:
			break;
	}
}
///////////////////////////////////////
//
//	Console::getText
//
///////////////////////////////////////
void Console::getText( const TQString &text )
{
	/* Append this text into our history */
	history.append( text );
	if( history.count() > 100 )
		history.remove( history.begin() );
	historyIT = history.end();
	emit sendCMD( Command( 0, CMD_Send_To_ICS, text ) );
	myLineEdit->clear();
}
///////////////////////////////////////
//
//	Console::historyBack
//
///////////////////////////////////////
void Console::historyBackward( void )
{
	if( history.count() && ( historyIT != history.begin() ) )
	{
		historyIT--;
		myLineEdit->setText( (*historyIT) );
	}
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::historyForward
//
///////////////////////////////////////
void Console::historyForward( void )
{
	if( history.count() && ( historyIT != history.end() ) )
	{
		historyIT++;
		myLineEdit->setText( (*historyIT) );
	}
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::replyPrivate
//
///////////////////////////////////////
void Console::replyPrivate( void )
{
	myLineEdit->setText( TQString( "tell %1 " ).arg( lastPrivateSource ) );
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::replyChannel
//
///////////////////////////////////////
void Console::replyChannel( void )
{
	myLineEdit->setText( TQString( "tell %1 " ).arg( lastChannelSource ) );
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::kibitz
//
///////////////////////////////////////
void Console::kibitz( void )
{
	myLineEdit->setText( TQString( "kibitz " ) );
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::whisper
//
///////////////////////////////////////
void Console::whisper( void )
{
	myLineEdit->setText( TQString( "whisper " ) );
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::getFocus
//
///////////////////////////////////////
void Console::getFocus( void )
{
	if( myLineEdit->hasFocus() )
	{
		getText( myLineEdit->text() );
	}
	setActiveWindow();
	myResource->tabManager->showTab( this );
	myLineEdit->setFocus();
}
void Console::getFocus( const TQChar &c )
{
	myLineEdit->setText( myLineEdit->text() + TQString( c ) );
	if( !myLineEdit->hasFocus() )
		getFocus();
}
///////////////////////////////////////
//
//	Console::setBG
//
///////////////////////////////////////
void Console::setBG( void )
{
	myTextView->setPaper( TQBrush( myResource->COLOR_Background ) );
}

///////////////////////////////////////
//
//	Console::insertTags(TQString data)
//
///////////////////////////////////////
TQString Console::insertTags(TQString data)
{
	TQRegExp hyperLinks("(http://(?:.)+(?:\\.(?:[^\\s\\r\\t<])+)+)");
	TQRegExp mailLinks("\\b((?:\\w|\\d)+\\@(?:\\w|\\d)+(?:\\.(?:\\d|\\w)+)+)\\b");
	int pos = 0;

	pos = hyperLinks.search(data, 0);
	if(pos >= 0)
	{
		data.replace(hyperLinks, "<A HREF=\"" + hyperLinks.cap(0) + "\">" + hyperLinks.cap(0) + "</A>");
	}
	pos = mailLinks.search(data, 0);
	if(pos >= 0)
	{
		data.replace(mailLinks, "<A HREF=\"mailto:" + mailLinks.cap(0) + "\">" + mailLinks.cap(0) + "</A>");
	}
	return data;
}
