#include "rules.h"

#include "rule.h"

#include <qlayout.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qcombobox.h>
#include <qspinbox.h>
#include <qlabel.h>
#include <qcheckbox.h>

#include <klocale.h>
#include <ksimpleconfig.h>
#include <kinputdialog.h>

#include "config.h"

// Changeable attributes
// * player.lives           [1  - 3]      Initial number of lives per player
// * player.power           [1  - 3]      Initial power per player
// * player.bombs           [1  - 3]      Initial number of bombs per player
// * monster.lives          [1  - 3]      Initial number of lives per monster
// * monster.power          [1  - 3]      Initial power per monster
// * monster.bombs          [1  - 3]      Initial number of bombs per monster
// - monster.blastfrequency [0% - 100%]   Probability of monsters placing bombs
// * flash.number           [0  - 3]      Number of hidden flash bomb items
// * invisible.number       [0  - 3]      Number of hidden invisibility items
// * grail.number           [0  - 3]      Number of hidden grail items
// * speed.number           [0  - 3]      Number of hidden speed items
// * power.number           [0  - 10]     Number of hidden power items
// * life.number            [0  - 10]     Number of hidden life items
// * bomb.number            [0  - 10]     Number of hidden bomb items
// - bomb.destroy           [y  / n]      Destroy bombs when hit by explosion?
// - bomb.lock              [y  / n]      Lock players and monsters by bombs?
// - bomb.duration          [10 - 100]    Ticks until a bomb explodes
// * timebomb.allowed       [y  / n]      Are time bombs allowed?
// * moveablebomb.allowed   [y  / n]      Are moveable bombs allowed?
// * scree.percentage       [0% - 50%]    Scree ground coverage
// - wall.damage            [y  / n]      Damage walls consecutively?
// - ground.damage          [y  / n]      Damage ground consecutively?

Rules::Rules(QWidget *parent, const char *name)
: QTabDialog(parent, name)
{
	QGridLayout *vbox_player, *vbox_monster, *vbox_map, *vbox_rules;
	QWidget *playertab, *monstertab, *maptab, *rulestab;

	playertab = new QWidget(this);
	monstertab = new QWidget(this);
	maptab = new QWidget(this);
	rulestab = new QWidget(this);

	player_lives = new QSpinBox(1, 3, 1, playertab);
	player_power = new QSpinBox(1, 3, 1, playertab);
	player_bombs = new QSpinBox(1, 3, 1, playertab);

	lplayer_lives = new QLabel(i18n("Lives"), playertab);
	lplayer_power = new QLabel(i18n("Power"), playertab);
	lplayer_bombs = new QLabel(i18n("Bombs"), playertab);

	monster_lives = new QSpinBox(1, 3, 1, monstertab);
	monster_power = new QSpinBox(1, 3, 1, monstertab);
	monster_bombs = new QSpinBox(1, 3, 1, monstertab);
	monster_blast = new QSpinBox(0, 100, 1, monstertab);

	lmonster_lives = new QLabel(i18n("Lives"), monstertab);
	lmonster_power = new QLabel(i18n("Power"), monstertab);
	lmonster_bombs = new QLabel(i18n("Bombs"), monstertab);
	lmonster_blast = new QLabel(i18n("Blast frequency in %"), monstertab);

	map_grail = new QSpinBox(0, 3, 1, maptab);
	map_speed = new QSpinBox(0, 3, 1, maptab);
	map_power = new QSpinBox(0, 10, 1, maptab);
	map_life = new QSpinBox(0, 10, 1, maptab);
	map_bombs = new QSpinBox(0, 10, 1, maptab);
	map_invisible = new QSpinBox(0, 3, 1, maptab);
	map_flash = new QSpinBox(0, 3, 1, maptab);

	lmap_grail = new QLabel(i18n("Grails"), maptab);
	lmap_speed = new QLabel(i18n("Speed"), maptab);
	lmap_power = new QLabel(i18n("Power"), maptab);
	lmap_life = new QLabel(i18n("Life"), maptab);
	lmap_bombs = new QLabel(i18n("Bombs"), maptab);
	lmap_invisible = new QLabel(i18n("Invisible"), maptab);
	lmap_flash = new QLabel(i18n("Flash"), maptab);

	rules_bombduration = new QSpinBox(10, 100, 1, rulestab);
	rules_screepercentage = new QSpinBox(0, 80, 1, rulestab);
	rules_bombdestroy = new QCheckBox(rulestab);
	rules_bomblock = new QCheckBox(rulestab);
	rules_timebomballowed = new QCheckBox(rulestab);
	rules_moveablebomballowed = new QCheckBox(rulestab);
	rules_walldamage = new QCheckBox(rulestab);
	rules_grounddamage = new QCheckBox(rulestab);

	lrules_bombduration = new QLabel(i18n("Bomb tick duration"), rulestab);
	lrules_screepercentage = new QLabel(i18n("Initial scree in %"), rulestab);
	lrules_bombdestroy = new QLabel(i18n("Destroy bombs by blasts"), rulestab);
	lrules_bomblock = new QLabel(i18n("Bombs lock players"), rulestab);
	lrules_timebomballowed = new QLabel(i18n("Allow time bombs"), rulestab);
	lrules_moveablebomballowed = new QLabel(i18n("Allow moveable bombs"), rulestab);
	lrules_walldamage = new QLabel(i18n("Damage walls by explosions"), rulestab);
	lrules_grounddamage = new QLabel(i18n("Damage grounds by explosions"), rulestab);

	vbox_monster = new QGridLayout(monstertab, 5, 4, 2);
	vbox_player = new QGridLayout(playertab, 5, 3, 2);
	vbox_map = new QGridLayout(maptab, 5, 7, 2);
	vbox_rules = new QGridLayout(rulestab, 5, 8, 2);

	vbox_player->addWidget(lplayer_lives, 0, 0);
	vbox_player->addWidget(player_lives, 0, 1);
	vbox_player->addWidget(lplayer_power, 1, 0);
	vbox_player->addWidget(player_power, 1, 1);
	vbox_player->addWidget(lplayer_bombs, 2, 0);
	vbox_player->addWidget(player_bombs, 2, 1);

	vbox_monster->addWidget(lmonster_lives, 0, 0);
	vbox_monster->addWidget(monster_lives, 0, 1);
	vbox_monster->addWidget(lmonster_power, 1, 0);
	vbox_monster->addWidget(monster_power, 1, 1);
	vbox_monster->addWidget(lmonster_bombs, 2, 0);
	vbox_monster->addWidget(monster_bombs, 2, 1);
	vbox_monster->addWidget(lmonster_blast, 3, 0);
	vbox_monster->addWidget(monster_blast, 3, 1);

	vbox_map->addWidget(lmap_grail, 0, 0);
	vbox_map->addWidget(map_grail, 0, 1);
	vbox_map->addWidget(lmap_speed, 1, 0);
	vbox_map->addWidget(map_speed, 1, 1);
	vbox_map->addWidget(lmap_power, 2, 0);
	vbox_map->addWidget(map_power, 2, 1);
	vbox_map->addWidget(lmap_life, 3, 0);
	vbox_map->addWidget(map_life, 3, 1);
	vbox_map->addWidget(lmap_bombs, 4, 0);
	vbox_map->addWidget(map_bombs, 4, 1);
	vbox_map->addWidget(lmap_invisible, 5, 0);
	vbox_map->addWidget(map_invisible, 5, 1);
	vbox_map->addWidget(lmap_flash, 6, 0);
	vbox_map->addWidget(map_flash, 6, 1);

	vbox_rules->addWidget(lrules_bombduration, 0, 0);
	vbox_rules->addWidget(rules_bombduration, 0, 1);
	vbox_rules->addWidget(lrules_screepercentage, 1, 0);
	vbox_rules->addWidget(rules_screepercentage, 1, 1);
	vbox_rules->addWidget(lrules_bombdestroy, 2, 0);
	vbox_rules->addWidget(rules_bombdestroy, 2, 1);
	vbox_rules->addWidget(lrules_bomblock, 3, 0);
	vbox_rules->addWidget(rules_bomblock, 3, 1);
	vbox_rules->addWidget(lrules_timebomballowed, 4, 0);
	vbox_rules->addWidget(rules_timebomballowed, 4, 1);
	vbox_rules->addWidget(lrules_moveablebomballowed, 5, 0);
	vbox_rules->addWidget(rules_moveablebomballowed, 5, 1);
	vbox_rules->addWidget(lrules_walldamage, 6, 0);
	vbox_rules->addWidget(rules_walldamage, 6, 1);
	vbox_rules->addWidget(lrules_grounddamage, 7, 0);
	vbox_rules->addWidget(rules_grounddamage, 7, 1);

	addTab(playertab, i18n("Players"));
	addTab(monstertab, i18n("Monsters"));
	addTab(maptab, i18n("Map"));
	addTab(rulestab, i18n("Rules"));

	connect(this, SIGNAL(applyButtonPressed()), SLOT(slotAccept()));

	setCaption(i18n("Change game rules"));
	resize(600, 400);
}

Rules::~Rules()
{
}

void Rules::slotAccept()
{
	m_rulesname = KInputDialog::getText(i18n("Rules profile"), i18n("Name of the rules profile:"), m_rulesname);
	if(!m_rulesname.isNull()) saveRules(rules());
	accept();
}

Rule *Rules::rules()
{
	Rule *r = new Rule();
	r->player_lives = player_lives->value();
	r->player_power = player_power->value();
	r->player_bombs = player_bombs->value();
	r->monster_lives = monster_lives->value();
	r->monster_power = monster_power->value();
	r->monster_bombs = monster_bombs->value();
	r->monster_blastfrequency = monster_blast->value();
	r->invisible_number = map_invisible->value();
	r->flash_number = map_flash->value();
	r->grail_number = map_grail->value();
	r->speed_number = map_speed->value();
	r->power_number = map_power->value();
	r->life_number = map_life->value();
	r->bomb_number = map_bombs->value();
	r->bomb_destroy = rules_bombdestroy->isChecked();
	r->bomb_lock = rules_bomblock->isChecked();
	r->bomb_duration = rules_bombduration->value();
	r->timebomb_allowed = rules_timebomballowed->isChecked();
	r->moveablebomb_allowed = rules_moveablebomballowed->isChecked();
	r->scree_percentage = rules_screepercentage->value();
	r->wall_damage = rules_walldamage->isChecked();
	r->ground_damage = rules_grounddamage->isChecked();

	return r;
}

void Rules::setRules(Rule *rules)
{
	player_lives->setValue(rules->player_lives);
	player_power->setValue(rules->player_power);
	player_bombs->setValue(rules->player_bombs);
	monster_lives->setValue(rules->monster_lives);
	monster_power->setValue(rules->monster_power);
	monster_bombs->setValue(rules->monster_bombs);
	monster_blast->setValue(rules->monster_blastfrequency);
	map_invisible->setValue(rules->invisible_number);
	map_flash->setValue(rules->flash_number);
	map_grail->setValue(rules->grail_number);
	map_speed->setValue(rules->speed_number);
	map_power->setValue(rules->power_number);
	map_life->setValue(rules->life_number);
	map_bombs->setValue(rules->bomb_number);
	rules_bombdestroy->setChecked(rules->bomb_destroy);
	rules_bomblock->setChecked(rules->bomb_lock);
	rules_bombduration->setValue(rules->bomb_duration);
	rules_timebomballowed->setChecked(rules->timebomb_allowed);
	rules_moveablebomballowed->setChecked(rules->moveablebomb_allowed);
	rules_screepercentage->setValue(rules->scree_percentage);
	rules_walldamage->setChecked(rules->wall_damage);
	rules_grounddamage->setChecked(rules->ground_damage);
}

QString Rules::name()
{
	return m_rulesname;
}

void Rules::setName(QString name)
{
	m_rulesname = name;
	Rule *rules = loadRules();
	setRules(rules);
	delete rules;
}

void Rules::saveRules(Rule *rules)
{
	if(m_rulesname == i18n("Standard rules")) return;

	KSimpleConfig conf("kamikazerules");
	conf.setGroup(m_rulesname);

	conf.writeEntry("player_lives", rules->player_lives);
	conf.writeEntry("player_power", rules->player_power);
	conf.writeEntry("player_bombs", rules->player_bombs);
	conf.writeEntry("monster_lives", rules->monster_lives);
	conf.writeEntry("monster_power", rules->monster_power);
	conf.writeEntry("monster_bombs", rules->monster_power);
	conf.writeEntry("monster_blastfrequency", rules->monster_bombs);
	conf.writeEntry("invisible_number", rules->invisible_number);
	conf.writeEntry("flash_number", rules->flash_number);
	conf.writeEntry("grail_number", rules->grail_number);
	conf.writeEntry("speed_number", rules->speed_number);
	conf.writeEntry("power_number", rules->power_number);
	conf.writeEntry("life_number", rules->life_number);
	conf.writeEntry("bomb_number", rules->bomb_number);
	conf.writeEntry("bomb_destroy", rules->bomb_destroy);
	conf.writeEntry("bomb_lock", rules->bomb_lock);
	conf.writeEntry("bomb_duration", rules->bomb_duration);
	conf.writeEntry("timebomb_allowed", rules->timebomb_allowed);
	conf.writeEntry("moveablebomb_allowed", rules->moveablebomb_allowed);
	conf.writeEntry("scree_percentage", rules->scree_percentage);
	conf.writeEntry("wall_damage", rules->wall_damage);
	conf.writeEntry("ground_damage", rules->ground_damage);

	conf.sync();
}

Rule *Rules::loadRules()
{
	Rule *rules = new Rule();

	KSimpleConfig conf("kamikazerules");
	if(!conf.hasGroup(m_rulesname)) return rules;
	conf.setGroup(m_rulesname);

	rules->player_lives = conf.readNumEntry("player_lives");
	rules->player_power = conf.readNumEntry("player_power");
	rules->player_bombs = conf.readNumEntry("player_bombs");
	rules->monster_lives = conf.readNumEntry("monster_lives");
	rules->monster_power = conf.readNumEntry("monster_power");
	rules->monster_power = conf.readNumEntry("monster_bombs");
	rules->monster_bombs = conf.readNumEntry("monster_blastfrequency");
	rules->invisible_number = conf.readNumEntry("invisible_number");
	rules->flash_number = conf.readNumEntry("flash_number");
	rules->grail_number = conf.readNumEntry("grail_number");
	rules->speed_number = conf.readNumEntry("speed_number");
	rules->power_number = conf.readNumEntry("power_number");
	rules->life_number = conf.readNumEntry("life_number");
	rules->bomb_number = conf.readNumEntry("bomb_number");
	rules->bomb_destroy = conf.readNumEntry("bomb_destroy");
	rules->bomb_lock = conf.readNumEntry("bomb_lock");
	rules->bomb_duration = conf.readNumEntry("bomb_duration");
	rules->timebomb_allowed = conf.readNumEntry("timebomb_allowed");
	rules->moveablebomb_allowed = conf.readNumEntry("moveablebomb_allowed");
	rules->scree_percentage = conf.readNumEntry("scree_percentage");
	rules->wall_damage = conf.readNumEntry("wall_damage");
	rules->ground_damage = conf.readNumEntry("ground_damage");

	return rules;
}

