#include "global.h"
#include "main.h"
#include "menu.h"
#include "map_draw.h"
#include "bff_load.h"
#include "collide.h"
#include "debris.h"
#include "lights.h"
#include "timer.h"
#include "maths.h"
#include "overlays.h"
#include "fx.h"
#include "deth.h"
#include "demo.h"
//#include "gametext.h"
#include "enemies.h"
#include "dualshock.h"
#include "map_view.h"
#include "card.h"
#include "map_play.h"
#include "wings.h"
#include "construct.h"
#include "subgame.h"
//#include "text_ids.h"
#include "sound.h"
#include "startup.h"
#include "loadsnd.h"
#include "pause.h"


// All these should be commented out

#define WING_COUNTDOWN_TIME  120
#define WING_TIME_LEFT_FOR_GOLD   40
#define WING_TIME_LEFT_FOR_SILVER 20

#define WING_NUM_OBJECTS_NEEDED 5

#define WING_DEBUG_CAMERA
//#define  WING_VIEW_POS
//#define WING_VIEW_BARS

int WING_FOV = 360;

unsigned int wingButtons[3][2] = {{PAD_TRIANGLE, PAD_SQUARE},{PAD_TRIANGLE, PAD_CROSS},{PAD_CIRCLE, PAD_CROSS}};
int wmButtons[3][2] = { {WM_TRIANGLE, WM_SQUARE},{WM_TRIANGLE, WM_CROSS},{WM_CIRCLE, WM_CROSS}};

VECTOR	wingCamPos[3]=
{
	{256, -496, -840},		
	{-296, -572, -996},		
	{24, -512, -624},		

};

int wingCamXRot[3] = {-68, 40, 44};
int wingCamYRot[3] = {2216, 1856, 4092};


WINGCTRL *wing;



// pole worker
int WW0_XPOS = 952;
int WW0_YPOS = 40;
int WW0_ZPOS = -2829;
int WW0_YROT = 1950;

int WW0_YPOS_DOWN = 460;
int WW0_YPOS_PEEK = 240;


// material worker
int WW1_XPOS = -943;
int WW1_YPOS = 40;
int WW1_ZPOS = -3015;
int WW1_YROT = 2190;

int WW1_YPOS_DOWN = 470;
int WW1_YPOS_PEEK = 260;


// stitch worker BABS
int WW2_XPOS = -9;
int WW2_YPOS = 40;
int WW2_ZPOS = 1450;
int WW2_YROT = 4020;

int WW2_YPOS_DOWN = 360;
int WW2_YPOS_PEEK = 180;


// for camera
int WING_NUM_FRAMES_FOR_CAM_MOVE = 12;


//SOUNDS
//SFX_WINGS_MAKECLOTH,   *  
//SFX_WINGS_MAKEPOLES,    * 
//SFX_WINGS_MAKESTITCHES,  *
//SFX_WINGS_THROWCLOTH,    *
//SFX_WINGS_THROWPOLES,    	*
//SFX_WINGS_THROWSTITCHES, 	 *
//SFX_WINGS_GETUP1,        *
//SFX_WINGS_GETUP2,        	*
//SFX_WINGS_GETUP3,        	 *
//SFX_WINGS_GETUP4,        	  *
//SFX_WINGS_TIRED,         
//SFX_WINGS_BORED,         
//SFX_WINGS_CANTSEE,       
//SFX_WINGS_THEREYOUGO,    
//SFX_WINGS_TOILET,        
//SFX_WINGS_CANWESTOP,     
//SFX_WINGS_FRIGHTENED,    
//SFX_WINGS_THIRSTY,       
//SFX_WINGS_ISFARMER,      
//SFX_WINGS_ENCOURAGE1,		   *
//SFX_WINGS_ENCOURAGE2,			*
//SFX_WINGS_ENCOURAGE3,			 *




// ====================================================================================================
void wingStart()
{
	PSIMODEL *model;

	subGameRestart = FALSE;

	overlayLoadingBegin(1);



	draw_routine = wingDraw;
	cycle_routine = wingCycle;


	wing = (WINGCTRL*)MALLOC(sizeof(WINGCTRL));
	memset(wing, 0, sizeof(WINGCTRL));

	if(gameCalledFrom != GAMECALLEDFROM_DEBUG)
	{
		if(!gameSaveData.levels_available[REPLAY_AVAILABLE_WINGMAKING])
		{
			gameSaveData.levels_available[REPLAY_AVAILABLE_WINGMAKING] = REPLAY_NOTBEATEN;
		}
	}

//	pReadPad->shockEnable=1;	// Need to go from the options screen now. Sorry. Fred
	dsEvent_Init();

	loadsndLoadBank("A4_WINGSHUT");
	mapviewLoadMap("A4_WINGSHUT");
	EXLIGHT_PostBFF();

	loadsndSubGames(LEVNUMBER_A4_WINGSHUT, wing->pSamples, NUM_WINGS_SAMPLES);

	overlayLoadingEnd();





	// pole worker
	wing->workers[WING_POLE].model = BFF_IsModelLoaded("WINGMAKER1");
	ASSERT(wing->workers[WING_POLE].model);
	wing->workers[WING_POLE].actor = actorCreate(wing->workers[WING_POLE].model);
	ASSERT(wing->workers[WING_POLE].actor);
	actorInitAnim(wing->workers[WING_POLE].actor);
	
	wing->workers[WING_POLE].actor->position.vx  = WW0_XPOS;
	wing->workers[WING_POLE].actor->position.vy = WW0_YPOS_PEEK;
	wing->workers[WING_POLE].actor->position.vz  = WW0_ZPOS;
	wing->workers[WING_POLE].actor->psiData.object->rotate.vy = WW0_YROT;

	// material worker
	wing->workers[WING_MATERIAL].model = BFF_IsModelLoaded("WINGMAKER2");
	ASSERT(wing->workers[WING_MATERIAL].model);
	wing->workers[WING_MATERIAL].actor = actorCreate(wing->workers[WING_MATERIAL].model);
	ASSERT(wing->workers[WING_MATERIAL].actor);
	actorInitAnim(wing->workers[WING_MATERIAL].actor);
	
	wing->workers[WING_MATERIAL].actor->position.vx  = WW1_XPOS;
	wing->workers[WING_MATERIAL].actor->position.vy = WW1_YPOS_PEEK;
	wing->workers[WING_MATERIAL].actor->position.vz  = WW1_ZPOS;
	wing->workers[WING_MATERIAL].actor->psiData.object->rotate.vy = WW1_YROT;

	// stitching worker
	wing->workers[WING_STITCH].model = BFF_IsModelLoaded("BABS");
	ASSERT(wing->workers[WING_STITCH].model);
	wing->workers[WING_STITCH].actor = actorCreate(wing->workers[WING_STITCH].model);
	ASSERT(wing->workers[WING_STITCH].actor);
	actorInitAnim(wing->workers[WING_STITCH].actor);
	
	wing->workers[WING_STITCH].actor->position.vx  = WW2_XPOS;
	wing->workers[WING_STITCH].actor->position.vy = WW2_YPOS_PEEK;
	wing->workers[WING_STITCH].actor->position.vz  = WW2_ZPOS;
	wing->workers[WING_STITCH].actor->psiData.object->rotate.vy = WW2_YROT;



	wing->workers[0].targetActorYPos = wing->workers[0].actor->position.vy; 
	wing->workers[1].targetActorYPos = wing->workers[1].actor->position.vy; 
	wing->workers[2].targetActorYPos = wing->workers[2].actor->position.vy; 


	model = BFF_IsModelLoaded("POLES");
	ASSERT(model);
	wing->workers[WING_POLE].produce = actorCreate(model);
	ASSERT(wing->workers[WING_POLE].produce);
	wing->workers[WING_POLE].produce->position.vy = -900;


	model = BFF_IsModelLoaded("MATERIAL");
	ASSERT(model);
	wing->workers[WING_MATERIAL].produce = actorCreate(model);
	ASSERT(wing->workers[WING_MATERIAL].produce);
	wing->workers[WING_MATERIAL].produce->position.vy = -900;


	model = BFF_IsModelLoaded("STITCHES");
	ASSERT(model);
	wing->workers[WING_STITCH].produce = actorCreate(model);
	ASSERT(wing->workers[WING_STITCH].produce);

	wing->workers[WING_STITCH].produce->position.vy = -900;

	



	// so the camera updates once and sets it's position
//	wing->cameraMovingCount = WING_NUM_FRAMES_FOR_CAM_MOVE-2;
//	wing->cameraMoving = TRUE;

	mycamera.vpx = wingCamPos[0].vx;
	mycamera.vpy = wingCamPos[0].vy;
	mycamera.vpz = wingCamPos[0].vz;

	// for ease 
	mycamera.vrx = 1294;
	mycamera.vry = -170;
	mycamera.vrz = -3683;


	// bar back stuff
	wing->bars.backPoles = textureFindInAllBanks("FRAME");
	ASSERT(wing->bars.backPoles);                   
	
	wing->bars.backPolesSelected = textureFindInAllBanks("SELFRAME");
	ASSERT(wing->bars.backPolesSelected);              
	                                
	wing->bars.backCanvas[0] = textureFindInAllBanks("POLES");
	ASSERT(wing->bars.backCanvas[0]);

	wing->bars.backCanvas[1] = textureFindInAllBanks("NAMECANVASS");
	ASSERT(wing->bars.backCanvas[1]);

	wing->bars.backCanvas[2] = textureFindInAllBanks("STITCH");
	ASSERT(wing->bars.backCanvas[2]);
	                                
	//buttons
	wing->bars.buttonTexture = textureFindInAllBanks("BUTBACK");
	ASSERT(wing->bars.buttonTexture);

//	wing->bars.buttonTexture[WM_CROSS] = textureFindInAllBanks("CCROSS");
//	ASSERT(wing->bars.buttonTexture[WM_CROSS]);

//	wing->bars.buttonTexture[WM_TRIANGLE] = textureFindInAllBanks("CTRI");
//	ASSERT(wing->bars.buttonTexture[WM_TRIANGLE]);

//	wing->bars.buttonTexture[WM_CIRCLE] = textureFindInAllBanks("CCIRCLE");
//	ASSERT(wing->bars.buttonTexture[WM_CIRCLE]);	

	// main buttons
	wing->bars.mButtonTexture[WM_SQUARE] = textureFindInAllBanks("SQUARE");
	ASSERT(wing->bars.mButtonTexture[WM_SQUARE]);

	wing->bars.mButtonTexture[WM_CROSS] = textureFindInAllBanks("CROSS");
	ASSERT(wing->bars.mButtonTexture[WM_CROSS]);

	wing->bars.mButtonTexture[WM_TRIANGLE] = textureFindInAllBanks("TRIANGLE");
	ASSERT(wing->bars.mButtonTexture[WM_TRIANGLE]);

	wing->bars.mButtonTexture[WM_CIRCLE] = textureFindInAllBanks("CIRCLE");
	ASSERT(wing->bars.mButtonTexture[WM_CIRCLE]);	



	// In buttons
	wing->bars.buttonInTexture = textureFindInAllBanks("BUTBACK2");
	ASSERT(wing->bars.buttonInTexture);

//	wing->bars.buttonInTexture[WM_CROSS] = textureFindInAllBanks("CINCROSS");
//	ASSERT(wing->bars.buttonInTexture[WM_CROSS]);
	                                
//	wing->bars.buttonInTexture[WM_TRIANGLE] = textureFindInAllBanks("CINTRI");
//	ASSERT(wing->bars.buttonInTexture[WM_TRIANGLE]);
	                                
//	wing->bars.buttonInTexture[WM_CIRCLE] = textureFindInAllBanks("CINCIRCLE");
//	ASSERT(wing->bars.buttonInTexture[WM_CIRCLE]);

	// main In buttons
	wing->bars.mButtonInTexture[WM_SQUARE] = textureFindInAllBanks("INSQUARE");
	ASSERT(wing->bars.mButtonInTexture[WM_SQUARE]);

	wing->bars.mButtonInTexture[WM_CROSS] = textureFindInAllBanks("INCROSS");
	ASSERT(wing->bars.mButtonInTexture[WM_CROSS]);
	                                
	wing->bars.mButtonInTexture[WM_TRIANGLE] = textureFindInAllBanks("INTRIANGLE");
	ASSERT(wing->bars.mButtonInTexture[WM_TRIANGLE]);
	                                
	wing->bars.mButtonInTexture[WM_CIRCLE] = textureFindInAllBanks("INCIRCLE");
	ASSERT(wing->bars.mButtonInTexture[WM_CIRCLE]);

	                                
	

	// bulb
	wing->bars.bulb = textureFindInAllBanks("BULB");
	ASSERT(wing->bars.bulb); 
	wing->bars.bulbAlpha = textureFindInAllBanks("BULBALPHA");
	ASSERT(wing->bars.bulbAlpha);
	       
	
	//fuse
	wing->bars.fuse = textureFindInAllBanks("FUSE");
	ASSERT(wing->bars.fuse);

	wing->bars.pumpup = textureFindInAllBanks("PUMPUP");
	ASSERT(wing->bars.pumpup);

	wing->bars.spring = textureFindInAllBanks("SPRING");
	ASSERT(wing->bars.spring);


	//progress wing bar

	wing->progressBar.wing = textureFindInAllBanks("WMPLAN");
	ASSERT(wing->progressBar.wing);
	
	wing->progressBar.poles = textureFindInAllBanks("WMPOLES");
	ASSERT(wing->progressBar.poles);

	wing->progressBar.material = textureFindInAllBanks("WMMATERIAL");
	ASSERT(wing->progressBar.material);

	wing->progressBar.stitching = textureFindInAllBanks("WMSTITCHING");
	ASSERT(wing->progressBar.stitching);

	wing->arrow = textureFindInAllBanks("RARROW");
	ASSERT(wing->arrow);


//	nmeDogEnsureHourglass();
	initStopWatch(160, 90, WING_FOV);
	initFowler(WING_FOV, SG_WINGS);

	wing->countdown = WING_COUNTDOWN_TIME * FRAMESEC;


	myactor = wing->workers[WING_STITCH].actor;

}

void wingReset()
{
	int i;


	dsEvent_Init();

	wing->state = WM_FADEIN;
	wing->station = 0;//?
	wing->progressBar.progress[0] = 0;
	wing->progressBar.progress[1] = 0;
	wing->progressBar.progress[2] = 0;

	for(i=0; i<3; i++)
	{
		wing->bars.done[i] = 0;
	}



	// pole worker
	wing->workers[WING_POLE].actor->position.vx  = WW0_XPOS;
	wing->workers[WING_POLE].actor->position.vy = WW0_YPOS_PEEK;
	wing->workers[WING_POLE].actor->position.vz  = WW0_ZPOS;
	wing->workers[WING_POLE].actor->psiData.object->rotate.vy = WW0_YROT;

	// material worker
	wing->workers[WING_MATERIAL].actor->position.vx  = WW1_XPOS;
	wing->workers[WING_MATERIAL].actor->position.vy = WW1_YPOS_PEEK;
	wing->workers[WING_MATERIAL].actor->position.vz  = WW1_ZPOS;
	wing->workers[WING_MATERIAL].actor->psiData.object->rotate.vy = WW1_YROT;

	// stitching worker
	wing->workers[WING_STITCH].actor->position.vx  = WW2_XPOS;
	wing->workers[WING_STITCH].actor->position.vy = WW2_YPOS_PEEK;
	wing->workers[WING_STITCH].actor->position.vz  = WW2_ZPOS;
	wing->workers[WING_STITCH].actor->psiData.object->rotate.vy = WW2_YROT;

	wing->workers[0].targetActorYPos = wing->workers[0].actor->position.vy; 
	wing->workers[1].targetActorYPos = wing->workers[1].actor->position.vy; 
	wing->workers[2].targetActorYPos = wing->workers[2].actor->position.vy; 

	wing->workers[WING_POLE].produce->position.vy = -900;
	wing->workers[WING_MATERIAL].produce->position.vy = -900;
	wing->workers[WING_STITCH].produce->position.vy = -900;

	// so the camera updates once and sets it's position
//	wing->cameraMovingCount = WING_NUM_FRAMES_FOR_CAM_MOVE-2;
//	wing->cameraMoving = TRUE;

	mycamera.vpx = wingCamPos[0].vx;
	mycamera.vpy = wingCamPos[0].vy;
	mycamera.vpz = wingCamPos[0].vz;

	// for ease 
	mycamera.vrx = 1294;
	mycamera.vry = -170;
	mycamera.vrz = -3683;

	//progress wing bar
	wing->countdown = WING_COUNTDOWN_TIME * FRAMESEC;


	myactor = wing->workers[WING_STITCH].actor;

	resetStopWatch();
	sound_XA_Start(levinfo->tune_number);


}


/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void wingRestart()
{
	subGameRestart = TRUE;
	wing->frameCount = 1;
	wing->state = WM_FADEOUT;
}



// ====================================================================================================
void wingEnd()
{

	sound_XA_Stop();
	sfxStopChannel(-1);


	if(subGameRestart == TRUE)
	{
		wingReset();
	}
	else
	{
		
		mapviewReleaseMap();
		dsEvent_Init();

		actorFree(wing->workers[0].actor);
		actorFree(wing->workers[1].actor);
		actorFree(wing->workers[2].actor);

		actorFree(wing->workers[0].produce);
		actorFree(wing->workers[1].produce);
		actorFree(wing->workers[2].produce);

		freeStopWatch();
		freeFowler();
		FREE(wing);

		mapviewReleaseMap();

		
		memoryShowStats();
		memoryShow();

		act4SubgameComplete("A4_WORKHUT3");
	}


//	if(subGameRestart == TRUE)
//	{
//		wingStart();
//	}
//	else
//	{
//		act4SubgameComplete("A4_WORKHUT3");
//	}

}

int WING_HGLASS_X = 144;
#if PALMODE == 1
int WING_HGLASS_Y = 48;
#else
int WING_HGLASS_Y = 38;
#endif

int WM_ARROW_Y = -10;




/*	--------------------------------------------------------------------------------
	Function 	: 
	Purpose 	: 
	Parameters 	: 
	Returns 	: 
	Info 		:
*/
void wingFree()
{

	sound_XA_Stop();
	sfxStopChannel(-1);

	mapviewReleaseMap();
	dsEvent_Init();

	actorFree(wing->workers[0].actor);
	actorFree(wing->workers[1].actor);
	actorFree(wing->workers[2].actor);

	actorFree(wing->workers[0].produce);
	actorFree(wing->workers[1].produce);
	actorFree(wing->workers[2].produce);

	freeStopWatch();
	freeFowler();
	FREE(wing);

	memoryShowStats();
	memoryShow();

}



// ====================================================================================================
void wingDraw()
{
	int i;

	GsSetProjection(WING_FOV);

	mapCamSetRefView2L(&mycamera);
	MapDraw_DrawFMA_World((FMA_WORLD2 *)mapview_fma_world);

	EXLIGHT_SetupActorLights(wing->workers[WING_POLE].actor);
	actorDraw(wing->workers[WING_POLE].actor);

	EXLIGHT_SetupActorLights(wing->workers[WING_MATERIAL].actor);
	actorDraw(wing->workers[WING_MATERIAL].actor);

	EXLIGHT_SetupActorLights(wing->workers[WING_STITCH].actor);
	actorDraw(wing->workers[WING_STITCH].actor);


// things they make
	EXLIGHT_SetupActorLights(wing->workers[WING_POLE].produce);
	actorDraw(wing->workers[WING_POLE].produce);

	EXLIGHT_SetupActorLights(wing->workers[WING_MATERIAL].produce);
	actorDraw(wing->workers[WING_MATERIAL].produce);

	EXLIGHT_SetupActorLights(wing->workers[WING_STITCH].produce);
	actorDraw(wing->workers[WING_STITCH].produce);


	wingBarDraw();
	wingDrawProgress();

//	drawStopWatch(4096 - ((4096*wing->countdown)/(WING_COUNTDOWN_TIME * FRAMESEC)));





	switch(wing->state)
	{
		case WM_FADEIN:

			if(subGameRestart == TRUE)
			{
				i= 256 - (wing->frameCount)*10;
				if(i <= 0)
					wing->state = WM_INTRO;
				else
					deathScreenAdd(i, i, i, SEMITRANS_SUB, 2);
			}
			else
				wing->state = WM_INTRO;

			break;

		case WM_INTRO:
			wingDrawIntro();
			drawStopWatch(4096 - ((4096*wing->countdown)/(WING_COUNTDOWN_TIME * FRAMESEC)));

			break;

		case WM_RUNNING:
			DrawDirectionArrows(wing->arrow, WM_ARROW_Y);
			drawStopWatch(4096 - ((4096*wing->countdown)/(WING_COUNTDOWN_TIME * FRAMESEC)));
			break;
		case WM_FINISHING_SUCCEED:
			drawStopWatch(4096 - ((4096*wing->countdown)/(WING_COUNTDOWN_TIME * FRAMESEC)));
			break;
		case WM_FINISHING_FAIL:			 
			drawStopWatch(4096 - ((4096*wing->countdown)/(WING_COUNTDOWN_TIME * FRAMESEC)));
			fontPrintCentred(font, 0, 0, (char*)TEXTSTR(TEXTSTR_SUB_WING_FINISH), 120, 120, 120);
			break;
		case WM_BRONZE_SUCCESS:
			fowlerDraw();
			wingDrawBronzeSuccess();
			break;
		case WM_SILVER_SUCCESS:
			fowlerDraw();
			wingDrawSilverSuccess();
			break;
		case WM_GOLD_SUCCESS:
			fowlerDraw();
			wingDrawGoldSuccess();
			break;
		
		case WM_FAILED:
			fowlerDraw();
			wingDrawFail();
			break;
		case WM_FADEOUT:
			if(subGameRestart == TRUE)
			{
				i= (wing->frameCount)*20;
				if(i > 220)
					deathScreenAdd(255, 255, 255, SEMITRANS_SUB, 0);

				if(i >=255)
				{
					wingEnd();
					return;
				}
				else
					deathScreenAdd(i, i, i, SEMITRANS_SUB, 0);
			}
			else
				wingEnd();

			break;
	}


}

#if PALMODE==1
#define WM_BAR_POSY  -118
#else
#define WM_BAR_POSY  -108
#endif

#define WM_BAR_POSX        -234
#define WM_BAR_POSX_DELTA  154



#define WM_BAR_CANVAS_DX  44
#define WM_BAR_CANVAS_DY  1

#define WM_BAR_BULB_D1X  39
#define WM_BAR_BULB_D2X	 113
#define WM_BAR_BULB_DY	 47


#define WM_BAR_GLOW_D1X  36
#define WM_BAR_GLOW_D2X	 110
#define WM_BAR_GLOW_DY	 48


#define WM_BAR_FUSE_DX     44
//int WM_BAR_FUSE_DX_MAX =44;
#define WM_BAR_FUSE_WIDTH  74

#define WM_BAR_FUSE_DY  21

#define WM_BUTTON_DX   6
#define WM_BUTTON1_DY  5
#define WM_BUTTON2_DY  23
#define WM_BULB_FADE   15

#define	WM_BAR_TEXT_DX  55
#define	WM_BAR_TEXT_DY  5

#define WM_PUMPUP_DX  -34
#define WM_PUMPUP_DY  29
#define WM_PUMPUP_L   41
#define WM_PUMPUP_R   121
#define WM_PUMPUP_T   20
#define WM_PUMPUP_B   40
//int WM_PUMPUP_FUSE_FACTOR = 0;


#define WM_SPRING_X  60
#define WM_SPRING_W  78
#define WM_SPRING_Y  28
#define WM_SPRING_H  12


#define WM_MBUTTON_DX   8
#define WM_MBUTTON1_DY  6
#define WM_MBUTTON2_DY  24



// ====================================================================================================
void wingBarDraw()
{
	int i, x, y, fuse;
	unsigned long alpha;

	for(i=0; i<NUM_WING_WORKERS; i++)
	{
		x = WM_BAR_POSX + i*WM_BAR_POSX_DELTA;
		y = WM_BAR_POSY;

		fuse = (((wing->workers[i].fusePos + wing->workers[i].lastFusePos) * WM_BAR_FUSE_WIDTH)/8192);

		// draw springs 
		if(wing->bars.done[i] == FALSE)
		{
			drawClippedSpriteOverlay(wing->bars.pumpup, x+WM_PUMPUP_DX + fuse, WM_PUMPUP_DY+y, 5, x+WM_PUMPUP_L, x+WM_PUMPUP_R , y+WM_PUMPUP_T, y+WM_PUMPUP_B);
			overlaySizeableSprite(wing->bars.spring, x + fuse + WM_SPRING_X, y + WM_SPRING_Y, WM_SPRING_W - fuse, WM_SPRING_H, 5, 0xff808080);
		}

//		if(wing->state != WM_FADEOUT)
//		{
//			if(wing->bars.done[i] == TRUE)
//				fontPrint(font, x+WM_BAR_TEXT_DX, y+WM_BAR_TEXT_DY, (char*)TEXTSTR(TEXTSTR_SUB_WING_DONE), 30, 38, 35);
//			else if(i == WING_POLE)
//				fontPrint(font, x+WM_BAR_TEXT_DX, y+WM_BAR_TEXT_DY, (char*)TEXTSTR(TEXTSTR_SUB_WING_POLES), 128, 128, 128);
//			else if(i == WING_MATERIAL)
//				fontPrint(font, x+WM_BAR_TEXT_DX, y+WM_BAR_TEXT_DY, (char*)TEXTSTR(TEXTSTR_SUB_WING_CLOTH), 128, 128, 128);
//			else if(i == WING_STITCH)
//				fontPrint(font, x+WM_BAR_TEXT_DX, y+WM_BAR_TEXT_DY, (char*)TEXTSTR(TEXTSTR_SUB_WING_STITCHES), 128, 128, 128);
//		}

																		
		if(wing->bars.done[i] == TRUE)
			overlayTranspSprite(wing->bars.backPoles,x,y,3,0x808080);
		else if((i == wing->station)&&(wing->state != WM_FADEOUT))
			overlaySprite(wing->bars.backPoles,x,y,3,0xffeeeecc | OV_TRANSSPR_SEMI);
		else
			overlaySprite(wing->bars.backPoles,x,y,3,0xff808080);


		if(wing->bars.done[i] == TRUE)
		{																					 //4
			overlayTranspSprite(wing->bars.backCanvas[i],x+WM_BAR_CANVAS_DX,y+WM_BAR_CANVAS_DY,2,0x808080|OV_TRANSSPR_SEMI);
			overlayTranspSprite(wing->bars.bulb, x+WM_BAR_BULB_D1X,y+WM_BAR_BULB_DY,2,0x404040 | OV_TRANSSPR_SEMI);
			overlayTranspSprite(wing->bars.bulb, x+WM_BAR_BULB_D2X,y+WM_BAR_BULB_DY,2,0x404040 | OV_TRANSSPR_SEMI);
		}
		else
		{																			   //4
			overlaySprite(wing->bars.backCanvas[i],x+WM_BAR_CANVAS_DX,y+WM_BAR_CANVAS_DY,2,0xff808080);

			overlayTranspSprite(wing->bars.bulb, x+WM_BAR_BULB_D1X,y+WM_BAR_BULB_DY,2,0x808080 | OV_TRANSSPR_SEMI);
			overlayTranspSprite(wing->bars.bulb, x+WM_BAR_BULB_D2X,y+WM_BAR_BULB_DY,2,0x808080 | OV_TRANSSPR_SEMI);
		}


		if(wing->workers[i].state == WM_CHICKEN_WORKING)
		{
			wing->bars.barAlpha[i][0] =(255 * wing->workers[i].fusePos)/4096;
		}
		else if(wing->bars.barAlpha[i][0] > 0)
		{
			wing->bars.barAlpha[i][0] -= WM_BULB_FADE;
			if(wing->bars.barAlpha[i][0] < 0)
				wing->bars.barAlpha[i][0] = 0;
		}


		if(wing->bars.barAlpha[i][0] > 0)
		{
			alpha =  ((((wing->bars.barAlpha[i][0] * (0x01))>>2)&0xff)) + ((wing->bars.barAlpha[i][0] * (0x01))<<8) + ((((wing->bars.barAlpha[i][0] * (0x01))>>2)&0xff)<<16);
			overlayTranspSprite(wing->bars.bulbAlpha, x+WM_BAR_GLOW_D2X,y+WM_BAR_BULB_DY,1,alpha | OV_TRANSSPR_ADD);
		}


		if(wing->workers[i].state == WM_CHICKEN_READY)
		{
			if(wing->bars.barAlpha[i][1] == 0)
			{
				wing->bars.barAlpha[i][1] = 255;
			}

			if(wing->frameCount % 8  == 0)
				wing->bars.barAlpha[i][1] = 255;

			wing->bars.barAlpha[i][1] -= WM_BULB_FADE;
			if(wing->bars.barAlpha[i][1] < 0)
				wing->bars.barAlpha[i][1] = 0;


		}
		else if(wing->bars.barAlpha[i][1] > 0)
		{
			wing->bars.barAlpha[i][1] -= WM_BULB_FADE;
			if(wing->bars.barAlpha[i][1] < 0)
				wing->bars.barAlpha[i][1] = 0;
		}

		if(wing->bars.barAlpha[i][1] > 0)
		{
			alpha = (wing->bars.barAlpha[i][1] * (0x01)) + ((((wing->bars.barAlpha[i][1] * (0x01))>>2)&0xff)<<8) + ((((wing->bars.barAlpha[i][1] * (0x01))>>2)&0xff)<<16);

			overlayTranspSprite(wing->bars.bulbAlpha, x+WM_BAR_GLOW_D1X,y+WM_BAR_BULB_DY,1, alpha|OV_TRANSSPR_ADD);
		}

		if(wing->bars.done[i] == TRUE)							//  (((wing->workers[i].fusePos + wing->workers[i].lastFusePos) * WM_BAR_FUSE_WIDTH)/8192)
		{
			overlayTranspSprite(wing->bars.fuse,x+WM_BAR_FUSE_DX+fuse ,y+WM_BAR_FUSE_DY,1,0x808080|OV_TRANSSPR_SEMI);
		}
		else
		{
			overlaySprite(wing->bars.fuse,x+WM_BAR_FUSE_DX+ (((wing->workers[i].fusePos + wing->workers[i].lastFusePos) * WM_BAR_FUSE_WIDTH)/8192),y+WM_BAR_FUSE_DY,1,0xff808080);
		}

		if((wing->bars.buttonState[i][0] > 0)||((i == wing->station) && (wing->bars.done[i] == 0) && (wing->workers[i].state != WM_CHICKEN_WORKING)&&(wing->workers[i].state != WM_CHICKEN_READY) && (pReadPad->digital[0] & wingButtons[i][0])))
		{
			overlaySprite(wing->bars.buttonInTexture,x+WM_BUTTON_DX,y+WM_BUTTON1_DY,2,0xff808080);
			overlaySprite(wing->bars.mButtonInTexture[wmButtons[i][0]],x+WM_MBUTTON_DX,y+WM_MBUTTON1_DY,1,0xff808080);


			if(wing->bars.buttonState[i][0] > 0)
				wing->bars.buttonState[i][0]--;
			else
				wing->bars.buttonState[i][0] = 1;

		}
		else  if(wing->bars.done[i] == TRUE)
		{
			overlayTranspSprite(wing->bars.buttonTexture,x+WM_BUTTON_DX,y+WM_BUTTON1_DY,2,0x808080|OV_TRANSSPR_SEMI);
			overlayTranspSprite(wing->bars.mButtonTexture[wmButtons[i][0]],x+WM_MBUTTON_DX,y+WM_MBUTTON1_DY,1,0x808080|OV_TRANSSPR_SEMI);
  		}
		else
		{
			overlaySprite(wing->bars.buttonTexture,x+WM_BUTTON_DX,y+WM_BUTTON1_DY,2,0xff808080);
			overlaySprite(wing->bars.mButtonTexture[wmButtons[i][0]],x+WM_MBUTTON_DX,y+WM_MBUTTON1_DY,1,0xff808080);

		}

		
		
		if((wing->bars.buttonState[i][1] > 0)||((i == wing->station) && (wing->bars.done[i] == 0) && (wing->workers[i].state != WM_CHICKEN_WORKING)&&(wing->workers[i].state != WM_CHICKEN_READY) && (pReadPad->digital[0] & wingButtons[i][1])))
		{
			overlaySprite(wing->bars.buttonInTexture,x+WM_BUTTON_DX,y+WM_BUTTON2_DY,2,0xff808080);
			overlaySprite(wing->bars.mButtonInTexture[wmButtons[i][1]],x+WM_MBUTTON_DX,y+WM_MBUTTON2_DY,1,0xff808080);

			if(wing->bars.buttonState[i][1] > 0)
				wing->bars.buttonState[i][1]--;
			else
				wing->bars.buttonState[i][1] = 1;

		}
		else if(wing->bars.done[i] == TRUE)
		{
			overlayTranspSprite(wing->bars.buttonTexture,x+WM_BUTTON_DX,y+WM_BUTTON2_DY,2,0x808080|OV_TRANSSPR_SEMI);
			overlayTranspSprite(wing->bars.mButtonTexture[wmButtons[i][1]],x+WM_MBUTTON_DX,y+WM_MBUTTON2_DY,1,0x808080|OV_TRANSSPR_SEMI);

		}
		else
		{
			overlaySprite(wing->bars.buttonTexture,x+WM_BUTTON_DX,y+WM_BUTTON2_DY, 2,0xff808080);
			overlaySprite(wing->bars.mButtonTexture[wmButtons[i][1]],x+WM_MBUTTON_DX,y+WM_MBUTTON2_DY,1,0xff808080);

		}

	}
}


// ====================================================================================================
void wingCycle()
{
	int i;

	wing->frameCount++;

	wingCamera();
	dsEvent_Update();

	switch(wing->state)
	{
		case WM_FADEIN:
			break;
		case WM_INTRO:
			if(wing->frameCount > 10)
			{
				if(pReadPad->debounce[0] & PAD_CROSS)
				{
					subGameRestart = FALSE;
					wing->state = WM_RUNNING;
				}
				else if(pReadPad->debounce[0] & PAD_TRIANGLE)
				{
					wing->state = WM_FADEOUT;
					wing->frameCount = 1;
					subGameRestart = FALSE;
				}
			}
			break;
		case WM_RUNNING:


			if(pReadPad->debounce[0] & PAD_START)
			{
				pause_levelplaying = LEVNUMBER_A4_WINGSHUT;
				pauseStart();
				return;
			}

			
			
			
			wing->countdown--;

#ifdef DEBUG
			if(SwimCheatCycle())
			{
				wing->bars.done[0] = TRUE;
				wing->bars.done[1] = TRUE;
				wing->bars.done[2] = TRUE;
				wing->state = WM_FINISHING_SUCCEED;
				wing->frameCount = 1;
			}
#endif



			if(wing->countdown <= 0)
			{
		
				//here
				// at this ppoint any thing already made should carry on being thrown
				// but things not made yet don't get made and all the chickens get scared...
				wing->state = WM_FINISHING_FAIL; // remember succeed gets triggered when games completed
				sfxStopChannel(-1);
				wing->frameCount = 1;

				for(i=0; i<NUM_WING_WORKERS; i++)
				{
					if((wing->workers[i].state <= WM_CHICKEN_WORKING) && ((wing->workers[i].state != WM_CHICKEN_GETTING_SCARED) || (wing->workers[i].state != WM_CHICK_SCARED)))
					{
						wing->workers[i].state = WM_CHICKEN_GETTING_SCARED;
					
					}
				}



//	WM_CHICKEN_GETTING_SCARED,
//	WM_CHICK_SCARED,
//	WM_CHICK_PEEKING,
//	WM_CHICKEN_LOOKING_LR,
//	WM_CHICKEN_MOVING_UP,
//	WM_CHICKEN_UP,
//	WM_CHICKEN_WORKING,
//	WM_CHICKEN_READY,
//	WM_CHICKEN_HANDED_BACK,

			}
			
//			constructControl();

#ifdef DEBUG			
	//		constructDebugMoveActor();
#endif


			wingWorkerUpdate();


			wingPrintDebug();


//			if(pReadPad->debounce[0] & PAD_START)
//				wing->state = WM_FADEOUT;

			break;


		case WM_FINISHING_SUCCEED:

			if(wing->frameCount > 20)
			{
				if(gameCalledFrom != GAMECALLEDFROM_DEBUG)
				{
					gamePlayData->SubGameStates[SUBGAME_WINGS] = REPLAY_BEATEN;
					gameSaveData.levels_available[REPLAY_AVAILABLE_WINGMAKING] = REPLAY_BEATEN;
				}

				if(wing->countdown > (WING_TIME_LEFT_FOR_GOLD*FRAMESEC))
				{
					gameSaveData.medals_won[MEDAL_WON_WINGS] = 3;
					wing->state = WM_GOLD_SUCCESS;
//					fowlerSetMedalSfx(SFX_FOWLER_GOLD);
					startFowler(GOLD);
				}
				else if(wing->countdown > (WING_TIME_LEFT_FOR_SILVER*FRAMESEC))
				{
					if(gameSaveData.medals_won[MEDAL_WON_WINGS] < 2)
						gameSaveData.medals_won[MEDAL_WON_WINGS] = 2;

					wing->state = WM_SILVER_SUCCESS;
					startFowler(SILVER);
				}
				else
				{
					if(gameSaveData.medals_won[MEDAL_WON_WINGS] < 1)
						gameSaveData.medals_won[MEDAL_WON_WINGS] = 1;

					wing->state = WM_BRONZE_SUCCESS;
					startFowler(BRONZE);
				}
				sound_XA_Start(TUNE_3_COMPLETE + SOUND_XA_NOLOOP);
			}
			wingWorkerUpdate();

			break;

		case WM_FINISHING_FAIL:
			
			wingWorkerUpdate();


			if(wing->frameCount > 40)
			{

				for(i=0; i<NUM_WING_WORKERS; i++)
					if(wing->workers[i].state != WM_CHICK_SCARED)
						break;

				if((i==NUM_WING_WORKERS))
				{
					wing->frameCount = 1;
					wing->state = WM_FAILED; // if you complete the game by one of these last things then the state will be made successfull elsewhere!!!!
					sound_XA_Start(TUNE_4_FAILED + SOUND_XA_NOLOOP);
					startFowler(FAIL);
				}
			}
			break;

		case WM_BRONZE_SUCCESS:
		case WM_SILVER_SUCCESS:
		case WM_GOLD_SUCCESS:
		case WM_FAILED:
			makeFowlerSpeak();
			wingWorkerUpdate();
			if(wing->frameCount > 30) 
			{
				if(pReadPad->debounce[0] & PAD_CROSS)
				{
					wing->frameCount = 1;
					wing->state = WM_FADEOUT;
					subGameRestart = TRUE;
				}
				else if(pReadPad->debounce[0] & PAD_TRIANGLE)
				{
					wing->frameCount = 1;
					wing->state = WM_FADEOUT;
					subGameRestart = FALSE;
				}
			}
			break;

		case WM_FADEOUT:
			break;
	}

	actorMaintainAnimation(wing->workers[WING_POLE].actor);
	actorMaintainAnimation(wing->workers[WING_MATERIAL].actor);
	actorMaintainAnimation(wing->workers[WING_STITCH].actor);
	actorMaintainAnimation(wing->workers[WING_POLE].produce);
	actorMaintainAnimation(wing->workers[WING_MATERIAL].produce);
	actorMaintainAnimation(wing->workers[WING_STITCH].produce);
}



// ====================================================================================================
void wingCamera()
{
	VECTOR look = {0, 0, 4096};
	int xRot, yRot, i, j;
	
	if(wing->cameraMoving)
	{
		wing->cameraMovingCount++;

		xRot = ((wing->cameraMovingCount*wingCamXRot[wing->station]) + ((WING_NUM_FRAMES_FOR_CAM_MOVE -wing->cameraMovingCount)*wingCamXRot[wing->lastStation]))/WING_NUM_FRAMES_FOR_CAM_MOVE;
		yRot = ((wing->cameraMovingCount*wing->cameraTargetYRot) + ((WING_NUM_FRAMES_FOR_CAM_MOVE -wing->cameraMovingCount)*wingCamYRot[wing->lastStation]))/WING_NUM_FRAMES_FOR_CAM_MOVE;


		//DB("xRot = %d, yRot = %d\n",xRot, yRot );

		RotateVector2DXYZ(&look, &look, xRot, 0);
		RotateVector2DXYZ(&look, &look, yRot, 1);


		mycamera.vpx = ((wing->cameraMovingCount*wingCamPos[wing->station].vx) + ((WING_NUM_FRAMES_FOR_CAM_MOVE -wing->cameraMovingCount)*wingCamPos[wing->lastStation].vx))/WING_NUM_FRAMES_FOR_CAM_MOVE;
 		mycamera.vpy = ((wing->cameraMovingCount*wingCamPos[wing->station].vy) + ((WING_NUM_FRAMES_FOR_CAM_MOVE -wing->cameraMovingCount)*wingCamPos[wing->lastStation].vy))/WING_NUM_FRAMES_FOR_CAM_MOVE;
		mycamera.vpz = ((wing->cameraMovingCount*wingCamPos[wing->station].vz) + ((WING_NUM_FRAMES_FOR_CAM_MOVE -wing->cameraMovingCount)*wingCamPos[wing->lastStation].vz))/WING_NUM_FRAMES_FOR_CAM_MOVE;

		mycamera.vrx = mycamera.vpx + look.vx;
		mycamera.vry = mycamera.vpx + look.vy;
		mycamera.vrz = mycamera.vpx + look.vz;


		// update camera
		if (wing->cameraMovingCount >= WING_NUM_FRAMES_FOR_CAM_MOVE) 
			wing->cameraMoving = FALSE;

	}
	else
	{
		//debug

#ifdef WING_DEBUG_CAMERA

		if((pReadPad->digital[0] & PAD_R1) && (!(pReadPad->digital[0] & PAD_L1)))

		{

			if(pReadPad->digital[0] & PAD_LEFT)
				wingCamYRot[wing->station] += 4;
			if(pReadPad->digital[0] & PAD_RIGHT)
				wingCamYRot[wing->station] -= 4;

			if(pReadPad->digital[0] & PAD_UP)
				wingCamXRot[wing->station] -= 4;
			if(pReadPad->digital[0] & PAD_DOWN)
				wingCamXRot[wing->station] += 4;


	//		wingCamXRot[wing->station] &= 4095;
//			wingCamYRot[wing->station] &= 4095;



			RotateVector2DXYZ(&look, &look, wingCamXRot[wing->station], 0);
			RotateVector2DXYZ(&look, &look, wingCamYRot[wing->station], 1);

			mycamera.vrx = mycamera.vpx + look.vx;
			mycamera.vry = mycamera.vpy + look.vy;
			mycamera.vrz = mycamera.vpz + look.vz;
		}

		if((pReadPad->digital[0] & PAD_R2)&& (!(pReadPad->digital[0] & PAD_L1)))
		{
			int dx=0, dy=0, dz=0;



			if(pReadPad->digital[0] & PAD_LEFT)
				dx = 4;
			if(pReadPad->digital[0] & PAD_RIGHT)
				dx = -4;

			if(pReadPad->digital[0] & PAD_UP)
				dz = -4;
			if(pReadPad->digital[0] & PAD_DOWN)
				dz = 4;
		
			if(pReadPad->digital[0] & PAD_TRIANGLE)
				dy = -4;

			if(pReadPad->digital[0] & PAD_SQUARE)
				dy = 4;

			mycamera.vrx += dx;
			mycamera.vry += dy;
			mycamera.vrz += dz;

			mycamera.vpx +=	dx;
			mycamera.vpy +=	dy;
			mycamera.vpz +=	dz;

			wingCamPos[wing->station].vx += dx;
			wingCamPos[wing->station].vy += dy;
			wingCamPos[wing->station].vz += dz;

		}
		else if(!(pReadPad->digital[0] & PAD_L1))
		{
		
		
//	wingCamPos[wing->station].vx = mycamera.vpx;
//	wingCamPos[wing->station].vy = mycamera.vpy;
//	wingCamPos[wing->station].vz = mycamera.vpz;

#endif



		if(wing->state == WM_RUNNING)
		{

			if((pReadPad->analogXS[0] > 400) || (pReadPad->digital[0] & PAD_RIGHT))
			{
				wing->lastStation = wing->station;
				wing->station++;


				if(wing->station >= NUM_WING_WORKERS)
					wing->station = 0;

				// done it like this to avoid getting stuck in a loop
				if(wing->bars.done[wing->station] == TRUE)
				{
					wing->station++;

					if(wing->station >= NUM_WING_WORKERS)
					wing->station = 0;

					if(wing->bars.done[wing->station] == TRUE)
					{
						wing->station++;

						if(wing->station >= NUM_WING_WORKERS)
						wing->station = 0;
					}
				}


	//			sgStartCameraMove(&wingCamPos[wing->station], &wingCamLook[wing->station], WING_NUM_FRAMES_FOR_CAM_MOVE);

				// find out which direction we're going in!
				if(wingCamYRot[wing->lastStation] > wingCamYRot[wing->station])
				{
					i = wingCamYRot[wing->lastStation] - wingCamYRot[wing->station];
					j = 4096 + wingCamYRot[wing->station] - wingCamYRot[wing->lastStation];

					if(j < i)
						wing->cameraTargetYRot = wingCamYRot[wing->station] + 4096;
					else
						wing->cameraTargetYRot = wingCamYRot[wing->station];
				}
				else
				{
					i =  wingCamYRot[wing->station] - wingCamYRot[wing->lastStation];
					j = 4096 + wingCamYRot[wing->lastStation] - wingCamYRot[wing->station];

					if(j < i)
						wing->cameraTargetYRot = wingCamYRot[wing->station] - 4096;
					else
						wing->cameraTargetYRot = wingCamYRot[wing->station];
				}

			//	DB("targetYrot = %d\n", wing->cameraTargetYRot);
			//	DB("lastRot = %d\n\n", wingCamYRot[wing->lastStation]);
				wing->cameraMovingCount = 0;
				wing->cameraMoving = TRUE;
			}
			else if((pReadPad->analogXS[0] < -400)|| (pReadPad->digital[0] & PAD_LEFT))
			{
				wing->lastStation = wing->station;
				wing->station--;

				if(wing->station < 0)
					wing->station = NUM_WING_WORKERS-1;

				if(wing->bars.done[wing->station] == TRUE)
				{
					wing->station--;

					if(wing->station < 0)
						wing->station = NUM_WING_WORKERS-1;

					if(wing->bars.done[wing->station] == TRUE)
					{
						wing->station--;

						if(wing->station < 0)
							wing->station = NUM_WING_WORKERS-1;
					}
				}


	//			sgStartCameraMove(&wingCamPos[wing->station], &wingCamLook[wing->station], WING_NUM_FRAMES_FOR_CAM_MOVE);

				if(wingCamYRot[wing->lastStation] > wingCamYRot[wing->station])
				{
					i = wingCamYRot[wing->lastStation] - wingCamYRot[wing->station];
					j = 4096 + wingCamYRot[wing->station] - wingCamYRot[wing->lastStation];

					if(j < i)
						wing->cameraTargetYRot = wingCamYRot[wing->station] + 4096;
					else
						wing->cameraTargetYRot = wingCamYRot[wing->station];
				}
				else
				{
					i =  wingCamYRot[wing->station] - wingCamYRot[wing->lastStation];
					j = 4096 + wingCamYRot[wing->lastStation] - wingCamYRot[wing->station];

					if(j < i)
						wing->cameraTargetYRot = wingCamYRot[wing->station] - 4096;
					else
						wing->cameraTargetYRot = wingCamYRot[wing->station];
				}

		//		DB("targetYrot = %d\n", wing->cameraTargetYRot);
		//		DB("lastRot = %d\n\n", wingCamYRot[wing->lastStation]);
		//		DB("targetx %d, lastx %d\n\n", wingCamXRot[wing->station], wingCamXRot[wing->lastStation]);


				wing->cameraMovingCount = 0;
				wing->cameraMoving = TRUE;
			}
		}

		myactor = wing->workers[wing->station].produce;//wing->workers[wing->station].actor;


#ifdef WING_DEBUG_CAMERA
		}
#endif

	
	}
}


#define WM_CHICK_YSPEED  18
#define WM_PEEK_POS		 800
#define WM_UP_POS	     3000
#define WM_CHICKEN_WORK  4096
//#define WM_TIME_TO_MAKE  120

// red light timer
#define WM_TIME_TO_WAIT     50

#define WM_MIN_TIME_TO_WAIT 20
int WM_TIME_TOGIVEBACK = 30;

int WM_FUSE_DROP_INACTIVE  = 4;
int WM_FUSE_SPEED		   = 150;
int WM_FUSE_DROP_WORKING   = 20;
int WM_FUSE_DROP_RANDOM    = 40;

int WM_DESK_LEVEL = -270;
int WM_PRODUCE_TOWARDS_CAM = 100;
int WM_INITIAL_PRODUCT_YVEL = -50;
int WM_PRODUCT_GRAVITY  = 20;
int WM_PRODUCE_SPEED = 150;
int WM_PRODUCE_XROT_SPEED = 136;
int WM_PRODUCE_INERTIA = 3900;

VECTOR produceTargetPos[3] = { {330, -255, -1062}, {-402, -244, -1340}, {54, -247, -388} };


// ====================================================================================================
void wingWorkerUpdate()
{
	int i, dist;
	VECTOR tempVect, tempVect2;

	
	
	if((wing->state == WM_RUNNING) && (wing->workers[wing->station].state != WM_CHICKEN_WORKING) && (wing->workers[wing->station].state != WM_CHICKEN_READY) && (wing->bars.done[wing->station] == FALSE))
	{

		if((pReadPad->debounce[0] & wingButtons[wing->station][0]) || (pReadPad->debounce[0] & wingButtons[wing->station][1]))
		{
			wing->gingerCallCount--;
			
			wing->workers[wing->station].fusePos += WM_FUSE_SPEED + WM_FUSE_DROP_INACTIVE;

			if(wing->workers[wing->station].fusePos	> (WM_CHICKEN_WORK+WM_FUSE_DROP_INACTIVE))
				wing->workers[wing->station].fusePos = WM_CHICKEN_WORK+WM_FUSE_DROP_INACTIVE;

		
			if(wing->gingerCallCount <= 0)
			{
				wing->gingerCallCount = 18 + utilRandomInt(12);

//				if(wing->workers[wing->station].fusePos > 3000)
//				{
//					soundPlaySample(wing->pSamples[SFX_WINGS_ENCOURAGE1], 0x9090, 0);
//				}
				if(wing->workers[wing->station].fusePos > 2000)
				{
					soundPlaySample(wing->pSamples[SFX_WINGS_ENCOURAGE3], 0x9090, 0);
				}
				else// if(wing->workers[wing->station].fusePos > 1000)
				{
					soundPlaySample(wing->pSamples[SFX_WINGS_ENCOURAGE2], 0x9090, 0);
				}
			}
		}
	}


	if((wing->babsCallCount-- < 0) &&(wing->station == WING_STITCH)
		&&(wing->state == WM_RUNNING)&&(wing->workers[WING_STITCH].state != WM_CHICKEN_WORKING)&&(wing->workers[WING_STITCH].state != WW_THROW_STUFF)&&(wing->workers[WING_STITCH].state != WM_CHICKEN_READY))
	{
		wing->babsCallCount = 100;

		i = utilRandomInt(9);


		switch(i)
		{
			case 0:		
				soundPlaySample(wing->pSamples[SFX_WINGS_TIRED], 0x8080, 0);
				break;
			case 1:		
				soundPlaySample(wing->pSamples[SFX_WINGS_BORED], 0x8080, 0);
				break;
			case 2:		
				if(wing->workers[WING_STITCH].state == WM_CHICK_SCARED)
					soundPlaySample(wing->pSamples[SFX_WINGS_CANTSEE], 0x8080, 0);
				else
					soundPlaySample(wing->pSamples[SFX_WINGS_FRIGHTENED], 0x8080, 0);

				break;
			case 3:
			case 4:
				soundPlaySample(wing->pSamples[SFX_WINGS_TOILET], 0x8080, 0);
				break;
			case 5:		
				soundPlaySample(wing->pSamples[SFX_WINGS_CANWESTOP], 0x8080, 0);
				break;
			case 6:		
				soundPlaySample(wing->pSamples[SFX_WINGS_FRIGHTENED], 0x8080, 0);
				break;
			case 7:		
				soundPlaySample(wing->pSamples[SFX_WINGS_THIRSTY], 0x8080, 0);
				break;
			case 8:		
			case 9:
				soundPlaySample(wing->pSamples[SFX_WINGS_ISFARMER], 0x8080, 0);
				break;
		}
	}

	for(i=0; i<NUM_WING_WORKERS; i++)
	{
		if(wing->state != WM_RUNNING)
		{
			wing->workers[i].fusePos -= 200;
		}
		
		if(wing->workers[i].state == WM_CHICKEN_WORKING)
		{
			wing->workers[i].fusePos -= wing->workers[i].fuseSpeed;//WM_FUSE_DROP_WORKING;
		}
		else
		{
			wing->workers[i].fusePos -= WM_FUSE_DROP_INACTIVE;
		}

		if(wing->workers[i].fusePos < 0)
			wing->workers[i].fusePos = 0;

		// tryning to smooth out the fuse movement
		wing->workers[i].lastFusePos += wing->workers[i].fusePos;
		wing->workers[i].lastFusePos /= 2;


		switch(wing->workers[i].state)
		{
			case WM_CHICKEN_GETTING_SCARED:
				wing->workers[i].state = WM_CHICK_SCARED;
				actorAnimate(wing->workers[i].actor, WING_LOOK_AROUND, FALSE, FALSE, 156, 0, 1024);
				actorAnimate(wing->workers[i].actor, WING_BREATHE, TRUE, TRUE, 256, 0, 1024);

				switch(i)
				{
					case 0:
						wing->workers[i].targetActorYPos = WW0_YPOS_DOWN;
						break;

					case 1:
						wing->workers[i].targetActorYPos = WW1_YPOS_DOWN;
						break;

					case 2:
						wing->workers[i].targetActorYPos = WW2_YPOS_DOWN;
						break;
				}

				break;
			case WM_CHICK_SCARED:
				if(wing->workers[i].fusePos > WM_PEEK_POS)
				{
					wing->workers[i].state = WM_CHICK_PEEKING;
					wing->workers[i].timer = 10;
					
					switch(i)
					{
						case 0:
							wing->workers[i].targetActorYPos = WW0_YPOS_PEEK;
							break;

						case 1:
							wing->workers[i].targetActorYPos = WW1_YPOS_PEEK;
							break;

						case 2:
							wing->workers[i].targetActorYPos = WW2_YPOS_PEEK;
							break;

					}
				}
				break;
			case WM_CHICK_PEEKING:
				if(--(wing->workers[i].timer) == 0)
				{
					actorAnimate(wing->workers[i].actor, WING_LOOK_AROUND, FALSE, FALSE, 156, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_BREATHE, TRUE, TRUE, 256, 0, 1024);
					wing->workers[i].state = WM_CHICKEN_LOOKING_LR;
					wing->workers[i].timer = 60;

					i = utilRandomInt(3);

					switch(i)
					{
						case 0:
							soundPlaySample(wing->pSamples[SFX_WINGS_GETUP1], 0x7070, 0);
							break;
						
						case 1:
							soundPlaySample(wing->pSamples[SFX_WINGS_GETUP2], 0x7070, 0);
							break;
						
						case 2:
							soundPlaySample(wing->pSamples[SFX_WINGS_GETUP3], 0x7070, 0);
							break;
						
						case 3:
							soundPlaySample(wing->pSamples[SFX_WINGS_GETUP4], 0x7070, 0);
							break;

					}
				}
				break;
			case WM_CHICKEN_LOOKING_LR:   
				if(wing->workers[i].fusePos < WM_PEEK_POS)
				{
					wing->workers[i].state = WM_CHICKEN_GETTING_SCARED;

				}
				else if(wing->workers[i].fusePos > WM_UP_POS)
				{
					wing->workers[i].state = WM_CHICKEN_UP;
					actorAnimate(wing->workers[i].actor, WING_IDLE_SCRATCH_HEAD, FALSE, FALSE, 256, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_BREATHE, TRUE, TRUE, 256, 0, 1024);

					switch(i)
					{
						case 0:
							wing->workers[i].targetActorYPos = WW0_YPOS;
							break;

						case 1:
							wing->workers[i].targetActorYPos = WW1_YPOS;
							break;

						case 2:
							wing->workers[i].targetActorYPos = WW2_YPOS;
							break;

					}
				}
				else if(--(wing->workers[i].timer) == 0)
				{
					wing->workers[i].timer = 80;
					actorAnimate(wing->workers[i].actor, WING_LOOK_AROUND, FALSE, FALSE, 156, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_BREATHE, TRUE, TRUE, 256, 0, 1024);
				}

				break;

			case WM_CHICKEN_MOVING_UP:
				break;
			case WM_CHICKEN_UP:
				if(wing->workers[i].fusePos == WM_CHICKEN_WORK)
				{
					actorAnimate(wing->workers[i].actor, WING_TURN_MAKE, FALSE, FALSE, 256, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_MAKE, FALSE, TRUE, 256, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_MAKE_DISCARD, FALSE, TRUE, 256, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_MAKE, TRUE, TRUE, 256, 0, 1024);

					wing->workers[i].state = WM_CHICKEN_WORKING;
					wing->workers[i].workSound = 0;
					wing->workers[i].fuseSpeed = WM_FUSE_DROP_WORKING + random(WM_FUSE_DROP_RANDOM);
					

					//wing->workers[i].timer = WM_TIME_TO_MAKE;
				}
				break;

			case WM_CHICKEN_WORKING:

				if((wing->workers[i].workSound == 0) && (wing->workers[i].actor->animation.animData[0].segment != WING_TURN_MAKE))
				{
					wing->workers[i].workSound = 1;

					switch(i)
					{
						case 0:
							soundPlaySample(wing->pSamples[SFX_WINGS_MAKEPOLES], 0x8080, 0);
							break;

						case 1:
							soundPlaySample(wing->pSamples[SFX_WINGS_MAKECLOTH], 0x8080, 0);
							break;

						case 2:
							soundPlaySample(wing->pSamples[SFX_WINGS_MAKESTITCHES], 0x8080, 0);
							break;
					}
				}
				
				
				
				if(wing->workers[i].fusePos == 0)//--(wing->workers[i].timer) == 0)
				{

					// stop sound
					switch(i)
					{
						case 0:
							//DB("stopping sample\n");
							sfxStopSample(wing->pSamples[SFX_WINGS_MAKEPOLES], -1);
							break;

						case 1:
							//DB("stopping sample\n");
							sfxStopSample(wing->pSamples[SFX_WINGS_MAKECLOTH], -1);
							break;

						case 2:
							//DB("stopping sample\n");
							sfxStopSample(wing->pSamples[SFX_WINGS_MAKESTITCHES], -1);
							break;
					}



					actorAnimate(wing->workers[i].actor, WING_TURN_ROUND_WITH_SOMETHING, FALSE, FALSE, 256, 0, 1024);


					//actorAnimate(wing->workers[i].actor, WING_TURN_BACK, TRUE, FALSE, 256, 0, 1024);
					wing->workers[i].state = WM_CHICKEN_READY;
					wing->workers[i].timer = WM_TIME_TO_WAIT;
				}
				break;

			case WM_CHICKEN_READY:
				getWorldPosOfBone(wing->workers[i].actor, "LEFT HAND", &tempVect);
				getWorldPosOfBone(wing->workers[i].actor, "RIGHT HAND", &tempVect2);
				ADDTOVECTOR(&tempVect, &tempVect2);
				SCALEVECTOR(&tempVect, 2048);
				moveActorTowardsCamera(wing->workers[i].produce, WM_PRODUCE_TOWARDS_CAM);

				wing->workers[i].produce->position = tempVect;
				wing->workers[i].produce->psiData.object->rotate.vy = wing->workers[i].actor->psiData.object->rotate.vy;




				
				if((--(wing->workers[i].timer) == 0) ||((wing->station == i) && (wing->cameraMoving == 0) && (wing->workers[i].timer < (WM_TIME_TO_WAIT-WM_MIN_TIME_TO_WAIT))))
				{
					//throw down thing
					actorAnimate(wing->workers[i].actor, WING_GIVE, FALSE, FALSE, 256, 0, 1024);
					actorAnimate(wing->workers[i].actor, WING_LOOK_AROUND, TRUE, TRUE, 200, 0, 1024);
					
					wing->workers[i].state = WM_CHICKEN_HANDED_BACK;
					wing->workers[i].timer = WM_TIME_TOGIVEBACK;

					wing->workers[i].velProduce.vx = ((produceTargetPos[i].vx - wing->workers[i].produce->position.vx)*WM_PRODUCE_SPEED)/4096;
					wing->workers[i].velProduce.vz = ((produceTargetPos[i].vz - wing->workers[i].produce->position.vz)*WM_PRODUCE_SPEED)/4096;
					wing->workers[i].velProduce.vy = WM_INITIAL_PRODUCT_YVEL;

					switch(i)
					{
						case 0:
							soundPlaySample(wing->pSamples[SFX_WINGS_FINISH], 0x8070, 0);
							break;

						case 1:
							soundPlaySample(wing->pSamples[SFX_WINGS_FINISH], 0x7080, 0);
							break;

						case 2:
							
							soundPlaySample(wing->pSamples[SFX_WINGS_THEREYOUGO], 0x8080, 0);
							wing->babsCallCount = 100;
							break;
					}




				}
//				else if((wing->station == i) && (wing->cameraMoving == 0) && (wing->workers[i].timer < (WM_TIME_TO_WAIT-WM_MIN_TIME_TO_WAIT)))
//				{
//					actorAnimate(wing->workers[i].actor, WING_GIVE, FALSE, FALSE, 256, 0, 1024);
//					actorAnimate(wing->workers[i].actor, WING_LOOK_AROUND, TRUE, TRUE, 200, 0, 1024);
					
//					wing->workers[i].state = WM_CHICKEN_HANDED_BACK;
//					wing->workers[i].timer = WM_TIME_TOGIVEBACK;


//					wing->workers[i].velProduce.vx = ((produceTargetPos[i].vx - wing->workers[i].produce->position.vx)*WM_PRODUCE_SPEED)/4096;
//					wing->workers[i].velProduce.vz = ((produceTargetPos[i].vz - wing->workers[i].produce->position.vz)*WM_PRODUCE_SPEED)/4096;
//					wing->workers[i].velProduce.vy = WM_INITIAL_PRODUCT_YVEL;

//				}
				break;

			case WM_CHICKEN_HANDED_BACK:
				
				ADDTOVECTOR(&wing->workers[i].produce->position, &wing->workers[i].velProduce);
				wing->workers[i].produce->psiData.object->rotate.vx += WM_PRODUCE_XROT_SPEED;

				if(wing->workers[i].produce->position.vy > WM_DESK_LEVEL)//below desk
				{

					switch(i)
					{
						case 0:
							soundPlaySample(wing->pSamples[SFX_WINGS_DROPPOLES], 0x2020, 0);
							break;

						case 1:
							soundPlaySample(wing->pSamples[SFX_WINGS_DROPCLOTH], 0x2020, 0);
							break;

						case 2:
							soundPlaySample(wing->pSamples[SFX_WINGS_DROPSTITCHES], 0x2020, 0);
							break;
					}

					wing->workers[i].produce->position.vy = WM_DESK_LEVEL - (2048*(wing->workers[i].produce->position.vy - WM_DESK_LEVEL))/4096;
					
					if(i== WING_POLE)
					{
						wing->workers[i].velProduce.vy = -(2448 *wing->workers[i].velProduce.vy)/4096;
						dsEvent_Add(0, 0, 1, 200, 0, 1, 0);
					}
					else
					{
						wing->workers[i].velProduce.vy = -(1824 *wing->workers[i].velProduce.vy)/4096;
						dsEvent_Add(0, 0, 1, 160, 0, 1, 0);
					}

				}
				else
				{
					wing->workers[i].velProduce.vy += WM_PRODUCT_GRAVITY;
				}
				
				if(--(wing->workers[i].timer) == 0)
				{
					wing->workers[i].state = WM_CHICKEN_GETTING_SCARED;
					wing->workers[i].produce->position.vy = -1000;

					if(i == wing->station)
					{
						if(i== WING_POLE)
							dsEvent_Add(0, 0, 1, 200, 0, 3, 0);
						else
							dsEvent_Add(0, 0, 1, 160, 0, 2, 0);

						wing->progressBar.progress[i]++;

						if(wing->progressBar.progress[i] >= WING_NUM_OBJECTS_NEEDED)
						{
							wing->bars.done[i] = TRUE;
							if((wing->bars.done[0] == TRUE)&&(wing->bars.done[1] == TRUE)&&(wing->bars.done[2] == TRUE))
							{
								wing->state = WM_FINISHING_SUCCEED;
								sfxStopChannel(-1);
								wing->frameCount = 1;
							}
						}
					}
				}
				break;
		}

		//move chickens up and down towards target pos
		if(wing->workers[i].actor->position.vy != wing->workers[i].targetActorYPos)
		{
			dist = wing->workers[i].targetActorYPos - wing->workers[i].actor->position.vy;
			if(dist>0)
			{
				if(dist < WM_CHICK_YSPEED)
					wing->workers[i].actor->position.vy = wing->workers[i].targetActorYPos;
				else
					wing->workers[i].actor->position.vy += WM_CHICK_YSPEED;

			}
			else //if(dist<0)
			{
				if(dist > -WM_CHICK_YSPEED)
					wing->workers[i].actor->position.vy = wing->workers[i].targetActorYPos;
				else
					wing->workers[i].actor->position.vy -= WM_CHICK_YSPEED;
			}
		}
	}
}



int WM_PROGRESS_X = -230;
#if PALMODE==1
int WM_PROGRESS_Y = 60;
#else
int WM_PROGRESS_Y = 50;
#endif

int WM_PROGRESS_BACK_DY = 0;
int WM_PROGRESS_BACK_DX = 0;

int WM_CLIP_TOP	   =  0 ;
int WM_CLIP_BOTTOM =  60 ;
int WM_CLIP_LEFT   =  0 ;
int WM_CLIP_RIGHT  =  120 ;


// ====================================================================================================
void wingDrawProgress()
{
	short l,r,t,b;
	
	l = WM_CLIP_LEFT + WM_PROGRESS_X;
	t =	WM_CLIP_TOP + WM_PROGRESS_Y;	  
	b =	WM_CLIP_BOTTOM + WM_PROGRESS_Y;



	r =	(WM_CLIP_RIGHT*wing->progressBar.progress[WING_POLE])/WING_NUM_OBJECTS_NEEDED + WM_PROGRESS_X; 
	drawClippedSpriteOverlay(wing->progressBar.poles, WM_PROGRESS_X, WM_PROGRESS_Y, 3, l, r, t, b);

	r =	(WM_CLIP_RIGHT*wing->progressBar.progress[WING_MATERIAL])/WING_NUM_OBJECTS_NEEDED + WM_PROGRESS_X; 
	drawClippedSpriteOverlay(wing->progressBar.material, WM_PROGRESS_X, WM_PROGRESS_Y, 4, l, r, t, b);

	r =	(WM_CLIP_RIGHT*wing->progressBar.progress[WING_STITCH])/WING_NUM_OBJECTS_NEEDED + WM_PROGRESS_X; 
	drawClippedSpriteOverlay(wing->progressBar.stitching, WM_PROGRESS_X, WM_PROGRESS_Y, 2, l, r, t, b);
		

//	overlaySprite(wing->progressBar.poles, WM_PROGRESS_X+140, WM_PROGRESS_Y, 4,0xff808080);
//	overlaySprite(wing->progressBar.material, WM_PROGRESS_X+240, WM_PROGRESS_Y, 3,0xff808080);
//	overlaySprite(wing->progressBar.stitching, WM_PROGRESS_X+340, WM_PROGRESS_Y, 2,0xff808080);

//	overlaySprite(wing->progressBar.stitching, WM_PROGRESS_X, WM_PROGRESS_Y, 2,0xff808080);
	overlayTranspSprite(wing->progressBar.wing, WM_PROGRESS_X+(WM_PROGRESS_BACK_DX), WM_PROGRESS_Y+(WM_PROGRESS_BACK_DY),5,0x808080 | OV_TRANSSPR_SEMI);

}


void wingDrawIntro()
{

	char string[256];
	
	sprintf(string, "%s\n\n%s\n\n%s\n\n%s",
			fontUpper((char*)TEXTSTR(TEXTSTR_NAME_OF_WINGMAKING)),

			(char*)TEXTSTR(TEXTSTR_SUB_WING_INTRO),
			(char*)TEXTSTR(TEXTSTR_SUB_ENG_BUTTONS),
			(char*)TEXTSTR(TEXTSTR_SUB_XSTART)
			);

	fontPrintMultiLineBox(font, 0, 30, 340, string, 120, 100, 100);
}


// ====================================================================================================
void wingDrawFail()
{
	char string[256];
	
	sprintf(string, "%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_WING_FAIL), (char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, 0, 10, 340, string, 120, 100, 0,2);
}

// ====================================================================================================
void wingDrawGoldSuccess()
{
	char string[256];
	
	sprintf(string, "%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_WING_GOLD), (char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, 0, 10, 340, string, 120, 100, 0,2);
}

// ====================================================================================================
void wingDrawSilverSuccess()
{
	char string[256];
	
	sprintf(string, "%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_WING_SILVER), (char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, 0, 10, 340, string, 120, 100, 0,2);
}

// ====================================================================================================
void wingDrawBronzeSuccess()
{
	char string[256];
	
	sprintf(string, "%s\n%s", (char*)TEXTSTR(TEXTSTR_SUB_WING_BRONZE), (char*)TEXTSTR(TEXTSTR_SUB_GAME_EXIT_RESTART));
	fontPrintMultiLineBoxSetDepth(font, 0, 10, 340, string, 120, 100, 0,2);
}


// ====================================================================================================
void wingPrintDebug()
{
	char strBuff[128];


#ifdef WING_VIEW_POS

	if(myactor)
	{
		sprintf(strBuff, "actorPos: %d %d %d rot %d", (int)myactor->position.vx, (int)myactor->position.vy, (int)myactor->position.vz, (int)myactor->psiData.object->rotate.vy);
		fontPrint(font, -140, 90, strBuff, 128, 128, 0);
	}
#endif

#ifdef UNDEFINEDLY
	sprintf(strBuff, "cam pos: %d  %d  %d", (int)mycamera.vpx, (int)mycamera.vpy, (int)mycamera.vpz);
	fontPrint(font, -240, -110, strBuff, 128, 128, 0);
	sprintf(strBuff, "garib  : %d %d %d", (int)mycamera.vrx, (int)mycamera.vry, (int)mycamera.vrz);
	fontPrint(font, -240, -100, strBuff, 128, 128, 0);

	sprintf(strBuff, "station %d camMove %d", wing->station, wing->cameraMoving);
	fontPrint(font, -240, -90, strBuff, 128, 128, 0);

	

	sprintf(strBuff, "wingCamXRot %d wingCamYRot %d", wingCamXRot[wing->station], wingCamYRot[wing->station]);
	fontPrint(font, -240, -80, strBuff, 128, 128, 0);


//	sprintf(strBuff, "target:%d, last:%d, state:%d", con->cam.targetTool, con->cam.lastTool, con->cam.state);
//	fontPrint(font, -240, -90, strBuff, 128, 128, 0);


#endif

#ifdef WING_VIEW_BARS


	sprintf(strBuff, "fusePos = %d", wing->workers[wing->station].fusePos);
	fontPrint(font, -240, -120, strBuff, 128, 128, 0);

	sprintf(strBuff, "worker state = %d", wing->workers[wing->station].state);
	fontPrint(font, -240, -110, strBuff, 128, 128, 0);

	sprintf(strBuff, "fusePos = %d, lastFuse = %d", wing->workers[wing->station].fusePos, wing->workers[wing->station].lastFusePos);
	fontPrint(font, -240, -100, strBuff, 128, 128, 0);


#endif

#ifdef WING_VIEW_WORKERS_TIMERS
	sprintf(strBuff, "t = %d", wing->workers[0].timer);
	fontPrint(font, -240, -40, strBuff, 128, 128, 128);

	sprintf(strBuff, "t = %d", wing->workers[1].timer);
	fontPrint(font, -240, -30, strBuff, 128, 128, 128);

	sprintf(strBuff, "t = %d", wing->workers[2].timer);
	fontPrint(font, -240, -20, strBuff, 128, 128, 128);

#endif



}


/*
  	WING_TALK,
	WING_TALK_YES,
	WING_TALK_NO,
	WING_TURN_MAKE,
	WING_MAKE,
	WING_MAKE_DISCARD,
	WING_BREATHE,
	WING_IDLE_UMMM,
	WING_IDLE_SCRATCH_HEAD,
	WING_TURN_ROUND_WITH_SOMETHING,
	WING_GIVE,
	WING_LOOK_AROUND,
*/

