/***************************************************************************
*   Copyright (C) 2004 by Christoph Thielecke                             *
*   crissi99@gmx.de                                                       *
*                                                                         *
*   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.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
//BEGIN includes
#include "newprofiledialog.h"
#include <kcombobox.h>
#include <klineedit.h>
#include <tqcheckbox.h>
#include <kurlrequester.h>
#include <tdemessagebox.h>
#include <tqlistbox.h>
#include <klineedit.h>
#include <klineeditdlg.h>
#include <tdelocale.h>
#include <knuminput.h>
#include <tqobject.h>
#include <ktextedit.h>

#include <tqlabel.h>
#include "utils.h"


#include "networkinterface.h"
#include "importcertificatedialog.h"
#include "importprofiledialog.h"
#include "vpnaccountdata.h"

//END includes

NewProfileDialog::NewProfileDialog( TQApplication *app,TQWidget *parent, const TQString& caption, KVpncConfig *GlobalConfig)
		: KDialogBase( parent, "New_profile", true, caption,
		               KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true )
{
	this->GlobalConfig = GlobalConfig;

	main = new NewProfileDialogbase(this);
	setMainWidget(main);
	main->setMinimumSize(main->sizeHint());

	connect( main->ConnectionTypeComboBox, TQ_SIGNAL( activated( const TQString& ) ), this, TQ_SLOT( connectiontypeChanged( const TQString& ) ) );
	connect( main->AuthTypeComboBox , TQ_SIGNAL( activated( const TQString& ) ), this, TQ_SLOT( authTypeChanged( const TQString& ) ) );
	//	connect( main->buttonCancel , TQ_SIGNAL( clicked () ), this, TQ_SLOT( reject() ) );
	connect( main->ImportCertificatePushButton, TQ_SIGNAL( clicked () ), this, TQ_SLOT( importCertificate() ) );
	connect( main->AdvancedSettingsPushButton, TQ_SIGNAL( clicked () ), this, TQ_SLOT( advancedSettingsClicked() ) );
	connect( main->ImportPcfProfilePushButton , TQ_SIGNAL( clicked () ), this, TQ_SLOT( importPcfFileClicked() ) );
	connect( main->GroupPasswordEdit, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( groupPasswordContentChanged() ) );
	connect( main->PasswordEdit, TQ_SIGNAL( textChanged(const TQString&) ), this, TQ_SLOT( passwordContentChanged() ) );
	newProfileCreated = false;
	Name = "";

	// currently static for new profile
	VpnAccountData::ConnectionType ConnType = VpnAccountData::ConnectionType(VpnAccountData::other);
	Port = 500;
	Gateway = "";
	ID = "";
	Username = "";
	UserPassword = "";
	PreSharedKey = "";
	ApplicationVersion = "";
	NtDomainName = "";
	PerfectForwardSecrecy = "";
	IkeGroup = "";
	Description ="";
	useApplicationVersion = false;
	useGlobalIpsecSecret = false;
	useIkeGroup = false;
	useLocalPort = false;
	useNtDomainName = false;
	useSingleDes = false;
	useAdvancedSettings = false;
	usePerfectSecrecy = false;
	saveUserPassword = false;
	savePsk = false;
	useUdp=false;
	useUdpPort=false;
	useDnsServer=false;
	DnsServer="";
	useGetDnsFromPeer=true;
	refuse40BitEncryption=true;
	refuse128BitEncryption=false;
	allowStatefulMode=false;
	requireMppe=true;
	refuseEap=false;
	useNoBsdComp=true;
	useNoDeflate=true;
	savePsk=false;


	profileData = new VpnAccountData( ConnType, Name );
	profileData->setGateway ( Gateway );
	profileData->setID( ID );
	profileData->setPreSharedKey( PreSharedKey);
	profileData->setSavePsk( savePsk );
	profileData->setUserName( Username );
	profileData->setUserPassword( UserPassword );
	profileData->setSaveUserPassword( saveUserPassword );
	profileData->setSavePsk(  savePsk );
	profileData->setApplicationVersion( ApplicationVersion );
	profileData->setUseLocalPort( useLocalPort );
	profileData->setLocalPort( Port );
	profileData->setUseSingleDes ( useSingleDes );
	profileData->setPerfectForwardSecrety ( PerfectForwardSecrecy );
	profileData->setIkeGroup( IkeGroup );
	profileData->setUseGlobalIpsecSecret (useGlobalIpsecSecret );
	profileData->setUseIkeGroup ( useIkeGroup );
	profileData->setNtDomainName (NtDomainName );
	profileData->setUseAdvancedSettings ( useAdvancedSettings );
	profileData->setUsePerfectForwardSecrety (usePerfectSecrecy );




	NetworkInterface iface(GlobalConfig,app);
	TQStringList list = iface.getAllNetworkInterfaces();
	main->NetworkDeviceComboBox->insertItem( "default" );
	for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
	{
		main->NetworkDeviceComboBox->insertItem( TQString( *it ) );
	}
	main->NetworkDeviceComboBox->setEnabled( true );
	main->NetworkDeviceComboBox->setCurrentText( "default" );

	main->certpathURLRequester->setURL( "/etc/racoon/certs" );
	main->certpathURLRequester->setMode( 2 ); // directory

	main->ConnectionTypeComboBox->insertItem( i18n( "Cisco (vpnc)" ) );
	main->ConnectionTypeComboBox->insertItem( i18n( "IPSec (racoon)" ) );
	main->ConnectionTypeComboBox->insertItem( i18n( "IPSec (FreeS/WAN)" ) );
	main->ConnectionTypeComboBox->insertItem( i18n( "PPTP" ) );
	main->ConnectionTypeComboBox->insertItem( i18n( "OpenVPN" ) );
	main->AuthTypeComboBox->setCurrentItem(1); // cisco

	main->RemoteNetMaskComboBox->setCurrentText("24");

	authTypeChanged( "" );
	connectiontypeChanged( "" );
}

NewProfileDialog::~NewProfileDialog()
{}

void NewProfileDialog::accept()
{
	bool canSave = true;
	if ( main->ConnectionTypeComboBox->currentItem() == 0 ) {
		profileData->setConnectionType( VpnAccountData::cisco );
		UdpPort=10000;
}
	else if ( main->ConnectionTypeComboBox->currentItem() == 1 )
	{
		profileData->setConnectionType( VpnAccountData::racoon );

		if (main->AuthTypeComboBox->currentItem() == 0)
			profileData->setAuthType( VpnAccountData::cert );
		else
			profileData->setAuthType( VpnAccountData::psk );

		profileData->setX509Certificate( main->x509certURLRequester->url() );
		profileData->setCertPath( main->certpathURLRequester->url() );

		UdpPort=4500;
	}
	else if ( main->ConnectionTypeComboBox->currentItem() == 2 )
	{
		profileData->setConnectionType( VpnAccountData::freeswan );
		UdpPort=4500;
	}
	else if ( main->ConnectionTypeComboBox->currentItem() == 3 )
	{
		profileData->setConnectionType( VpnAccountData::pptp );
	}
	else if ( main->ConnectionTypeComboBox->currentItem() == 4 )
	{
		profileData->setConnectionType( VpnAccountData::openvpn );
	}
	else
		profileData->setConnectionType( VpnAccountData::other );

	bool validAddr = true;

	if ( profileData->getConnectionType() != VpnAccountData::cisco && profileData->getConnectionType() != VpnAccountData::openvpn )
	{
		if ( main->RemoteNetAddrLineEdit->text().contains( '.' ) != 3 )
		{
			KMessageBox::error ( this, i18n( "No IP address for remote network entered!" ), i18n( "No IP Address" ) );
			GlobalConfig->appendLogEntry(  i18n( "No IP address for remote network entered!" ),GlobalConfig->error);
			validAddr = canSave = false;
		}
		else
		{
			if (!Utils(GlobalConfig).isValidIPv4Address(main->RemoteNetAddrLineEdit->text()))
			{

				KMessageBox::error ( this, i18n( "IP address of remote network is not valid!" ), i18n( "Invalid IP Address" ) );
				GlobalConfig->appendLogEntry( i18n( "IP address of remote network not valid!" ) ,GlobalConfig->error);

				validAddr = canSave = false;
			}
			if ( validAddr )
			{
				profileData->setRemoteNetAddr( main->RemoteNetAddrLineEdit->text());
				profileData->setRemoteNetMask( main->RemoteNetMaskComboBox->currentText() );
			}

		}
	}

	// 	profileData->setSavePsk( main->CheckGroupPass->isChecked() );
	// 	profileData->setSaveUserPassword( main->CheckUserPass->isChecked () );
	profileData->setSavePsk( !main->PSKLineEdit->text().isEmpty() );
	profileData->setSaveUserPassword( !main->PasswordEdit->text().isEmpty() );
	profileData->setID( main->IDLineEdit->text() );

	profileData->setDescription( main->DescriptionLineEdit->text() );

	profileData->setUserName( main->UsernameLineEdit->text () );

	if ( main->CheckUserPass->isChecked ())
	{
		profileData->setUserPassword( main->PasswordEdit->text ( ) );
		profileData->setSaveUserPassword(true);
	}

	profileData->setGateway( main->gatewayLineEdit->text() );


	if ( main->CheckGroupPass->isChecked())
	{
		if (!profileData->getConnectionType() == VpnAccountData::cisco)
			profileData->setPreSharedKey( main->PSKLineEdit->text() );
		else
			profileData->setPreSharedKey( main->GroupPasswordEdit->text() );
		profileData->setSavePsk(true);
	}

	profileData->setX509Certificate( main->x509certURLRequester->url() );
	profileData->setCertPath( main->certpathURLRequester->url() );
	profileData->setNetworkDevice( main->NetworkDeviceComboBox->currentText() );
	if (main->AuthTypeComboBox->currentItem() == 0)
		profileData->setAuthType( VpnAccountData::cert );
	else
		profileData->setAuthType( VpnAccountData::psk );

	if ( canSave )
	{

		bool nameOk = true;
		Name = main->ProfileLineEdit->text();

		if (Name.contains(' '))
		{
			KMessageBox::error ( this, i18n( "Profile name can not contain spaces!" ), i18n( "Spaces Not Allowed" ) );
			GlobalConfig->appendLogEntry( i18n( "Profile name can not contain spaces!" ) ,GlobalConfig->error);

			nameOk = false;
		}

		if (Name.isEmpty())
		{
			KMessageBox::error ( this, i18n( "Profile name can not be empty!" ), i18n( "No Name Entered" ) );
			GlobalConfig->appendLogEntry( i18n( "Profile name can not be empty!" ) ,GlobalConfig->error);

			nameOk = false;
		}

		VpnAccountData * it;
		for ( it = GlobalConfig->AccountList->first(); it; it = GlobalConfig->AccountList->next() )
		{
			if ( it->getName() == Name )
			{
				KMessageBox::error ( this, i18n( "Profile name already exists!" ), i18n( "Name Already Exists" ) );
				GlobalConfig->appendLogEntry(i18n( "Profile name already exists!" ) ,GlobalConfig->error);

				nameOk = false;
				break;
			}
		}

		if ( nameOk )
		{
			profileData->setName(Name);
			GlobalConfig->AccountList->append( profileData );
			newProfileCreated = true;
			TQDialog::accept();
		}

	}
}

void NewProfileDialog::importCertificate()
{
	//FIXME make dynamiclly
	ImportCertificateDialog importdlg(  this, i18n("Import certificate...").ascii(), GlobalConfig);
	//dlg.resize(dlg.height(),600);
	//int result =
	importdlg.exec();
}


void NewProfileDialog::connectiontypeChanged( const TQString& )
{

	// First we should set a type
	//buttonOk->setEnabled( false );
	main->AdvancedSettingsPushButton->setEnabled( false );

	int item = main->ConnectionTypeComboBox->currentItem();

	if ( item == VpnAccountData::ConnectionType(VpnAccountData::cisco) )
	{


		GlobalConfig->appendLogEntry( i18n("New type: %1").arg("cisco"),GlobalConfig->debug );

		profileData->setConnectionType( VpnAccountData::cisco );

		main->CheckGroupPass->setEnabled( true );
		main->CheckUserPass->setEnabled( true );

		main->IDLineEdit->setEnabled( true );
		main->LabelID->setEnabled( true );

		main->UsernameLineEdit->setEnabled( true );
		main->LabelUsername->setEnabled( true );

		main->PasswordEdit->setEnabled( true );
		main->LabelPassword->setEnabled( true );

		main->AdvancedSettingsPushButton->setEnabled( true );

		main->x509certURLRequester->setEnabled( false );
		main->LabelCertificate->setEnabled( false );

		main->certpathURLRequester->setEnabled( false );
		main->LabelCertificatePath->setEnabled( false );

		main->NetworkDeviceComboBox->setEnabled( false );
		main->LabelNetworkDevice->setEnabled( false );
		main->AuthTypeComboBox->setEnabled( false );
		main->LabelAuthType->setEnabled( false );

		main->PSKLineEdit->setEnabled( false );
		main->LabelPsk->setEnabled( false );

		//buttonCancel->setEnabled( true );
		//buttonOk->setEnabled( true );

		main->RemoteNetAddrLineEdit->setEnabled( false );
		main->LabelRemoteNetwork->setEnabled( false );

		main->RemoteNetMaskComboBox->setEnabled( false );

	} // vpnc

	else if ( item == VpnAccountData::ConnectionType(VpnAccountData::racoon) )
	{


		GlobalConfig->appendLogEntry( i18n("New type: %1").arg("racoon"),GlobalConfig->debug );
		//     KURLRequester* main->x509certURLRequester;
		//     KComboBox* main->AuthTypeComboBox;
		//     KPushButton* ImportCertificatePushButton;
		//     KLineEdit* main->PSKLineEdit;

		profileData->setConnectionType( VpnAccountData::racoon );

		main->x509certURLRequester->setEnabled( true );
		main->LabelCertificate->setEnabled( true );

		main->certpathURLRequester->setEnabled( true );
		main->LabelCertificatePath->setEnabled( true );

		main->NetworkDeviceComboBox->setEnabled ( true );
		main->LabelNetworkDevice->setEnabled( true );

		main->AuthTypeComboBox->setEnabled( true );
		main->LabelAuthType->setEnabled( true );

		main->PSKLineEdit->setEnabled( true );
		main->LabelPsk->setEnabled( true );

		main->RemoteNetAddrLineEdit->setEnabled( true );
		main->LabelRemoteNetwork->setEnabled( true );

		main->RemoteNetMaskComboBox->setEnabled( true );

		main->PasswordEdit->setEnabled( false );
		main->LabelPassword->setEnabled( false );

		main->CheckGroupPass->setEnabled( false );
		main->CheckUserPass->setEnabled( false );

		main->IDLineEdit->setEnabled( false );
		main->LabelID->setEnabled( false );

		main->UsernameLineEdit->setEnabled( false );
		main->LabelUsername->setEnabled( false );

		main->GroupPasswordEdit->setEnabled( false );
		main->LabelGroupPassword->setEnabled( false );

		//buttonCancel->setEnabled( true );
		//buttonOk->setEnabled( true );
		main->AdvancedSettingsPushButton->setEnabled( true );
	} // racoon

	else if ( item == VpnAccountData::ConnectionType(VpnAccountData::freeswan) )
	{


		GlobalConfig->appendLogEntry( i18n("New type: %1").arg("freeswan"), GlobalConfig->debug );
		//     KURLRequester* main->x509certURLRequester;
		//     KComboBox* main->AuthTypeComboBox;
		//     KPushButton* ImportCertificatePushButton;
		//     KLineEdit* main->PSKLineEdit;

		profileData->setConnectionType( VpnAccountData::freeswan );

		main->x509certURLRequester->setEnabled( true );
		main->LabelCertificate->setEnabled( true );

		main->certpathURLRequester->setEnabled( true );
		main->LabelCertificatePath->setEnabled( true );

		main->NetworkDeviceComboBox->setEnabled ( true );
		main->LabelNetworkDevice->setEnabled( true );

		main->AuthTypeComboBox->setEnabled( true );
		main->LabelAuthType->setEnabled( true );

		main->PSKLineEdit->setEnabled( true );
		main->LabelPsk->setEnabled( true );

		main->RemoteNetAddrLineEdit->setEnabled( true );
		main->LabelRemoteNetwork->setEnabled( true );

		main->RemoteNetMaskComboBox->setEnabled( true );

		main->CheckGroupPass->setEnabled( false );
		main->CheckUserPass->setEnabled( false );

		main->IDLineEdit->setEnabled( false );
		main->LabelID->setEnabled( false );

		main->PasswordEdit->setEnabled( false );
		main->LabelPassword->setEnabled( false );

		main->UsernameLineEdit->setEnabled( false );
		main->LabelUsername->setEnabled( false );

		main->GroupPasswordEdit->setEnabled( false );
		main->LabelGroupPassword->setEnabled( false );

		//		buttonCancel->setEnabled( true );
		//		buttonOk->setEnabled( true );
		main->AdvancedSettingsPushButton->setEnabled( true );
	} // freeswan

	else if ( item == VpnAccountData::ConnectionType(VpnAccountData::pptp) )
	{


		GlobalConfig->appendLogEntry( i18n("New type: %1").arg("pptp"),GlobalConfig->debug );
		//     KURLRequester* main->x509certURLRequester;
		//     KComboBox* main->AuthTypeComboBox;
		//     KPushButton* ImportCertificatePushButton;
		//     KLineEdit* main->PSKLineEdit;

		profileData->setConnectionType( VpnAccountData::pptp );

		main->x509certURLRequester->setEnabled( false );
		main->LabelCertificate->setEnabled( false );

		main->certpathURLRequester->setEnabled( false );
		main->LabelCertificatePath->setEnabled( false );

		main->NetworkDeviceComboBox->setEnabled ( false );
		main->LabelNetworkDevice->setEnabled( false );

		main->AuthTypeComboBox->setEnabled( false );
		main->LabelAuthType->setEnabled( false );

		main->PSKLineEdit->setEnabled( false );
		main->LabelPsk->setEnabled( false );

		main->RemoteNetAddrLineEdit->setEnabled( true );
		main->LabelRemoteNetwork->setEnabled( true );

		main->RemoteNetMaskComboBox->setEnabled( true );

		main->CheckGroupPass->setEnabled( false );
		main->CheckUserPass->setEnabled( true );

		main->IDLineEdit->setEnabled( false );
		main->LabelID->setEnabled( false );

		main->PasswordEdit->setEnabled( true );
		main->LabelPassword->setEnabled( true );

		main->UsernameLineEdit->setEnabled( true );
		main->LabelUsername->setEnabled( true );

		main->GroupPasswordEdit->setEnabled( false );
		main->LabelGroupPassword->setEnabled( false );

		//buttonCancel->setEnabled( true );
		//buttonOk->setEnabled( true );
		main->AdvancedSettingsPushButton->setEnabled( true );
	} // pptp
	else if ( item == VpnAccountData::ConnectionType(VpnAccountData::openvpn) )
	{
		if (GlobalConfig->KvpncDebugLevel > 0)
			GlobalConfig->appendLogEntry( i18n("New type: %1").arg("openvpn"),GlobalConfig->debug );
		//     KURLRequester* main->x509certURLRequester;
		//     KComboBox* main->AuthTypeComboBox;
		//     KPushButton* ImportCertificatePushButton;
		//     KLineEdit* main->PSKLineEdit;

		profileData->setConnectionType( VpnAccountData::openvpn );

		main->x509certURLRequester->setEnabled( true );
		main->LabelCertificate->setEnabled( true );

		main->certpathURLRequester->setEnabled( true );
		main->LabelCertificatePath->setEnabled( true );

		main->NetworkDeviceComboBox->setEnabled ( true );
		main->LabelNetworkDevice->setEnabled( true );

		main->AuthTypeComboBox->setEnabled( true );
		main->LabelAuthType->setEnabled( true );

		main->PSKLineEdit->setEnabled( true );
		main->LabelPsk->setEnabled( true );

		main->RemoteNetAddrLineEdit->setEnabled( false );
		main->LabelRemoteNetwork->setEnabled( false );

		main->RemoteNetMaskComboBox->setEnabled( true );

		main->PasswordEdit->setEnabled( false );
		main->LabelPassword->setEnabled( false );

		main->CheckGroupPass->setEnabled( false );
		main->CheckUserPass->setEnabled( false );

		main->IDLineEdit->setEnabled( false );
		main->LabelID->setEnabled( false );


		main->UsernameLineEdit->setEnabled( false );
		main->LabelUsername->setEnabled( false );

		main->GroupPasswordEdit->setEnabled( false );
		main->LabelGroupPassword->setEnabled( false );

		//buttonCancel->setEnabled( true );
		//buttonOk->setEnabled( true );
		main->AdvancedSettingsPushButton->setEnabled( true );
	} // openvpn

	// other
	else
	{

		if (GlobalConfig->KvpncDebugLevel > 0)
			GlobalConfig->appendLogEntry( "new type: other",GlobalConfig->debug );
		// 		main->x509certURLRequester->setEnabled( false );
		// 		main->AuthTypeComboBox->setEnabled( false );
		// 		main->PSKLineEdit->setEnabled( false );
		//
		// 		main->CheckGroupPass->setEnabled( false );
		// 		main->CheckUserPass->setEnabled( false );
		// 		main->IDLineEdit->setEnabled( false );
		// 		main->UsernameLineEdit->setEnabled( false );
		// 		main->AdvancedSettingsPushButton->setEnabled( false );
		//		buttonCancel->setEnabled( false );
		//buttonOk->setEnabled( false );
	}
}

void NewProfileDialog::authTypeChanged( const TQString& )
{
	if ( main->AuthTypeComboBox->currentItem() == VpnAccountData::AuthenticationType(VpnAccountData::cert ))
	{
		// certificate
		main->PSKLineEdit->setEnabled( false );
		main->LabelPsk->setEnabled( false );

		main->x509certURLRequester->setEnabled( true );
		main->LabelCertificate->setEnabled( true );

		main->certpathURLRequester->setEnabled( true );
		main->LabelCertificatePath->setEnabled( true );
	}
	if ( main->AuthTypeComboBox->currentItem() == VpnAccountData::AuthenticationType(VpnAccountData::psk ))
	{
		// psk
		main->PSKLineEdit->setEnabled( true );
		main->LabelPsk->setEnabled( true );

		main->x509certURLRequester->setEnabled( false );
		main->LabelCertificate->setEnabled( false );

		main->certpathURLRequester->setEnabled( false );
		main->LabelCertificatePath->setEnabled( false );
	}

}

void NewProfileDialog::reject()
{
	TQDialog::reject();
}

void NewProfileDialog::profileNameChanged( const TQString& )
{
	// 	LogOutput->append ( "text changed!" );
	// 	if ( main->ProfileLineEdit->text().isEmpty() )
	// 		buttonOk->setEnabled( false );
	// 	else
	// 		buttonOk->setEnabled( true );
}

TQString NewProfileDialog::getName()
{
	return Name;
}

void NewProfileDialog::importPcfFileClicked()
{
	ImportProfileDialog dlg(GlobalConfig,this, i18n("Import Cisco PCF Profile..."),"");
	dlg.exec();
	dlg.resize(800,dlg.height());
}

void NewProfileDialog::groupPasswordContentChanged()
{
	if (!main->GroupPasswordEdit->text().isEmpty())
		main->CheckGroupPass->setChecked(true);
	else
		main->CheckGroupPass->setChecked(false);
}


void NewProfileDialog::passwordContentChanged()
{
	if (!main->PasswordEdit->text().isEmpty())
		main->CheckUserPass ->setChecked(true);
	else
		main->CheckUserPass->setChecked(false);
}

#include "newprofiledialog.moc"
