

function unix_to_win(path)
  return gsub(path, "/", "\\")
end


function dir_exists_v1(path)
  -- The LFS library is part of GeeXLab built-in libs.
  -- More on LFS functions: https://keplerproject.github.io/luafilesystem/manual.html
  --
  if (lfs.attributes(path,"mode") == "directory") then
    return true
  end
  return false
end

function file_exists_v1(filepath)
  local d = io.open(filepath, "r")
  if d ~= nil then
    d:close()
    return true
  end
  return false
end




function file_exists_v2(file)
  -- some error codes:
  -- 13 : EACCES - Permission denied
  -- 17 : EEXIST - File exists
  -- 20	: ENOTDIR - Not a directory
  -- 21	: EISDIR - Is a directory
  --
  local isok, errstr, errcode = os.rename(file, file)
  if isok == nil then
     if errcode == 13 then 
        -- Permission denied, but it exists
        return true
     end
     return false
  end
  return true
end

function dir_exists_v2(path)
  return file_exists_v2(path.."/")
end







local elapsed_time = gh_utils.get_elapsed_time()
local dt = gh_utils.get_time_step()
local dt_ms = dt * 1000.0

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



if (alpha < 1.0) then
  alpha = alpha + 2.0*dt
end




--print("******** DEMO frame.lua - elapsed_time: " .. elapsed_time)
--print("******** DEMO frame.lua - frames: " .. frames)




local mx, my = gh_input.mouse_get_position()
local mouse_x_2d = mx - winW/2
local mouse_y_2d = winH/2 - my







gh_renderer.set_depth_test_state(1)

-- Background color
--
if (show_mouse_fx == 1) then
  gh_renderer.clear_color_depth_buffers(0, 0, 0, 0, 1.0)
else
  gh_renderer.clear_color_depth_buffers(bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a, 1.0)
end


---[[

-- Effect moving with mouse position
--
if (show_mouse_fx == 1) then
  gh_gpu_program.bind(fx1_prog)
  gh_gpu_program.uniform2f(fx1_prog, "resolution", winW, winH)
  gh_gpu_program.uniform1f(fx1_prog, "time", elapsed_time)
  gh_gpu_program.uniform2f(fx1_prog, "mouse", mx, winH/2 - my)

  gh_mesh.set_vertex_color(fxquad, 0, bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a, 1) --bottom-left
  gh_mesh.set_vertex_color(fxquad, 1, bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a, 1) -- top-left
  gh_mesh.set_vertex_color(fxquad, 2, bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a, 1) --top-right
  gh_mesh.set_vertex_color(fxquad, 3, bgcolor.r, bgcolor.g, bgcolor.b, bgcolor.a, 1) --bottom-right

  gh_object.set_position(fxquad, 0, 0, 0)
  gh_object.render(fxquad)
end



logo_color[4] = alpha

local logocol = logo_color


gh_camera.bind(camera_ortho)

gh_renderer.set_depth_test_state(0)



-- BLEND_FACTOR_ZERO = 0
-- BLEND_FACTOR_ONE = 1
-- BLEND_FACTOR_SRC_ALPHA = 2
-- BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 3
-- BLEND_FACTOR_ONE_MINUS_DST_COLOR = 4
-- BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 5
-- BLEND_FACTOR_DST_COLOR = 6
-- BLEND_FACTOR_DST_ALPHA = 7
-- BLEND_FACTOR_SRC_COLOR = 8
-- BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 9
gh_renderer.set_blending_state(1)
gh_renderer.set_blending_factors(2, 1) -- BLEND_FACTOR_SRC_ALPHA, BLEND_FACTOR_ONE


-- Logo rendering
--
gh_texture.bind(tex_geexlab, 0)
gh_gpu_program.bind(texture_prog)
gh_gpu_program.uniform2f(texture_prog, "uv_tiling", 1, -1)

gh_gpu_program.uniform4f(texture_prog, "color", logocol[1], logocol[2], logocol[3], logocol[4])
gh_object.set_position(quad, 0.0, 80.0, 0.0)
gh_object.render(quad)




-- Animation of three blue quads above the logo.
--
q = quad4

gh_gpu_program.bind(vertex_color_prog)
gh_mesh.set_vertices_color(q, logocol[1], logocol[2], logocol[3], logocol[4])
local k = 1.0 + 0.8*math.sin(elapsed_time * 8.0)
local posy = 110 + (quad4_h/2) * k
gh_object.set_scale(quad4, 1, k, 1)
gh_object.set_position(q, -60, posy, 0)
gh_object.render(q)

k = 0.8 + 0.6*math.sin(elapsed_time * -3.0)
posy = 110 + (quad4_h/2) * k
gh_object.set_scale(q, 1, k, 1)
gh_object.set_position(q, -75, posy, 0)
gh_object.render(q)

k = 0.8 + 0.6*math.cos(elapsed_time * 3.0)
posy = 110 + (quad4_h/2) * k
gh_object.set_scale(q, 1, k, 1)
gh_object.set_position(q, -45, posy, 0)
gh_object.render(q)



gh_renderer.set_blending_state(0)








-- Mouse big crosshair cursor
--
if (show_mouse_fx == 1) then

  gh_renderer.set_blending_state(1)
  gh_renderer.set_blending_factors(1, 1)


  local quad2_y = winH/2 - my
  local quad3_x = mx - winW/2



  local q = quad2
  gh_gpu_program.bind(vertex_color_prog)
  gh_mesh.set_vertices_color(q, 0.1, 0.1, 0.1, 1.0)
  gh_object.set_position(q, 0, quad2_y, 0)
  gh_object.render(q)

  q = quad3
  gh_mesh.set_vertices_color(q, 0.1, 0.1, 0.1, 1.0)
  gh_object.set_position(q, quad3_x, 0, 0)
  gh_object.render(q)


  gh_renderer.set_blending_state(0)

end

--]]















-- Text rendering -----------------------------------------------------------------------------
--

---[[

local font = font_coolvetica_24
libfont2_clear(font)
--local text = geexlab_version .. " - " .. geexlab_build_date
local text = geexlab_version
local text_width = libfont2_get_text_width(font, text)
libfont2_print(font, winW/2 - text_width/2, winH/2-30, logocol[1]*1.4, logocol[2]*1.4, logocol[3]*1.4, logocol[4], text)
text = "Scriptable Proto-Engine"
text_width = libfont2_get_text_width(font, text)
libfont2_print(font, winW/2 - text_width/2, winH/2-10, logocol[1]*1.4, logocol[2]*1.4, logocol[3]*1.4, logocol[4], text)

-- local timestamp = os.time()
-- local tmp = os.date("*t", timestamp)
-- local day_str = os.date("%A, %B %d %Y", timestamp)
-- local day_str2 = os.date("%d/%m/%Y", timestamp)
-- local day_str3 = os.date("day: %j - week: %W", timestamp)
-- local time_str = string.format("%.2d:%.2d:%.2d", tmp.hour, tmp.min, tmp.sec)
-- text = time_str .. " - " .. day_str3
-- text_width = libfont2_get_text_width(font, text)
-- libfont2_print(font, winW/2 - text_width/2, winH-70, 0.4, 0.4, 0.4, 1.0, text)

libfont2_render(font)


font = font_coolvetica_50
libfont2_clear(font)
text = "Drop a demo file (.xml) to run here."
text_width = libfont2_get_text_width(font, text)
libfont2_print(font, winW/2 - text_width/2, winH/2+50, 1.0, 1.0, 1.0, alpha, text)
libfont2_render(font)


font = font_hack_reg_20
libfont2_clear(font)
text = gh_utils.time_to_hour_min_sec(elapsed_time)
text_width = libfont2_get_text_width(font, text)
libfont2_print(font, winW/2 - text_width/2, winH-50, 0.4, 0.4, 0.4, alpha, text)
libfont2_render(font)

--]]













--[[
imgui_frame_begin()

is_open, show = imgui_window_begin_close_button_no_collapse("Useful links##links", 200, 360, 40, 40, 1)
if (is_open == 1) then

  gh_imgui.text(string.format("- GeeXLab %s", geexlab_version))

  imgui_window_end()
end

imgui_frame_end()
--]]








-- ImGui rendering -----------------------------------------------------------------------
--

---[[

gh_imgui.set_default_font(font_RobotoRegular_16)

imgui_frame_begin()

gh_imgui.set_color(IMGUI_WINDOW_BG_COLOR, 0.1, 0.1, 0.1, 0.85)
gh_imgui.set_color(IMGUI_TEXT_COLOR, 1.0, 1.0, 1.0, 1.0)

gh_imgui.set_color(IMGUI_TITLE_BG_COLOR, 0.35, 0.35, 0.35, 1.0)
gh_imgui.set_color(IMGUI_TITLE_BG_ACTIVE_COLOR, 0.5, 0.5, 0.5, 1.0)

gh_imgui.set_color(IMGUI_FRAME_BG_COLOR, 0.6, 0.6, 0.6, 0.90)
gh_imgui.set_color(IMGUI_FRAME_BG_HOVERED_COLOR, 0.7, 0.7, 0.7, 0.9)

gh_imgui.set_color(IMGUI_BUTTON_COLOR, 0.3, 0.3, 0.3, 0.8)
gh_imgui.set_color(IMGUI_BUTTON_HOVERED_COLOR, 0.4, 0.4, 0.4, 0.8)

gh_imgui.set_color(IMGUI_CHECK_MARK_COLOR, 0.1, 0.1, 0.1, 1.0)

  

  


if (show_info_versions_window == 1) then

  is_open, show = imgui_window_begin_close_button_no_collapse("About##aboutbox0", 300, 160, 40, 40, show_info_versions_window)
  if (is_open == 1) then

    gh_imgui.text(string.format("- GeeXLab %s", geexlab_version))
    gh_imgui.set_color(IMGUI_TEXT_COLOR, 0.7, 0.7, 0.7, 1.0)
    gh_imgui.text(string.format("- build: %s", geexlab_build_date))
    gh_imgui.set_color(IMGUI_TEXT_COLOR, 1.0, 1.0, 1.0, 1.0)
    gh_imgui.text(string.format("- Lua %s", lua_version_str))
    gh_imgui.text(string.format("- Dear ImGui %s", imgui_version))
    gh_imgui.text(string.format("- %s", software_platform))

    --for n in pairs(_G) do gh_imgui.text(n) end

    show_info_versions_window = show
  end
  imgui_window_end()
end







if (show_links_window == 1) then

  is_open, show = imgui_window_begin_close_button_no_collapse("Useful links##links", 200, 360, 40, 40, show_links_window)
  if (is_open == 1) then

    local button_width = 180
  
    if (gh_imgui.button("GeeXLab homepage", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/geexlab/")
    end
    if (gh_imgui.button("GeeXLab blog", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/hacklab/")
    end
    if (gh_imgui.button("Forum", button_width, 20) == 1) then
      gh_utils.open_url("https://www.geeks3d.com/forums/index.php?board=5.0")
    end
    if (gh_imgui.button("Discord Server", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/discord/")
    end
    if (gh_imgui.button("Downloads", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/615")
    end
    gh_imgui.spacing()
    gh_imgui.spacing()
    if (gh_imgui.button("Getting Started", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/610")
    end
    if (gh_imgui.button("Learn Pack", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/612")
    end
    if (gh_imgui.button("Scripting API", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/611")
    end
    if (gh_imgui.button("Rootard Guide", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/613")
    end
    gh_imgui.spacing()
    gh_imgui.spacing()
    if (gh_imgui.button("Demo Of the Day", button_width, 20) == 1) then
      gh_utils.open_url("https://geeks3d.com/r/617")
    end



    gh_imgui.spacing()
    gh_imgui.spacing()
    gh_imgui.set_color(IMGUI_BUTTON_COLOR, 0.75, 0.75, 0.75, 1.0)
    gh_imgui.set_color(IMGUI_BUTTON_HOVERED_COLOR, 0.85, 0.85, 0.85, 1.0)
    gh_imgui.set_color(IMGUI_TEXT_COLOR, 0.0, 0.0, 0.0, 1.0)
  
  
    if (gh_imgui.button("GeeXLab folder", button_width, 20) == 1) then
      local app_dir = gh_utils.get_app_dir()
      gh_utils.open_url(app_dir)
    end

    if (gh_imgui.button("GeeXLab libs folder", button_width, 20) == 1) then
      local app_dir = gh_utils.get_app_dir()
      gh_utils.open_url(app_dir .. "/libs/")
    end

    gh_imgui.set_color(IMGUI_TEXT_COLOR, 1.0, 1.0, 1.0, 1.0)
    gh_imgui.set_color(IMGUI_BUTTON_COLOR, 0.3, 0.3, 0.3, 0.8)
    gh_imgui.set_color(IMGUI_BUTTON_HOVERED_COLOR, 0.4, 0.4, 0.4, 0.8)
      
    
    show_links_window = show

  end
  imgui_window_end()
end
  







if (show_gl_vk_info == 1) then

  is_open, show = imgui_window_begin_close_button_no_collapse("OpenGL/Vulkan info##glvkinfog", 360, 360, 20, 20, show_gl_vk_info)
  if (is_open == 1) then
  

    win_hovered = gh_imgui.is_window_hovered()

    local window_w = gh_imgui.get_content_region_available_width()

    local widget_width = window_w * 1.0

    gh_imgui.push_font(font_BebasNeue_Regular_26)
    gh_imgui.text("OpenGL:")
    gh_imgui.pop_font()
    
    gh_imgui.push_font(font_RobotoRegular_16)

    gh_imgui.text(string.format("GL_RENDERER: %s", gl.renderer))
    gh_imgui.text(string.format("GL_VERSION: %s", gl.version))
    gh_imgui.text(string.format("OpenGL extensions: %d", gl.num_extensions))

    if (gh_imgui.button("Show GL extensions", 160, 20) == 1) then
      show_gl_extensions_window = 1
    end

    gh_imgui.pop_font()



    imgui_vertical_space_v2(4)



    if (num_vk_gpus > 0) then

      gh_imgui.separator()

      gh_imgui.push_font(font_BebasNeue_Regular_26)
      gh_imgui.text("Vulkan:")
      gh_imgui.pop_font()
      gh_imgui.push_font(font_RobotoRegular_16)
      for i=0, num_vk_gpus-1 do
        local vkgpu = vk_gpus[i+1]
        gh_imgui.text(string.format("GPU %d: Vulkan %d.%d.%d", i+1, vkgpu.api_ver_major, vkgpu.api_ver_minor, vkgpu.api_ver_patch))
        gh_imgui.text(string.format("- %s (%.4X-%.4X)", vkgpu.name, vkgpu.vendor_id, vkgpu.device_id))
        if (gh_imgui.button(string.format("Show VK extensions##gpu%d", i), 160, 20) == 1) then
          vkgpu.show_extensions_window = 1
          show_vk_extensions_window = 1
        end
    
        imgui_vertical_space_v2(2)
      end
      gh_imgui.pop_font()
    end

    show_gl_vk_info = show

  end 
  imgui_window_end()
end






  
window_height = 38
is_open = imgui_window_begin_no_titlebar("GeeXLab##bottombar", winW, window_height, 0, winH-window_height)
if (is_open == 1) then

  gh_imgui.push_font(font_Hack_Regular_14)

  logo_color[1], logo_color[2], logo_color[3], logo_color[4] = gh_imgui.color_edit_rgba_v2("logo##logocolor", logocol[1], logocol[2], logocol[3], logocol[4], ImGuiColorEditFlags_NoInputs)
  gh_imgui.same_line(0,10)

  local app_dir = gh_utils.get_app_dir()
  local demos_dir = app_dir .. "/demos/"
  if (dir_exists_v1(demos_dir)) then
    if (gh_imgui.button("Demos folder", button_width, 20) == 1) then
      gh_utils.open_url(demos_dir)
    end
    gh_imgui.same_line(0,10)
  end


  if (gh_imgui.button("About", 60, 20) == 1) then
    show_info_versions_window = 1
  end
  gh_imgui.same_line(0,10)



  if (gh_imgui.button("OpenGL/Vulkan info", 140, 20) == 1) then
    show_gl_vk_info = 1
  end
  gh_imgui.same_line(0,10)

  if (gh_imgui.button("Links", 60, 20) == 1) then
    show_links_window = 1
  end
  gh_imgui.same_line(0,10)


  show_mouse_fx = gh_imgui.checkbox("mouse", show_mouse_fx)
  gh_imgui.same_line(0,10)


  local l_vsync = gh_imgui.checkbox("vsync", vsync)
  if (l_vsync ~= vsync) then
    vsync = l_vsync
    gh_renderer.vsync(vsync)
  end






  gh_imgui.same_line(0,10)



  -- Some spinners (GeeXLab 0.49+)
  --
  gh_imgui.group_begin() -- trick to align the text with the color-edit widget...

  gh_imgui.dummy(0, 0)

  label = "spinner_twin_pulsar"
  radius = 6.0
  thickness = 1.0
  color = {1.0, 1.0, 1.0, 1.0}
  velocity = 0.5
  speed = 1.1
  local rings  = 2
  gh_imgui.imspinner_spinner_twin_pulsar(label, radius, thickness, color[1], color[2], color[3], color[4], speed, rings)

  gh_imgui.same_line(0,10)

  label = "spinner_fade_bars"
  w = 3.0
  color = {1.0, 1.0, 1.0, 1.0}
  velocity = 0.5
  speed = 2.8
  bars = 4
  scale = 1
  gh_imgui.imspinner_spinner_fade_bars(label, w, color[1], color[2], color[3], color[4], speed, bars, scale)

  gh_imgui.same_line(0,15)

  label = "spinner_lemniscate"
  radius = 6.0
  thickness = 2.0
  color = {1.0, 1.0, 1.0, 1.0}
  velocity = 0.5
  speed = 2.8
  angle = 3.14159
  gh_imgui.imspinner_spinner_lemniscate(label, radius, thickness, color[1], color[2], color[3], color[4], speed, angle)

  gh_imgui.group_end()






  gh_imgui.same_line(0,5)





  gh_imgui.group_begin() -- trick to align the text with the color-edit widget...
  gh_imgui.dummy(0, 0)
  --gh_imgui.text(string.format("- %.0fFPS (%.2fms) - %dx%d - [%d;%d] - [%.0f;%.0f]", fps, dt_ms, winW, winH, mx, my, mouse_x_2d, mouse_y_2d))
  gh_imgui.text(string.format(" %.0fFPS (%.2fms) | %dx%d [%d;%d]", fps, dt_ms, winW, winH, mx, my))
  gh_imgui.group_end()






  gh_imgui.pop_font()

end 
imgui_window_end()








if (show_gl_extensions_window == 1) then
  is_open, show = imgui_window_begin_close_button_no_collapse("OpenGL extensions##glextensions", 400, 400, 100, 100, show_gl_extensions_window)

  if (is_open == 1) then
    gh_imgui.push_font(font_Hack_Regular_14)

    gh_imgui.text(gl.renderer)
    gh_imgui.text(string.format("# extensions: %d", gl.num_extensions))

    local border = 1
    local flags = 0 --ImGuiWindowFlags_HorizontalScrollbar
    gh_imgui.begin_child("##glext", cw, 0, border, flags)

    
    for i=1, gl.num_extensions do
      local ext_name = gl.extensions[i]
      gh_imgui.text(string.format("[%03d] %s", i, ext_name))
    end
    gh_imgui.end_child()

    gh_imgui.pop_font()


    show_gl_extensions_window = show

  end 
  imgui_window_end()
end







if (show_vk_extensions_window == 1) then

  for i=0, num_vk_gpus-1 do
    local vkgpu = vk_gpus[i+1]
    if (vkgpu.show_extensions_window == 1) then

      is_open, show = imgui_window_begin_close_button_no_collapse(string.format("Vulkan extensions##glextensions_%d", i), 400, 400, 100, 100, vkgpu.show_extensions_window)
        if (is_open == 1) then

        gh_imgui.push_font(font_Hack_Regular_14)

        gh_imgui.text(vkgpu.name)
        gh_imgui.text(string.format("# extensions: %d", vkgpu.num_extensions))

        local border = 1
        local flags = 0 --ImGuiWindowFlags_HorizontalScrollbar
        gh_imgui.begin_child("##vkext", cw, 0, border, flags)

        for j=1, vkgpu.num_extensions do
          local ename = vkgpu.extensions[j]
          gh_imgui.text(string.format("[%03d] %s", j, ename))
        end
        gh_imgui.end_child()

        gh_imgui.pop_font()

        vkgpu.show_extensions_window = show

      end 
      imgui_window_end()
    end
  end

end






if (geexlab_new_version_available == 1) then

  gh_imgui.set_color(IMGUI_WINDOW_BG_COLOR, 0.1, 0.1, 0.1, 1.0)
  
  
  local is_open, show = imgui_window_begin_close_button("GeeXLab - New version##new_version", 300, 150, winW/2-150, winH/2-75, 1)
  if (is_open == 1) then
    gh_imgui.spacing()
    gh_imgui.spacing()

    gh_imgui.push_font(font_BebasNeue_Regular_26)
    gh_imgui.text_rgba(string.format("New version %s is available", geexlab_new_version), 1.0, 1.0, 0.0, 1.0)
    gh_imgui.pop_font()

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

    if (gh_imgui.button("DOWNLOAD", 140, 24) == 1) then
      --gh_utils.open_url("https://www.geeks3d.com/geexlab/downloads/")
      gh_utils.open_url(geexlab_download_url)
    end
    
    gh_imgui.same_line(0, 20)
    
    if (gh_imgui.button("Close", 60, 24) == 1) then
      geexlab_new_version_available = 0
    end

  end

  imgui_window_end()

  if (show == 0) then
    geexlab_new_version_available = 0
  end

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

end



imgui_frame_end()
--]]






--[[
local glerr = gh_renderer.get_opengl_error()
if (glerr > 0) then
  local glerr_str = gh_renderer.opengl_error_code_to_str(glerr)
  print("OpenGL error: " .. glerr .. " (" .. glerr_str .. ")")
end
--]]


--print("******** DEMO frame.lua - END - frames: " .. frames)
