/*
    irceditaccountwidget.cpp - IRC Account Widget

    Copyright (c) 2005      by Tommi Rantala  <tommi.rantala@cs.helsinki.fi>
    Copyright (c) 2003      by Olivier Goffart  <ogoffart @ kde.org>
    Copyright (c) 2003      by Jason Keirstead  <jason@keirstead.org>
    Kopete    (c) 2003-2005 by the Kopete developers  <kopete-devel@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 "irceditaccountwidget.h"

#include "ircaccount.h"
#include "ircusercontact.h"
#include "ircprotocol.h"
#include "kcodecaction.h"

#include "kircengine.h"

#include "kopetepasswordwidget.h"

#include <tdemessagebox.h>
#include <tdelocale.h>
#include <tdelistview.h>
#include <kdebug.h>
#include <kextsock.h>
#include <tdeconfig.h>
#include <tdeglobal.h>
#include <kcharsets.h>

#include <tqlabel.h>
#include <tqpopupmenu.h>
#include <tqpushbutton.h>
#include <tqcheckbox.h>
#include <tqconnection.h>
#include <tqvalidator.h>
#include <tqcombobox.h>
#include <tqlistbox.h>
#include <tqlineedit.h>

IRCEditAccountWidget::IRCEditAccountWidget(IRCProtocol *proto, IRCAccount *ident, TQWidget *parent, const char * )
	  : IRCEditAccountBase(parent), KopeteEditAccountWidget(ident)
{
	mProtocol = proto;

	// default charset/encoding for new accounts: utf-8, see http://www.iana.org/assignments/character-sets
	int currentCodec = 106;

	if( account() )
	{
		TQString nickName = account()->mySelf()->nickName();
		TQString serverInfo = account()->accountId();

		mNickName->setText( nickName );
		mAltNickname->setText( account()->altNick() );
		mUserName->setText( account()->userName() );
		m_realNameLineEdit->setText( account()->realName() );

		partMessage->setText( account()->defaultPart() );
		quitMessage->setText( account()->defaultQuit() );
		if( account()->codec() )
			currentCodec = account()->codec()->mibEnum();

		mPasswordWidget->load ( &account()->password() );

		preferSSL->setChecked(account()->configGroup()->readBoolEntry("PreferSSL"));
		autoShowServerWindow->setChecked( account()->configGroup()->readBoolEntry("AutoShowServerWindow") );
		autoConnect->setChecked( static_cast<Kopete::Account*>(account())->excludeConnect() );

		TDEConfigGroup *config = account()->configGroup();

		serverNotices->setCurrentItem( config->readNumEntry( "ServerNotices", IRCAccount::ServerWindow ) - 1 );
		serverMessages->setCurrentItem( config->readNumEntry( "ServerMessages", IRCAccount::ServerWindow ) - 1 );
		informationReplies->setCurrentItem( config->readNumEntry( "InformationReplies", IRCAccount::ActiveWindow ) - 1 );
		errorMessages->setCurrentItem( config->readNumEntry( "ErrorMessages", IRCAccount::ActiveWindow ) - 1 );

		TQStringList cmds = account()->connectCommands();
		for( TQStringList::Iterator i = cmds.begin(); i != cmds.end(); ++i )
			new TQListViewItem( commandList, *i );

		const TQMap< TQString, TQString > replies = account()->customCtcpReplies();
		for( TQMap< TQString, TQString >::ConstIterator it = replies.begin(); it != replies.end(); ++it )
			new TQListViewItem( ctcpList, it.key(), it.data() );
	}

	mUserName->setValidator( new TQRegExpValidator( TQString::fromLatin1("^[^\\s]*$"), mUserName ) );
	mNickName->setValidator( new TQRegExpValidator( TQString::fromLatin1("^[^#+&][^\\s]*$"), mNickName ) );
	mAltNickname->setValidator( new TQRegExpValidator( TQString::fromLatin1("^[^#+&][^\\s]*$"), mAltNickname ) );

	charset->insertStringList( KCodecAction::supportedEncodings() );

	for (int i = 0; i < charset->count(); ++i) {
		TQString encoding = TDEGlobal::charsets()->encodingForName(charset->text(i));
		
		if (TDEGlobal::charsets()->codecForName(encoding)->mibEnum() == currentCodec) {
			charset->setCurrentItem( i );
			break;
		}
	}

	connect( commandList, TQ_SIGNAL( contextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ),
		this, TQ_SLOT( slotCommandContextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ) );

	connect( ctcpList, TQ_SIGNAL( contextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ),
		this, TQ_SLOT( slotCtcpContextMenu( TDEListView *, TQListViewItem *, const TQPoint & ) ) );

	connect( addButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotAddCommand() ) );
	connect( editButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT(slotEditNetworks() ) );
	connect( addReply, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotAddCtcp() ) );

	connect( network, TQ_SIGNAL( activated( const TQString & ) ),
		this, TQ_SLOT( slotUpdateNetworkDescription( const TQString &) ) );

	connect( IRCProtocol::protocol(), TQ_SIGNAL( networkConfigUpdated( const TQString & ) ),
		this, TQ_SLOT( slotUpdateNetworks( const TQString & ) ) );

	slotUpdateNetworks( TQString() );
}

IRCEditAccountWidget::~IRCEditAccountWidget()
{
}

IRCAccount *IRCEditAccountWidget::account ()
{
	return dynamic_cast<IRCAccount *>(KopeteEditAccountWidget::account () );
}

void IRCEditAccountWidget::slotUpdateNetworks( const TQString & selectedNetwork )
{
	network->clear();

	uint i = 0;
	TQStringList keys;
	for( TQDictIterator<IRCNetwork> it( IRCProtocol::protocol()->networks() ); it.current(); ++it )
		keys.append( it.currentKey() );

	keys.sort();

	TQStringList::Iterator end = keys.end();
	for( TQStringList::Iterator it = keys.begin(); it != end; ++it )
	{
		IRCNetwork * current = IRCProtocol::protocol()->networks()[*it];
		network->insertItem( current->name );
		if ( ( account() && account()->networkName() == current->name ) || current->name == selectedNetwork )
		{
			network->setCurrentItem( i );
			description->setText( current->description );
		}
		++i;
	}
}

void IRCEditAccountWidget::slotEditNetworks()
{
	IRCProtocol::protocol()->editNetworks( network->currentText() );
}

void IRCEditAccountWidget::slotUpdateNetworkDescription( const TQString &network )
{
	description->setText(
		IRCProtocol::protocol()->networks()[ network ]->description
	);
}

void IRCEditAccountWidget::slotCommandContextMenu( TDEListView *, TQListViewItem *item, const TQPoint &p )
{
	TQPopupMenu popup;
	popup.insertItem( i18n("Remove Command"), 1 );
	if( popup.exec( p ) == 1 )
		delete item;
}

void IRCEditAccountWidget::slotCtcpContextMenu( TDEListView *, TQListViewItem *item, const TQPoint &p )
{
	TQPopupMenu popup;
	popup.insertItem( i18n("Remove CTCP Reply"), 1 );
	if( popup.exec( p ) == 1 )
		delete item;
}

void IRCEditAccountWidget::slotAddCommand()
{
    if ( !commandEdit->text().isEmpty() )
    {
	new TQListViewItem( commandList, commandEdit->text() );
	commandEdit->clear();
    }
}

void IRCEditAccountWidget::slotAddCtcp()
{
    if (  !newCTCP->text().isEmpty() && !newReply->text().isEmpty() )
    {
	new TQListViewItem( ctcpList, newCTCP->text(), newReply->text() );
	newCTCP->clear();
	newReply->clear();
    }
}

TQString IRCEditAccountWidget::generateAccountId( const TQString &network )
{
	TDEConfig *config = TDEGlobal::config();
	TQString nextId = network;

	uint accountNumber = 1;
	while( config->hasGroup( TQString("Account_%1_%2").arg( m_protocol->pluginId() ).arg( nextId ) ) )
	{
		nextId = TQString::fromLatin1("%1_%2").arg( network ).arg( ++accountNumber );
	}
	kdDebug( 14120 ) << k_funcinfo << " ID IS: " << nextId << endl;
	return nextId;
}

Kopete::Account *IRCEditAccountWidget::apply()
{
	TQString nickName = mNickName->text();
	TQString networkName = network->currentText();

	if( !account() )
	{
		setAccount( new IRCAccount( mProtocol, generateAccountId(networkName), TQString(), networkName, nickName ) );

	}
	else
	{
		account()->setNickName( nickName );
		account()->setNetwork( networkName );
	}

	mPasswordWidget->save( &account()->password() );

	account()->setAltNick( mAltNickname->text() );
	account()->setUserName( mUserName->text() );
	account()->setRealName( m_realNameLineEdit->text() );
	account()->setDefaultPart( partMessage->text() );
	account()->setDefaultQuit( quitMessage->text() );
	account()->setAutoShowServerWindow( autoShowServerWindow->isChecked() );
	account()->setExcludeConnect( autoConnect->isChecked() );
	account()->setMessageDestinations( serverNotices->currentItem() + 1, serverMessages->currentItem() + 1,
		informationReplies->currentItem() + 1, errorMessages->currentItem() + 1
	);

	account()->configGroup()->writeEntry("PreferSSL", preferSSL->isChecked());

	TQStringList cmds;
	for( TQListViewItem *i = commandList->firstChild(); i; i = i->nextSibling() )
		cmds.append( i->text(0) );

	TQMap< TQString, TQString > replies;
	for( TQListViewItem *i = ctcpList->firstChild(); i; i = i->nextSibling() )
		replies[ i->text(0) ] = i->text(1);

	account()->setCustomCtcpReplies( replies );
	account()->setConnectCommands( cmds );

	KCharsets *c = TDEGlobal::charsets();
	account()->setCodec( c->codecForName( c->encodingForName( charset->currentText() ) ) );

	return account();
}


bool IRCEditAccountWidget::validateData()
{
	if( mNickName->text().isEmpty() )
		KMessageBox::sorry(this, i18n("<qt>You must enter a nickname.</qt>"), i18n("Kopete"));
	else
		return true;

	return false;
}

#include "irceditaccountwidget.moc"
