Strict

Import mojo
Import door
Import runningmovement
Import animated
Import font
Import common
Import scene
Import constants
Import scenemanager
Import fontmanager
Import gamedata
Import soundmanager

Const RUNSTAGE_APPROACHING:		Int = 1
Const RUNSTAGE_PREPAREAPPROACH:	Int = 2
Const RUNSTAGE_FINDANOTHER:		Int = 3
Const RUNSTAGE_ENTER:			Int = 4

'This is a mess....
'...
'... but it works...

Class RunScene Extends Scene
	Field currentDoor: Door
	Field doorGeometry: IntRect
	Field movement: RunningMovement
	Field animTimer: Animated
	Field runStage: Int
	Field floorLine: Int
	Field reactionBar: Float
	Field reactionBarRate: Float
	Field approachSpeed: Float
	Field scrollSpeed: Float
	Field frameTime: Int
	Field curDifficultyLevel: Int
	Field numberOfDoors: Int
	Field runningTime: Animated
	Field dialog: Image
	Field reactionTip: Image
	
	Method New()
		animTimer = New Animated()
		
		currentDoor = New Door()		
		doorGeometry = New IntRect(0,0,0,0)

		movement = New RunningMovement (50, 0.006, 6)
		dialog = ImageManager.LoadImg("dialog", 1, Image.MidHandle)
		reactionTip = ImageManager.LoadImg("reaction")
		
		numberOfDoors = 0
		runningTime = New Animated()
		SetRunStage(RUNSTAGE_APPROACHING)
		SetDifficulty (0)
	End
		
	Method Render: Void()
		Local wallStart: Int = 0

		Cls 255, 255, 255
		
		SetColor 0,0,0
		currentDoor.GetInsideGeometry(doorGeometry)
		If runStage = RUNSTAGE_PREPAREAPPROACH Then
			wallStart = currentDoor.x - 400
			DrawLine(wallStart, 0, wallStart, floorLine)
			DrawLine(0, floorLine, wallStart, floorLine)
		Endif
				
		DrawRect (doorGeometry.x, doorGeometry.y, doorGeometry.w, doorGeometry.h)
		DrawLine (wallStart, doorGeometry.y+doorGeometry.h, DeviceWidth(), doorGeometry.y+doorGeometry.h)
		
		If runStage = RUNSTAGE_APPROACHING Then
			SetColor 255, 0, 0
			DrawRect(2, 2, 60*(reactionBar/100), 16)
			DrawImage(reactionTip, 30, 20)
			If currentDoor.GetState() = DOOR_OPENED Then
				DrawImage(dialog, currentDoor.x+40, currentDoor.y-70)
				FontManager.GetBigFont().RenderString(currentDoor.theKey.name, currentDoor.x+40, currentDoor.y-100, True)
			Endif
			SetColor 255,255,255
		Endif
		
		currentDoor.Render()

		FontManager.GetNormalFont().RenderTimeString(runningTime.GetElapsedTime(), DeviceWidth()-120, 2)
	End
	
	Method Update:Void()
		Local cam: Point2D
		
		Select runStage
			Case RUNSTAGE_ENTER
				'Logic
				If animTimer.GetElapsedTime() >= frameTime Then
					currentDoor.SetScale(MINFLOAT(currentDoor.GetScale()*approachSpeed*1.5, 8.0))
					animTimer.ResetTime()
				Endif
				If currentDoor.GetScale() >= 8.0 Then
					If currentDoor.theKey.isBad Then 
						SceneManager.GetCurrent().SwitchToScene(SCENE_GAMEOVER)
					Elseif numberOfDoors >= TOTAL_STAGES
						GameData.SetThisTime(runningTime.GetElapsedTime())
						SceneManager.GetCurrent().SwitchToScene(SCENE_VICTORY)
					Else
						SetRunStage(RUNSTAGE_APPROACHING)
					Endif
				Endif

			Case RUNSTAGE_PREPAREAPPROACH
				If animTimer.GetElapsedTime() >= frameTime Then
					currentDoor.x = MAX(currentDoor.x - scrollSpeed, DeviceWidth()/2)
					animTimer.ResetTime()
				Endif
				If currentDoor.x = DeviceWidth()/2 Then SetRunStage(RUNSTAGE_APPROACHING)
				
			Case RUNSTAGE_APPROACHING
				'Logic
				If currentDoor.GetState() <> DOOR_OPENED 
					If animTimer.GetElapsedTime() >= frameTime Then
						currentDoor.SetScale(MINFLOAT(currentDoor.GetScale()*approachSpeed, 1.0))
						If movement.IsEndPoint() Then SoundManager.PlayFX(SOUND_STEP)
						movement.Update()
						currentDoor.Update()
						animTimer.ResetTime()
					Endif
				Else
					If animTimer.GetElapsedTime() >= frameTime Then
						reactionBar = MAXFLOAT(reactionBar-reactionBarRate, 0)
						If reactionBar <=0 Then
							'Force Enter
							SetRunStage(RUNSTAGE_ENTER)
						Endif
					Endif				
				Endif
				If currentDoor.GetScale() >= 0.9  Then currentDoor.Open()
				cam = movement.GetPosition()
				currentDoor.x = DeviceWidth()/2 + cam.x
				currentDoor.y = DeviceHeight()/2 - cam.y
		
				'Input
				If currentDoor.GetState() = DOOR_OPENED Then
					If KeyHit(KEY_ESCAPE) Then
						currentDoor.Close()
						SetRunStage(RUNSTAGE_FINDANOTHER)
					Elseif KeyHit(KEY_ENTER)
						SetRunStage(RUNSTAGE_ENTER)
					Endif
				Endif

			Case RUNSTAGE_FINDANOTHER
				'Logic
				If animTimer.GetElapsedTime() >= frameTime Then
					currentDoor.x = MAX(currentDoor.x - scrollSpeed, -300)
					currentDoor.Update()
					animTimer.ResetTime()
				Endif
				If currentDoor.x <= -300 Then
					SetRunStage(RUNSTAGE_PREPAREAPPROACH)
				Endif
		End
	End
	
Private
	Method SetDifficulty:Void(level: Int)
		curDifficultyLevel = MIN(level, 20)
		reactionBarRate = RANGED(0.75 + curDifficultyLevel*0.25, 0.75, 6.0)
		approachSpeed = RANGED(1.02 + curDifficultyLevel*0.01, 1.02, 2.0)
		scrollSpeed = RANGED (100 + curDifficultyLevel*10, 100, 200)
		frameTime = RANGED(50 - curDifficultyLevel, 20, 50)
	End

	Method SetRunStage: Void(st: Int)
		If runStage = st Then Return

		Select st
			Case RUNSTAGE_ENTER
				If currentDoor.theKey.isBad = False Then
					numberOfDoors = numberOfDoors + 1
					If numberOfDoors Mod 2 = 0 Then 
						SetDifficulty(curDifficultyLevel + 1)
					Endif
					Print numberOfDoors
				Endif

			Case RUNSTAGE_FINDANOTHER
				If currentDoor.theKey.isBad = True Then
					numberOfDoors = numberOfDoors + 1
					If numberOfDoors Mod 2 = 0 Then 
						SetDifficulty(curDifficultyLevel + 1)
					Endif
					Print numberOfDoors 
				Endif

			Case RUNSTAGE_PREPAREAPPROACH
				currentDoor.Reset()
				'Prepare height constant for scroll. This should be constant, but since I
				'reserve the right to modify door dimensions/layout i prefer to keep it as variable
				floorLine = doorGeometry.y+doorGeometry.h

				'Move the door offscreen to the right and reset
				currentDoor.x = DeviceWidth()+500
				currentDoor.y = DeviceHeight()/2
				currentDoor.SetScale(0.5)
	
			Case RUNSTAGE_APPROACHING
				currentDoor.theKey = Keyboard.GetNewKey()
				reactionBar = 100
				currentDoor.Reset()
				movement.Reset()
				currentDoor.x = DeviceWidth()/2
				currentDoor.SetScale(0.5)
		End
		
		runStage = st
	End
End



