//===========================================================================//
// File:	AnimationState.cpp											
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 02/23/999  JSE  Inital coding
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Microsoft Corp.										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "MW4Headers.hpp"
#include "Vehicle.hpp"
#include "MechAnimationState.hpp"
#include "Mech.hpp"

//#############################################################################
//##########################    AnimationStateEngine    ########################
//#############################################################################


MechAnimationStateEngine::ClassData*
	MechAnimationStateEngine::DefaultData = NULL;

const StateEngine::StateEntry
	MechAnimationStateEngine::StateEntries[]=
{
	STATE_ENTRY(MechAnimationStateEngine, Stand),
	STATE_ENTRY(MechAnimationStateEngine, StandHalf),

	STATE_ENTRY(MechAnimationStateEngine, Stand_1_8_th),
	STATE_ENTRY(MechAnimationStateEngine, Stand_2_8_th),
	STATE_ENTRY(MechAnimationStateEngine, Stand_3_8_th),
	STATE_ENTRY(MechAnimationStateEngine, Stand_5_8_th),
	STATE_ENTRY(MechAnimationStateEngine, Stand_6_8_th),
	STATE_ENTRY(MechAnimationStateEngine, Stand_7_8_th),

	STATE_ENTRY(MechAnimationStateEngine, Forward),
	STATE_ENTRY(MechAnimationStateEngine, Backward),

	STATE_ENTRY(MechAnimationStateEngine, TurnLeft),
	STATE_ENTRY(MechAnimationStateEngine, TurnRight),
	
	STATE_ENTRY(MechAnimationStateEngine, LGimpTurnRight),
	STATE_ENTRY(MechAnimationStateEngine, RGimpTurnRight),
	STATE_ENTRY(MechAnimationStateEngine, LGimpTurnLeft),
	STATE_ENTRY(MechAnimationStateEngine, RGimpTurnLeft),


	STATE_ENTRY(MechAnimationStateEngine, GimpStandLeft),
	STATE_ENTRY(MechAnimationStateEngine, GimpForwardLeft),
	STATE_ENTRY(MechAnimationStateEngine, GimpForwardRight),
	STATE_ENTRY(MechAnimationStateEngine, GimpStandRight),

	STATE_ENTRY(MechAnimationStateEngine, FallForward),
	STATE_ENTRY(MechAnimationStateEngine, FallBackward),
	STATE_ENTRY(MechAnimationStateEngine, FallLeft),
	STATE_ENTRY(MechAnimationStateEngine, FallRight),
	STATE_ENTRY(MechAnimationStateEngine, FallCataclysmic),

	STATE_ENTRY(MechAnimationStateEngine, PowerDown),
	STATE_ENTRY(MechAnimationStateEngine, PowerDownCataclysmic),
	
	STATE_ENTRY(MechAnimationStateEngine, Crouch),
	STATE_ENTRY(MechAnimationStateEngine, Fly)

};


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MechAnimationStateEngine::InitializeClass()
{
	Check_Object(AnimationStateEngine::DefaultData);
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MechAnimationStateEngineClassID,
			"MechAnimationStateEngine",
			AnimationStateEngine::DefaultData,
			ELEMENTS(StateEntries),
			StateEntries,
			NULL,
			NULL
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MechAnimationStateEngine::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MechAnimationStateEngine*
	MechAnimationStateEngine::Make(Vehicle *vehicle, const FactoryRequest *request)
{
	Check_Object(request);
	Check_Object(vehicle);
	gos_PushCurrentHeap(Heap);
	MechAnimationStateEngine* engine = new MechAnimationStateEngine(vehicle, DefaultData, request);
	gos_PopCurrentHeap();
	return engine;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MechAnimationStateEngine::Save(FactoryRequest *request)
{
	Check_Object(this);
	Check_Object(request);
	
	AnimationStateEngine::Save(request);


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MechAnimationStateEngine::Reuse(const FactoryRequest *request)
{
	Check_Object(this);
	Check_Object(request);

	AnimationStateEngine::Reuse(request);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MechAnimationStateEngine::MechAnimationStateEngine(
	Vehicle *vehicle,
	ClassData *class_data,
	const FactoryRequest *request
):
	AnimationStateEngine(vehicle, class_data, request)
{
	//can't castobject as it is in the object constructor that this happens
	m_Mech = (Mech*) vehicle;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

MechAnimationStateEngine::~MechAnimationStateEngine()
{

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

int
	MechAnimationStateEngine::RequestState(
		int new_state,
		bool run_minimal,
		void* data
	)
{





	Verify(new_state < StateCount);

	if (m_Mech->GetFastTransition())
	{
		if (new_state == StandState)
		{
			if (GetState() == ForwardState || GetState() == BackwardState)
			{
				if (statePlaying.GetCurrent() != NULL)
				{

					Scalar state_percentage = statePlaying.GetCurrent()->GetStatePercentage();


					if (state_percentage < 0.5)
					{
						if (state_percentage < 0.125)
						{
							new_state = Stand_1_8_thState;
							//SPEW(("jerryeds", "1/8"));
						}
						else if (state_percentage < 0.250)
						{
							new_state = Stand_2_8_thState;
							//SPEW(("jerryeds", "2/8"));
						}
						else if (state_percentage < 0.375)
						{
							new_state = Stand_3_8_thState;
							//SPEW(("jerryeds", "3/8"));
						}
						else
						{
							new_state = StandHalfState;
							//SPEW(("jerryeds", "4/8"));
						}
					}
					else 
					{
					
						if (state_percentage < 0.625)
						{
							new_state = Stand_5_8_thState;
							//SPEW(("jerryeds", "5/8"));
						}
						else if (state_percentage < 0.750)
						{
							new_state = Stand_6_8_thState;
							//SPEW(("jerryeds", "6/8"));
						}
						else if (state_percentage < 0.875)
						{
							new_state = Stand_7_8_thState;
							//SPEW(("jerryeds", "7/8"));
						}
						else 
						{
							new_state = StandState;
							//SPEW(("jerryeds", "8/8"));
						}
					}
				}
			}
		}
	}
	else
	{
		if (new_state == StandState)
		{
			if (GetState() == ForwardState || GetState() == BackwardState)
			{
				if (statePlaying.GetCurrent() != NULL)
				{

					if (statePlaying.GetCurrent()->GetStatePercentage() > 0.95f || statePlaying.GetCurrent()->GetStatePercentage() < 0.45f)
					{
						//SPEWALWAYS(("jerryeds", "HALF STOP : %f", statePlaying.GetCurrent()->GetStatePercentage()));
						new_state = StandHalfState;
					}
				}
			}
		}
	}


	int return_state = AnimationStateEngine::RequestState(new_state, run_minimal, data);

	Mech *mech = Cast_Object( Mech *, vehicleParent);


	switch(GetTransitionState())
	{
		
	
		case FallForwardState:
		case FallBackwardState:
		case FallLeftState:
		case FallRightState:
		case FallCataclysmicState:
		case PowerDownState:
		case PowerDownCataclysmicState:
		case CrouchState:
			mech->FadeUndampened();
			break;

		default:
			mech->FadeDampened();
			break;
	}


	return return_state;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	MechAnimationStateEngine::RunStates(Stuff::Scalar time_slice, bool run_minimal)
{

	//SPEW(("jerryeds", "-------------"));

	if(statePlaying.GetCurrent() != NULL)
	{
		switch(GetState())
		{
			case StandHalfState:
			case Stand_1_8_thState:
			case Stand_2_8_thState:
			case Stand_3_8_thState:
			case Stand_5_8_thState:
			case Stand_6_8_thState:
			case Stand_7_8_thState:
				AnimationStateEngine::RequestState(StandState);
				break;
		}
	}
	
#if 0
	MW4Animation::AnimHierarchyIteratorManager::doTransitionBlend = true;
	if (IsTransitioning())
	{
		if (GetState() == FlyState)
		{
			// turn off transition
			// we only want to turn this off during the first
			// phase of the land...

			if (quedCurrentState)
			{
				MW4Animation::AnimHierarchyIteratorManager::doTransitionBlend = false;
			}
		}
	}
#endif


	AnimationStateEngine::RunStates(time_slice, run_minimal);

}


//#############################################################################
//##########################    AnimationStateEngine    #######################
//#############################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void
	MechAnimationStateEngine::TestClass()
{
	Verify(IsDerivedFrom(DefaultData));
}

