#renderer "Basic"

#include "../include/scancodes.agc"
#include "../include/constants.agc"
#include "../include/easing.agc"

#constant VERSION					"2.0"

#constant SCALE_3D					50
#constant RESET_DISTANCE				4000

#constant MAP_SCALE_X				20
#constant MAP_SCALE_Z				20
#constant MAP_SCALE_Y				7

#constant TRACK_SCALE				18

global DEBUG 		as integer =	0

global TO_TILE_X		as float
global TO_TILE_Z		as float
global TO_TILE_Y		as float
//global TILE_MARKER	as integer

#constant GAMESTATE_SPLASH			1
#constant GAMESTATE_SETTINGS			2
#constant GAMESTATE_PLAY				3
#constant GAMESTATE_CUSTOMIZE		4
#constant GAMESTATE_EXIT				5
#constant GAMESTATE_FINISH			6
#constant GAMESTATE_SELECT			7

#constant STEER_WASD					1
#constant STEER_ARROW				2
#constant STEER_BOTH					3

#constant INPUT_CONTROLLER			1
#constant INPUT_KEYBOARD				2

#constant PLAYER_ID					5000
#constant BANANAS 					3000
#constant GRENADES 					2000
#constant ROCKS						6000

#constant FONTS_8BIT					0

type tSlider
	id				as integer
	range 			as tRange
endtype

type tCustom
	panel			as integer
	set				as tObject
	ground			as integer
	sliders			as tSlider[]
	rumble			as integer[]
endtype

type tStop
	id				as integer
	time			as float
endtype

type tPlace
	id				as integer
	chain			as integer
	tweens			as integer[]
endtype

type tController
	steer			as integer
	shoot			as integer
	u				as integer
	d				as integer
	r				as integer
	l				as integer
endtype

type tKeyboard		
	l				as integer
	r				as integer
	acc				as integer
	rev				as integer
	shoot			as integer
endtype

type tInput
	device			as integer	
	keyboard			as tKeyboard
	controller		as tController
endtype

type tEnvironment
	canvas			as integer
	sundirection		as tPoint
	gravity			as tPoint
	msg				as integer
	window			as tPoint2D	
	custom			as tCustom
	stop			as tStop
	place			as integer
	placebg			as integer	
	loading			as integer
	spot			as integer	
	pickup			as tObject
	coin			as tObject
	boost			as tObject	
	pickupDist		as float
	coinDist			as float
	banana			as tObject
	grenade			as tObject
	input			as tInput
	arrow			as integer
	bump			as integer
	engine			as integer
	//no				as integer[]
	//no1				as integer[]	
	laps			as integer
	lap				as integer
	land			as integer
	fonts			as integer[]
	boostEffect		as integer
	position			as integer
	scale			as integer
	theme			as integer
	start			as integer
	seam			as integer
	level			as integer	
	pickups			as integer
endtype

// If we change the car model then make new bits
// The new bits will be in C:\Users\your_id\AppData\Local\AGKApps\your_app
MakeCarFromModel("hotdog", "hotdog.obj")

// Setup the Environment
// Window/Physics/Shadows
//
global environment	as tEnvironment
environment = SetuptEnvironment()


// Splash(env)
// CustomizeVehicle(env)
// end

//
// Load the vehicles
   
global gVehicles		as tVehicle[]
global gGameState	as integer = GAMESTATE_SPLASH
first as integer = TRUE

repeat
	
	select gGameState
		case GAMESTATE_SETTINGS
			Settings(environment)
		endcase
		case GAMESTATE_SPLASH
			Splash(environment)
		endcase
		case GAMESTATE_SELECT
			SelectTrack(environment)
		endcase
		case GAMESTATE_PLAY
			GamePlay(environment)
		endcase
		case GAMESTATE_FINISH
			GameFinish(environment)
		endcase		
	endselect

until gGameState = GAMESTATE_EXIT
end

function FlushEscapeKey()
	repeat
		sync()
	until GetRawKeyState(KEY_ESCAPE) = 0
endfunction	

function CreateVehicle(name as string, path as string, velocity as float, npc as integer, no as integer, e ref as tEnvironment, level ref as tLevel)
	v as tVehicle
	id as integer
	i as integer
	g as integer
		
	v = LoadVehicle("hotdog", "hotdog.png", name, no)
	v.spot = CreateSprite(e.spot)
	SetSpriteTransparency(v.spot, 1)
	SetSpriteDepth(v.spot, 100)
	v.path = FindPathByName(path)
	v.colour = v.path.colour
	v.drift.on = TRUE
	v.drift.amount = 0.6
	SetObjectColor(v.detail, v.colour.r,  v.colour.g,  v.colour.b, 0xff)
	SetSpriteColor(v.spot, v.colour.r,  v.colour.g,  v.colour.b, 0xff)	
	v.npc = npc	
	v.velocity.max = velocity * SCALE_3D	
	v.velocity.save = v.velocity.max
		
	SetupVehiclePhysics(v, TRUE, GetPathPoint(v, 1))
	v.action = GetAction(ACTION_STOP, v)
	v.path = FindPathByName("path")	
	v.lap = -1
	if npc = FALSE
		//v.slot = 2
		//SetTextColor(e.place, v.colour.r,  v.colour.g,  v.colour.b, 0xff)	
		SetTextColor(e.place, 0xff,  0xff,  0xff, 0xff)			
		SetTextColor(e.lap, 0xff,  0xff,  0xff, 0xff)	
		//v.marker = CreateObjectSphere(60, 8, 8)
		//SetObjectColor(v.marker, v.colour.r,  v.colour.g,  v.colour.b, 0xff)	
	endif
	
	SetObject3DPhysicsRestitution(v.hit, 0.8)
	
endfunction v	

function DisplayStats(vehicles ref as tVehicle[], env ref as tEnvironment)
	i as integer
	v as tVehicle
	s as string
	p as tPoint2D
	
	for i=0 to vehicles.length
		// Message at bottom of screen
		v = vehicles[i]
		s = s + v.name + " : " + v.action.name + "("+ str(DistancePoint(v.velocity.last),0) + ")["+str(v.stopped,2)+"] "
		
		// Tag
		p = Get2DFromPoint(GetObjectPosition(v.hit))
		SetTextPosition(v.tag, p.x, p.y)
		if v.action.name = "go" or v.action.name = "stop"
			SetTextString(v.tag, right(v.name,1)+ "["+str(v.slot)+"]")
		else
			SetTextString(v.tag, v.name+"("+v.action.name+") C=["+str(v.path.current)+"]")
		endif
	next	
	
	SetTextString(env.msg, s)
endfunction

function PrintVelocity(vehicles as tVehicle[])
	i as integer
	v as tVehicle
	for i=0 to vehicles.length
		v = vehicles[i]
		//Print( "Velocity(last:current)="+str(DistancePoint(v.velocity.last))+":"+str(v.velocity.current)+" ["+str(v.velocity.max)+"]")
	next
endfunction

function ViewTrack(env as tEnvironment, level ref as tLevel)
	p as tPoint
	
	p = GetObjectPosition(level.ground.id)
	
	SetCameraPosition(1, p.x, 7000, p.z - 100)
	SetCameraLookAt(1, p.x, 0, p.z, 0)
	
endfunction

function	DrawSensors(vehicle as tVehicle)
	vf 	as tPoint
	vt 	as tPoint
	w	as tWheel
	i	as integer
	
	for i=0 to vehicle.wheels.length
		w = vehicle.wheels[i]
		vf.x = GetScreenXFrom3D(GetObjectWorldX(w.sensor.f), GetObjectWorldY(w.sensor.f), GetObjectWorldZ(w.sensor.f))
		vf.y = GetScreenYfrom3D(GetObjectWorldX(w.sensor.f), GetObjectWorldY(w.sensor.f), GetObjectWorldZ(w.sensor.f))
		vt.x = GetScreenXFrom3D(GetObjectWorldX(w.sensor.t), GetObjectWorldY(w.sensor.t), GetObjectWorldZ(w.sensor.t))
		vt.y = GetScreenYFrom3D(GetObjectWorldX(w.sensor.t), GetObjectWorldY(w.sensor.t), GetObjectWorldZ(w.sensor.t))		
		DrawLine(vf.x, vf.y, vt.x, vt.y, 0xffff00, 0xffff00)
	next
endfunction

type tLevelImage
	name	as string
	id		as integer
endtype


function LowRez(env ref as tEnvironment)
	
	exitfunction
	SetSpriteVisible(env.canvas, 0)
	SetVirtualResolution(64, 64)
	SetRenderToImage(GetSpriteImageID(env.canvas), -1)
	ClearScreen()	
	render()
	SetRenderToScreen()
	SetVirtualResolution(env.scale, env.scale)	
	ClearScreen()	
	SetSpriteVisible(env.canvas, 1)
endfunction

//
//	Setup basic stuff like Window/Physics/Shadows
//
function	SetuptEnvironment()
	e		as tEnvironment
	texture	as integer
	id		as integer
	scale  	as float
	i		as integer
	in		as integer
	out		as integer
	obj		as tObject
	start	as float
	
	gSoundRange = SCALE_3D * 100
	
 	TO_TILE_X = MAP_SCALE_X * TRACK_SCALE * 4	
 	TO_TILE_Z = MAP_SCALE_Z * TRACK_SCALE * 4
 	TO_TILE_Y = MAP_SCALE_Y * TRACK_SCALE 
 	
 	e.scale = 512
	
	//TILE_MARKER = CreateObjectBox(TO_TILE_X, 50, TO_TILE_Z)
	//SetObjectColor(TILE_MARKER, 0xfff, 0, 0, 0xff)
	
	SetErrorMode(2)
	
	// set window properties
	SetWindowTitle( "" )
	SetWindowSize( e.scale,  e.scale, 0 )					// Full screen
	//SetWindowAllowResize( 1 ) 
	SetVirtualResolution( 64, 64 ) 				// Display properties
	SetOrientationAllowed( 0, 0, 1, 1 ) 										// Only landscape orientation
	SetScissor( 0,0,0,0 ) 													
	
	UseNewDefaultFonts( 1 ) 									
	SetPrintSize(16)
	
	SetDefaultMinFilter(0)
	SetDefaultMagFilter(0)	

			
	SetCameraRange( 1, 1, 50000 )	
	SetCameraFOV(1, 50)
//	SetSyncRate(30, 0)
	SetVSync(1)

	id = LoadFont("fonts/8bitwonder.ttf")
	e.fonts.insert(id)
	
	
	e.placebg = CreateSprite(LoadImage("texture/placebg.png"))
	SetSpriteDepth(e.placebg, 111)
	
	e.place = CreateSprite(LoadImage("texture/place.png"))
	CreateText(e.place, "1st")
	SetTextFont(e.place, id)
	SetTextSize(e.place, 6)
	SetTextDepth(e.place, 100) : SetSpriteDepth(e.place, 110)
	
	
	id = LoadFont("fonts/tiny.ttf")
	e.fonts.insert(id)

	e.lap = CreateText("1/5")
	SetTextFont(e.lap, id)
	SetTextSize(e.lap, 6)
	SetTextPosition(e.lap, 1, 0)
	SetTextDepth(e.lap, 50)
	SetTextPosition(e.lap, 2, GetVirtualHeight() - GetTextTotalHeight(e.lap) - 1)


	e.canvas = CreateSprite(CreateRenderImage(64, 64, 0, 0))
	SetSpriteSize(e.canvas, e.scale, e.scale)
	SetSpriteDepth(e.canvas, 2)
	SetSpriteVisible(e.canvas, 0)
	SetSpriteShapeBox( e.canvas, 0, 0, 0, 0, 0 ) 
	
	e.sundirection = CreatePoint(0.2, -1, -0.2)									// Setup Sun and lighting
	SetSunDirection(e.sundirection.x, e.sundirection.y, e.sundirection.z)
	SetAmbientColor(0x80, 0x80, 0x80)											// Brght ambient = soft shadows
	SetSunColor(0x60, 0x60, 0x60)

	SetShadowMappingMode( 3 )													// SHadows
	SetShadowSmoothing( 1 ) 														// Random sampling
	SetShadowMapSize( 1024, 1024 )												// Shadow map size
	SetShadowRange( 10000) 														// Use a short range for better shadows
	SetShadowBias( 0.0012 ) 														// Offset shadows slightly to avoid shadow artifacts



	create3DPhysicsWorld(SCALE_3D)
	
//	e.gravity = CreatePoint(0, -10, 0)
//	Set3DPhysicsGravity(e.gravity.x, e.gravity.y, e.gravity.z)

	e.window.x = GetWindowWidth()
	e.window.y = GetWindowHeight()	
	
	e.pickups = CreateSprite(LoadImage("texture/pickups.png"))
	SetSpriteAnimation( e.pickups, 8, 8, 4)
	SetSpritePosition(e.pickups, 64-9, 64-9)
	SetSpriteVisible(e.pickups, 0)
	
	e.stop.id = CreateSprite(LoadImage("texture/stop.png"))
	SetSpriteShapeBox( e.stop.id, 0, 0, 0, 0, 0 ) 	
	scale = ((GetScreenBoundsBottom() - GetScreenBoundsTop()) * 0.95 ) / GetSpriteHeight(e.stop.id)
	SetSpriteSize(e.stop.id, GetSpriteHeight(e.stop.id) * scale, GetSpriteWidth(e.stop.id) * scale)
	SetSpritePositionByOffset(e.stop.id, ((GetScreenBoundsRight() - GetScreenBoundsLeft()) * 0.5 ), ((GetScreenBoundsBottom() - GetScreenBoundsTop()) * 0.5 ))
	SetSpriteVisible(e.stop.id, 0)
	SetSpriteDepth(e.stop.id, 100)
	
	e.spot = LoadImage("texture/spot.png")

	e.pickup = LoadObjectAndTexture("global/toolbox.obj", "texture/toolbox.png", 0, 0, TRACK_SCALE, CAST_SHADOW)
	CenterObject(e.pickup.id)	
	SetObjectVisible(e.pickup.id, 0)
	SetObjectPosition(e.pickup.id, -10000, -10000, -10000)
		
	e.coin = LoadObjectAndTexture("global/coin.obj", "texture/coin.png", 0, 0, TRACK_SCALE, CAST_SHADOW)	
	CenterObject(e.coin.id)		
	SetObjectVisible(e.coin.id, 0)
	SetObjectPosition(e.coin.id, -10000, -10000, -10000)
	e.coin.sound = LoadSound("sounds/coin.wav")
	e.start = LoadSound("sounds/start.wav")


	e.theme = LoadMusicOGG("sounds/theme.ogg")
	PlayMusicOGG(e.theme, 1)
	SetMusicVolumeOGG(e.theme, 30)
			
	e.boost = LoadObjectAndTexture("global/boost.obj", "texture/boost.png", 0, 0, TRACK_SCALE, RECEIVE_SHADOW)	
	CenterObject(e.boost.id)		
	SetObjectVisible(e.boost.id, 0)	
	SetObjectPosition(e.boost.id, -10000, -10000, -10000)
	SetObjectTransparency(e.boost.id, 1)		
	//SetObjectCastShadow(e.boost.id, 1)	
	/*			
	SetObjectDepthWrite(e.boost.id, 1) 
	SetObjectCullMode(e.boost.id, 0)				
	*/
	
	e.seam = CreateSprite(LoadImage("texture/seam.png"))
	SetSpriteVisible(e.seam, 0)


	LoadActions("actions.json")	
	

	e.bump = LoadSound("sounds/bump.wav")
	e.land = LoadSound("sounds/land.wav")	
	e.engine = LoadSound("sounds/engine.wav")	
	
	//SetSoundSystemVolume( 0 ) 
	//SetMusicSystemVolumeOGG( 0 )
	
	e.loading = CreateSprite(LoadImage("texture/agk.png"))
	SetSpriteShapeBox( e.loading, 0, 0, 0, 0, 0 ) 
	SetSpriteDepth(e.loading, 8)
	scale = GetVirtualHeight() / GetSpriteHeight(e.loading)
	SetSpriteSize(e.loading, GetSpriteWidth(e.loading) * scale, GetSpriteHeight(e.loading) * scale)	
	SetSpritePositionByOffset(e.loading, GetScreenBoundsLeft() + (GetScreenBoundsRight() - GetScreenBoundsLeft()) * 0.5, GetVirtualHeight() * 0.5)
	LowRez(e)
	
	start = Timer() + 1
	
	repeat
		sync()
	until Timer() > start 
	
	e.input = LoadInputSettings()
	

	
endfunction e

function LoadInputSettings()
	input as tInput[]
	
	if GetFileExists("input.json")
		input.load("input.json")	
	else
		input.length = 0
	endif
	
endfunction input[0]

function SaveInputSettings(input as tInput)
	i as tInput[]
	
	i.insert(input)
	i.save("input.json")	
	
endfunction
	

function AnyButton()
	i as integer
	r as integer = FALSE
	
	r = AnyJoystickButton(FALSE)
	
	if r = FALSE and GetKeyboardExists()
		for i=1 to 256
			if GetRawKeyPressed(i)
				r = i
				exit
			endif
		next		
	endif
endfunction r



function Transition(env ref as tEnvironment)
	s1 as integer
	s2 as integer
	i1 as integer
	i2 as integer
	t1 as float
	t2 as float
	m1 as float
	m2 as float
	x1 as float
	x2 as float
	w as float
	h as float
	ease as float = 0.3
	img as integer
	x as float

	img = GetSpriteImageID(env.canvas)
	SetSpriteVisible(env.canvas, 0)
	
	w = GetImageWidth(img) 
	h = GetImageheight(img)
	i1 = CopyImage(img, 0, 0, w, h)
	s1 = CreateSprite(i1)
	SetSpriteDepth(s1, 5)
	
	SetSpriteVisible(env.seam, 1)
	SetSpriteDepth(env.seam, 4)
	x = 32 - GetSpriteWidth(env.seam) * 0.5
	SetSpritePosition(env.seam, x, -GetSpriteHeight(env.seam))
	x1 = GetSpriteY(env.seam)
	t1 = 0
	
	repeat
		m1 = (t1 - x1) * ease
		inc x1, m1
		SetSpritePosition(env.seam, x, x1)
		LowRez(env)
		sync()
	until abs(m1) < 0.1

	SetSpritePosition(env.seam, x, t1)
	LowRez(env)
	sync()

	sleep(50)
	
	SetSpriteVisible(env.seam, 0)
	DeleteSprite(s1) : DeleteImage(i1)

	img = GetSpriteImageID(env.canvas)
	SetSpriteVisible(env.canvas, 0)
	
	w = GetImageWidth(img) / 2
	h = GetImageheight(img)
	
	i1 = CopyImage(img, 0, 0, w, h)
	i2 = CopyImage(img, w, 0, w, h)
	
	s1 = CreateSprite(i1)
	s2 = CreateSprite(i2)	
	SetSpritePosition(s2, GetSpriteWidth(s1), 0)	
	SetSpriteDepth(s1, 5)
	SetSpriteDepth(s2, 5)
	
//	SetSpriteScale(s1, .25, .25)
//	SetSpriteScale(s2, .25, .25)
	
	t1 = -(GetSpriteWidth(s1) + 5)
	t2 = GetImageWidth(img) + 5
	
	x1 = GetSpriteX(s1)
	x2 = GetSpriteX(s2)
	
	repeat
		m1 = (t1 - x1) * ease
		m2 = (t2 - x2) * ease		
		inc x1, m1
		inc x2, m2
		SetSpritePosition(s1, x1, 0)
		SetSpritePosition(s2, x2, 0)		
		LowRez(env)
		sync()		
	until abs(m2) < 0.1

	DeleteSprite(s1) : DeleteImage(i1)
	DeleteSprite(s2) : DeleteImage(i2)	
			
endfunction
	


#include "MakeCar.agc"
#include "LoadVehicle.agc"
#include "MoveVehicle.agc"
#include "Path.agc"
#include "Actions.agc"
#include "StartLights.agc"
#include "splash.agc"
#include "pickups.agc"
#include "coins.agc"
#include "gameplay.agc"
#include "level.agc"
#include "boost.agc"
#include "object.agc"
#include "settings.agc"
#include "finish.agc"
#include "select.agc"

