"""
Quick tutorial:

- In the INIT script: 

lib_dir = gh_utils.get_scripting_libs_dir()     
dofile(lib_dir .. "lua/libfont/libfont1.lua")    

libfont_init_font_height(20)

- In the FRAME script:

libfont_clear()
libfont_print(20, 20, 1, 1, 0, 1, "Hello in Yellow")
libfont_print(20, 40, 1, 0, 0, 1, "Hello in Red")

# UTF8
libfont_wprint(20, 40, 1, 0, 0, 1, "Héllô UTF8")

libfont_render()
"""




import gh_utils
import gh_renderer
import gh_window
import gh_camera
import gh_texture
import gh_object
import gh_font
import gh_gpu_program



_libfont_initialized = 0
_libfont_font = 0
_libfont_font_height = 18
_libfont_texture = 0
_libfont_camera_ortho = 0
_libfont_gpu_program = 0



#------------------------------------------------------------------------------------
#--
def _libfont_init_gpu_program():
  global _libfont_gpu_program
  if (_libfont_gpu_program > 0):
    return

  vs_gl3="""
  in vec4 gxl3d_Position; 
  in vec4 gxl3d_TexCoord0; 
  in vec4 gxl3d_Normal; // Bugfix for Radeon + Adrenalin 22.7.1+ 
  in vec4 gxl3d_Color; 
  uniform mat4 gxl3d_ModelViewProjectionMatrix;
  uniform vec4 gxl3d_Viewport; 
  out vec4 Vertex_UV; 
  out vec4 Vertex_Color; 
  void main() 
  { 
    vec4 V = vec4(gxl3d_Position.xyz, 1); 
    V.x = V.x - gxl3d_Viewport.z / 2.0; 
    V.y = V.y + gxl3d_Viewport.w / 2.0; 
    gl_Position = gxl3d_ModelViewProjectionMatrix * V; 
    Vertex_UV = gxl3d_TexCoord0;
    vec4 _AMD_dummy0 = gxl3d_Normal; // Bugfix for Radeon + Adrenalin 22.7.1+
    Vertex_Color = gxl3d_Color; 
  }"""
    
  ps_gl3=""" 
  uniform sampler2D tex0; 
  in vec4 Vertex_UV; 
  in vec4 Vertex_Color; 
  out vec4 FragColor; 
  void main (void) 
  { 
    vec2 uv = Vertex_UV.xy; 
    float t = texture(tex0,uv).r; 
    FragColor = vec4(t * Vertex_Color.rgb, Vertex_Color.a * t); 
    //FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
  }"""
    
  vs_gl2="""
  #version 120
  attribute vec4 gxl3d_Position;
  attribute vec4 gxl3d_TexCoord0;
  attribute vec4 gxl3d_Color; 
  uniform mat4 gxl3d_ModelViewProjectionMatrix; 
  uniform vec4 gxl3d_Viewport;
  varying vec4 Vertex_UV;
  varying vec4 Vertex_Color;
  void main() 
  { 
    vec4 V = vec4(gxl3d_Position.xyz, 1); 
    V.x = V.x - gxl3d_Viewport.z / 2.0; 
    V.y = V.y + gxl3d_Viewport.w / 2.0; 
    gl_Position = gl_ModelViewProjectionMatrix * V;	
    Vertex_UV = gxl3d_TexCoord0;
    Vertex_Color = gxl3d_Color;
  }"""
    
  ps_gl2="""
  #version 120
  uniform sampler2D tex0; 
  varying vec4 Vertex_UV; 
  varying vec4 Vertex_Color; 
  void main (void) 
  { 
    vec2 uv = Vertex_UV.xy; 
    float t = texture2D(tex0,uv).r; 
    gl_FragColor = vec4(t * Vertex_Color.rgb, Vertex_Color.a * t); 
    //gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 
  }"""
  
  
  
  vs_gles2="""
  attribute vec4 gxl3d_Position; 
  attribute vec4 gxl3d_TexCoord0; 
  attribute vec4 gxl3d_Color; 
  uniform mat4 gxl3d_ModelViewProjectionMatrix; 
  uniform vec4 gxl3d_Viewport; 
  varying vec4 Vertex_UV; 
  varying vec4 Vertex_Color; 
  void main() 
  { 
    vec4 V = vec4(gxl3d_Position.xyz, 1.0); 
    V.x = V.x - gxl3d_Viewport.z / 2.0; 
    V.y = V.y + gxl3d_Viewport.w / 2.0; 
    gl_Position = gxl3d_ModelViewProjectionMatrix * V;
    Vertex_UV = gxl3d_TexCoord0; 
    Vertex_Color = gxl3d_Color; 
  }"""
    
  ps_gles2=""" 
  uniform sampler2D tex0; 
  varying highp vec4 Vertex_UV; 
  varying highp vec4 Vertex_Color; 
  void main (void) 
  { 
    highp vec2 uv = Vertex_UV.xy; 
    highp float t = texture2D(tex0,uv).r; 
    gl_FragColor = vec4(t * Vertex_Color.rgb, Vertex_Color.a * t); 
  }"""
  
  if ((gh_utils.get_platform() == 4) and (gh_renderer.is_opengl_es() == 1)):
    # Raspberry Pi
    _libfont_gpu_program = gh_gpu_program.create_v2("libfont_gpu_program",vs_gles2, ps_gles2)
  else:
    vs = ""
    ps = ""
    if (gh_renderer.get_api_version_major() > 3):
      # OpenGL 4.x
      vs = "#version 150\n" + vs_gl3
      ps = "#version 150\n" + ps_gl3
      _libfont_gpu_program = gh_gpu_program.create_v2("libfont_gpu_program", vs, ps)
    
    elif (gh_renderer.get_api_version_major() == 3):
      if (gh_renderer.is_opengl_es() == 1):
        # OpenGL ES 3.1
        vs = vs_gles2
        ps = ps_gles2
      else:
        if (gh_renderer.get_api_version_minor() < 2):
          # OpenGL 3.0 or 3.1
          vs = "#version 130\n" + vs_gl3
          ps = "#version 130\n" + ps_gl3
        else:
          # OpenGL 3.2, 3.3 
          vs = "#version 150\n" + vs_gl3
          ps = "#version 150\n" + ps_gl3

      _libfont_gpu_program = gh_gpu_program.create_v2("libfont_gpu_program", vs, ps)
    
    else:
      # OpenGL 2.1
      _libfont_gpu_program = gh_gpu_program.create_v2("libfont_gpu_program", vs_gl2, ps_gl2)

  gh_gpu_program.uniform1i(_libfont_gpu_program, "tex0", 0)




#------------------------------------------------------------------------------------
#--
def _libfont_init():
  global _libfont_initialized
  global _libfont_camera_ortho
  global _libfont_font
  global _libfont_texture
  global _libfont_font_height

  if (_libfont_initialized == 0):
    
    _libfont_init_gpu_program()

    win_w, win_h = gh_window.getsize(0)
    _libfont_camera_ortho = gh_camera.create_ortho(-win_w/2, win_w/2, -win_h/2, win_h/2, 1.0, 10.0)
    gh_camera.set_viewport(_libfont_camera_ortho, 0, 0, win_w, win_h)
    gh_camera.set_position(_libfont_camera_ortho, 0, 0, 4)
    gh_camera.set_lookat(_libfont_camera_ortho, 0, 0, 0, 1)
    

    lib_dir = gh_utils.get_lib_dir()     
    #_libfont_font = gh_font.create(lib_dir + "python/libfont/roboto/Roboto-Regular.ttf", 20, 512, 512)
    _libfont_font = gh_font.create(lib_dir + "python/libfont/consolasboldmod8.2.ttf", _libfont_font_height, 512, 512)

    gh_font.build_texture(_libfont_font)
    _libfont_texture = gh_font.get_texture(_libfont_font)

    _libfont_initialized = 1




#------------------------------------------------------------------------------------
#--
# libfont_kill is not necessary.
#--
def libfont_kill():
  global _libfont_font
  if (_libfont_font > 0):
    gh_utils.ftgl_font_kill(_libfont_font)



#------------------------------------------------------------------------------------
#--
def _libfont_resize(w, h):
  global _libfont_camera_ortho
  gh_camera.update_ortho(_libfont_camera_ortho, -w/2, w/2, -h/2, h/2, 1.0, 10.0)
  gh_camera.set_viewport(_libfont_camera_ortho, 0, 0, w, h)



#------------------------------------------------------------------------------------
#--
def libfont_get_text_width(text):
  global _libfont_font
  _libfont_init()
  return gh_font.get_text_width(_libfont_font, text)



#------------------------------------------------------------------------------------
#--
def libfont_clear():
  global _libfont_font
  _libfont_init()
  gh_font.clear(_libfont_font)


#------------------------------------------------------------------------------------
#--
def libfont_print(x, y, r, g, b, a, text):
  global _libfont_font
  _libfont_init()
  gh_font.text_2d(_libfont_font, x, y, r, g, b, a, text)

#------------------------------------------------------------------------------------
#--
def libfont_print2(r, g, b, a, text):
  global _libfont_font
  _libfont_init()
  gh_font.text_2d_v2(_libfont_font, r, g, b, a, text)

#------------------------------------------------------------------------------------
#--
def libfont_wprint(x, y, r, g, b, a, text):
  global _libfont_font
  _libfont_init()
  gh_font.wtext_2d(_libfont_font, x, y, r, g, b, a, text)

#------------------------------------------------------------------------------------
#--
def libfont_wprint2(r, g, b, a, text):
  global _libfont_font
  _libfont_init()
  gh_font.wtext_2d_v2(_libfont_font, r, g, b, a, text)

#------------------------------------------------------------------------------------
#--
def libfont_init_font_height(height):
  global _libfont_font_height
  _libfont_font_height = height


#------------------------------------------------------------------------------------
#--
def libfont_render():
  global _libfont_font
  global _libfont_camera_ortho
  global _libfont_gpu_program
  global _libfont_texture

  _libfont_init()

  gh_renderer.set_depth_test_state(0)
  #gh_renderer.blending_on("") # defaut is additive: BLEND_FACTOR_ONE + BLEND_FACTOR_ONE
  gh_renderer.set_blending_state(1)
  gh_renderer.set_blending_factors(2, 5)

  win_w, win_h = gh_window.getsize(0)
  _libfont_resize(win_w, win_h)

  gh_camera.bind(_libfont_camera_ortho)
  gh_gpu_program.bind(_libfont_gpu_program)
  gh_texture.bind(_libfont_texture, 0)

  gh_font.update(_libfont_font, 0)
  gh_font.render(_libfont_font)

  gh_renderer.set_blending_state(0)
  #gh_renderer.blending_off()
  gh_renderer.set_depth_test_state(1)

