/*
* shell.cpp -- Implementation of class KornShell.
* Author:	Sirtaj Singh Kang
* Version:	$Id: shell.cpp,v 1.6 1999/11/13 03:39:55 ettrich Exp $
* Generated:	Sun May  3 10:30:24 EST 1998
*/

#include<assert.h>
#include<qpopmenu.h>
#include<qlayout.h>
#include<qcursor.h>

#include<qmessagebox.h>
#include<kglobal.h>
#include<kapp.h>
#include <kconfig.h>
#include<klocale.h>
#include<kwm.h>

#include"shell.h"

#include"kornbutt.h"
#include"kornset.h"
#include"dropman.h"

#include"optdlg.h"
#include"dropdlg.h"

KornShell::KornShell( QWidget *parent )
	: QWidget( parent ),
	_configDirty( false ),
	_toWrite( false ),
	_layout( 0 ),
	_optDlg( 0 )
{
        _buttons = new QList<KornButton>;
	_buttons->setAutoDelete( false );
        _menu = initMenu();

        _manager = new KDropManager;

	connect( _manager, SIGNAL(monitorCreated()),
			this, SLOT(configDirty()) );
	connect( _manager, SIGNAL(monitorDeleted()),
			this, SLOT(configDirty()) );

        _settings= new KornSettings( kapp->config() );

}

KornShell::~KornShell()
{
	if ( _toWrite ) {
		// write config if changed
		_manager->writeConfig( *(kapp->config()), "Korn" );
		kapp->config()->sync();
	}
			
	delete _buttons;
	delete _menu;
	delete _manager;
	delete _settings;
	delete _optDlg;
	delete _layout;
}

bool KornShell::init()
{
	_settings->readConfig();

	bool ok = _manager->readConfig( *(kapp->config()),
			"Korn" );

	if( !ok && firstTimeInit() == false ) {
		warning( "KornShell: DropManager configuration not valid." );
		return false;
	}

	createButtons( _settings->layout() );

	return true;
}

void KornShell::createButtons( KornSettings::Layout layout )
{
	// create layout manager if buttons are
	// not to be docked

	if( _layout != 0 ) {
		delete _layout;
		_layout = 0;
	}

	_buttons->setAutoDelete( true );
	_buttons->clear();
	
 	if( layout == KornSettings::Dock
 			&& !KWM::isKWMInitialized() ) {
 		// No KWM, go to fallback style
 		_settings->setLayout( KornSettings::Horizontal );
		layout = _settings->layout();
 	}

	switch ( layout ) {
		case KornSettings::Vertical:
			_layout = new QBoxLayout( this,
					QBoxLayout::TopToBottom, 2 );
			break;

		case KornSettings::Horizontal:
			_layout = new QBoxLayout( this,
					QBoxLayout::LeftToRight, 2 );
			break;

		default:
			_layout = 0;
			break;
	}

	// create buttons

	QListIterator<KMailDrop> list = _manager->monitors();
	QWidget *parent = ( _layout != 0 ) ? this : 0;

	_buttons->setAutoDelete( (_layout == 0) );
	int size = 0;

	for( ; list.current(); ++list ) {
		KornButton *butt = new KornButton( parent, list.current() );

		connect( butt, SIGNAL (rightClick()), this, SLOT(popupMenu()));
//		connect( butt, SIGNAL (dying(KornButton *)),
//			this, SLOT(disconnectButton(KornButton *)) );

		_buttons->append( butt );

		if ( _layout ) {
			_layout->addWidget( butt );
			size++;
			kapp->setMainWidget( this );
		}
		else {
			KWM::setDockWindow( butt->winId() );
			QApplication::syncX();
			kapp->setMainWidget( 0 );
		}

		butt->show();
	}

	// set size of top level widget

	if ( size ) {
		int vert;
		int horiz;

		if( layout == KornSettings::Vertical ) {
			vert = size * 25;
			horiz = 25;
		}
		else {
			vert = 25;
			horiz = size * 25;
		}
		resize( horiz, vert );
	}
}	

void KornShell::show()
{
	// If docked, there's no real toplevel widget
	if( ( _settings->layout() != KornSettings::Dock ) ) {
		QWidget::show();
	}
}

void KornShell::popupMenu()
{
	_menu->popup( QCursor::pos() );
}

void KornShell::optionDlg()
{
	if( _optDlg != 0 ) {
		_optDlg->show();
		return;
	}
	
	_optDlg = new KornOptDlg( _manager, 0 );

	_optDlg->setKornLayout( _settings->layout() );

	connect( _optDlg, SIGNAL(finished(int)), this, SLOT(dlgClosed(int)) );

	_optDlg->show();
}

void KornShell::dlgClosed( int )
{
	if( _optDlg == 0 ) {
		warning( "KornShell:: dlgClosed() called without a dialog." );
		return;
	}

	bool needsCreate = false;

	// ok, read and update settings

	if ( _settings->layout() != _optDlg->kornLayout() ) {

		_settings->setLayout( _optDlg->kornLayout() );
		_settings->writeConfig();

		needsCreate = true;
	}

	if ( _configDirty ) {
		needsCreate = true;
		_configDirty = false;
	}

	if ( needsCreate ) {
		// change only if not the same layout
		hide();
		createButtons( _settings->layout() );
		show();
	}

	delete _optDlg;
	_optDlg = 0;
}

void KornShell::help()
{
	kapp->invokeHTMLHelp( "korn/korn.html", "" );
}

void KornShell::about()
{
	QMessageBox::information( 0, i18n( "About KOrn" ), "Korn <VERSION>"
			"-- Multi-mailbox message monitor.\n\n"
			"1997 Sirtaj Singh Kang<taj@kde.org>,\n"
			"for The K Desktop Environment\n\n"
			"IMAP4 support: Kurt Granoth <granoth@kde.org>\n",
				  i18n("OK"));
}

QPopupMenu *KornShell::initMenu()
{
	QPopupMenu *menu = new QPopupMenu;

	menu->insertItem( i18n("&Setup..."), this, SLOT( optionDlg() ) );
        menu->insertSeparator();
        menu->insertItem( i18n("&Help"),  this, SLOT( help() ) );
        menu->insertItem( i18n("&About..."), this, SLOT( about() ) );
        menu->insertSeparator();
        menu->insertItem( i18n("E&xit"),  qApp, SLOT( quit() ) );

	return menu;
}

bool KornShell::firstTimeInit()
{
	// ask user whether a sample config is wanted

	int status = QMessageBox::warning( 0, i18n("Welcome to KOrn"),
		i18n( "You do not appear to have used KOrn before.\n"
		"Would you like a basic configuration created for you?" ),
		i18n("Yes"), i18n( "No, Exit" ), 0, 1 );

	if( status != 0 ) {
		return false;
	}

	// get manager to create default config

	return _manager->createBasicConfig();
}

void KornShell::disconnectButton( KornButton *button )
{
	assert( button != 0 );

	if( _buttons->remove( button )  ) {
		// button was in list

		if( !_buttons->autoDelete() ) {
			delete button;
		}
	}
}

void KornShell::configDirty()
{
	_configDirty = true;
	_toWrite = true;
}

void KornShell::saveSession()
{
	// No Session management saving required... should
	// just restore itself with last config.
}
