viewport= require("viewport")
require "abad"
require "cacau"
require "caco"
require "zombie"
require "gota"
require "bol"
require "gorro"
require "gps"
require "peu"
require "premiere"
require "elalien"
require "score"

local tile_w = arcade_config.tiles_width
local tile_h = arcade_config.tiles_height
local res_w  = arcade_config.resolucion.width
local res_h  = arcade_config.resolucion.height

local view_tile_id = false
local view_checking_tile = false

viewp = viewport.new(arcade_config.resolucion.width, arcade_config.resolucion.height)
viewp:position(0,0)

local warp_rot = 0

actors={}

function game_init(menu)
    abad_init()
    table.insert(actors,abad)
    
    gps.init()
    table.insert(actors,gps)
    
    gorro.init()
    table.insert(actors,gorro)
    
    peu.init()
    table.insert(actors,peu)
    
    premiere.init()
    table.insert(actors,premiere)
    
    elalien.init()
    table.insert(actors,elalien)
    
    bol.init()
    table.insert(actors,bol)
    
    table.insert( actors, gota.new(70,5,1,20) )
    table.insert( actors, gota.new(70,9,1,30) )
    table.insert( actors, gota.new(63,5,1,25,2,-7) )
    table.insert( actors, gota.new(63,9,1,20,0,-8) )
    table.insert( actors, gota.new(64,3,1,10,0,-6) )
    table.insert( actors, gota.new(64,6,1,25,-1,-5) )
    table.insert( actors, gota.new(65,7,1,10,0,-7) )
    table.insert( actors, gota.new(65,8,1,25,0,-7) )
    table.insert( actors, gota.new(66,3,1,10,0,-7) )
    table.insert( actors, gota.new(66,4,1,15,0,-7) )
    table.insert( actors, gota.new(77,2,1,30,-5,-7) )
    table.insert( actors, gota.new(77,9,1,25,-5,-7) )
    
    table.insert( actors, caco.new(13,3,2,true ) )
    table.insert( actors, caco.new(17,3,2,false) )
    table.insert( actors, caco.new(20,3,2,false) )
    table.insert( actors, caco.new(26,3,2,false) )
    table.insert( actors, caco.new(37,3,2,false) )
    table.insert( actors, caco.new(41,3,2,false) )
    table.insert( actors, caco.new(50,3,2,false) )
    table.insert( actors, caco.new(57,3,2,false) )
    table.insert( actors, caco.new(61,3,2,false) )
    
    table.insert( actors, zombie.new(2,  3, 3,false) )
    table.insert( actors, zombie.new(28, 3, 3,false) )
    table.insert( actors, zombie.new(32, 3, 3,false) )
    table.insert( actors, zombie.new(44, 3, 3,false) )
    table.insert( actors, zombie.new(46, 3, 3,false) )
    table.insert( actors, zombie.new(54, 3, 3,false) )
    table.insert( actors, zombie.new(68, 3, 3,false) )
    table.insert( actors, zombie.new(73, 3, 3,false) )
    
    score.create()
    
    local abad_x, abad_y = coords.room_to_world ( 10, 4, 3 )
    -- local abad_x, abad_y = arc_mapa_get_coords ( 77, 3, 2 )
    abad:move(abad_x, abad_y)
    abad_make_safe( true )
    
    local scr_ax, scr_ay = viewp:screen_coords(abad_x, abad_y)
    
	game_update=update_game
end

function render_map( sf_map, sf_tiles, x, y )
    map.surf(sf_map)
    map.cell(16, 16)
    surf.source(sf_tiles)
    surf.target(0)
    view.origin(-x,-y)
    map.draw()
    view.origin(0,0)
end

function update_game()
    surf.target(0)
    surf.cls(16)
	
    -- surf.target(logo)
    -- surf.cls(16)
    -- draw.text("UPDATE_GAME",0,0,15)
    -- surf.source(logo)
    -- draw.surf(0,0,36,5,56,70,arcade_config.logo_sf.width,arcade_config.logo_sf.height)

	---       if abad.hurting == 0 then
    ---        draw_hab(abad.hab,0,0)
    ---        --text(abad.hab,1,1,2)
    ---        draw_hab(cameras[current_camera].hab,0,48)
    ---        -- text(camera_names[current_camera],2*o2aX,49*o2aX,8)
    ---        arc_textB(camera_names[current_camera],2*o2aX,49*o2aX,8)
	---
    ---        score.draw()
    ---        surf.source(tiles)
    ---        -- draw.text("x"..abad.vides,114*o2aX,13*o2aX,2)
    ---        arc_text("x"..abad.vides,114*o2aX,13*o2aX,2)
    ---        draw.rectf((102+(abad.energia>>1))*o2aX,30*o2aX,(21-(abad.energia>>1))*o2aX,8*o2aX,16)
    ---    else
    ---        draw.surf(0,0,16*o2aX,9*o2aX,50*o2aX,40*o2aX,16*o2aX,9*o2aX,true)
    ---        if abad.hurting > 40 then
    ---            -- draw.text("x"..abad.vides+1,63*o2aX,43*o2aX,3)
    ---            arc_text("x"..abad.vides+1,63*o2aX,43*o2aX,3)
    ---        elseif abad.hurting < 20 then
    ---            -- draw.text("x"..abad.vides,63*o2aX,43*o2aX,2)
    ---            arc_text("x"..abad.vides,63*o2aX,43*o2aX,2)
    ---        end
    ---    end
	---
    ---    mapa_update(abad.hab,cameras[current_camera].hab)
	
    --local vp_x, vp_y = viewp:position()
	--if key.down(keyRight) then
    --    if vp_x+1<=(tile_w*mapa_room_cols*(mapa_rooms_per_piso))-(res_w) then vp_x = vp_x+1 end
	--elseif key.down(keyLeft) then
	--	if vp_x>0 then vp_x = vp_x-1 end
	--elseif key.down(keyUp) then
	--	if vp_y>0 then vp_y = vp_y -1 end
	--elseif key.down(keyDown) then
	--	if vp_y+1<=(tile_h*mapa_room_rows*mapa_pisos)-(res_h) then vp_y = vp_y+1 end
	--end
    
    if key.press(key.N1) then
        local hab = abad.hab-1
        if hab<0 then hab=0 end
        local hab_x = 4
        local hab_y = 3
        local abad_x, abad_y = coords.room_to_world ( hab, hab_x, hab_y)
        abad:move(abad_x, abad_y)
        local scr_ax, scr_ay = viewp:screen_coords(abad_x, abad_y)
    end
    if key.press(key.N2) then
        local hab = abad.hab+1
        if hab<0 then hab=0 end
        local hab_x = 4
        local hab_y = 3
        local abad_x, abad_y = coords.room_to_world ( hab, hab_x, hab_y)
        abad:move(abad_x, abad_y)
        local scr_ax, scr_ay = viewp:screen_coords(abad_x, abad_y)
    end
    if key.press(key.N0) then
        local abad_x, abad_y = coords.room_to_world ( 24, 1, 3 )
        print(abad_x..", "..abad_y)
        abad:move(abad_x, abad_y)
        local scr_ax, scr_ay = viewp:screen_coords(abad_x, abad_y)
    end
    
    arc_mapa_update()
    
    
    -- Moure a tots
    for key,actor in pairs(actors) do
        actor:update()
        
        -- Comprovar dispars contra "monstres"
        if viewp:inside(actor.x, actor.y, actor.w, actor.h) and actor~=abad then
            for _, cacau_shot in pairs(cacau.shots()) do
                if cacau_shot.alive and collision(actor,cacau_shot) then
                    if actor.hit ~= nil then
                        actor:hit()
                        cacau:kill(cacau_shot)
                    end
                end
            end
        end
    end
    
    cacau.update()
    switches.update()

    -- Moure el viewport
    local vp_x = viewp.x
    local vp_y = viewp.y
	--viewp:position(vp_x, vp_y)
    
    local vp_center_offset_x = (viewp.width >> 1)
    local vp_center_offset_y = (viewp.height >> 1)
    
    vp_x = abad.x - vp_center_offset_x
    if vp_x < 0 then vp_x = 0 end
    
    vp_y = abad.y - vp_center_offset_y
    if vp_y < 0 then vp_y = 0 end

	viewp:position(vp_x, vp_y)
    
    -- Pintar la finestra del mon
    render_map(sf_mapa, tiles, vp_x, vp_y)
	
    for key,actor in pairs(actors) do
        if viewp:inside(actor.x, actor.y, actor.w, actor.h) then
            actor:draw()
        end
    end
    cacau:draw()

    score.draw()
    
    -- Proves de warp
    surf.source(warp)
    -- draw.surf(0,0,32,32,0,0)
    draw.surfrot(0,0,32,32,0,0,warp_rot)
    warp_rot=warp_rot+5
    if warp_rot>=360 then warp_rot=0 end
    
    fps_print()
	-- viewp:print()
    -- msg_print(0,14,"ABAD= "..abad.x..", "..abad.y, true)
    -- msg_print(0,21,"VIEW= "..vp_x..", "..vp_y, true)
    -- local hab, xx, yy = coords.world_to_tile(abad.x, abad.y)
    -- msg_print(0,28,hab.." ( "..xx..", "..yy.." )", true)
    -- msg_print(0,35,hab.." ( "..xx..", "..yy.." )", true)
    -- msg_print(0,42," JH= "..abad.jump_height,true)
    
    -- view_coord(abad.x+8, abad.y+0, 16, 32, 6)
    -- view_coord(abad.x+abad.bb.x,  abad.y+abad.bb.h, 2, 2, 4)
    -- view_coord(abad.x+abad.bb.x+abad.bb.w, abad.y+abad.bb.h, 2, 2, 2)
    -- view_coord(abad.x, abad.y, 2, 2, 3)
    
    -- if key.press(key.T) then 
    --     view_tile_id = not view_tile_id 
    --     view_checking_tile = false
    -- end
    -- if key.press(key.C) then 
    --     view_checking_tile = not view_checking_tile 
    --     view_tile_id = false
    -- end
    -- 
    -- if view_tile_id then
    --     write_tile(abad.x, abad.y, 0, true, "R")
    --     write_tile(abad.x, abad.y+16, 0, true, "R")
    --     write_tile(abad.x, abad.y+32, 0, true, "R")
    --     
    --     write_tile(abad.x+16, abad.y+32, 0, true, "C")
    -- 
    --     write_tile(abad.x+32, abad.y, 0, true, "L")
    --     write_tile(abad.x+32, abad.y+16, 0, true, "L")
    --     write_tile(abad.x+32, abad.y+32, 0, true, "L")
    -- end
    -- 
    -- if view_checking_tile then
    --     local msg = "FLIP= true"
    --     if not abad.flip then 
    --         msg ="FLIP= false"
    --         view_coord(abad.x+abad.bb.w+abad.bb.x-1, abad.y+abad.bb.h-4, 2, 2, 2)
    --     else
    --         view_coord(abad.x+abad.bb.x-1, abad.y+abad.bb.h-4, 2, 2, 2)
    --     end
    --     msg_print(abad.x, abad.y-8,msg)
    -- end
end

function collision(a, b)
    return     (a.x+a.bb.x+a.bb.w >= b.x+b.bb.x) 
           and (a.x+a.bb.x <= b.x+b.bb.x+b.bb.w) 
           and (a.y+a.bb.y+a.bb.h >= b.y+b.bb.y) 
           and (a.y+a.bb.y <= b.y+b.bb.y+b.bb.h)
end

