/****************************************************************
**
** Attal : Lords of Doom
**
** fightUnit.cpp
** Manage Units
**
** Version : $Id: fightUnit.cpp,v 1.11 2004/05/12 17:33:41 tribunal2 Exp $
**
** Author(s) : Pascal Audoux
**
** Date : 28/12/2000
**
** Licence :
**	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, 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.
**
****************************************************************/

#include "fightUnit.h"

// generic include files
#include <math.h>
// include files for QT
#include <qbrush.h>
#include <qimage.h>
#include <qpainter.h>
#include <qrect.h>
// application specific include files
#include "libCommon/attalSettings.h"
#include "libCommon/dataTheme.h"
#include "libCommon/log.h"

#include "libFight/fightCell.h"

#include "libClient/imageTheme.h"

#include "conf.h"

extern DataTheme DataTheme;
extern ImageTheme ImageTheme;

/** rtti number for GraphicalFightUnit class */
const int FightUnit::RTTI = 2234;


FightUnit::FightUnit( QCanvas * canvas )
: QCanvasSprite( (*ImageTheme.creatures[0])[0], canvas ), GenericFightUnit()
{
	_cpt = 0;
	_fifo.setAutoDelete( false );
 	collisions( true );
 	setFrame( 0 );
	setZ( CAN_LORD );
	show();
}

FightUnit::FightUnit( QCanvas * canvas, GenericFightUnit * unit, bool mirror )
	: QCanvasSprite( (*ImageTheme.creatures[0])[0], canvas ),
	  GenericFightUnit( *unit )
{
	_cpt = 0;
	_fifo.setAutoDelete( false );
 	collisions( true );
 	setFrame( 0 );
	setZ( CAN_LORD );
	show();
	QCanvasPixmapArray * sequence = (*ImageTheme.creatures[computeSequence( unit )])[ (mirror) ? 1 : 0 ];

	if( sequence ) {
		setSequence( sequence );
	}

	_lookingToRight = mirror;
}

FightUnit::~FightUnit()
{

}

void FightUnit::initCreatureForMove( GraphicalFightCell *cell )
{
	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();
	bool lookingToRight = isLookingToRight ();
	QCanvasPixmapArray frameArray;

	CreaturePixmap* basePixs = ImageTheme.getCreature ( race , level );
	setSequence ( (*basePixs)[ lookingToRight?0:1 ] );

	setFrame ( creature->getFirstAnimationFrame( Moving ) );

	QRect endRect = cell->boundingRect ();

	QRect startRect = endRect;

	if( _moving ) {
		startRect = _moving->boundingRect();
		double dx = double ( endRect.x() - startRect.x() ) / 10.0;
		double dy = double ( endRect.y() - startRect.y() ) / 10.0;
		setVelocity( dx, dy );
	} else {
		//setX( endRect.x () );
		//setY( endRect.y () );
		_cpt = 10;
		setVelocity( 0, 0 );
	}
}

/*!

*/

int FightUnit::hit( int nb )
{
	int ret = GenericFightUnit::hit( nb );
	if( _number == 0 ) {
		setDestroyed( true );
	}

	return ret;
}


void FightUnit::goTo( FightCell * cell )
{
	if( _currentFightCell ) {
		_currentFightCell->setUnit( NULL );
	}

	FightSettings fsettings = AttalSettings::getFightSettings ();

	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();

	if( fsettings.IsAnimationEnabled ) {
		if( DataTheme.creatures.at( race , level )->isAnimated() ) {
			_currentAnimationType = Moving;
			canvas()->setAdvancePeriod ( 100 );
			if( creature->getNumFrames() > 0 ) {
				_cpt = 10;
				setAnimated ( true );
				if( _fifo.count() == 0 ) {
					_moving = (FightCell*)getCell();

				}
				_fifo.enqueue( cell );
			}
		} else {
			setPosition( cell );
		}
	} else {
		setPosition( cell );
	}

	GenericFightUnit::goTo( (GenericFightCell *)cell );
	cell->setUnit( (GenericFightUnit *)this );
}

void FightUnit::setPosition( FightCell * cell )
{
	if( _currentFightCell ) {
		_currentFightCell->setUnit( NULL );
	}



	Creature * creature = getCreature();
	QRect rect = cell->boundingRect();

        move( rect.x() + creature->getXOffset() - boundingRect().width() + 2 * rect.width(), rect.y() + ( rect.height() ) - boundingRect().height() + creature->getYOffset() );

        canvas()->update();

	GenericFightUnit::goTo( (GenericFightCell *)cell );
	cell->setUnit( (GenericFightUnit *)this );
}

void FightUnit::advance( int stage )
{
	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();
	if( DataTheme.creatures.at( race , level )->isAnimated() ) {
		if( stage == 1 ) {
			setFrame ( frame() + 1 );

			Creature* creature = getCreature ();

			switch ( _currentAnimationType )
			{
			case Moving:

				if( (uint)frame() >= creature->getLastAnimationFrame( Moving ) ) {
					setFrame( creature->getFirstAnimationFrame( Moving ) );
				}
				_cpt++;
				if( _cpt > 10 ) {
					_cpt = 0;
					if( _fifo.count() > 0 ) {
						FightCell * temp = _fifo.dequeue();
						initCreatureForMove( temp );
						_moving = temp;
					} else {
						setFrame( creature->getFirstAnimationFrame( Moving ) );
						if( _moving ) {
							setPosition( _moving );
						}
						setVelocity( 0, 0 );
						_moving = 0;
						setAnimated( false );
					}
				}
				break;
			case Shooting:
				if( (uint)frame() >= creature->getLastAnimationFrame( Shooting ) ) {
					setFrame( creature->getFirstAnimationFrame( Moving ) );
					setAnimated ( false );
				}
				break;
			case Defending:
				if( (uint)frame() >= creature->getLastAnimationFrame( Defending ) ) {
					setFrame( creature->getFirstAnimationFrame( Moving ) );
					setAnimated ( false );
				}
				break;
			case Fighting:
				if( (uint)frame() >= creature->getLastAnimationFrame( Fighting ) ) {
					setAnimated ( false );
				}
				break;
			default: break;
			}
		} else {

		}

		QCanvasSprite::advance ( stage );
	} else {
		logDD( "advance not animated %d %d", race, level );
	}
}

void FightUnit::draw ( QPainter& painter )
{
	QCanvasSprite::draw ( painter );

	int numItems = getNumber ();

	QRect r = boundingRect ();

	int x = r.width () - 30;
	int y = r.height () - 16;

	QFont oldFont = painter.font ();
	QPen oldPen = painter.pen ();
	QBrush oldBrush = painter.brush ();
	QFont f = oldFont;
	QPen pen ( QColor ( 100, 255 , 255 ) );
	painter.setPen ( pen );
	QBrush br ( QColor ( 200, 150, 150 ) );
	painter.setBrush ( br );

	painter.drawRect ( r.left () + x, r.top () + y, 30, 16 );

	QPen fontPen ( QColor ( 120, 130, 240 ) );
	painter.setPen ( fontPen );

	f.setPixelSize ( 12 );
	painter.setFont ( f );

	QString s = QString::number ( numItems );
	painter.drawText ( r.left () + x, r.top () + y, 30, 16, Qt::AlignCenter, s );

	painter.setFont ( oldFont );
	painter.setPen ( oldPen );
	painter.setBrush ( oldBrush );
}

QCanvasPixmap * FightUnit::imageAdvanced() const
{
	return image();
}

void FightUnit::setDestroyed( bool state )
{
	if( state ) {
		setSequence( ImageTheme.deadCreature );
		setFrame( 0 );
	}
}

void FightUnit::animateShooting ()
{
	FightSettings fsettings = AttalSettings::getFightSettings ();

	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();

	if( fsettings.IsAnimationEnabled ) {
		if( DataTheme.creatures.at( race , level )->isAnimated() ) {
			_currentAnimationType = Shooting;

			canvas()->setAdvancePeriod ( 200 );
			setAnimated ( true );

			setFrame ( creature->getFirstAnimationFrame( Shooting ) );


		}
	}
}

void FightUnit::animateDefending ()
{
	FightSettings fsettings = AttalSettings::getFightSettings ();

	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();

	if( fsettings.IsAnimationEnabled ) {
		if( DataTheme.creatures.at( race , level )->isAnimated() ) {
			_currentAnimationType = Defending;

			canvas()->setAdvancePeriod ( 200 );
			setAnimated ( true );

			setFrame ( creature->getFirstAnimationFrame( Defending ) );
		}
	}
}

void FightUnit::animateFighting ()
{
	FightSettings fsettings = AttalSettings::getFightSettings ();

	Creature* creature = getCreature ();
	uint race = creature->getRace ();
	uint level = creature->getLevel ();

	if( fsettings.IsAnimationEnabled ) {
		if( DataTheme.creatures.at( race , level )->isAnimated() ) {
			_currentAnimationType = Fighting;

			canvas()->setAdvancePeriod ( 200 );
			setAnimated ( true );

			setFrame ( creature->getFirstAnimationFrame( Fighting ) );
		}
	}
}



