// ------------------------------------------------------------------------
/*
	\author: Jaap Suter
   
	Copyright (C) Electronic Arts Canada Inc. 2002.  All rights reserved.	
*/
// ------------------------------------------------------------------------

/*! \file */

#ifndef RANDOM_INPUT_STATE_IMPL_H
#define RANDOM_INPUT_STATE_IMPL_H

#include "reveal/input_state.h"
#include <math.h>
#include <time.h>

namespace Reveal {

// -------------------------------------------------------------------------------
/*!
	\brief Random input state implementation so we can debug things easily;
*/
// -------------------------------------------------------------------------------
class RandomInputStateImpl : public InputState
{
public:

	/*!
		\brief Constructor, does nothing special, seeds the random number generator;
	*/
    RandomInputStateImpl() : mMouseRelX( 0 ), mMouseRelY( 0 ), mAuxRelX( 0 ), mAuxRelY( 0 ), mLeftShoulder( 0 ), mRightShoulder( 0 ), mDown( 0 ) 
	{
		srand( static_cast< unsigned int >( time( 0 ) ) );
	}

protected:

	//! Implementation of the pure base virtual;
    virtual int DoMouseRelX()  const { return mMouseRelX; }
	
	//! Implementation of the pure base virtual;
	virtual int DoMouseRelY()  const { return mMouseRelY; }

	//! Implementation of the pure base virtual;
	virtual int DoAuxRelX() const { return mAuxRelX; }

	//! Implementation of the pure base virtual;
	virtual int DoAuxRelY() const { return mAuxRelY; }

	//! Implementation of the pure base virtual;
	virtual int DoLeftShoulder() const {  return mLeftShoulder; }

	//! Implementation of the pure base virtual;
	virtual int DoRightShoulder() const {  return mRightShoulder; }
	
	//! Implementation of the pure base virtual;
	virtual Reveal::uint32_t DoDown() const { return mDown;  }

private:
	
	//! Implementation of the base virtual;
	void DoUpdate()
	{
		if ( (rand() & 127) < 64 ) mMouseInsteadOfKeys = !mMouseInsteadOfKeys;

		if ( mMouseInsteadOfKeys )
		{
			if ( (rand() & 255) < 8 )
			{
				mMouseRelX = (rand() & 31) - 15;
				mMouseRelY = (rand() & 31) - 15;
			}
			if ( (rand() & 255) < 4 )
			{
				mMouseRelX = (rand() & 255) - 128;
				mMouseRelX = (rand() & 255) - 128;
			}
		}
		else
		{
			mMouseRelX = 0;
			mMouseRelY = 0;
		}		
		
		mAuxRelX   = (rand() & 1023) - 512;
		mAuxRelY   = (rand() & 1023) - 512;
        mLeftShoulder = (rand() & 511) - 256;
		mLeftShoulder = (rand() & 511) - 256;

		mDown &= ~(InputState::LEFT | InputState::RIGHT | InputState::UP | InputState::DOWN );
		const int direction = rand() % 4;
		if ( direction == 0 ) mDown |= InputState::LEFT; else
		if ( direction == 1 ) mDown |= InputState::RIGHT; else
		if ( direction == 2 ) mDown |= InputState::UP; else
		if ( direction == 3 ) mDown |= InputState::DOWN;

		if ( mMouseInsteadOfKeys )
		{
			mDown &= ~(InputState::LEFT_MOUSE| InputState::RIGHT_MOUSE);
			const int mouseButtons = rand() % 3;
			if ( mouseButtons == 0 ) mDown |= InputState::LEFT_MOUSE; else
			if ( mouseButtons == 1 ) mDown |= InputState::RIGHT_MOUSE;
		}
		
		mDown &= ~(InputState::BACK| InputState::CONFIRM);
		const int backOrConfirm = rand() % 3;
		if  ( backOrConfirm <= 1 ) mDown ^= InputState::CONFIRM; else
		if  ( backOrConfirm == 2 ) mDown ^= InputState::BACK;
	}

	int mMouseRelX;
	int mMouseRelY;
	int mAuxRelX;
	int mAuxRelY;
	int mLeftShoulder;
	int mRightShoulder;
	int mDown;

	bool mMouseInsteadOfKeys;
};

} // Namespace Reveal;

#endif
