if not SCORES_LUA then dofile("scores.lua") end

SCREEN_LUA = true

STATE_SCREEN_INCOMING = "incoming"
STATE_SCREEN_OUTGOING = "outgoing"


screen = FSM:instantiate{ tostr = "SCREEN", state="STATE_NONE" }

screen.txtscale = 80
screen.width    = 1024
screen.height   = 768
screen.smooth   = 1

function screen:create()

    -- create camera and light

    self.camera = E.create_camera(E.camera_type_orthogonal)
    self.light  = E.create_light (E.light_type_positional)
    self.pivot  = E.create_pivot ( )

    E.parent_entity(self.light, self.camera)
    E.parent_entity(self.pivot, self.light)

    E.set_entity_position(self.light, 0, 0, 10)


    -- find screen size
    self.dsp_x, self.dsp_y, self.dsp_w, self.dsp_h = E.get_display_union()
    --[[
    self.scale_fac_w = self.width  / self.dsp_w
    self.scale_fac_h = self.height / self.dsp_h

    E.set_entity_scale(self.camera, self.scale_fac_w, self.scale_fac_h, 1)
    --]]

    self.menus = {}

    self:create_title_menu()
    self:create_controls_menu()
    self:create_scores_menu()
    self:create_finish_menu()

    --self:show_menu("title", true, 5)

    -- create text entities to display on screen

--    E.set_typeface("data/CHEAPSIG.TTF", 0.01, 0.03125)
    E.set_typeface("data/CHEAPSIG.TTF", 0.01, 0.05)


    self.strings = {}
    --self:create_level_str( 25,               self.height - 50, self.txtscale)
    --self:create_time_str ( self.width - 300, self.height - 50, self.txtscale)
--    self:create_debug_str( 25,               50,               self.txtscale)
    
    -- create speedometer
    self:create_speedometer( 250, 50, 50)
    
    -- create temperature gauge
    self:create_tempgauge( 50, 50 )
    
    -- create time meter
    self:create_timer( self.width - 350, self.height - 50, self.txtscale)

    -- create load screen
    self:create_loadscreen()

    -- create pages --------------------------------------------------------

    self.pages = {}

    -- create static pages
    local plist = { "ready", "set", "go", "wipeout", "overheat" }
    for k, v in ipairs(plist) do
	local page = make_sprite("data/"..v..".png", true, true)
	E.set_entity_position(page, self.width*1.5, self.height/2, 0)
	E.parent_entity(page, self.pivot)
	self.pages[v] = page
    end

    -- create lap page
    local lp = E.create_pivot()
    local ls = make_sprite("data/lap1.png", true, true)
    self.laptime = make_time_sprite( 0, 80 )

    local x, y, z, xx, yy = E.get_entity_bound(self.laptime.pivot)
    E.set_entity_position(self.laptime.pivot, -80*1.8, -55, 0)
    E.set_entity_position(ls, 0, 55, 0)
    E.set_entity_position(lp, self.width*1.5, self.height/2, 0)

    E.parent_entity(ls, lp)
    E.parent_entity(self.laptime.pivot, lp)
    E.parent_entity(lp, self.pivot)
    self.pages.lap = lp

    -- create new initials page
    local ip = E.create_pivot()
    local is = make_sprite("data/newhighscore.png", true, true)
    self.highscore = make_time_sprite( 0, 80 )
    self.newinits  = make_init_sprite( "___", 80 )

    E.set_entity_position(is, 0, 150, 0)
    E.set_entity_position(self.highscore.pivot, -80*1.8, 50, 0)
    E.set_entity_position(self.newinits.pivot, -80, -75, 0)
    E.set_entity_position(ip, self.width*1.5, self.height/2, 0)

    E.parent_entity(is, ip)
    E.parent_entity(self.highscore.pivot, ip)
    E.parent_entity(self.newinits.pivot,  ip)
    E.parent_entity(ip, self.pivot)
    self.pages.inits = ip



end

function screen:hide_hud (hidden)
    E.set_entity_flags(self.tempgauge,     E.entity_flag_hidden, hidden)
    E.set_entity_flags(self.speedometer,   E.entity_flag_hidden, hidden)
    E.set_entity_flags(self.strings.time,  E.entity_flag_hidden, hidden)
    E.set_entity_flags(self.strings.level, E.entity_flag_hidden, hidden)
    E.set_entity_flags(self.strings.debug, E.entity_flag_hidden, hidden)
    E.set_entity_flags(self.timer.pivot,   E.entity_flag_hidden, hidden)
end

function screen:create_tempgauge(x, y)

    -- create main pivot for tempgauge
    self.tempgauge = E.create_pivot()
    
    -- create gauge indicator brush, save to self so we can change later
    self.gaugebrush = E.create_brush()
    E.set_brush_color(self.gaugebrush, 1, 1, 0, .7)
    E.set_brush_flags(self.gaugebrush, E.brush_flag_unlit, true)

    -- create gauge indicator bar, save so we can change later
    self.gaugebar = E.create_sprite(self.gaugebrush) 
    E.parent_entity(self.gaugebar, self.tempgauge)

    -- create temp brush for gauge background
    local bbrush = E.create_brush()
    E.set_brush_color(bbrush, 0, 0, 0, .5)
    E.set_brush_flags(bbrush, E.brush_flag_unlit, true)

    -- create background for gauge, position
    local bsprite = E.create_sprite(bbrush)
    E.parent_entity(bsprite, self.tempgauge)
    E.set_entity_scale(bsprite, 60/128, 410/128, 1)
    E.set_entity_position(bsprite, 30, 205, 0)
    
    -- parent gauge to screen
    E.parent_entity(self.tempgauge, self.pivot)
    E.set_entity_position(self.tempgauge, x, y, 0)
end

function screen:update_tempgauge( frac )
    E.set_entity_scale   (self.gaugebar, 50 / 128, 400 * frac / 128, 1)
    E.set_entity_position(self.gaugebar, 25 + 5,   200 * frac + 5,   0)
end

function screen:flash_tempgauge( dt )
    if math.mod(math.floor(dt * 4),2) == 0 then 
	E.set_brush_color(self.gaugebrush, 1, 0, 0, .7)
    else
	E.set_brush_color(self.gaugebrush, 1, 1, 0, .7)
    end
    --E.set_sprite_brush(bar, brush)
end

function screen:create_speedometer(x, y, maxSpeed)

    local pivot  = E.create_pivot()
    local dial   = make_sprite("data/spdo.png", true, true)
    local needle = make_sprite("data/needle.png", true, true)

    -- DISPLAY THE DIAL
    E.parent_entity(pivot, self.pivot)
    E.parent_entity(dial, pivot)
    E.parent_entity(needle, pivot)

    E.set_entity_position(dial,   0, 60, 0)
    E.set_entity_position(needle, 0, 0,  0)
    
    E.set_entity_position(pivot, x, y, 0)
	
    screen.speedometer = pivot
    screen.needle      = needle
    screen.max_speed   = maxSpeed
    screen.last_speed  = 0

    self:update_speedometer( 0 )

end


function screen:update_speedometer( speed )
    
    speed = (( 4 * self.last_speed ) + speed ) / 5

    if speed < 0.1 then 
	speed = speed + math.random() * self.max_speed * 0.02
    elseif speed > (self.max_speed * 1.1) then
	speed = self.max_speed * 1.1 + math.random() * self.max_speed * 0.05
    end

    self.last_speed = speed
    local degrees = speed/self.max_speed * -180
    E.set_entity_rotation(self.needle, 0, 0, degrees)

end

function screen:destroy_speedometer()
   E.delete_entity(self.spdo_sprite)
   E.delete_entity(self.dial_sprite)
end

function screen:create_time_str(x, y, scale)

    local fill = E.create_brush() -- for time
    local line = E.create_brush() -- for outlines

    E.set_brush_flags(fill, E.brush_flag_unlit, true)
    E.set_brush_flags(line, E.brush_flag_unlit, true)

    E.set_brush_color(fill, 0.8, 0.8, 0.2, 0.5)
    E.set_brush_color(line, 0.0, 0.0, 0.0, 0.8)
    
    self.strings.time = E.create_string("00:00:00")

    E.set_string_fill(self.strings.time, fill)
    E.set_string_line(self.strings.time, line)

    E.parent_entity(self.strings.time, self.pivot)

    E.set_entity_scale   (self.strings.time, scale, scale, 1)
    E.set_entity_position(self.strings.time, x,     y,     0)

end


function screen:create_level_str(x, y, scale)

    local fill = E.create_brush() -- for level
    local line = E.create_brush() -- for outlines

    E.set_brush_flags(fill, E.brush_flag_unlit, true)
    E.set_brush_flags(line, E.brush_flag_unlit, true)

    E.set_brush_color(fill, 0.6, 0.6, 0.6, 0.5)
    E.set_brush_color(line, 0.0, 0.0, 0.0, 0.8)

    self.strings.level = E.create_string("Level 1")

    E.set_string_fill(self.strings.level, fill)
    E.set_string_line(self.strings.level, line)

    E.parent_entity(self.strings.level, self.pivot)
    E.set_entity_scale   (self.strings.level, scale, scale, 1)
    E.set_entity_position(self.strings.level, x,     y,     0)

end

function screen:create_debug_str(x, y, scale)

    local fill = E.create_brush() -- for level
    local line = E.create_brush() -- for outlines

    E.set_brush_flags(fill, E.brush_flag_unlit, true)
    E.set_brush_flags(line, E.brush_flag_unlit, true)

    E.set_brush_color(fill, 0.6, 0.6, 0.6, 0.5)
    E.set_brush_color(line, 0.0, 0.0, 0.0, 0.8)

    self.strings.debug = E.create_string("debug")

    E.set_string_fill(self.strings.debug, fill)
    E.set_string_line(self.strings.debug, line)

    E.parent_entity(self.strings.debug, self.pivot)
    E.set_entity_scale   (self.strings.debug, scale, scale, 1)
    E.set_entity_position(self.strings.debug, x,     y,     0)

end

function screen:create_loadscreen()
	
    self.loadscreen = make_sprite("data/bmstitle.png", true, true)
    
    E.parent_entity(self.loadscreen, self.pivot)
    
    local px = self.dsp_w/2
    local py = self.dsp_h/2
    
    E.set_entity_position(self.loadscreen, px, py, 3)	
    E.set_entity_alpha(self.loadscreen, 0.99)
    E.set_entity_scale(self.loadscreen, 1.2, 1.2, 1)
end

function screen:destroy_loadscreen()
    E.delete_entity(self.loadscreen)
    self.loadscreen = nil
end

function screen:create_new_menu( menuoptions )
    local menu = {}
    menu.num_options = table.getn(menuoptions)

    local spacing = self.width / table.getn(menuoptions)
    
    for i, line in ipairs(menuoptions) do
	menu[i] = self:make_menu_item(line, 
				      spacing / 2 + spacing*(i-1), 
				      100)
    end

    menu.pivot = E.create_pivot()
    E.set_entity_position(menu.pivot, 
			  self.width*1.5, 
			  self.height/2, 0)
    E.parent_entity(menu.pivot, self.pivot)

    return menu
end

function screen:show_menu( menu, visible, smooth )
    -- if [visible] is true, causes the menu screen indicated by 
    -- the index [menu] to be visible.  
    -- Requires that the menu specified contain a primary image contained in
    -- the .img property, and an array of menu options, each with a 
    -- .on and .off property that contain the selected and unselected images.

--    E.set_entity_flags(self.menus[menu].img, E.entity_flag_hidden, not visible)

    if visible then
	self:turn_page(self.menus[menu].pivot, smooth )
    end

    for i, v in ipairs(self.menus[menu]) do
	E.set_entity_flags(v.off, E.entity_flag_hidden, not visible)
	if not visible then
	    E.set_entity_flags(v.on, E.entity_flag_hidden, true)
	end
    end
    
    if visible then
	self.cur_menu = self.menus[menu]
	self.cur_option = nil
	self:set_menu_option(1)
    end
end

function screen:set_menu_option( option )
    -- highlights the menu choice with index [option]
    -- and sets current option variables which will ensure the 
    -- correct events will occur if that option is executed.

    if self.cur_option then
	E.set_entity_flags(self.cur_menu[self.cur_option].off, 
			   E.entity_flag_hidden, false)
	E.set_entity_flags(self.cur_menu[self.cur_option].on,  
			   E.entity_flag_hidden, true)
    end

    self.cur_option = option

    E.set_entity_flags(self.cur_menu[option].off, E.entity_flag_hidden, 
		       true)
    E.set_entity_flags(self.cur_menu[option].on,  E.entity_flag_hidden, 
		       false)

    self.cur_menu.cur_func = self.cur_menu[option].func

    E.play_sound(sounds.menu_click)
end 

function screen:exec_menu()
    -- executes the current menu option

    E.play_sound(sounds.menu_select)
    self.cur_menu.cur_func()
end

function screen:make_menu_item(value, xpos, ypos)
    -- value is a string 
    --    The string is the text of the option, "back" for ex.
    --    The image files containing the selected and unselected states
    --    should be named "backon.png" and "backoff.png"
    -- xpos, ypos are the positions of the text
    local item    = {}
    local onfile  = "data/menu/" .. value[1] .. "on.png"
    local offfile = "data/menu/" .. value[1] .. "off.png"

    item.on   = make_sprite(onfile,  true, true)
    item.off  = make_sprite(offfile, true, true)
    item.func = value[2]

    E.parent_entity(item.on,  self.pivot)
    E.parent_entity(item.off, self.pivot)

    E.set_entity_flags(item.on,  E.entity_flag_hidden, true)
    E.set_entity_flags(item.off, E.entity_flag_hidden, true)

    E.set_entity_position(item.on,  xpos, ypos, 0)
    E.set_entity_position(item.off, xpos, ypos, 0)

    return item
end

function screen:create_title_menu()

    local menuoptions = {
	{"play",     function ()
			 screen:show_menu("title", false)
			 screen:turn_page(nil, 5)
			 -- create bikes now

			 table.foreachi(mob, function (i, v) 
						 v:hide(false) 
					     end)
			 put_bikes()
			 
			 scene.chase = mob[chasetarg].base
			 scene.camera_smooth_factor = 10
			 scene:set_state(STATE_SCENE_SIDE)
			 screen:hide_hud(false)
			 gamefsm:set_state(STATE_GAME_INIT)
		     end},
	{"controls", function ()
			 screen:show_menu("title", false)
			 screen:show_menu("controls", true, 5)
		     end},
	{"scores", function ()
		       screen:show_menu("title", false)
		       screen:show_menu("scores", true, 5)
		     end},
	{"exit",     function ()
			 E.exit()
		     end,
	}
    }

    self.menus.title = self:create_new_menu( menuoptions )

    local title = make_sprite("data/title.png", true, true)
    E.set_entity_position(title, 0, 75, 0)

    E.parent_entity(title, self.menus.title.pivot)
    
end

function screen:create_controls_menu()

    local menuoptions = {
	{"back", function ()
		     screen:show_menu("controls", false)
		     screen:show_menu("title", true, 5)
		 end},
    }

    self.menus.controls = self:create_new_menu( menuoptions )
    local ctrls = make_sprite("data/controls.png", true, true)
    E.parent_entity(ctrls, self.menus.controls.pivot)
end


function screen:create_score_sheet()
    -- ss is a pivot that will contain sprites, text elements
    --   or whatever that will make up the body of the score 
    --   screen
    -- Use screen.width and screen.height to position elements
    --   on the screen

    local ss    = E.create_pivot()
    local scale = self.txtscale * 3 / 4
    
    local step = scale + 15
    local top  = step * (scores.max + 3) / 2

    for i, v in ipairs(scores.data) do
	
	local place = make_sprite("data/digits.png", true, true)
	set_digit_sprite(place, i)
	E.set_entity_scale(place, 0.25 * scale/128, 0.25 * scale/128, 1)

	local init = make_init_sprite(v.initials,         scale)
	local time = make_time_sprite(parse_time(v.time), scale)

	E.set_entity_position(place,      -5*scale, top-i*step, 0)
	E.set_entity_position(init.pivot, -3*scale, top-i*step, 0)
	E.set_entity_position(time.pivot,  1*scale, top-i*step, 0)

	E.parent_entity(place,      ss)
	E.parent_entity(init.pivot, ss)
	E.parent_entity(time.pivot, ss)

    end

    local bkgrnd = make_sprite("data/highscores.png", true, true)
    E.parent_entity(bkgrnd, ss)

    return ss
end

function screen:reload_scores()
    local oldscores = E.get_entity_child(self.menus.scores.pivot, 0)
    local newscores = self:create_score_sheet()
    E.delete_entity(oldscores)
    E.parent_entity(newscores, self.menus.scores.pivot)
end

function screen:create_scores_menu()

    local menuoptions = {
	{"back", function ()
		     screen:show_menu("scores", false)
		     screen:show_menu("title", true, 5)
		 end},
    }

    self.menus.scores = self:create_new_menu( menuoptions )

    local sheet = self:create_score_sheet()

    E.parent_entity(sheet, self.menus.scores.pivot)
end

function screen:create_finish_menu()

    local menuoptions = {
	{"scores", function ()
		       do_reset_world()
		       gamefsm:set_state(STATE_GAME_MENU)
		       screen:show_menu("finish", false)
		       screen:show_menu("scores", true, 5)
		 end},
	{"back", function ()
		     do_reset_world()
		     gamefsm:set_state(STATE_GAME_MENU)
		     screen:show_menu("finish", false)
		     screen:show_menu("title", true, 5)
		 end},
    }

    self.menus.finish = self:create_new_menu( menuoptions )

    local fs = make_sprite("data/finish.png", true, true)
    self.fintime = make_time_sprite( 0, 80 )
    
    E.set_entity_position(fs, 0, 50, 0)
    E.set_entity_position(self.fintime.pivot, -80*1.8, -50, 0)
    E.parent_entity(fs, self.menus.finish.pivot)
    E.parent_entity(self.fintime.pivot, self.menus.finish.pivot)
end


function screen:create_timer( px, py, scale )
    self.timer = make_time_sprite( 0, scale )
    E.set_entity_position(self.timer.pivot, px, py, 1)
    E.parent_entity(self.timer.pivot, self.pivot)
end

function screen:update_timer( time )
    set_time_sprite(self.timer, time)
end


function screen:create_inits_page()
    local ip = E.create_pivot()
    local is = make_sprite("data/newhighscore.png", true, true)
    self.highscore = make_time_sprite( 0, 50 )
    self.newinits  = make_alpha_sprite( "___", 60)

    E.set_entity_position(is, 0, 75, 0)
    E.set_entity_position(self.highscore.pivot, -150, 0, 0)
    E.set_entity_position(self.newinits.pivot, -60, -75, 0)
    E.parent_entity(is, ip)
    E.parent_entity(self.highscore.pivot, ip)
    E.parent_entity(self.newinits.pivot,  ip)

    return ip
end

function screen:turn_page( next_page, smooth )
    if smooth then
	self.smooth = smooth
    end

    if self.current_page then
	self.next_page = next_page
	self:set_state(STATE_SCREEN_OUTGOING)
    else
	if next_page then
	    self.current_page = next_page
	    self:set_state(STATE_SCREEN_INCOMING)
	end
    end
end


function screen:do_idle( dt )

    if self.state == STATE_NONE then return end

    local px, py = E.get_entity_position(self.current_page)
    local tx, ty
    if self.state == STATE_SCREEN_INCOMING then
	tx, ty = self.width/2, self.height/2
    elseif self.state == STATE_SCREEN_OUTGOING then
	tx, ty = -self.width/2, self.height/2
    end
    
    px = (px * (self.smooth - 1) + tx) / self.smooth
    py = (py * (self.smooth - 1) + ty) / self.smooth
    
    E.set_entity_position(self.current_page, px, py, 0)
    
    if math.floor(px/10) == math.floor(tx/10) and 
	math.floor(py/10) == math.floor(ty/10) then
	
	if self.state == STATE_SCREEN_OUTGOING then
	
	    E.set_entity_position(self.current_page, 
				  self.width*1.5, self.height/2, 0)
  
	    self.current_page = self.next_page

	    if self.next_page then
		self.next_page = nil
		self:set_state(STATE_SCREEN_INCOMING)
	    else
		self:set_state(STATE_NONE)
	    end

	elseif self.state == STATE_SCREEN_INCOMING then
	    self:set_state(STATE_NONE)
	end
    end	
end


function screen:destroy()
    E.delete_entity(self.camera)
end

function screen:set_string ( name, str )
    E.set_string_text(self.strings[name], str)
end
