//=============================================================================
//
//   File : kvi_tal_wizard.cpp
//   Creation date : Tue Feb 06 2007 14:35:08 by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 2007 Szymon Stefanek (pragma at kvirc dot 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 opinion) 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================

#define __KVILIB__
#include "kvi_tal_wizard.h"
#include "kvi_tal_hbox.h"
#include "kvi_pointerlist.h"
#include "kvi_locale.h"

	#include <tqlabel.h>
	#include <tqpushbutton.h>
	#include <tqlayout.h>
	#include <tqevent.h>
	#include <tqframe.h>
	#include <tqwidgetstack.h>
	#include <tqpalette.h>


class KviTalWizardPageData
{
public:
	enum EnableFlags
	{
		EnableNext = 1,
		EnableBack = 2,
		EnableHelp = 4,
		EnableCancel = 8,
		EnableFinish = 16
	};
public:
	TQWidget * pWidget;
	TQString   szTitle;
	bool      bEnabled;
	int       iEnableFlags;
	int       iVisibleIndex;
};

class KviTalWizardPrivate
{
public:
	KviPointerList<KviTalWizardPageData> * pPageList;
	int                                iEnabledPageCount;
	KviTalWizardPageData             * pCurrentPage;
	TQGridLayout                      * pLayout;
	TQLabel                           * pTitleLabel;
	TQLabel                           * pStepsLabel;
	TQPushButton                      * pBackButton;
	TQPushButton                      * pCancelButton;
	TQPushButton                      * pHelpButton;
	TQPushButton                      * pNextButton;
	TQWidget                          * pNextSpacer;
	TQPushButton                      * pFinishButton;
	TQWidget                          * pFinishSpacer;
	TQWidgetStack                     * pWidgetStack;
public:
	KviTalWizardPageData * findPage(TQWidget * pWidget)
	{
		for(KviTalWizardPageData * pData = pPageList->first();pData;pData = pPageList->next())
		{
			if(pData->pWidget == pWidget)
				return pData;
		}
		return NULL;
	}

	KviTalWizardPageData * findFirstEnabledPage()
	{
		KviTalWizardPageData * pData;
		for(pData = pPageList->first();pData;pData = pPageList->next())
		{
			if(pData->bEnabled)
				return pData;
		}
		return NULL;
	}

	KviTalWizardPageData * findLastEnabledPage()
	{
		KviTalWizardPageData * pData;
		for(pData = pPageList->last();pData;pData = pPageList->prev())
		{
			if(pData->bEnabled)
				return pData;
		}
		return NULL;
	}

	KviTalWizardPageData * findNextEnabledPage(TQWidget * pReference)
	{
		if(!pReference)
			return findFirstEnabledPage();
		KviTalWizardPageData * pData = findPage(pReference);
		if(!pData)
			return NULL;
		for(pData = pPageList->next();pData;pData = pPageList->next())
		{
			if(pData->bEnabled)
				return pData;
		}
		return NULL;
	}

	KviTalWizardPageData * findPrevEnabledPage(TQWidget * pReference)
	{
		if(!pReference)
			return findLastEnabledPage();
		KviTalWizardPageData * pData = findPage(pReference);
		if(!pData)
			return NULL;
		for(pData = pPageList->prev();pData;pData = pPageList->prev())
		{
			if(pData->bEnabled)
				return pData;
		}
		return NULL;
	}
	
	int reindexPages()
	{
		int iEnabledCount = 0;
		for(KviTalWizardPageData * pData = pPageList->next();pData;pData = pPageList->next())
		{
			if(pData->bEnabled)
			{
				iEnabledCount++;
				pData->iVisibleIndex = iEnabledCount;
			}
		}
		return iEnabledCount;
	}
};


KviTalWizard::KviTalWizard(TQWidget * pParent)
: TQDialog(pParent)
{
	m_p = new KviTalWizardPrivate;
	m_p->pPageList = new KviPointerList<KviTalWizardPageData>;
	m_p->pPageList->setAutoDelete(true);
	m_p->pCurrentPage = NULL;
	m_p->iEnabledPageCount = 0;
	m_p->pLayout = new TQGridLayout(this);

	m_p->pTitleLabel = new TQLabel(this);
	m_p->pLayout->addMultiCellWidget(m_p->pTitleLabel,0,0,0,3);
	m_p->pStepsLabel = new TQLabel(this);
	m_p->pStepsLabel->setMinimumWidth(80);
	m_p->pStepsLabel->setAlignment(TQt::AlignRight);
	m_p->pLayout->addMultiCellWidget(m_p->pStepsLabel,0,0,4,6);

	TQFrame * f1 = new TQFrame(this);
	f1->setFrameStyle(TQFrame::Sunken | TQFrame::HLine);
	m_p->pLayout->addMultiCellWidget(f1,1,1,0,6);

	m_p->pWidgetStack = new TQWidgetStack(this);
	m_p->pLayout->addMultiCellWidget(m_p->pWidgetStack,2,2,0,6);

	TQFrame * f2 = new TQFrame(this);
	f2->setFrameStyle(TQFrame::Sunken | TQFrame::HLine);
	m_p->pLayout->addMultiCellWidget(f2,3,3,0,6);

	KviTalHBox * pButtonBox = new KviTalHBox(this);
	m_p->pLayout->addMultiCellWidget(pButtonBox,4,4,0,6);

	pButtonBox->setMargin(0);
	pButtonBox->setSpacing(0);


	m_p->pCancelButton = new TQPushButton(__tr("Cancel"),pButtonBox);
	m_p->pCancelButton->setMinimumWidth(80);
	TQObject::connect(
			m_p->pCancelButton,
			TQ_SIGNAL(clicked()),
			this,
			TQ_SLOT(cancelButtonClicked())
		);

	TQWidget * pSpacer = new TQWidget(pButtonBox);
	pSpacer->setFixedWidth(4);

	m_p->pHelpButton = new TQPushButton(__tr("Help"),pButtonBox);
	m_p->pHelpButton->setMinimumWidth(80);
	TQObject::connect(
			m_p->pHelpButton,
			TQ_SIGNAL(clicked()),
			this,
			TQ_SLOT(helpButtonClicked())
		);

	TQWidget * pLargeSpacer = new TQWidget(pButtonBox);
	pLargeSpacer->setMinimumWidth(50);
	pButtonBox->setStretchFactor(pLargeSpacer,100);

	TQString szText = "< ";
	szText += __tr("Back");
	m_p->pBackButton = new TQPushButton(szText,pButtonBox);
	m_p->pBackButton->setMinimumWidth(80);
	TQObject::connect(
			m_p->pBackButton,
			TQ_SIGNAL(clicked()),
			this,
			TQ_SLOT(backButtonClicked())
		);

	m_p->pNextSpacer = new TQWidget(pButtonBox);
	m_p->pNextSpacer->setFixedWidth(4);

	szText = __tr("Next");
	szText += " >";
	m_p->pNextButton = new TQPushButton(szText,pButtonBox);
	m_p->pNextButton->setMinimumWidth(80);
	TQObject::connect(
			m_p->pNextButton,
			TQ_SIGNAL(clicked()),
			this,
			TQ_SLOT(nextButtonClicked())
		);

	m_p->pFinishSpacer = new TQWidget(pButtonBox);
	m_p->pFinishSpacer->setFixedWidth(4);

	m_p->pFinishButton = new TQPushButton(__tr("Finish"),pButtonBox);
	m_p->pFinishButton->setMinimumWidth(80);
	TQObject::connect(
			m_p->pFinishButton,
			TQ_SIGNAL(clicked()),
			this,
			TQ_SLOT(finishButtonClicked())
		);
		
	m_p->pLayout->setMargin(8);
	m_p->pLayout->setSpacing(4);
	m_p->pLayout->setRowStretch(2,1);
	m_p->pLayout->setColStretch(0,1);
}

KviTalWizard::~KviTalWizard()
{
	delete m_p->pPageList;
	delete m_p;
}

void KviTalWizard::insertPage(TQWidget * pWidget,const TQString &szTitle,int iIndex)
{
	KviTalWizardPageData * pPageData = m_p->findPage(pWidget);
	if(!pPageData)
	{
		pPageData = new KviTalWizardPageData;
		pPageData->pWidget = pWidget;
		pPageData->iEnableFlags = \
			KviTalWizardPageData::EnableNext | \
			KviTalWizardPageData::EnableCancel | \
			KviTalWizardPageData::EnableBack;
		if(iIndex < 0)
		{
			m_p->pPageList->append(pPageData);
			m_p->iEnabledPageCount++;
			pPageData->iVisibleIndex = m_p->iEnabledPageCount;
		} else {
			m_p->pPageList->insert(iIndex,pPageData);
			m_p->iEnabledPageCount = m_p->reindexPages();
		}
		m_p->pWidgetStack->addWidget(pWidget);
	}
	pPageData->szTitle = szTitle;
	pPageData->bEnabled = true;

}

void KviTalWizard::addPage(TQWidget * pWidget,const TQString &szTitle)
{
	insertPage(pWidget,szTitle,-1);
}

bool KviTalWizard::setPageEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return false;
	pData->bEnabled = bEnabled;
	m_p->iEnabledPageCount = m_p->reindexPages();
	setCurrentPage(m_p->pCurrentPage);
	return true;
}

bool KviTalWizard::setPageTitle(TQWidget * pWidget,const TQString &szTitle)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return false;
	pData->szTitle = szTitle;
	return true;
}

bool KviTalWizard::setCurrentPage(TQWidget * pWidget)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return false;
	setCurrentPage(pData);
	return true;
}

TQWidget * KviTalWizard::currentPage()
{
	if(!m_p->pCurrentPage)
		return NULL;
	return m_p->pCurrentPage->pWidget;
}

void KviTalWizard::setCurrentPage(KviTalWizardPageData * pData)
{
	m_p->pCurrentPage = pData;

	bool bCancelEnabled = true;
	bool bNextEnabled = false;
	bool bBackEnabled = false;
	bool bHelpEnabled = false;
	bool bFinishEnabled = false;

	TQString szTitle;
	TQString szSteps;

	if(pData)
	{
		bNextEnabled = (pData->iEnableFlags & KviTalWizardPageData::EnableNext) && m_p->findNextEnabledPage(pData->pWidget);
		bBackEnabled = (pData->iEnableFlags & KviTalWizardPageData::EnableBack) && m_p->findPrevEnabledPage(pData->pWidget);
		bCancelEnabled = (pData->iEnableFlags & KviTalWizardPageData::EnableCancel);
		bFinishEnabled = (pData->iEnableFlags & KviTalWizardPageData::EnableFinish);
		bHelpEnabled = (pData->iEnableFlags & KviTalWizardPageData::EnableHelp);
		m_p->pWidgetStack->raiseWidget(pData->pWidget);
		szTitle = "<b>";
		szTitle += pData->szTitle;
		szTitle += "</b>";
		TQPalette pal = m_p->pStepsLabel->palette();
		TQColor clrWin = pal.color(TQPalette::Normal,TQColorGroup::Foreground);
		TQColor clrTxt = pal.color(TQPalette::Normal,TQColorGroup::Background);
		TQColor clrMid = tqRgb(
							(clrWin.red() + clrTxt.red()) / 2,
							(clrWin.green() + clrTxt.green()) / 2,
							(clrWin.blue() + clrTxt.blue()) / 2
						);
		
		szSteps = "<nobr><font color=\"";
		szSteps += clrMid.name();
		szSteps += "\"><b>[";
		szSteps += TQString("Step %1 of %2").arg(pData->iVisibleIndex).arg(m_p->iEnabledPageCount);
		szSteps += "]</b></font></nobr>";
	}

	m_p->pTitleLabel->setText(szTitle);
	m_p->pStepsLabel->setText(szSteps);

	m_p->pNextButton->setEnabled(bNextEnabled);
	if(bNextEnabled)
	{
		m_p->pNextButton->show();
		m_p->pNextSpacer->show();
	} else {
		m_p->pNextButton->hide();
		m_p->pNextSpacer->hide();
	}
	m_p->pBackButton->setEnabled(bBackEnabled);
	m_p->pHelpButton->setEnabled(bHelpEnabled);
	if(bHelpEnabled)
		m_p->pHelpButton->show();
	else
		m_p->pHelpButton->hide();
	m_p->pCancelButton->setEnabled(bCancelEnabled);
	m_p->pFinishButton->setEnabled(bFinishEnabled);
	if(bFinishEnabled)
	{
		m_p->pFinishButton->show();
		m_p->pFinishSpacer->show();
	} else {
		m_p->pFinishButton->hide();
		m_p->pFinishSpacer->hide();
	}
}

void KviTalWizard::showEvent(TQShowEvent * e)
{
	if(!(m_p->pCurrentPage))
	{
		// display the first page
		KviTalWizardPageData * pData = m_p->findFirstEnabledPage();
		if(pData)
			setCurrentPage(pData->pWidget);
	}
	TQDialog::showEvent(e);
}

void KviTalWizard::closeEvent(TQCloseEvent * e)
{
	e->ignore();
	cancelButtonClicked();
}

void KviTalWizard::backButtonClicked()
{
	if(!m_p->pCurrentPage)
		return;
	setCurrentPage(m_p->findPrevEnabledPage(m_p->pCurrentPage->pWidget));
}

void KviTalWizard::nextButtonClicked()
{
	setCurrentPage(m_p->findNextEnabledPage(m_p->pCurrentPage->pWidget));
}

void KviTalWizard::helpButtonClicked()
{
	emit helpClicked();
}

void KviTalWizard::cancelButtonClicked()
{
	reject();
}

void KviTalWizard::finishButtonClicked()
{
	accept();
}

void KviTalWizard::setHelpEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return;
	if(bEnabled)
		pData->iEnableFlags |= KviTalWizardPageData::EnableHelp;
	else
		pData->iEnableFlags &= ~KviTalWizardPageData::EnableHelp;
	if(pData == m_p->pCurrentPage)
		setCurrentPage(pData);
}

void KviTalWizard::setCancelEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return;
	if(bEnabled)
		pData->iEnableFlags |= KviTalWizardPageData::EnableCancel;
	else
		pData->iEnableFlags &= ~KviTalWizardPageData::EnableCancel;
	if(pData == m_p->pCurrentPage)
		setCurrentPage(pData);
}

void KviTalWizard::setFinishEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return;
	if(bEnabled)
		pData->iEnableFlags |= KviTalWizardPageData::EnableFinish;
	else
		pData->iEnableFlags &= ~KviTalWizardPageData::EnableFinish;
	if(pData == m_p->pCurrentPage)
		setCurrentPage(pData);
}

void KviTalWizard::setNextEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return;
	if(bEnabled)
		pData->iEnableFlags |= KviTalWizardPageData::EnableNext;
	else
		pData->iEnableFlags &= ~KviTalWizardPageData::EnableNext;
	if(pData == m_p->pCurrentPage)
		setCurrentPage(pData);
}

void KviTalWizard::setBackEnabled(TQWidget * pWidget,bool bEnabled)
{
	KviTalWizardPageData * pData = m_p->findPage(pWidget);
	if(!pData)
		return;
	if(bEnabled)
		pData->iEnableFlags |= KviTalWizardPageData::EnableBack;
	else
		pData->iEnableFlags &= ~KviTalWizardPageData::EnableBack;
	if(pData == m_p->pCurrentPage)
		setCurrentPage(pData);
}

TQPushButton * KviTalWizard::cancelButton()
{
	return m_p->pCancelButton;
}

TQPushButton * KviTalWizard::helpButton()
{
	return m_p->pHelpButton;
}

TQPushButton * KviTalWizard::finishButton()
{
	return m_p->pFinishButton;
}

TQPushButton * KviTalWizard::nextButton()
{
	return m_p->pNextButton;
}

TQPushButton * KviTalWizard::backButton()
{
	return m_p->pBackButton;
}

#include "kvi_tal_wizard.moc"
