
local elapsed_time = gh_utils.get_elapsed_time()
local dt = gh_utils.get_time_step()


frames = frames+1
fps_time = fps_time + dt
if (fps_time >= 1.0) then
  fps_time = 0
  fps = frames
  frames = 0
end  


total_frames = total_frames + 1



rendering_scale = 10.0
world_y_offset = -200







-- Run a simulatiuon every 1/60 second (sim_dt == 1/60).
--
local can_run_simulation = 0

sim_time = sim_time + dt
if (sim_time >= sim_dt) then
  can_run_simulation = 1
  sim_time = 0
end












  -- Windows platform.
  if (gh_utils.get_platform() == 1) then
    gh_window.keyboard_update_buffer(0)
  end

  local KC_S = 31
  local KC_W = 17
  local KC_Z = 44
  local	KC_UP = 200
  local	KC_LEFT = 203
  local KC_RIGHT = 205
  local	KC_DOWN = 208


  if ((gh_input.keyboard_is_key_down(KC_UP) == 1) or 
      (gh_input.keyboard_is_key_down(KC_W) == 1) or 
      (gh_input.keyboard_is_key_down(KC_Z) == 1)) then
    spaceship_pos_y = spaceship_pos_y + (spaceship_speed_y*dt)
  end

  if ((gh_input.keyboard_is_key_down(KC_DOWN) == 1) or 
      (gh_input.keyboard_is_key_down(KC_S) == 1)) then
    spaceship_pos_y = spaceship_pos_y - (spaceship_speed_y*dt)
  end


  local KC_SPACE = 57
  if ((spaceship_can_shoot == 1) and (gh_input.keyboard_is_key_down(KC_SPACE) == 1)) then
    spaceship_can_shoot = 0
    shoot = 1

    if (bullet_counter0 == 0) then bullet_counter0 = 1 else bullet_counter0 = 0 end

  end
  if (gh_input.keyboard_is_key_down(KC_SPACE) == 0) then
    spaceship_can_shoot = 1
  end



  if (spaceship_pos_y > 260) then
    spaceship_pos_y = 260
  end

  if (spaceship_pos_y < -130) then
    spaceship_pos_y = -130
  end





if ((run_simulation == 1) and (can_run_simulation == 1)) then









  -- Reset the position of all dynamic obstacles and bullets
  --
  if (reset_simulation == 1) then
    reset_simulation = 0
  

    -- bullets.
    --
    gh_box2d.actor_set_transform(b2_box, -20, box_size.y/2,    deg2rad(0.0))
    --gh_box2d.actor_set_transform(b2_box, -20, 200,    deg2rad(0.0))
    gh_box2d.actor_set_linear_velocity(b2_box, 0, 0)
    gh_box2d.actor_set_angular_velocity(b2_box, 0, 0)
    gh_box2d.actor_set_awake(b2_box, 0) -- Put to sleep
  
    gh_box2d.actor_set_transform(b2_disc, -25, disc_radius,   deg2rad(0.0))
    --gh_box2d.actor_set_transform(b2_disc, -25, 200,   deg2rad(0.0))
    gh_box2d.actor_set_linear_velocity(b2_disc, 0, 0)
    gh_box2d.actor_set_angular_velocity(b2_disc, 0, 0)
    gh_box2d.actor_set_awake(b2_disc, 0) -- Put to sleep
  
  
    -- obstacles.
    --
    for i=1, num_boxes do
      local box = boxes[i] 
      gh_box2d.actor_set_transform(box.b2id, box.posx, box.posy,   deg2rad(0.0))
      gh_box2d.actor_set_linear_velocity(box.b2id, 0, 0)
      gh_box2d.actor_set_angular_velocity(box.b2id, 0, 0)
    end
 
  end
  
  
  
  

  -- Can we shoot bullets (two bullets at the same time!) ?
  --
  if (shoot == 1) then
    shoot = 0

    local bx = spaceship_pos_x / rendering_scale
    local by = (spaceship_pos_y-world_y_offset) / rendering_scale


    if (bullet_counter0 == 0) then
      --bullet_counter0 = 1
      gh_box2d.actor_set_awake(b2_box, 1)
      gh_box2d.actor_set_transform(b2_box, bx+4, by,    deg2rad(-40.0))
      gh_box2d.actor_set_damping(b2_box, 0.0, 0.1)
      gh_box2d.actor_set_linear_velocity(b2_box, bullet1_speed.x, bullet1_speed.y)
      gh_box2d.actor_set_angular_velocity(b2_box, deg2rad(80.0))
    else
      --bullet_counter0 = 0
      gh_box2d.actor_set_awake(b2_disc, 1)
      gh_box2d.actor_set_transform(b2_disc, bx+4, by,    deg2rad(0.0))
      gh_box2d.actor_set_damping(b2_disc, 0.0, 0.1)
      gh_box2d.actor_set_linear_velocity(b2_disc, bullet2_speed.x, bullet2_speed.y)
      gh_box2d.actor_set_angular_velocity(b2_disc, deg2rad(0.0))
    end
    



    -- Bullet 1
    -- gh_box2d.actor_set_transform(b2_box, -20, math.random(5, 15),    deg2rad(-40.0))
    -- gh_box2d.actor_set_damping(b2_box, 0.0, 0.1)
    -- gh_box2d.actor_set_linear_velocity(b2_box, bullet1_speed.x, bullet1_speed.y)
    -- gh_box2d.actor_set_angular_velocity(b2_box, deg2rad(80.0))
  
    -- Bullet 2
    --gh_box2d.actor_set_transform(b2_disc, -25, math.random(10, 20),    deg2rad(0.0))
    -- gh_box2d.actor_set_damping(b2_disc, 0.0, 0.1)
    -- gh_box2d.actor_set_linear_velocity(b2_disc, bullet2_speed.x, bullet2_speed.y)
    -- gh_box2d.actor_set_angular_velocity(b2_disc, deg2rad(0.0))
  
  end
  
  

  -- Can we move kinematic obstacle (the big one in orange) ?
  --
  if (move_kinematic_box1 == 1) then
    gh_box2d.actor_set_transform(b2_kinematic_box1, static_box1_pos.x, static_box1_pos.y,   deg2rad(0.0))
    move_kinematic_box1 = 0
  end



  -- Perform a step simulation
  --
  local velocity_iterations = 16
  local position_iterations = 8
  gh_box2d.world_step_simulation(b2_world, sim_dt, velocity_iterations, position_iterations)

  total_simulations = total_simulations + 1


  -- Update the 3D objects position and rotation (around Z axis only).
  --
  posx, posy, angle = gh_box2d.actor_get_transform(b2_ground)
  gh_object.set_position(ground, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
  gh_object.set_euler_angles(ground, 0, 0, rad2deg(angle))

  posx, posy, angle = gh_box2d.actor_get_transform(b2_kinematic_box1)
  gh_object.set_position(kinematic_box1, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
  gh_object.set_euler_angles(kinematic_box1, 0, 0, rad2deg(angle))

  posx, posy, angle = gh_box2d.actor_get_transform(b2_static_box2)
  gh_object.set_position(static_box2, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
  gh_object.set_euler_angles(static_box2, 0, 0, rad2deg(angle))

  box_num_contact_points, box_contact_point.x, box_contact_point.y = gh_box2d.actor_read_contacts(b2_box)
  disc_num_contact_points, disc_contact_point.x, disc_contact_point.y = gh_box2d.actor_read_contacts(b2_disc)

  posx, posy, angle = gh_box2d.actor_get_transform(b2_box)
  gh_object.set_position(box, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
  gh_object.set_euler_angles(box, 0, 0, rad2deg(angle))

  posx, posy, angle = gh_box2d.actor_get_transform(b2_disc)
  gh_object.set_position(disc, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
  -- The disc is the unique object that is rotated around Y axis because of the X-axis 90 degrees rotation.
  gh_object.set_euler_angles(disc, 90.0, rad2deg(angle), 0)


  for i=1, num_boxes do
    local box = boxes[i] 
    posx, posy, angle = gh_box2d.actor_get_transform(box.b2id)
    gh_object.set_position(box.quad_id, posx*rendering_scale, posy*rendering_scale+world_y_offset, 0)
    gh_object.set_euler_angles(box.quad_id, 0, 0, rad2deg(angle))
  end

end










gh_camera.bind(camera_ortho)

gh_renderer.set_depth_test_state(0)

gh_renderer.clear_color_depth_buffers(0.2, 0.2, 0.2, 1, 1.0)




if (wireframe == 1) then
  gh_renderer.wireframe()
end




gh_gpu_program.bind(color_prog)


-- Render all static obstacles
--
gh_gpu_program.uniform4f(color_prog, "color", 1.0, 1.0, 0.0, 1)
gh_object.set_scale(ground, rendering_scale, rendering_scale, 1.0)
gh_object.render(ground)
gh_object.set_scale(static_box2, rendering_scale, rendering_scale, 1.0)
gh_object.render(static_box2)


-- Render all kinematic obstacles
--
gh_gpu_program.uniform4f(color_prog, "color", 1.0, 0.5, 0.0, 1)
gh_object.set_scale(kinematic_box1, rendering_scale, rendering_scale, 1.0)
gh_object.render(kinematic_box1)



-- Render all bullets.
--
gh_gpu_program.uniform4f(color_prog, "color", 0.0, 1.0, 0.0, 1)
gh_object.set_scale(box, rendering_scale, rendering_scale, 1.0)
gh_object.render(box)

gh_object.set_scale(disc, rendering_scale, 1.0, rendering_scale)
gh_object.render(disc)



-- Render all dynamic obstacles
--
gh_gpu_program.uniform4f(color_prog, "color", 0.0, 1.0, 1.0, 1)

for i=1, num_boxes do
  local box = boxes[i] 
  gh_object.set_scale(box.quad_id, rendering_scale, rendering_scale, 1.0)
  gh_object.render(box.quad_id)
end



if (wireframe == 1) then
  gh_renderer.solid()
end







gh_renderer.set_blending_state(1)
if (gh_utils.get_platform() == 4) then
  -- RPi platform: their is a weird bug with alpha blending...
  gh_renderer.set_blending_factors(1, 1)
else
  -- Windows, Linux: the correct way to alpha-blend.
  gh_renderer.set_blending_factors(2, 5)
end
gh_gpu_program.bind(texture_prog)
gh_texture.bind(spaceship_tex, 0)
gh_object.set_position(spaceship_quad, spaceship_pos_x, spaceship_pos_y, 1.0)
gh_object.render(spaceship_quad)
gh_renderer.set_blending_state(0)










-- Display contacts between bullets and obstacles.
--
if (show_contacts == 1) then
  gh_gpu_program.uniform4f(color_prog, "color", 1.0, 1.0, 1.0, 1)
  if (box_num_contact_points > 0) then
    gh_object.set_position(circle, box_contact_point.x*rendering_scale, box_contact_point.y*rendering_scale+world_y_offset, 0, 1.0)
    gh_object.render(circle)
  end

  if (disc_num_contact_points > 0) then
    gh_object.set_position(circle, disc_contact_point.x*rendering_scale, disc_contact_point.y*rendering_scale+world_y_offset, 0, 1.0)
    gh_object.render(circle)
  end
end













  imgui_frame_begin()

  gh_imgui.set_color(IMGUI_WINDOW_BG_COLOR, 0.1, 0.1, 0.1, 0.6)

  local is_open = imgui_window_begin_pos_size_always("Control panel", 320, winH, 0, 0)
  if (is_open == 1) then
  

    win_hovered = gh_imgui.is_window_hovered()
            
    
    gh_imgui.text_rgba(string.format("Box2D Physics version: %d.%d.%d", box2d_version.major, box2d_version.minor, box2d_version.revision), 1.0, 1.0, 0.0, 1.0)

    gh_imgui.spacing()
    gh_imgui.spacing()

    gh_imgui.text(string.format("FPS: %.0f", fps))
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.text(string.format("GL_RENDERER: %s", gl_renderer))
    gh_imgui.text(string.format("GL_VERSION: %s", gl_version))


    gh_imgui.spacing()
    gh_imgui.spacing()


    gh_imgui.text(string.format("Num frames: %d", total_frames))
    gh_imgui.text(string.format("Num simulations: %d", total_simulations))

    
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()

    
    gh_imgui.text("Controls:")
    gh_imgui.text("- [W / S / UP / DOWN]: move spaceship")
    gh_imgui.text("- [SPACE]: shoot")


    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()

    local run_pause_label = "Run Simulation"
    if (run_simulation == 1) then
      run_pause_label = "Pause Simulation"
    end
    if (gh_imgui.button(run_pause_label, 120, 30) == 1) then
      if (run_simulation == 1) then
        run_simulation = 0
      else
        run_simulation = 1
      end
    end


    if (run_simulation == 1) then

      gh_imgui.same_line(0, 10)

      if (gh_imgui.button("Reset Obstacles", 120, 30) == 1) then
        reset_simulation = 1
      end


    
      if (gh_imgui.button("SHOOT", 250, 30) == 1) then
        shoot = 1

        if (bullet_counter0 == 0) then bullet_counter0 = 1 else bullet_counter0 = 0 end
      end
    end


    gh_imgui.spacing()
    gh_imgui.spacing()

    




    gh_imgui.spacing()
    gh_imgui.spacing()

    show_contacts = gh_imgui.checkbox("Show bullets contact", show_contacts)

    wireframe = gh_imgui.checkbox("wireframe", wireframe)

    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()



    if (run_simulation == 1) then


      local v_min = 0;
      local v_max = 0;
      local power = 1.0;

      gh_imgui.text("Bullet speed (X and Y axis):")

      v_min = -100;
      v_max = 100;
      bullet1_speed.x, bullet1_speed.y = gh_imgui.slider_2f("square", bullet1_speed.x, bullet1_speed.y,  v_min, v_max, power)
      bullet2_speed.x, bullet2_speed.y = gh_imgui.slider_2f("disc", bullet2_speed.x, bullet2_speed.y,  v_min, v_max, power)


      gh_imgui.spacing()
      gh_imgui.spacing()
      gh_imgui.spacing()
      gh_imgui.spacing()



    

      gh_imgui.text("Move kinematic obstacle:")
      v_min = -42;
      v_max = 48;
      local pos_x = gh_imgui.slider_1f("X-axis##kinematic_box1", static_box1_pos.x, v_min, v_max, power)
      if (pos_x ~= static_box1_pos.x) then
        static_box1_pos.x = pos_x
        move_kinematic_box1 = 1
      end

    end





    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.spacing()

    gh_imgui.text("Legend:")
    gh_imgui.text_rgba("- green: dynamic RB (CCD ON)", 0, 1, 0, 1)
    gh_imgui.text_rgba("- blue: dynamic RB (CCD OFF)", 0, 1.0, 1.0, 1)
    gh_imgui.text_rgba("- orange: kinematic RB", 1, 0.5, 0, 1)
    gh_imgui.text_rgba("- yellow: static RB", 1, 1, 0, 1)
   

    --gh_imgui.text("spaceship_pos_y: " .. spaceship_pos_y)


  end 

  imgui_window_end()
  imgui_frame_end()
  --
  -- ImGui end ---------------------------------------------------------------
  ----------------------------------------------------------------------------
  --]]
