/***************************************************************************
                          glowconfigdialog.cpp  -  description
                             -------------------
    begin                : Thu Sep 12 2001
    copyright            : (C) 2001 by Henning Burchardt
    email                : h_burchardt@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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <qcheckbox.h>
#include <qgroupbox.h>
#include <qwhatsthis.h>
#include <qlayout.h>
#include <qabstractlayout.h>
#include <qpushbutton.h>
#include <qbitmap.h>
#include <qsignalmapper.h>
#include <qradiobutton.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <kglobal.h>
#include <kconfig.h>
#include <klocale.h>
#include <kcolorbutton.h>
#include <kpixmapeffect.h>

#include "glowconfigdialog.h"
#include "../bitmaps.h"

#define DEFAULT_BUTTON_COLOR Qt::white
#define DEFAULT_CLOSE_BUTTON_COLOR Qt::red

extern "C"
{
	QObject* allocate_config( KConfig* conf, QWidget* parent )
	{
		return(new GlowConfigDialog(conf, parent));
	}
}

GlowConfigDialog::GlowConfigDialog( KConfig * conf, QWidget * parent )
	: QObject(parent)
{
	m_glowConfig = new KConfig("kwinglowrc");
	KGlobal::locale()->insertCatalogue("kwin_glow_config");

	m_mainGroupBox = new QGroupBox(
		0, Qt::Vertical, i18n("Decoration Settings"), parent);
	QVBoxLayout *mainGroupBoxLayout = new QVBoxLayout(
		m_mainGroupBox->layout());
	mainGroupBoxLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
	mainGroupBoxLayout->setSpacing(6);

	m_showResizeHandleCheckBox = new QCheckBox(
		i18n("Show Resize Handle"), m_mainGroupBox);
	QObject::connect(m_showResizeHandleCheckBox, SIGNAL(clicked()),
		this, SLOT(slotChanged()));
	mainGroupBoxLayout->addWidget(m_showResizeHandleCheckBox);

	QHBoxLayout *titlebarGradientTypeLayout = new QHBoxLayout();
	m_titlebarGradientTypeComboBox = new QComboBox(m_mainGroupBox);
	m_titlebarGradientTypeComboBox->insertItem(i18n("Diagonal"), 0);
	m_titlebarGradientTypeComboBox->insertItem(i18n("Vertical"), 1);
	m_titlebarGradientTypeComboBox->insertItem(i18n("Horizontal"), 2);
	QObject::connect(m_titlebarGradientTypeComboBox, SIGNAL(activated(int)),
		this, SLOT(slotChanged(int)));
	titlebarGradientTypeLayout->addWidget(
		new QLabel(i18n("Titlebar Gradient Type"), m_mainGroupBox));
	titlebarGradientTypeLayout->addWidget(
		m_titlebarGradientTypeComboBox);
	mainGroupBoxLayout->addLayout(titlebarGradientTypeLayout);

	m_buttonGlowColorGroupBox = new QGroupBox(
		0, Qt::Horizontal, i18n("Button Glow Colors"), m_mainGroupBox);
	QHBoxLayout *buttonGlowColorGroupBoxLayout =
		new QHBoxLayout(m_buttonGlowColorGroupBox->layout());
	buttonGlowColorGroupBoxLayout->setSpacing(6);

	QVBoxLayout *buttonLayout = new QVBoxLayout(3);

	// create buttons
	QSize buttonSize(DEFAULT_BITMAP_SIZE, DEFAULT_BITMAP_SIZE);
	QPixmap pm(buttonSize);
	pm.fill(Qt::black);

	m_stickyButton = new QPushButton(m_buttonGlowColorGroupBox);
	pm.setMask(QBitmap(buttonSize, stickyoff_bits, true));
	m_stickyButton->setPixmap(pm);
	buttonLayout->addWidget(m_stickyButton);
	m_titleButtonList.push_back(m_stickyButton);

	m_helpButton = new QPushButton(m_buttonGlowColorGroupBox);
	pm.setMask(QBitmap(buttonSize, help_bits, true));
	m_helpButton->setPixmap(pm);
	buttonLayout->addWidget(m_helpButton);
	m_titleButtonList.push_back(m_helpButton);

	m_iconifyButton = new QPushButton(m_buttonGlowColorGroupBox);
	pm.setMask(QBitmap(buttonSize, minimize_bits, true));
	m_iconifyButton->setPixmap(pm);
	buttonLayout->addWidget(m_iconifyButton);
	m_titleButtonList.push_back(m_iconifyButton);

	m_maximizeButton = new QPushButton(m_buttonGlowColorGroupBox);
	pm.setMask(QBitmap(buttonSize, maximizeoff_bits, true));
	m_maximizeButton->setPixmap(pm);
	buttonLayout->addWidget(m_maximizeButton);
	m_titleButtonList.push_back(m_maximizeButton);

	m_closeButton = new QPushButton(m_buttonGlowColorGroupBox);
	pm.setMask(QBitmap(buttonSize, close_bits, true));
	m_closeButton->setPixmap(pm);
	buttonLayout->addWidget(m_closeButton);
	m_titleButtonList.push_back(m_closeButton);

	buttonGlowColorGroupBoxLayout->addLayout(buttonLayout);

	// create signal mapper
	m_titleButtonMapper = new QSignalMapper(this);
	for( int i=0; i<m_titleButtonList.size(); i++ )
	{
		m_titleButtonMapper->setMapping(m_titleButtonList[i], i);
		QObject::connect(m_titleButtonList[i], SIGNAL(clicked()),
			m_titleButtonMapper, SLOT(map()));
	}
	QObject::connect(m_titleButtonMapper, SIGNAL(mapped(int)),
		this, SLOT(slotTitleButtonClicked(int)));

	// vertical line
	QFrame *verticalLine = new QFrame(m_buttonGlowColorGroupBox);
	verticalLine->setFrameStyle(QFrame::VLine | QFrame::Sunken);
	buttonGlowColorGroupBoxLayout->addWidget(verticalLine);

	QGridLayout *colorRadioButtonLayout = new QGridLayout(3, 2);
	colorRadioButtonLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);

	// create color radio buttons
	m_titleBarColorButton = new QRadioButton(
		i18n("Title bar color"), m_buttonGlowColorGroupBox);
	m_colorRadioButtonList.push_back(m_titleBarColorButton);
	colorRadioButtonLayout->addWidget(
		m_titleBarColorButton, 0, 0);

	m_titleBlendColorButton = new QRadioButton(
		i18n("Title blend color"), m_buttonGlowColorGroupBox);
	m_colorRadioButtonList.push_back(m_titleBlendColorButton);
	colorRadioButtonLayout->addWidget(
		m_titleBlendColorButton, 1, 0);

	m_customColorButton = new QRadioButton(
		i18n("Custom color"), m_buttonGlowColorGroupBox);
	m_colorRadioButtonList.push_back(m_customColorButton);
	colorRadioButtonLayout->addWidget(
		m_customColorButton, 2, 0);

	m_colorRadioButtonMapper = new QSignalMapper(this);
	for(int i=0; i<m_colorRadioButtonList.size(); i++ )
	{
		m_colorRadioButtonMapper->setMapping(m_colorRadioButtonList[i], i);
		QObject::connect(m_colorRadioButtonList[i], SIGNAL(clicked()),
			m_colorRadioButtonMapper, SLOT(map()));
	}
	QObject::connect(m_colorRadioButtonMapper, SIGNAL(mapped(int)),
		this, SLOT(slotColorRadioButtonClicked(int)));

	m_colorButton = new KColorButton(m_buttonGlowColorGroupBox);
	QObject::connect(m_colorButton, SIGNAL(changed(const QColor&)),
		this, SLOT(slotChanged(const QColor&)));
	colorRadioButtonLayout->addWidget(m_colorButton, 2, 1);

	buttonGlowColorGroupBoxLayout->addLayout(colorRadioButtonLayout);
	buttonGlowColorGroupBoxLayout->addItem(new QSpacerItem(
		20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));

	mainGroupBoxLayout->addWidget(m_buttonGlowColorGroupBox);

	// load config and update user interface
	load(conf);

	m_mainGroupBox->show();
}

GlowConfigDialog::~GlowConfigDialog()
{
	delete m_mainGroupBox;
}

void GlowConfigDialog::load( KConfig* conf )
{
	m_glowConfig->setGroup("General");

	QColor defaultButtonColor = DEFAULT_BUTTON_COLOR;
	QColor defaultCloseButtonColor = DEFAULT_CLOSE_BUTTON_COLOR;
	struct ButtonConfig cnf;

	cnf.glowType = m_glowConfig->readEntry(
		"stickyButtonGlowType", "TitleBar");
	cnf.glowColor = m_glowConfig->readColorEntry(
		"stickyButtonGlowColor", &defaultButtonColor);
	m_buttonConfigMap["stickyButton"] = cnf;

	cnf.glowType = m_glowConfig->readEntry(
		"helpButtonGlowType", "TitleBar");
	cnf.glowColor = m_glowConfig->readColorEntry(
		"helpButtonGlowColor", &defaultButtonColor);
	m_buttonConfigMap["helpButton"] = cnf;

	cnf.glowType = m_glowConfig->readEntry(
		"iconifyButtonGlowType", "TitleBar");
	cnf.glowColor = m_glowConfig->readColorEntry(
		"iconifyButtonGlowColor", &defaultButtonColor);
	m_buttonConfigMap["iconifyButton"] = cnf;

	cnf.glowType = m_glowConfig->readEntry(
		"maximizeButtonGlowType", "TitleBar");
	cnf.glowColor = m_glowConfig->readColorEntry(
		"maximizeButtonGlowColor", &defaultButtonColor);
	m_buttonConfigMap["maximizeButton"] = cnf;

	cnf.glowType = m_glowConfig->readEntry(
		"closeButtonGlowType", "Custom");
	cnf.glowColor = m_glowConfig->readColorEntry(
		"closeButtonGlowColor", &defaultCloseButtonColor);
	m_buttonConfigMap["closeButton"] = cnf;

	m_showResizeHandle = m_glowConfig->readBoolEntry(
		"showResizeHandle", true);
	m_titlebarGradientType = m_glowConfig->readNumEntry(
		"titlebarGradientType", KPixmapEffect::DiagonalGradient);

	updateUI();
}

void GlowConfigDialog::save( KConfig *conf )
{
	updateConfig();

	m_glowConfig->setGroup("General");

	struct ButtonConfig cnf;

	cnf = m_buttonConfigMap["stickyButton"];
	m_glowConfig->writeEntry("stickyButtonGlowType", cnf.glowType);
	m_glowConfig->writeEntry("stickyButtonGlowColor", cnf.glowColor);

	cnf = m_buttonConfigMap["helpButton"];
	m_glowConfig->writeEntry("helpButtonGlowType", cnf.glowType);
	m_glowConfig->writeEntry("helpButtonGlowColor", cnf.glowColor);

	cnf = m_buttonConfigMap["iconifyButton"];
	m_glowConfig->writeEntry("iconifyButtonGlowType", cnf.glowType);
	m_glowConfig->writeEntry("iconifyButtonGlowColor", cnf.glowColor);

	cnf = m_buttonConfigMap["maximizeButton"];
	m_glowConfig->writeEntry("maximizeButtonGlowType", cnf.glowType);
	m_glowConfig->writeEntry("maximizeButtonGlowColor", cnf.glowColor);

	cnf = m_buttonConfigMap["closeButton"];
	m_glowConfig->writeEntry("closeButtonGlowType", cnf.glowType);
	m_glowConfig->writeEntry("closeButtonGlowColor", cnf.glowColor);

	m_glowConfig->writeEntry("showResizeHandle", m_showResizeHandle);
	m_glowConfig->writeEntry("titlebarGradientType", m_titlebarGradientType);

	m_glowConfig->sync();
}

void GlowConfigDialog::defaults()
{
	QColor defaultButtonColor = DEFAULT_BUTTON_COLOR;
	QColor defaultCloseButtonColor = DEFAULT_CLOSE_BUTTON_COLOR;
	struct ButtonConfig cnf;

	cnf.glowType = "TitleBar";
	cnf.glowColor = defaultButtonColor;

	m_buttonConfigMap["stickyButton"] = cnf;
	m_buttonConfigMap["helpButton"] = cnf;
	m_buttonConfigMap["iconifyButton"] = cnf;
	m_buttonConfigMap["maximizeButton"] = cnf;

	cnf.glowType = "Custom";
	cnf.glowColor = defaultCloseButtonColor;

	m_buttonConfigMap["closeButton"] = cnf;

	m_showResizeHandle = true;
	m_titlebarGradientType = KPixmapEffect::DiagonalGradient;

	updateUI();
}

void GlowConfigDialog::slotSelectionChanged()
{
	updateConfig();
	emit changed();
}

void GlowConfigDialog::slotTitleButtonClicked(int index)
{
	updateConfig();
	for( int i=0; i<m_titleButtonList.size(); i++ )
		m_titleButtonList[i]->setDown(i==index);
	updateUI();
}

void GlowConfigDialog::slotColorRadioButtonClicked(int index)
{
	for( int i=0; i<m_colorRadioButtonList.size(); i++ )
		m_colorRadioButtonList[i]->setChecked(i==index);
	m_colorButton->setEnabled(
		m_colorRadioButtonList[index]==m_customColorButton);

	slotSelectionChanged();
}

void GlowConfigDialog::slotChanged(const QColor&)
{
	slotSelectionChanged();
}

void GlowConfigDialog::slotChanged(int)
{
	slotSelectionChanged();
}

void GlowConfigDialog::slotChanged()
{
	slotSelectionChanged();
}

void GlowConfigDialog::updateUI()
{
	struct ButtonConfig cnf;
	if( m_stickyButton->isDown() )
		cnf = m_buttonConfigMap["stickyButton"];
	else if( m_helpButton->isDown() )
		cnf = m_buttonConfigMap["helpButton"];
	else if( m_iconifyButton->isDown() )
		cnf = m_buttonConfigMap["iconifyButton"];
	else if( m_maximizeButton->isDown() )
		cnf = m_buttonConfigMap["maximizeButton"];
	else if( m_closeButton->isDown() )
		cnf = m_buttonConfigMap["closeButton"];
	else
	{
		m_stickyButton->setDown(true);
		cnf = m_buttonConfigMap["stickyButton"];
	}

	if( cnf.glowType == "TitleBar" )
	{
		m_titleBarColorButton->setChecked(true);
		m_titleBlendColorButton->setChecked(false);
		m_customColorButton->setChecked(false);
	}
	else if( cnf.glowType == "TitleBlend" )
	{
		m_titleBarColorButton->setChecked(false);
		m_titleBlendColorButton->setChecked(true);
		m_customColorButton->setChecked(false);
	}
	else
	{
		m_titleBarColorButton->setChecked(false);
		m_titleBlendColorButton->setChecked(false);
		m_customColorButton->setChecked(true);
	}
	m_colorButton->setColor(cnf.glowColor);
	m_colorButton->setEnabled(m_customColorButton->isChecked());

	m_showResizeHandleCheckBox->setChecked(m_showResizeHandle);

	if( m_titlebarGradientType == KPixmapEffect::DiagonalGradient )
		m_titlebarGradientTypeComboBox->setCurrentItem(0);
	else if( m_titlebarGradientType == KPixmapEffect::VerticalGradient )
		m_titlebarGradientTypeComboBox->setCurrentItem(1);
	else if( m_titlebarGradientType == KPixmapEffect::HorizontalGradient )
		m_titlebarGradientTypeComboBox->setCurrentItem(2);
}

void GlowConfigDialog::updateConfig()
{
	QString glowType;
	if( m_titleBarColorButton->isChecked() )
		glowType = "TitleBar";
	else if( m_titleBlendColorButton->isChecked() )
		glowType = "TitleBlend";
	else
		glowType = "Custom";
	QColor glowColor = m_colorButton->color();
	if( m_stickyButton->isDown() )
	{
		m_buttonConfigMap["stickyButton"].glowType = glowType;
		m_buttonConfigMap["stickyButton"].glowColor = glowColor;
	}
	else if( m_helpButton->isDown() )
	{
		m_buttonConfigMap["helpButton"].glowType = glowType;
		m_buttonConfigMap["helpButton"].glowColor = glowColor;
	}
	else if( m_iconifyButton->isDown() )
	{
		m_buttonConfigMap["iconifyButton"].glowType = glowType;
		m_buttonConfigMap["iconifyButton"].glowColor = glowColor;
	}
	else if( m_maximizeButton->isDown() )
	{
		m_buttonConfigMap["maximizeButton"].glowType = glowType;
		m_buttonConfigMap["maximizeButton"].glowColor = glowColor;
	}
	else // if( m_closeButton->isDown() )
	{
		m_buttonConfigMap["closeButton"].glowType = glowType;
		m_buttonConfigMap["closeButton"].glowColor = glowColor;
	}
	m_showResizeHandle = m_showResizeHandleCheckBox->isChecked();
	switch(m_titlebarGradientTypeComboBox->currentItem())
	{
		case 0: m_titlebarGradientType = KPixmapEffect::DiagonalGradient;
			break;
		case 1: m_titlebarGradientType = KPixmapEffect::VerticalGradient;
			break;
		case 2:
		default: m_titlebarGradientType = KPixmapEffect::HorizontalGradient;
			break;
	}
}

#include "glowconfigdialog.moc"
