/***************************************************************************
 *   Copyright (C) 2005 by Daniel Stöckel                                  *
 *   the_docter@gmx.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 "configdialogimpl.h"

#include <klocale.h>
#include <kicondialog.h>
#include <kiconloader.h>
#include <kshell.h>
#include <kkeybutton.h>
#include <kcolorbutton.h>

#include <qslider.h>
#include <qdir.h>
#include <qcombobox.h>
#include <qregexp.h>
#include <qspinbox.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qcheckbox.h>

#include "menulistviewitem.h"
#include "servicemenu.h"
#include "configuration.h"

ConfigDialogImpl::ConfigDialogImpl(QWidget* parent, const char* name, WFlags fl)
	: ConfigDialog(parent,name,true,fl),
		sysTray(this,"SysTray"),
		Shortcut(this,"Shortcut"),
		configChanged(false)
{
	//activate the systray icons
	sysTray.setPixmap(sysTray.loadIcon("kommando"));
	sysTray.show();
	
	//initialize the form
	shortcutFrame->hide();
	colorFrame->hide();
	menuListView->setSorting(-1);

	new QListBoxPixmap(listBox,MainBarIcon("kommando",KIcon::SizeLarge),"Menu");
	new QListBoxPixmap(listBox,MainBarIcon("configure_shortcuts",KIcon::SizeLarge),"Shortcuts");
	new QListBoxPixmap(listBox,MainBarIcon("colors",KIcon::SizeLarge),"Appearance");
	listBox->setSelected(listBox->topItem(),true);

	//get the configuration
	Config& config = Config::getSingleton();
	QString path(KShell::homeDir("")+"/.kde/share/apps/kommando/");
	QDir dir;
	if(!dir.exists(path)){
		dir.mkdir(path);
	}
	config.setConfigPath(path+"kommandorc");
	if(!config.readConfigFile()){
		QMessageBox mb(i18n("Could not read configfile"),i18n("The configfile could not be read."
		                                                      "\nKommando is starting the configuration dialog "
		                                                      "with default values..."),
		QMessageBox::Information,
		QMessageBox::Ok,
		QMessageBox::NoButton,
		QMessageBox::NoButton);
		mb.exec();
		config.setDefaultValues();
		config.writeConfigFile();
		show();
	}
	
	config.toListView(menuListView);
	config.toKommandoMenu(&kommandoWin);
	readConfig();
	connect(kKeyButton1,SIGNAL(capturedShortcut(const KShortcut&)),this,SLOT(slotShortcutChanged(const KShortcut&)) );

	addService->setPopup(new ServiceMenu(this, SLOT(slotAddService(KService*)), addService));
}

ConfigDialogImpl::~ConfigDialogImpl()
{
}

void ConfigDialogImpl::readConfig()
{
	Config& config = Config::getSingleton();
	
	navButtonSize->setCurrentText(QString::number(config.navButtonSize()));
	menuButtonSize->setCurrentText(QString::number(config.menuButtonSize()));
	menuRadiusSpinbox->setValue(config.menuRadius());
	
	if(config.scheme()=="none"){
		customCheckbox->setChecked(true);
	} else {
		customCheckbox->setChecked(false);
		schemeCombobox->setCurrentText(config.scheme());
	}
	
	kColorButton1->setColor(config.tintColor());
	opacitySlider->setValue(static_cast<int>(config.opacity()*100));
	
	//set upshortcut(s)
	Shortcut.insert("Toggle",
					i18n("Toggle"),
					i18n("This shortcut toggles the visibility of the Kommando menu"),
					KShortcut(config.Shortcut()),
					KShortcut(config.Shortcut()),
					&kommandoWin,
					SLOT( slotGlobAccel() ) );
	Shortcut.setEnabled(true);
	Shortcut.updateConnections();
	kKeyButton1->setText(config.Shortcut());
}

void ConfigDialogImpl::setChanged(bool state)
{
	configChanged=state;
	buttonApply->setEnabled(state);
	buttonReset->setEnabled(state);
}

/*$SPECIALIZATION$*/
void ConfigDialogImpl::slotButtonDownPressed()
{
	QListViewItem* item = menuListView->selectedItem();
	if(item!=NULL){
		QListViewItem* below = item->itemBelow();
		while((below!=NULL)&&(item->parent()!=below->parent())){
			below=below->itemBelow();
		}
		if(below!=NULL){
			item->moveItem(below);
		}
	}
}

void ConfigDialogImpl::slotButtonUpPressed()
{
	QListViewItem* item = menuListView->selectedItem();
	if(item!=NULL){
		QListViewItem* above = item->itemAbove();
		while((above!=NULL)&&(item->parent()!=above->parent())){
			above=above->itemAbove();
		}
		if(above!=NULL){
			above->moveItem(item);
		}
	}
}

void ConfigDialogImpl::slotCustomSizeCheckboxToggled(bool mode)
{
	schemeCombobox->setEnabled(!mode);
	menuRadiusSpinbox->setEnabled(mode);
	menuButtonSize->setEnabled(mode);
	navButtonSize->setEnabled(mode);
	if(!mode){
		slotSchemeComboboxChanged(schemeCombobox->currentText());
	} else {
		Config::getSingleton().setScheme("none");
	}
}

void ConfigDialogImpl::slotSchemeComboboxChanged(const QString& scheme)
{
	Config& config=Config::getSingleton();
	if(scheme=="Tiny"){
		config.setMenuRadius(72);
		config.setNavButtonSize(22);
		config.setMenuButtonSize(16);
	} else if(scheme=="Small"){
		config.setMenuRadius(100);
		config.setNavButtonSize(32);
		config.setMenuButtonSize(22);
	} if(scheme=="Normal"){
		config.setMenuRadius(132);
		config.setNavButtonSize(32);
		config.setMenuButtonSize(32);
	} if(scheme=="Big"){
		config.setMenuRadius(200);
		config.setNavButtonSize(48);
		config.setMenuButtonSize(48);
	}

	config.setScheme(scheme);
	
	navButtonSize->setCurrentText(QString::number(config.navButtonSize()));
	menuButtonSize->setCurrentText(QString::number(config.menuButtonSize()));
	menuRadiusSpinbox->setValue(config.menuRadius());
	setChanged(true);
}

void ConfigDialogImpl::slotMenuRadiusSpinboxChanged(int size)
{
	Config::getSingleton().setMenuRadius(size);
	setChanged(true);
}

void ConfigDialogImpl::slotNavButtonSizeChanged(const QString& size)
{
	Config::getSingleton().setNavButtonSize(size.toShort());
	setChanged(true);
}

void ConfigDialogImpl::slotMenuButtonSizeChanged(const QString& size)
{
	Config::getSingleton().setMenuButtonSize(size.toShort());
	setChanged(true);
}

void ConfigDialogImpl::slotCommandoTyped(const QString& commando)
{
	menuListView->selectedItem()->setText(1,commando);
	setChanged(true);
}

void ConfigDialogImpl::slotMenuViewClicked(QListViewItem* item)
{
	MenuListViewItem* temp = static_cast<MenuListViewItem*>(item);
	if(item==NULL){
		iconButton->resetIcon();
		iconButton->setEnabled(false);
		commandoEdit->setEnabled(false);
		remove->setEnabled(false);
	} else {
		if(temp->iconPath()!=NULL){
			iconButton->setIcon(temp->iconPath());
		} else {
			iconButton->resetIcon();
		}
		if(temp->type()==MenuListViewItem::Button){
			commandoEdit->setEnabled(true);
			commandoEdit->setText(temp->text(1));
		} else {
			commandoEdit->setEnabled(false);
		}
		iconButton->setEnabled(true);
		remove->setEnabled(true);
	}
}

void ConfigDialogImpl::slotNewIcon()
{
	MenuListViewItem* temp = static_cast<MenuListViewItem*>(menuListView->selectedItem());
	temp->setIconPath(iconButton->icon());
	setChanged(true);
}

void ConfigDialogImpl::slotRemoveClicked()
{
	QListViewItem* temp = menuListView->selectedItem()->nextSibling();
	delete menuListView->selectedItem();
	menuListView->setSelected(temp,true);
	if(temp==NULL){
		remove->setEnabled(false);
	}
	setChanged(true);
}

void ConfigDialogImpl::slotAddButtonClicked()
{
	createEntry("Button");
}

void ConfigDialogImpl::slotAddMenuClicked()
{
	createEntry("Menu");
}

void ConfigDialogImpl::createEntry( QString kind )
{
	QListViewItem* parent=NULL;
	QListViewItem* newItem;
	MenuListViewItem* selected =static_cast<MenuListViewItem*>(menuListView->selectedItem());
	MenuListViewItem::ItemType type;
	if(selected!=NULL){
		if(selected->type()==MenuListViewItem::Menu){
			parent=selected;
			selected=selected->lastChild();
		} else if(selected->parent()!=NULL){
			parent=selected->parent();
		}
	} else {
		selected=static_cast<MenuListViewItem*>(menuListView->lastItem());
	}
	
	if(kind=="Menu"){
		type=MenuListViewItem::Menu;
	} else {
		type=MenuListViewItem::Button;
	}
	
	if(parent!=NULL){
		newItem=new MenuListViewItem(parent,selected,kind,type);
	} else {
		newItem=new MenuListViewItem(menuListView,selected,kind,type);
	}
	
	newItem->setOpen(true);
	menuListView->setSelected(newItem,true);
	setChanged(true);
}

void ConfigDialogImpl::slotListBoxClicked(QListBoxItem* item)
{
	if(item!=NULL){
		if(item->text()=="Menu"){
			shortcutFrame->hide();
			colorFrame->hide();
			MenuFrame->show();
		} else if(item->text()=="Shortcuts"){
			MenuFrame->hide();
			colorFrame->hide();
			shortcutFrame->show();
		} else if(item->text()=="Appearance"){
			MenuFrame->hide();
			colorFrame->show();
			shortcutFrame->hide();
		}
	}
}

void ConfigDialogImpl::slotResetClicked()
{
	Config::getSingleton().toListView(menuListView);
	commandoEdit->setEnabled(false);
	setChanged(false);
}

void ConfigDialogImpl::slotApplyClicked()
{
	Config::getSingleton().fromConfigDlg(menuListView);
	Config::getSingleton().writeConfigFile();
	Config::getSingleton().toKommandoMenu(&kommandoWin);
	setChanged(false);
}

void ConfigDialogImpl::reject()
{
	if(configChanged){
		slotResetClicked();
	}
	hide();
}

void ConfigDialogImpl::accept()
{
	if(configChanged){
		slotApplyClicked();
	}
	hide();
}

void ConfigDialogImpl::slotShortcutChanged(const KShortcut & cut )
{
	if(!KKeyChooser::checkGlobalShortcutsConflict(cut,true,this)){
		Shortcut.setShortcut("Toggle",cut);
		Shortcut.updateConnections();
		kKeyButton1->setText(cut.toString());
		Config::getSingleton().setShortcut(cut.toString());
		setChanged(true);
	}
}

void ConfigDialogImpl::slotColorButtonClicked(const QColor& color)
{
	Config::getSingleton().setTintColor(color);
	setChanged(true);
}

void ConfigDialogImpl::slotOpacitySliderChanged( int value )
{
	Config::getSingleton().setOpacity(static_cast<float>(value)/100.0f);
	setChanged(true);
}

void ConfigDialogImpl::slotAddService(KService* service)
{
	slotAddButtonClicked();

	QString commando = service->exec();
	commando.remove(QRegExp(" %.\\b"));
	commando.remove(" -caption \"%c\"");
	commandoEdit->setText(commando);
	menuListView->selectedItem()->setText(1, commando);
	iconButton->setIcon(service->icon());
	slotNewIcon();
}

#include "configdialogimpl.moc"