/***************************************************************************
 *   Copyright (C) 2004 by ian reinhart geiser                             *
 *   ian@geiseri.com                                                       *
 *                                                                         *
 *   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 "player.h"
#include "group.h"
#include "race.h"
#include "util.h"
#include "monster.h"
#include "wepon.h"
#include "armor.h"
#include "spell.h"

#include <QPixmap>

Player::Player(QString name, Race *race, Group *group) : Unit(name)
{
	seed();
	m_race = race;
	m_group = group;
	m_strength = roll( 5,4 );
	m_dexterity = roll( 5,4 );
	m_wisdom = roll( 5,4 );
	m_hitpoints = roll( 2,6 );
	m_experiance = 0;
	m_manna = 0;
	m_karma = 0;
	m_damage = 0;
	m_karmaUsed = 0;
	m_mannaUsed = 0;
}


Player::~Player()
{}

int Player::strength( ) const
{
	return range( 5, 20, m_strength + m_race->strength() + m_group->strength() );
}

int Player::dexterity( ) const
{
	return range( 5, 20, m_dexterity + m_race->dexterity() + m_group->dexterity() );
}

int Player::wisdom( ) const
{
	return range( 5, 20, m_wisdom + m_race->wisdom() + m_group->wisdom() );
}

int Player::experiance( ) const
{
	return m_experiance;
}

int Player::manna( ) const
{
	return m_manna + m_race->manna() + m_group->manna() - m_mannaUsed;
}

int Player::karma( ) const
{
	return m_karma + m_race->karma() + m_group->karma() - m_karmaUsed;
}

bool Player::save(const QString &vs ) const
{
	int save = m_saves[vs];
	save += m_race->saves(vs);
	save += m_wepon->saveVersus(vs);
	save += m_armor->saveVersus(vs);
	save += m_group->saves(vs);
	return ( roll( 2, 10 ) < save );
}

int Player::skill( const QString & skill ) const
{
	return m_skills[ skill ];
}

void Player::train( const QString & skill, int points )
{
	m_skills[skill] += points;
}

void Player::rest( )
{
	m_damage -= roll( 2, 8 );
	m_mannaUsed -= roll( 2, 8 );
	max( m_damage, 0 );
	max( m_mannaUsed, 0);
}

void Player::pray( )
{
	m_karmaUsed -= roll( 2, 8 );
	max( m_karmaUsed, 0 );
}

int Player::toHit(Attack at , Armor *ac ) const
{
	int val = m_group->baseThaco();
	switch( at )
	{
			case CUT:
			val -= ac->cut();
			break;
			case BASH:
			val -= ac->bash();
			break;
			case THRUST:
			val -= ac->thrust();
			break;
			default:
			break;
	}
	return val;
}

bool Player::cast( Monster * mon, const QString & spell ) const
{
	Spell *sp = m_group->spell( spell );
	if( sp == 0 )
		return false;
#warning Find a better way to do this.

	return sp->cast(mon, const_cast<Player*>( this) );
}

bool Player::melee( Unit * unit, Attack at) const
{
	int value = roll( 1, 20 );
	int skill = m_skills[m_wepon->name()];
	if( value == 20 ) // Natural hit
	{
		unit->hurt(1000);
		return true;
	}
	else if ( value >= unit->toHit( at, m_armor ) )
	{
		switch( at )
		{
				case CUT:
				unit->hurt(m_wepon->cut( this ) );
				break;
				case BASH:
				unit->hurt(m_wepon->bash( this ) );
				break;
				case THRUST:
				unit->hurt(m_wepon->thrust( this ) );
				break;
		}
		return true;
	}
	return false;
}

int Player::morale( ) const
{
	return 20 * (m_hitpoints + m_manna + m_karma - m_damage - m_karmaUsed - m_mannaUsed)
		/(m_hitpoints + m_manna + m_karma);
}

QPixmap Player::sprite() const
{
	qDebug("ask");
	QPixmap pix(16,16);
	pix.fill( Qt::red );
	return pix;
}

bool Player::wield( Wepon *wep)
{
	m_wepon = wep;
	return true;
}

bool Player::wear( Armor *arm)
{
	m_armor = arm;
	return true;
}



