/***************************************************************************
 *                                                                         *
 *   Copyright (C) 2005, 2006 by Kevin Gilbert                             *
 *   kev.gilbert@cdu.edu.au                                                *
 *                                                                         *
 *   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.             *
 *                                                                         *
 ***************************************************************************/

#include <ntqlabel.h>
#include <ntqlayout.h>
#include <ntqlineedit.h>
#include <ntqlistbox.h>
#include <ntqmap.h>
#include <ntqpopupmenu.h>

#include <tdeapplication.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <kinputdialog.h>
#include <tdelocale.h>
#include <tdemessagebox.h>

#include "profiledialog.h"

//	constructor
//	===========

ProfileDialog::ProfileDialog( Action         action,
							  const TQString& currentProfile,
							  TQWidget*       parent,
							  const char*    name )
: KDialogBase( Plain, "", Ok | Cancel, Ok, parent, name ),
  m_action( action )
{	switch( m_action )
	{	case Copy:   setCaption( "Copy profile"    ); break;
		case Delete: setCaption( "Delete profile"  ); break;
		case Load:   setCaption( "Load profile"    ); break;
		case Rename: setCaption( "Rename profile"  ); break;
		case SaveAs: setCaption( "Save profile as" ); break;
	}

	createlayout( );
	setInitialValues( currentProfile );

	connect( m_profileListBox, SIGNAL( contextMenuRequested( TQListBoxItem*, const TQPoint& )), SLOT( slotProfileListContextMenu( TQListBoxItem*, const TQPoint& )));
	connect( m_profileListBox, SIGNAL( doubleClicked( TQListBoxItem* )), SLOT( slotOk( )));
	connect( m_profileListBox, SIGNAL( selectionChanged( )), SLOT( slotProfileListBoxChanged( )));
}

//	checkForDuplicateName
//	=====================

bool ProfileDialog::checkForDuplicateName( const TQString& profileName )
{	if( !kapp->config( )->hasGroup( PROFILE_PREFIX + profileName ))
		return true;

	KMessageBox::sorry( this, TQString( i18n( "Profile \"%1\" already exists, please choose another name or press 'Cancel'" )).arg( profileName ), i18n( "Duplicate profile name" ));
	return false;
}

//	constructNewProfileName
//	=======================

TQString ProfileDialog::constructNewProfileName( const TQString& initialProfileName ) const
{	TQString profileName = PROFILE_PREFIX + initialProfileName + "_copy";

	while( kapp->config( )->hasGroup( profileName ))
		profileName += "_copy";

	return stripPrefix( profileName );
}

//	copy
//	====

void ProfileDialog::copy( const TQString& fromProfileName, const TQString& toProfileName )
{	TQMap<TQString, TQString> map = kapp->config( )->entryMap( PROFILE_PREFIX + fromProfileName );
	kapp->config( )->setGroup( PROFILE_PREFIX + toProfileName );

	for( TQMap<TQString, TQString>::Iterator it = map.begin( ); it != map.end( ); ++it )
		kapp->config( )->writeEntry( it.key( ), it.data( ));

	m_profileListBox->insertItem( toProfileName );
	m_profileListBox->sort( );
}

//	createlayout
//	============

void ProfileDialog::createlayout( )
{	TQGridLayout* layout = new TQGridLayout( plainPage( ));
	m_profileListBox    = new TQListBox( plainPage( ),  "profiles list box"  );
	m_profileLineEdit   = new TQLineEdit( plainPage( ), "profiles line edit" );

	layout->addWidget( new TQLabel( "Profile name: ", plainPage( ), "name label" ), 1, 1, TQt::AlignRight );
	layout->addWidget( m_profileLineEdit, 1, 2 );
	layout->addWidget( new TQLabel( "Known profiles: ", plainPage( ), "name label" ), 3, 1, TQt::AlignRight | TQt::AlignTop );
	layout->addWidget( m_profileListBox,  3, 2 );

	layout->setColStretch( 0,  1 );
	layout->setColStretch( 2, 20 );
	layout->setColStretch( 3,  1 );

	layout->setRowStretch( 0,  2 );
	layout->setRowStretch( 2,  1 );
	layout->setRowStretch( 3, 10 );
	layout->setRowStretch( 4,  2 );

	switch( m_action )
	{	case Delete:
		case Load:
			m_profileLineEdit->setReadOnly( true );
			break;

		default:
			break;
	}
}

//	deelete
//	=======

void ProfileDialog::deelete( const TQString& profileName, const bool ask )
{	if( !kapp->config( )->hasGroup( PROFILE_PREFIX + profileName ))
	{	Q_ASSERT( false );
		return ;
	}

	TQListBoxItem* item = m_profileListBox->findItem( profileName, TQt::ExactMatch );
	Q_ASSERT( item != NULL );

	if( item != NULL )
		deelete( item, ask );
}

//	deelete
//	=======

void ProfileDialog::deelete( TQListBoxItem* item, const bool ask )
{	if( ask && KMessageBox::Yes != KMessageBox::questionYesNo( this,
															   TQString( i18n( "Delete profile \"%1\"?" )).arg( item->text( )),
															   i18n( "Confirm profile deletion" )))
		return;

	kapp->config( )->deleteGroup( PROFILE_PREFIX + item->text( ));
	m_profileListBox->takeItem( item );
	delete item;
}

//	getNewProfileName
//	=================

bool ProfileDialog::getNewProfileName( TQString& profileName )
{	while( true )
	{	bool ok;
		profileName = KInputDialog::getText( i18n( "Profile name" ), i18n( "New profile name" ), profileName, &ok, this, "profile name" );

		if( !ok )
			return false;

		if( checkForDuplicateName( profileName ))
			break;
	}

	return true;
}

//	setInitialValues
//	================

void ProfileDialog::setInitialValues( const TQString& currentProfile )
{	ushort      currentItem = ushort( -1 );
	TQStringList profileList = kapp->config( )->groupList( );
	ushort      i;
	TQStringList::Iterator it;

	for( i = 0, it = profileList.begin( ); it != profileList.end( ); ++it )
		if( (*it).startsWith( PROFILE_PREFIX ))
		{	m_profileListBox->insertItem( stripPrefix( *it ), i );

			if( *it == currentProfile )
				currentItem = i;

			i++;
		}

	if( currentItem != ushort( -1 ))
	{	m_profileListBox->setSelected( currentItem, true );

		if( m_action == Copy )
			m_profileLineEdit->setText( constructNewProfileName( m_profileListBox->currentText( )));
		else
			m_profileLineEdit->setText( m_profileListBox->currentText( ));
	}

	m_profileListBox->sort( );
}

//	slotCopy
//	========

void ProfileDialog::slotCopy( )
{	TQString fromProfileName = m_contextItem->text( );
	TQString toProfileName   = constructNewProfileName( fromProfileName );

	if( getNewProfileName( toProfileName ))
		copy( fromProfileName, toProfileName );
}

//	slotDelete
//	==========

void ProfileDialog::slotDelete( )
{	deelete( m_contextItem, true );
}

//	slotOk
//	======

void ProfileDialog::slotOk( )
{	TQString       fromProfileName;
	TQListBoxItem* item;
	TQString       toProfileName;

	switch( m_action )
	{	case Copy:
			fromProfileName = m_profileListBox->currentText( );
			toProfileName   = m_profileLineEdit->text( );

			if( !checkForDuplicateName( toProfileName ))
				return;

			copy( fromProfileName, toProfileName );
			break;

		case Delete:
			deelete( m_profileLineEdit->text( ), true );
			break;

		case Load:
			m_profileName = PROFILE_PREFIX + m_profileLineEdit->text( );
			break;

		case Rename:
			fromProfileName = m_profileListBox->currentText( );
			toProfileName   = m_profileLineEdit->text( );

			if( !checkForDuplicateName( toProfileName ))
				return;

			copy( fromProfileName, toProfileName );
			deelete( fromProfileName, false );
			break;

		case SaveAs:
			m_profileName = m_profileLineEdit->text( );
			item          = m_profileListBox->findItem( m_profileName, TQt::ExactMatch );

			if( item != NULL )
				if( KMessageBox::Yes != KMessageBox::questionYesNo( this, TQString( i18n( "Profile \"%1\" already exists - overwrite it?" )).arg( m_profileName ), i18n( "Profile exists" )))
					return;

			m_profileName = PROFILE_PREFIX + m_profileName;
			break;
	}

	KDialogBase::slotOk( );
}

//	slotProfileListBoxChanged
//	=========================

void ProfileDialog::slotProfileListBoxChanged( )
{	if( m_action == Copy )
		m_profileLineEdit->setText( constructNewProfileName( m_profileListBox->currentText( )));
	else
		m_profileLineEdit->setText( m_profileListBox->currentText( ));
}

//	slotProfileListContextMenu
//	==========================

void ProfileDialog::slotProfileListContextMenu( TQListBoxItem* item, const TQPoint& pos )
{	m_contextItem = item;
	TQPopupMenu* contextMenu = new TQPopupMenu( this, "context menu" );

	contextMenu->insertItem( i18n( "&Copy"   ), this, SLOT( slotCopy( )));
	contextMenu->insertItem( i18n( "&Delete" ), this, SLOT( slotDelete( )));
	contextMenu->insertItem( i18n( "&Rename" ), this, SLOT( slotRename( )));

	contextMenu->exec( pos );
}

//	slotRename
//	==========

void ProfileDialog::slotRename( )
{	TQString profileName = m_contextItem->text( );

	if( getNewProfileName( profileName ))
	{	copy( m_contextItem->text( ), profileName );
		deelete( m_contextItem, false );
	}
}

//	stripPrefix
//	===========

TQString ProfileDialog::stripPrefix( const TQString& profileName ) const
{	return profileName.right( profileName.length( ) - strlen( PROFILE_PREFIX ));
}

#include "profiledialog.moc"
