/*
   Copyright (C) 2007 Daniel Lindenfelser

   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 "cg_local.h"

int damage_indicator_dir_values[DAMAGE_INDICATOR_DIR_MAX] = { 0, 0, 0, 0 };
int damage_indicator_health = 0;

static unsigned int damage_update_dir = 0;
static unsigned int damage_update = 0;

cvar_t *cg_damage_indicator_fade;
cvar_t *cg_damage_indicator_dir_fade;
cvar_t *cg_damage_indicator;
cvar_t *cg_damage_indicator_dir;

void CG_SetDamageIndicatorValues( int yaw, int damage )
{
	if( cg_damage_indicator->integer != 0 )
		damage_indicator_health += damage;

	if( cg_damage_indicator_dir->integer != 0 )
	{
		if( abs( yaw ) < 40 ) // Front
		{
			damage_indicator_dir_values[DAMAGE_INDICATOR_DIR_FRONT] += damage;
		}
		else if( ( abs( yaw ) > 140 ) ) // Behind
		{
			damage_indicator_dir_values[DAMAGE_INDICATOR_DIR_BEHIND] += damage;
		}
		else if( yaw >= 0 ) // Left
		{
			damage_indicator_dir_values[DAMAGE_INDICATOR_DIR_LEFT] += damage;
		}
		else // Right
		{
			damage_indicator_dir_values[DAMAGE_INDICATOR_DIR_RIGHT] += damage;
		}
	}
}

void CG_UpdateDamageIndicator( entity_state_t *ent )
{
	int yaw;
	vec3_t vec, angles;
	centity_t *owner = &cg_entities[ent->ownerNum];

	if( !ISVIEWERENTITY( ent->ownerNum ) )
		return;

	if( cg_damage_indicator->integer != 0 || cg_damage_indicator_dir->integer != 0 )
	{
		VectorSubtract( ent->origin, owner->current.origin, vec );
		VecToAngles( vec, angles );
		yaw = AngleNormalize180( angles[YAW] ) - AngleNormalize180( owner->current.angles[YAW] );
		CG_SetDamageIndicatorValues( yaw, ent->damage );
	}
}

void CG_UpdateDamageIndicatorValues( void )
{
	int i;
	int fade;

	if( cg_damage_indicator->integer != 0 )
	{
		fade = cg_damage_indicator_fade->integer;
		if( damage_update < cg.time )
		{
			damage_update = cg.time + fade;
			if( damage_indicator_health <= 0 )
				damage_indicator_health = 0;
			else
				damage_indicator_health -= 1;
		}
	}

	if( cg_damage_indicator_dir->integer != 0 )
	{
		fade = cg_damage_indicator_dir_fade->integer;
		if( damage_update_dir < cg.time )
		{
			damage_update_dir = cg.time + fade;
			for( i = 0; i < DAMAGE_INDICATOR_DIR_MAX; i++ )
			{
				if( damage_indicator_dir_values[i] <= 0 )
					damage_indicator_dir_values[i] = 0;
				else
					damage_indicator_dir_values[i] -= 1;
			}
		}
	}
}

int CG_GetDamageIndicatorDir( int type )
{
	if( type >= 0 && type < DAMAGE_INDICATOR_DIR_MAX )
		return damage_indicator_dir_values[type];
	return 0;
}

int CG_GetDamageIndicatorHealth( void )
{
	return damage_indicator_health;
}

void CG_ResetDamageIndicator( void )
{
	int i;

	damage_indicator_health = 0;
	for( i = 0; i < DAMAGE_INDICATOR_DIR_MAX; i++ )
		damage_indicator_dir_values[i] = 0;

	damage_update = 0;
	damage_update_dir = 0;
}

float CG_GetDamageAlpha( int damage )
{
	float alpha;

	alpha = cg.frame.playerState.stats[STAT_HEALTH] + cg.frame.playerState.stats[STAT_ARMOR];

	if( alpha < 0 )
		CG_ResetDamageIndicator();

	alpha = alpha / 1000;
	alpha = alpha * damage;

	if( alpha > 1 )
		alpha = 1;
	if( alpha < 0 )
		alpha = 0;

	return alpha;
}

float CG_GetDamageIndicatorDirAlpha( int type )
{
	float alpha = 0;

	if( cg_damage_indicator_dir->integer != 0 )
	{
		if( type >= 0 && type < DAMAGE_INDICATOR_DIR_MAX )
		{
			alpha = CG_GetDamageAlpha( damage_indicator_dir_values[type] );
		}
		return alpha;
	}
	else
	{
		return 0;
	}
}

float CG_GetDamageIndicatorAlpha( void )
{
	if( cg_damage_indicator->integer != 0 )
		return CG_GetDamageAlpha( damage_indicator_health );
	return 0;
}
