#include <iostream.h>
#include "User.h"
#include "Space.h"
#include "Globals.h"
#include "Pellet.h"

#include <stdio.h>

User::User( DisplayInterface &d, int x, int y, int _actingspeed, 
		    Direction _direction ) : Mobile( _actingspeed, _direction )
{
	d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT );

	super_time = 0;         // no eaten super pellet
	pacman_flash = false;
}

// returns user identity
int User::identify( )
{
	return user_id;
}

// takes a turn to act in the world:
//	Determines movement of pacman in world
bool User::act( DisplayInterface &d, World *w, int x, int y, int time )
{
	if (super_time > 0)
		if (--super_time <= 0)
		{
			pacman_flash = false;
			d.StopWAV();
		}

//	char intstring[10];
//	sprintf( intstring, "%d ", super_time);
//	d.DrawString(40,0,intstring);

	if( time % actingspeed == 0 && lastmoved != time ) {
		lastmoved = time;
		char c;
		bool quit = false;
		if (d.readchar(c, quit)) 
		{
			if (quit)
				return false;

			switch( c ) {
			case 'q': case 'Q': case (char)27:
				return false;
				break;
			case 'a': case 'A':
				direction = WEST;
				break;
			case 'd': case 'D':
				direction = EAST;
				break;
			case 'w': case 'W':
				direction = NORTH;
				break;
			case 's': case 'S':
				direction = SOUTH;
				break;
			}
		}
		
		//Level wrapping... 
		int newx = x + (direction == EAST ? 1 : 0) + (direction == WEST ? -1 : 0);
		if (newx < 0)
			newx = w->get_width()-1;
		if (newx > w->get_width()-1)
			newx = 0;

		int newy = y + (direction == NORTH ? -1 : 0) + (direction == SOUTH ? 1 : 0);
		if (newy < 0)
			newy = w->get_height()-1;
		if (newy > w->get_height()-1)
			newy = 0;

		if( newx != x || newy != y ) 
		{
			//alternates flash state, so pacman changes normal to super
			if (super_time > 0)
				pacman_flash = ! pacman_flash;

			switch( w->get_object( newx, newy )->identify( ) ) 
			{
			case space_id:
				w->swap_object( d, x, y, newx, newy );
				break;
			case ghost_id:
				if (super_time > 0)
				{
					// d.PlayWAV("eatghost.wav");
					Object *o = w->get_object( newx, newy );
					w->ChangeScoreBy(d, score_inc_eat_ghost);
					o->die( d, w, newx, newy );
					delete o;
					
					//replace ghost with space and swap
					Object *tmp = new Space( d, newx, newy );
					w->set_object( d, newx, newy, tmp );
					w->swap_object( d, x, y, newx, newy );
				}
				else
				{
					//die, and return true if remaining lives > 0
					die( d, w, x, y );
					return (w->GetLives() > 0);
				}
				break;
			case pellet_id:
				{ 
					if (super_time == 0)
						d.PlayWAV("pellet.wav");
   					Pellet *p = static_cast<Pellet*>(w->get_object( newx, newy ));
					if (p->is_super())
					{
						if (super_time == 0)
							d.LoopWAV("powermusic.wav");
						super_time += pellet_power_time_increment;
					}
					p->die( d, w, newx, newy );
					delete p;

					//replace pellet with space and swap
					Object *tmp = new Space( d, newx, newy );
					w->set_object( d, newx, newy, tmp );
					w->swap_object( d, x, y, newx, newy );
					w->ChangeScoreBy(d, 1);
					w->AtePellet(d);
					break;
				}
			case wall_id:
				if (super_time > 0)
					this->show(d, w, x, y);
				break;
			}  // end switch
		} // if
	}
	return true;
}

// disappears from the world
void User::die( DisplayInterface &d, World *w, int x, int y )
{
	w->UserDied(d, x, y);
}

// shows the object at its spot in the world
void User::show( DisplayInterface &d, World *w, int x, int y )
{
	if (pacman_flash)	
		d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT_FLASH );
	else
		d.DrawSprite( x, y, SPRITE_PACMAN_RIGHT );
}

// Returns true if SuperPellet has not run out
bool User::is_super () const
{
	return (super_time > 0);
}