' Missile Lock
'
' Copyright (C) 2006  Ian Cowburn (ianc@noddybox.co.uk)
'
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'
' -------------------------------------------------------------------------
'
' $Id$
'
Strict
Framework brl.basic
Import brl.max2d
Import brl.glmax2d
Import brl.Random

Import noddybox.bitmapfont
Import noddybox.keysyms
Import noddybox.ShowLicense

Import "global.bmx"
Import "gametypes.bmx"
'Import "game.bmx"
Import "particle.bmx"
'Import "help.bmx"
Import "sound.bmx"

Incbin "short_license.txt"
Incbin "license.txt"

' ===================================
' Initialise
' ===================================
'
SeedRnd(MilliSecs())

SetAudioDriver "FreeAudio"

Graphics 800,600,0
HideMouse

SetBlend(ALPHABLEND)
SetAlpha(1.0)


' ===================================
' Globals
' ===================================
'
GFX.Init()	' MUST be first
SFX.Init()

GameConfig.Load()

If Not GameConfig.accepted
	If Not ShowLicense("MISSILE LOCK -- LICENSE","incbin::short_license.txt","incbin::license.txt")
		EndGraphics()
		End
	EndIf
	GameConfig.accepted=True
	GameConfig.Save()
EndIf

Scroller.Init()
Thanks.Init()
Particles.Init()
Backdrop.Init()
Trail.Init()
MissileSet.Init()
AsteroidSet.Init()

Global quit:Int=False
Global start_level:Int=1


' ===================================
' Main
' ===================================
'
Menu()

FlushKeys()

While Not quit
	Local start_bonus:Int=1000*(start_level-1)
	
	GameState.Reset()
	GameState.SetLevel(start_level)
	MissileSet.StartLevel()
	AsteroidSet.StartLevel()
	
	While Not GameState.game_over
	
		Local alert_timer:Int=200
		
		SFX.Alert()
	
		While Not GameState.game_over And Not MissileSet.AllDestroyed()
			Cls()
			
			If alert_timer
				alert_timer:-1
				If alert_timer Mod 60 < 30
					GFX.font.Centre("RED ALERT!",300,255,0,0)
				EndIf
			EndIf
			
			ResetCollisions()
			
			Backdrop.Draw()
			Particles.Draw()
			Trail.Draw()
			
			GameState.Control()
			GameState.Move()
	
			SetRotation(GameState.ang)
	
			If GameState.shield
				SetColor(Rand(0,255),Rand(0,255),Rand(0,255))
			Else
				SetColor(255,255,255)
			EndIf
				
			DrawImage(GFX.ship,GameState.x,GameState.y)
			SetRotation(0)
			
			MissileSet.Update()
			AsteroidSet.Update()
			
			Local col:Object[]=CollideImage(GFX.ship,GameState.x,GameState.y,0,ALL_LAYERS,0)
			
			If Not GameState.shield Then
				If col
					GameState.ShieldDown()
					Particles.AddExplosion(GameState.x,GameState.y)
					For Local m:Missile=EachIn col
						If m
							MissileSet.RemoveMissile(m)
							GameState.AddScore(1*GameState.level)
							Exit
						EndIf
					Next
				EndIf
			EndIf
			
			If GameState.pause
				GFX.font.Centre("PAUSED!",300,255,255,0)
			EndIf
			
			GameState.Display()
			Flip(-1)

			If GameState.pause
				GameState.pause=False
				While Not KeyHit(GameConfig.kpause) And Not KeyHit(KEY_ESCAPE)
				Wend
			EndIf
		Wend
		
		If Not GameState.game_over
			AsteroidSet.Nuke()

			Local bonus=100*GameState.level
			Local added:Int=0
			Local timer:Int=Max(HERTZ*5,bonus/10+HERTZ*3)
			Local bt:Int=0
			
			If GameState.gonads
				GameState.AddScore(9999+(GameState.level-1)*10000)
			EndIf
			
			If Not GameState.hit
				GameState.AddScore(500*GameState.level)
			EndIf
			
			If start_bonus
				GameState.AddScore(start_bonus)
			EndIf
			
			If GameState.bonus_timer
				bonus:+GameState.bonus_timer
				bt=GameState.bonus_timer
			EndIf
			
			GameState.bonus_timer=0
			
			While timer And Not KeyHit(KEY_ESCAPE)
				Cls()
				ResetCollisions()
				
				GameState.ShieldShip()
				
				Backdrop.Draw()
				Particles.Draw()
				Trail.Draw()
				
				GameState.Control()
				GameState.Move()
		
				SetRotation(GameState.ang)
		
				If GameState.shield
					SetColor(Rand(0,255),Rand(0,255),Rand(0,255))
				Else
					SetColor(255,255,255)
				EndIf
					
				DrawImage(GFX.ship,GameState.x,GameState.y)
				SetRotation(0)
				
				GFX.font.Centre("LEVEL " + GameState.level + " COMPLETED!",200,255,255,0)

				GFX.font.Centre("BONUS " + Number.format(added) + "!!!",400,255,255,0)
				
				If bt
					GFX.font.Centre("TIMER BONUS " + bt + "!!!",420,255,255,0)
				EndIf
				
				Local y:Int=440
				
				If Not GameState.hit
					GFX.font.Centre("PERFECT BONUS " + (500*GameState.level) + "!!!",y,255,255,0)
					y:+20
				EndIf
				
				If start_bonus
					GFX.font.Centre("STARTING LEVEL BONUS " + start_bonus + "!!!",y,255,255,0)
					y:+20
				EndIf
				
				If GameState.gonads
					GFX.font.Centre("SECRET GONADS OF STEEL BONUS " + (9999+(GameState.level-1)*10000) + "!!!",y,255,255,0)
					y:+20
				EndIf
				
				If added<bonus
					GameState.AddScore(10)
					added:+10
				EndIf
				
				If timer<HERTZ*2
					GFX.font.Centre("GET READY!",300)
				EndIf
				
				If GameState.pause
					GFX.font.Centre("PAUSED!",300,255,255,0)
				EndIf
				
				GameState.Display()
				Flip(-1)
	
				If GameState.pause
					GameState.pause=False
					While Not KeyHit(GameConfig.kpause) And Not KeyHit(KEY_ESCAPE)
					Wend
				EndIf
				
				timer:-1
			Wend
			
			start_bonus=0

			GameState.AddScore(bonus-added)
			
			GameState.LevelUp()
			MissileSet.StartLevel()
			AsteroidSet.StartLevel()
		EndIf
	Wend
	
	GameConfig.maxlevel=Max(GameState.level,GameConfig.maxlevel)
	
	GameConfig.Save()
	
	MissileSet.Nuke()
	AsteroidSet.Nuke()
	Particles.AddBigExplosion(GameState.x,GameState.y)
	
	FlushKeys()
	Local timer:Int=0
	
	While Not KeyHit(KEY_SPACE) And Not KeyHit(KEY_ESCAPE) And timer<HERTZ*5
		Cls()
		
		Backdrop.Draw()
		Particles.Draw()
		Trail.Draw()
		
		GameState.Display()
		
		SetScale(3,3)
		GFX.font.Centre("GAME OVER!",280)
		SetScale(1,1)
		Flip(-1)
		
		timer:+1
	Wend
	
	TFadeScreen.DoFadeOut()
	
	Menu()
Wend

EndGraphics
End


' ===================================
' Argument Routines
' ===================================
'
Function Switch:Int(s:String)
	For Local a:String=EachIn AppArgs
		If a=s
			Return True
		EndIf
	Next
	
	Return False
End Function


' ===================================
' Menu Routines
' ===================================
'
Function Menu()
	Local fade:TFadeScreen=TFadeScreen.FadeIn()
	Local done:Int=False
	Local defkey:Int=0
	
	Particles.Clear()
	
	While Not done
		Cls
		
		Rem
		If Rand(100)>90
			Local x:Int=Rand(0,800)
			Local y:Int=Rand(0,600)
			Particles.AddScaledImage(GFX.fireball,x,y,0.1)
		End If
		End Rem
		
		Backdrop.Draw()
		Particles.Draw()
		Scroller.Draw(560)
			
		SetColor(255,255,255)
		DrawImage(GFX.title,0,0)
		
		If defkey>0
		
			If defkey=5
				GFX.font.Centre("PRESS A KEY TO GO BACK TO THE MENU",380)
			Else
				GFX.font.Centre("DEFINE KEYS",350)
				GFX.font.Centre("PRESS ESCAPE TO CANCEL",380)
			EndIf
			
			Local c1:Int=128+128*(defkey=1)
			Local c2:Int=128+128*(defkey=2)
			Local c3:Int=128+128*(defkey=3)
			Local c4:Int=128+128*(defkey=4)

			GFX.font.Draw("LEFT",250,200,c1,c1,c1)
			GFX.font.Draw("RIGHT",250,220,c2,c2,c2)
			GFX.font.Draw("THRUST",250,240,c3,c3,c3)
			GFX.font.Draw("PAUSE",250,260,c4,c4,c4)
			GFX.font.Draw(KeySym(GameConfig.kleft),500,200,c1,c1,0)
			GFX.font.Draw(KeySym(GameConfig.kright),500,220,c2,c2,0)
			GFX.font.Draw(KeySym(GameConfig.kthrust),500,240,c3,c3,0)
			GFX.font.Draw(KeySym(GameConfig.kpause),500,260,c4,c4,0)

			Local k:Int=-1
			
			For Local f:Int=0 To 255
				If KeyHit(f)
					k=f
					Continue
				EndIf
			Next
			
			If k=KEY_ESCAPE
				GameConfig.Load()
				defkey=0
				FlushKeys()
			ElseIf k<>-1
				Select defkey
					Case 1
						GameConfig.kleft=k
					Case 2
						GameConfig.kright=k
					Case 3
						GameConfig.kthrust=k
					Case 4
						GameConfig.kpause=k
				End Select
				
				defkey:+1
				
				If defkey=6
					GameConfig.Save()
					defkey=0
					FlushKeys()
				EndIf
			EndIf
		Else
			If KeyHit(KEY_ESCAPE)
				done=True
				quit=True
			EndIf
			
			If KeyHit(GameConfig.kthrust)
				done=True
			EndIf
			
			If KeyHit(KEY_R)
				defkey=1
				FlushKeys()
			EndIf
			
			If GameConfig.maxlevel>1
				If KeyHit(KEY_LEFT) Or KeyHit(KEY_DOWN)
					start_level=start_level-1
					If start_level<1
						start_level=GameConfig.maxlevel
					EndIf
				ElseIf KeyHit(KEY_RIGHT) Or KeyHit(KEY_UP)
					start_level=start_level+1
					If start_level>GameConfig.maxlevel
						start_level=1
					EndIf
				End If
			EndIf
			
			GFX.font.Centre("COPYRIGHT (C) NODDYBOX 2006",200)
			GFX.font.Centre("HTTP://WWW.DEATHSTATION9000.ORG.UK/",226)

			GFX.font.Centre("THANKS TO",300)
			Thanks.Draw(326)
			
			GFX.font.Centre("PRESS " + KeySym(GameConfig.kthrust).ToUpper() + " TO PLAY",400)

			If GameConfig.maxlevel>1
				GFX.font.Centre("CURSORS TO SELECT STARTING LEVEL: "+start_level,450)
			EndIf
			
			GFX.font.Centre("PRESS R TO REDEFINE KEYS",480)
			GFX.font.Centre("PRESS ESCAPE TO QUIT",500)
		EndIf

		If fade
			If fade.Fade()
				fade.Draw()
			Else
				fade=Null
			EndIf
		EndIf
		
		GameState.Display()
		Flip(-1)
	Wend
	
	Particles.Clear()
	TFadeScreen.DoFadeOut()
End Function