/*	Curtains.c - by Chris Wilson

	It's curtains for you, my lad!
*/


#include "global.h"
#include "main.h"

#include "maths.h"
#include "actor.h"
#include "scenics.h"
#include "enemies.h"
#include "charactr.h"
#include "fma.h"

#include "curtains.h"

#define MAX_ROPE_MOVEMENT	(800)

struct{
	SCENIC *pLeftRope;
	SCENIC *pRightRope;
	VECTOR leftPos;
	VECTOR rightPos;
	CHARACTER *pCharOnLeft;
	CHARACTER *pCharOnRight;
}curtainVars;

void curtainsInitialise(void)
{
	SCENIC *pS;
	
	curtainVars.pLeftRope = NULL;
	curtainVars.pRightRope = NULL;
	curtainVars.pCharOnLeft = NULL;
	curtainVars.pCharOnRight = NULL;

	// CPW: Find ropes
	for(pS = scenicList; pS; pS=pS->next)
	{
		if(pS->flags & SCENICFLAG_IS_CLINGY_FOR_RATS)
		{
			if(pS->tag & 1)
			{
				curtainVars.pRightRope = pS;
				COPYVECTOR(&curtainVars.rightPos, &pS->pActor->position);
			}
			else
			{
				curtainVars.pLeftRope = pS;
				COPYVECTOR(&curtainVars.leftPos, &pS->pActor->position);
			}
		}
	}


	if(curtainVars.pLeftRope)
		curtainVars.pLeftRope->pActor->position.vy+=MAX_ROPE_MOVEMENT;

	if(curtainVars.pRightRope)
		curtainVars.pRightRope->pActor->position.vy-=MAX_ROPE_MOVEMENT;

	if((!curtainVars.pLeftRope) && (!curtainVars.pRightRope))
		DB(" *** No ropes found\n");
	else
		DB(" *** Ropes: Left = %p, Right = %p\n", curtainVars.pLeftRope, curtainVars.pRightRope);
}

void curtainsRatOnRope(CHARACTER *pC, SCENIC *pRope)
{
	if(pRope == curtainVars.pLeftRope)
		curtainVars.pCharOnLeft = pC;
	else
	{
		if(pRope == curtainVars.pRightRope)
			curtainVars.pCharOnRight = pC;
		else
			ASSERT(0);
	}
}

// CPW: NICK is heavier than FETCHER
int curtainTable[3][3]={
/* left ->			NULL							NICK								FETCHER
   right */
/* NULL */{CURTAINS_PUZZLE_NOTHINGHAPPENS,	CURTAINS_PUZZLE_NOTHINGHAPPENS,		CURTAINS_PUZZLE_NOTHINGHAPPENS},
/* NICK */{CURTAINS_PUZZLE_CLOSEBUTNOCIGAR,	CURTAINS_PUZZLE_IMPOSSIBLE,			CURTAINS_PUZZLE_SUCCESS},
/* FCHR */{CURTAINS_PUZZLE_CLOSEBUTNOCIGAR,	CURTAINS_PUZZLE_NOTHINGHAPPENS,		CURTAINS_PUZZLE_IMPOSSIBLE}
};

void curtainsSetRatOnRope(int side, void *p)
{
	if(side==0)	// CPW: left
		curtainVars.pCharOnLeft = p;
	else
		curtainVars.pCharOnRight = p;
}

CHARACTER *curtainsGetRatOnRope(int side)
{
	if(side==0)	// CPW: left
		return curtainVars.pCharOnLeft;
	else
		return curtainVars.pCharOnRight;
}

int curtainsEvaluatePuzzle(void)
{
// CPW: 	if((curtainVars.pCharOnLeft->pEnemy->readData.nameCRC == CRC_NICK) && (curtainVars.pCharOnRight->pEnemy->readData.nameCRC == CRC_FETCHER))
// CPW: 		return CURTAINS_PUZZLE_SUCCESS;

	int left = 0, right = 0;

	if(curtainVars.pCharOnLeft)
		left = (curtainVars.pCharOnLeft->pEnemy->readData.nameCRC == CRC_NICK)?1:2;

	if(curtainVars.pCharOnRight)
		right = (curtainVars.pCharOnRight->pEnemy->readData.nameCRC == CRC_NICK)?1:2;

	// CPW: DB("right = %d, left = %d\n", right, left);

	return curtainTable[right][left];
}

int curtainsMain(void)
{
	int result = curtainsEvaluatePuzzle();
	// CPW: 		static VOID_SUBROUTINE oldCycleRoutine = NULL;
	CHARACTER *pLeftRat = curtainsGetRatOnRope(0), *pRightRat = curtainsGetRatOnRope(1);
	// CPW: static int result2 = CURTAINS_PUZZLE_NOTHINGHAPPENS;

	if(result == CURTAINS_PUZZLE_SUCCESS)
	{
		// CPW: VERIFY(pLeftRat);
		// CPW: VERIFY(pRightRat);

		// CPW: result2 = result;
		DB("Playing WORKS\n");
		startFMA("WORKS");
	}

	if(result == CURTAINS_PUZZLE_CLOSEBUTNOCIGAR)
	{
		// CPW: result2 = result;

		if((!pLeftRat) && (pRightRat && pRightRat->pEnemy->readData.nameCRC == CRC_NICK))
		{
			DB("Playing FAIL03\n");
			startFMA("FAIL03");
		}

		if((!pLeftRat) && (pRightRat && pRightRat->pEnemy->readData.nameCRC == CRC_FETCHER))
		{
			DB("Playing FAIL02\n");
			startFMA("FAIL02");
		}

		if(	(pLeftRat && pLeftRat->pEnemy->readData.nameCRC == CRC_NICK)
			&& (pRightRat && pRightRat->pEnemy->readData.nameCRC == CRC_FETCHER))
		{
			DB("Playing FAIL01\n");
			startFMA("FAIL01");
		}
	}

	// CPW: DB("cycle_routine = %p, FMAtestCycle = %p\n", cycle_routine, FMAtestCycle);

	if(((result == CURTAINS_PUZZLE_SUCCESS) || (result == CURTAINS_PUZZLE_CLOSEBUTNOCIGAR))/* && (cycle_routine != FMAtestCycle)*/)
	{
		POSMARK *pMark;

		DB("Setting to STATE_WANDERING\n");
		
		// CPW: result2 == CURTAINS_PUZZLE_NOTHINGHAPPENS;

		// CPW: force rats to a different state. Should normally use SETSTATE()
		if(pLeftRat)
		{
			pLeftRat->pEnemy->state = STATE_WANDERING;
			pLeftRat->pEnemy->stateCtr = 0;
			curtainsSetRatOnRope(0, NULL);
		}

		if(pRightRat)
		{
			pRightRat->pEnemy->state = STATE_WANDERING;
			pRightRat->pEnemy->stateCtr = 0;
			curtainsSetRatOnRope(1, NULL);
		}

		// CPW: put the rat on the windowsill
		pMark = levinfoFindMarker(123);
		VERIFY(pMark);

		pLeftRat->pEnemy->pos.vx = pMark->x;
		pLeftRat->pEnemy->pos.vy = pMark->y;
		pLeftRat->pEnemy->pos.vz = pMark->z;

		characterMakeMain(pLeftRat);

	}

// CPW: 			oldCycleRoutine = cycle_routine;

	return 0;
}
