/***************************************************************************
 *   Copyright (C) 2012 by Timothy Pearson                                 *
 *   kb9vqf@pearsoncomputing.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.                                   *
 *                                                                         *
 *   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 <unistd.h>

#include <tqpushbutton.h>
#include <tqlabel.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqfile.h>
#include <tqtimer.h>
#include <tqcursor.h>
#include <tqspinbox.h>

#include <ksimpleconfig.h>
#include <tdeglobal.h>
#include <tdeglobalsettings.h>
#include <kstandarddirs.h>
#include <tdelocale.h>
#include <tdeapplication.h>
#include <tdelistview.h>
#include <krun.h>
#include <tdemessagebox.h>
#include <tdeconfig.h>
#include <knuminput.h>
#include <klineedit.h>
#include <ktextedit.h>
#include <kpassdlg.h>

#include <stdlib.h>

#include <kdebug.h>

#include "bondintropage.h"
#include "bondrealmpage.h"
#include "bondfinishpage.h"

#include "bondwizard.h"
#include "bondwizard.moc"

BondWizard::BondWizard(LDAPRealmConfigList *realmlist, LDAPConfig *ldapconfig, TQWidget *parent, const char *name)
	: KWizard(parent, name, true), m_realmList(realmlist), m_ldapConfig(ldapconfig) {

	setCaption(i18n("LDAP Bonding Wizard"));

	intropage = new BondIntroPage(this);
	addPage (intropage, i18n( "Step 1: Introduction" ) );
	setHelpEnabled(TQWizard::page(0), false);

	realmpage = new BondRealmPage(this);
	addPage (realmpage, i18n( "Step 2: Add New Realm" ) );
	setHelpEnabled(TQWizard::page(1), false);

	finishpage = new BondFinishPage(this);
	addPage (finishpage, i18n( "Step 3: Bond to New Realm" ) );
	setHelpEnabled(TQWizard::page(2), false);

	// Set up some defaults
	realmpage->txtKDCPort->setValue(88);
	realmpage->txtAdminServerPort->setValue(749);
	realmpage->txtUIDOffset->setValue(5000);
	realmpage->txtGIDOffset->setValue(5000);

	// Other setup
	finishpage->ldapAdminRealm->setEnabled(false);

	setFinishEnabled(TQWizard::page(2), true);

	setPosition();
}

BondWizard::~BondWizard() {
}


void BondWizard::next() {
	if (currentPage()==intropage) {
		TQWizard::next();
		realmpage->validateEntries();

		// Focus the first entry field on the new wizard page
		realmpage->txtRealmName->setFocus();
		realmpage->txtRealmName->selectAll();
	}
	else if (currentPage()==realmpage) {
		// Save realm information
		LDAPRealmConfig realm;

		realm.name = realmpage->txtRealmName->text();
		realm.bonded = false;
		realm.uid_offset = realmpage->txtUIDOffset->value();
		realm.gid_offset = realmpage->txtGIDOffset->value();
		realm.domain_mappings = TQStringList::split("\n", realmpage->txtDomains->text(), false);
		realm.kdc = realmpage->txtKDC->text();
		realm.kdc_port = realmpage->txtKDCPort->value();
		realm.admin_server = realmpage->txtAdminServer->text();
		realm.admin_server_port = realmpage->txtAdminServerPort->value();
		realm.pkinit_require_eku = realmpage->checkRequireEKU->isChecked();
		realm.pkinit_require_krbtgt_otherName = realmpage->checkRequireKrbtgtOtherName->isChecked();
		realm.win2k_pkinit = realmpage->checkWin2k->isChecked();
		realm.win2k_pkinit_require_binding = realmpage->checkWin2kPkinitRequireBinding->isChecked();

		if (!m_realmList->contains(realm.name)) {
			m_realmList->insert(realm.name, realm);
			m_ldapConfig->save();
			finishpage->ldapAdminRealm->setText(realm.name);
			m_finalRealm = realm;
			TQWizard::next();

			// Focus the first entry field on the new wizard page
			finishpage->ldapAdminUsername->setFocus();
			finishpage->ldapAdminUsername->selectAll();
		}
		else {
			KMessageBox::error(this, i18n("<qt><b>The specified realm is already known to this system.</b><p>If the realm name is correct, please exit the Wizard and select 'Re-Bond to Realm' in the LDAP configuration module.</qt>"), i18n("Duplicate Realm Entry Detected"));
		}
	}
	if (currentPage()==finishpage) {
		backButton()->setEnabled(false);
	}
}

void BondWizard::slotNext() {
	TQWizard::next();
}

void BondWizard::back() {
	TQWizard::back();
}

bool BondWizard::askClose(){
	TQString text;
	if (currentPage()==intropage) {
		return true;
	}
	else {
		if (currentPage()==realmpage) {
			text = i18n("<p>Are you sure you want to quit the LDAP Bonding Wizard?</p>"
				"<p>If yes, click <b>Quit</b> and all changes will be lost."
				"<br>If not, click <b>Cancel</b> to return and finish your setup.</p>");
		}
		else if (currentPage()==finishpage) {
			text = i18n("<p>Are you sure you want to quit the LDAP Bonding Wizard?</p>"
				"<p>If yes, click <b>Quit</b> and the new realm will remain deactivated pending bonding."
				"<br>If not, click <b>Cancel</b> to return and finish your setup.</p>");
		}
		else {
			text = i18n("<p>Are you sure you want to quit the LDAP Bonding Wizard?</p>"
				"<p>If not, click <b>Cancel</b> to return and finish bonding.</p>");
		}
		int status = KMessageBox::warningContinueCancel(this,  text, i18n("All Changes Will Be Lost"), KStdGuiItem::quit());
		if(status==KMessageBox::Continue){
			setDefaults();
			return true;
		} else {
			return false;
		}
	}
}

/** the cancel button is connected to the reject() slot of TQDialog,
 *  so we have to reimplement this here to add a dialogbox to ask if we
 *  really want to quit the wizard.
 */
void BondWizard::reject(){
	if (askClose()){
		done(0);
	}
}

void BondWizard::closeEvent(TQCloseEvent* e){
	if ( askClose() )
		done(0);
	else
		e->ignore();
}

/** maybe call a dialog that the wizard has finished. */
void BondWizard::accept(){
	// Try to bond
	TQString errorString;
	backButton()->setEnabled(false);
	nextButton()->setEnabled(false);
	finishButton()->setEnabled(false);
	cancelButton()->setEnabled(false);
	finishpage->setEnabled(false);

	// Write settings before attempting to connect to kadmin
	m_ldapConfig->save();

	if (LDAPManager::bondRealm(finishpage->ldapAdminUsername->text(), finishpage->ldapAdminPassword->password(), finishpage->ldapAdminRealm->text(), &errorString) == 0) {
		m_finalRealm.bonded = true;
		if (m_realmList->contains(m_finalRealm.name)) {
			m_realmList->remove(m_finalRealm.name);
		}
		m_realmList->insert(m_finalRealm.name, m_finalRealm);
		m_ldapConfig->save();
		done(0);
	}
	else {
		KMessageBox::error(this, i18n("<qt><b>Unable to bond to realm!</b><p>Details: %1</qt>").arg(errorString), i18n("Unable to Bond to Realm"));
	}

	finishpage->setEnabled(true);
	backButton()->setEnabled(true);
	finishButton()->setEnabled(true);
	cancelButton()->setEnabled(true);
}

/** calls all save functions after resetting all features/ OS/ theme selections to Trinity default */
void BondWizard::setDefaults(){
// 	if(realm_dirty)
// 		realmpage->save(false);
}

/** there seems to be a bug in TQWizard, that makes this evil hack necessary */
void BondWizard::setPosition() {
	TQSize hint = intropage->sizeHint();
	TQSize realm_size = realmpage->sizeHint();
	TQSize finish_size = finishpage->sizeHint();

	// get the width of the broadest child-widget
	if ( hint.width() < realm_size.width() )
		hint.setWidth(realm_size.width());
	if ( hint.width() < finish_size.width() )
		hint.setWidth(finish_size.width());

	// get the height of the highest child-widget
	if ( hint.height() < realm_size.height() )
		hint.setHeight(realm_size.height());
	if ( hint.height() < finish_size.height() )
		hint.setHeight(finish_size.height());

	// set the position
	TQRect rect = TDEGlobalSettings::desktopGeometry(TQCursor::pos());
	int w = rect.x() + (rect.width() - hint.width())/2 - 9;
	int h = rect.y() + (rect.height() - hint.height())/2;
	move(w, h);
}
