/*
 * GStreamer
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gl/gl.h>

#include "gstglsl.h"
#include "gstglsl_private.h"

GQuark
gst_glsl_error_quark (void)
{
  return g_quark_from_static_string ("gst-glsl-error");
}

struct glsl_version_string
{
  GstGLSLVersion version;
  const gchar *name;
};

static const struct glsl_version_string glsl_versions[] = {
  /* keep in sync with definition in the header */
  {GST_GLSL_VERSION_100, "100"},
  {GST_GLSL_VERSION_110, "110"},
  {GST_GLSL_VERSION_120, "120"},
  {GST_GLSL_VERSION_130, "130"},
  {GST_GLSL_VERSION_140, "140"},
  {GST_GLSL_VERSION_150, "150"},
  {GST_GLSL_VERSION_300, "300"},
  {GST_GLSL_VERSION_310, "310"},
  {GST_GLSL_VERSION_320, "320"},
  {GST_GLSL_VERSION_330, "330"},
  {GST_GLSL_VERSION_400, "400"},
  {GST_GLSL_VERSION_410, "410"},
  {GST_GLSL_VERSION_420, "420"},
  {GST_GLSL_VERSION_430, "430"},
  {GST_GLSL_VERSION_440, "440"},
  {GST_GLSL_VERSION_450, "450"},
};

struct glsl_profile_string
{
  GstGLSLProfile profile;
  const gchar *name;
};

static const struct glsl_profile_string glsl_profiles[] = {
  /* keep in sync with definition in the header */
  {GST_GLSL_PROFILE_ES, "es"},
  {GST_GLSL_PROFILE_CORE, "core"},
  {GST_GLSL_PROFILE_COMPATIBILITY, "compatibility"},
};

const gchar *
gst_glsl_version_to_string (GstGLSLVersion version)
{
  int i;

  if (version == GST_GLSL_VERSION_NONE)
    return NULL;

  for (i = 0; i < G_N_ELEMENTS (glsl_versions); i++) {
    if (version == glsl_versions[i].version)
      return glsl_versions[i].name;
  }

  return NULL;
}

GstGLSLVersion
gst_glsl_version_from_string (const gchar * string)
{
  gchar *str;
  int i;

  if (string == NULL)
    return 0;

  str = g_strdup (string);
  str = g_strstrip (str);

  for (i = 0; i < G_N_ELEMENTS (glsl_versions); i++) {
    if (g_strcmp0 (str, glsl_versions[i].name) == 0) {
      g_free (str);
      return glsl_versions[i].version;
    }
  }

  g_free (str);
  return 0;
}

const gchar *
gst_glsl_profile_to_string (GstGLSLProfile profile)
{
  int i;

  if (profile == GST_GLSL_PROFILE_NONE)
    return NULL;

  /* multiple profiles are not allowed */
  if ((profile & (profile - 1)) != 0)
    return NULL;

  for (i = 0; i < G_N_ELEMENTS (glsl_profiles); i++) {
    if (profile == glsl_profiles[i].profile)
      return glsl_profiles[i].name;
  }

  return NULL;
}

GstGLSLProfile
gst_glsl_profile_from_string (const gchar * string)
{
  gchar *str;
  int i;

  if (string == NULL)
    return GST_GLSL_PROFILE_NONE;

  str = g_strdup (string);
  str = g_strstrip (str);

  for (i = 0; i < G_N_ELEMENTS (glsl_profiles); i++) {
    if (g_strcmp0 (str, glsl_profiles[i].name) == 0) {
      g_free (str);
      return glsl_profiles[i].profile;
    }
  }

  g_free (str);
  return GST_GLSL_PROFILE_NONE;
}

static gboolean
_is_valid_version_profile (GstGLSLVersion version, GstGLSLProfile profile)
{
  if (version == GST_GLSL_VERSION_NONE)
    return TRUE;

  /* versions that may not need an explicit profile */
  if (version <= GST_GLSL_VERSION_150 && profile == GST_GLSL_PROFILE_NONE)
    return TRUE;

  /* ES versions require an ES profile */
  if (version == GST_GLSL_VERSION_100 || version == GST_GLSL_VERSION_300
      || version == GST_GLSL_VERSION_310 || version == GST_GLSL_VERSION_320)
    return profile == GST_GLSL_PROFILE_ES;

  /* required profile and no ES profile for normal GL contexts */
  if (version >= GST_GLSL_VERSION_330)
    return profile == GST_GLSL_PROFILE_NONE || profile == GST_GLSL_PROFILE_CORE
        || profile == GST_GLSL_PROFILE_COMPATIBILITY;

  if (version <= GST_GLSL_VERSION_150)
    return profile == GST_GLSL_PROFILE_NONE
        || profile == GST_GLSL_PROFILE_COMPATIBILITY;

  return FALSE;
}

gchar *
gst_glsl_version_profile_to_string (GstGLSLVersion version,
    GstGLSLProfile profile)
{
  const gchar *version_s, *profile_s;

  if (!_is_valid_version_profile (version, profile))
    return NULL;

  version_s = gst_glsl_version_to_string (version);
  /* no profiles in GL/ES <= 150 */
  if (version <= GST_GLSL_VERSION_150)
    profile_s = NULL;
  else
    profile_s = gst_glsl_profile_to_string (profile);

  if (!version_s)
    return NULL;

  if (profile_s)
    return g_strdup_printf ("%s %s", version_s, profile_s);

  return g_strdup (version_s);
}

static void
_fixup_version_profile (GstGLSLVersion * version, GstGLSLProfile * profile)
{
  if (*version == GST_GLSL_VERSION_100 || *version == GST_GLSL_VERSION_300
      || *version == GST_GLSL_VERSION_310 || *version == GST_GLSL_VERSION_320)
    *profile = GST_GLSL_PROFILE_ES;
  else if (*version <= GST_GLSL_VERSION_150)
    *profile = GST_GLSL_PROFILE_COMPATIBILITY;
  else if (*profile == GST_GLSL_PROFILE_NONE
      && *version >= GST_GLSL_VERSION_330)
    *profile = GST_GLSL_PROFILE_CORE;
}

/* @str points to the start of "#version", "#    version" or "#\tversion", etc */
static const gchar *
_check_valid_version_preprocessor_string (const gchar * str)
{
  gint i = 0;

  if (!str || !str[i])
    return NULL;

  /* there can be whitespace between the '#' and 'version' */
  do {
    i++;
    if (str[i] == '\0' || str[i] == '\n' || str[i] == '\r')
      return NULL;
  } while (g_ascii_isspace (str[i]));
  if (g_strstr_len (&str[i], 7, "version"))
    return &str[i + 7];

  return NULL;
}

gboolean
gst_glsl_version_profile_from_string (const gchar * string,
    GstGLSLVersion * version_ret, GstGLSLProfile * profile_ret)
{
  gchar *str, *version_s, *profile_s;
  GstGLSLVersion version = GST_GLSL_VERSION_NONE;
  GstGLSLProfile profile = GST_GLSL_PROFILE_NONE;
  gint i;

  if (!string)
    goto error;

  str = g_strdup (string);
  version_s = g_strstrip (str);

  /* skip possible #version prefix */
  if (str[0] == '#') {
    if (!(version_s =
            (gchar *) _check_valid_version_preprocessor_string (version_s))) {
      g_free (str);
      goto error;
    }
  }

  version_s = g_strstrip (version_s);

  i = 0;
  while (version_s && version_s[i] != '\0' && g_ascii_isdigit (version_s[i]))
    i++;
  /* wrong version length */
  if (i != 3) {
    g_free (str);
    goto error;
  }

  if (version_s[i] != 0) {
    version_s[i] = '\0';
    i++;
    profile_s = &version_s[i];
    profile_s = g_strstrip (profile_s);

    profile = gst_glsl_profile_from_string (profile_s);
  }
  version = gst_glsl_version_from_string (version_s);
  g_free (str);

  /* check whether the parsed data is valid */
  if (!version)
    goto error;
  if (!_is_valid_version_profile (version, profile))
    goto error;
  /* got a profile when none was expected */
  if (version <= GST_GLSL_VERSION_150 && profile != GST_GLSL_PROFILE_NONE)
    goto error;

  _fixup_version_profile (&version, &profile);

  if (profile_ret)
    *profile_ret = profile;
  if (version_ret)
    *version_ret = version;

  return TRUE;

error:
  {
    if (profile_ret)
      *profile_ret = GST_GLSL_PROFILE_NONE;
    if (version_ret)
      *version_ret = GST_GLSL_VERSION_NONE;
    return FALSE;
  }
}

/* returns the pointer in @str to the #version declaration */
const gchar *
_gst_glsl_shader_string_find_version (const gchar * str)
{
  gboolean sl_comment = FALSE;
  gboolean ml_comment = FALSE;
  gboolean newline = TRUE;
  gint i = 0;

  /* search for #version while allowing for preceeding comments/whitespace as
   * permitted by the GLSL specification */
  while (str && str[i] != '\0' && i < 1024) {
    if (str[i] == '\n' || str[i] == '\r') {
      newline = TRUE;
      sl_comment = FALSE;
      i++;
      continue;
    }

    if (g_ascii_isspace (str[i]))
      goto next;

    if (sl_comment)
      goto next;

    if (ml_comment) {
      if (g_strstr_len (&str[i], 2, "*/")) {
        ml_comment = FALSE;
        i++;
      }
      goto next;
    }

    if (g_strstr_len (&str[i], 2, "//")) {
      sl_comment = TRUE;
      i++;
      goto next;
    }

    if (g_strstr_len (&str[i], 2, "/*")) {
      ml_comment = TRUE;
      i++;
      goto next;
    }

    if (str[i] == '#') {
      if (newline && _check_valid_version_preprocessor_string (&str[i]))
        return &str[i];
      break;
    }

  next:
    newline = FALSE;
    i++;
  }

  return NULL;
}

gboolean
gst_glsl_string_get_version_profile (const gchar * s, GstGLSLVersion * version,
    GstGLSLProfile * profile)
{
  const gchar *version_profile_s;

  version_profile_s = _gst_glsl_shader_string_find_version (s);
  if (!version_profile_s)
    goto error;

  if (!gst_glsl_version_profile_from_string (version_profile_s, version,
          profile))
    goto error;

  return TRUE;

error:
  {
    if (version)
      *version = GST_GLSL_VERSION_NONE;
    if (profile)
      *profile = GST_GLSL_PROFILE_NONE;
    return FALSE;
  }
}

GstGLSLVersion
gst_gl_version_to_glsl_version (GstGLAPI gl_api, gint maj, gint min)
{
  g_return_val_if_fail (gl_api != GST_GL_API_NONE, 0);

  if (gl_api & GST_GL_API_GLES2) {
    if (maj == 2 && min == 0)
      return 100;

    if (maj == 3 && min >= 0 && min <= 2)
      return maj * 100 + min * 10;

    return 0;
  }

  /* versions match for >= 3.3 */
  if (gl_api & (GST_GL_API_OPENGL3 | GST_GL_API_OPENGL)) {
    if (maj > 3 || (maj == 3 && min >= 3))
      return maj * 100 + min * 10;

    if (maj == 3 && min == 2)
      return 150;
    if (maj == 3 && min == 1)
      return 140;
    if (maj == 3 && min == 0)
      return 130;
    if (maj == 2 && min == 1)
      return 120;
    if (maj == 2 && min == 0)
      return 110;

    return 0;
  }

  return 0;
}

gboolean
gst_gl_context_supports_glsl_profile_version (GstGLContext * context,
    GstGLSLVersion version, GstGLSLProfile profile)
{
  g_return_val_if_fail (GST_IS_GL_CONTEXT (context), FALSE);

  if (!_is_valid_version_profile (version, profile))
    return FALSE;

  if (profile != GST_GLSL_PROFILE_NONE) {
    if (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0)) {
      if ((profile & GST_GLSL_PROFILE_ES) == 0)
        return FALSE;
    } else if ((gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) != 0) {
      if ((profile & GST_GLSL_PROFILE_COMPATIBILITY) == 0)
        return FALSE;
    } else if ((gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL3) != 0) {
      /* GL_ARB_es2_compatibility is requried for GL3 contexts */
      if ((profile & (GST_GLSL_PROFILE_CORE | GST_GLSL_PROFILE_ES)) == 0)
        return FALSE;
    } else {
      g_assert_not_reached ();
    }
  }

  if (version != GST_GLSL_VERSION_NONE) {
    GstGLAPI gl_api;
    gint maj, min, glsl_version;

    if (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 1)) {
      if (version > GST_GLSL_VERSION_310)
        return FALSE;
    } else if (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3,
            0)) {
      if (version > GST_GLSL_VERSION_300)
        return FALSE;
    } else if (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2,
            0)) {
      if (version > GST_GLSL_VERSION_100)
        return FALSE;
    }

    gl_api = gst_gl_context_get_gl_api (context);
    gst_gl_context_get_gl_version (context, &maj, &min);
    glsl_version = gst_gl_version_to_glsl_version (gl_api, maj, min);
    if (version > glsl_version)
      return FALSE;

    if (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 1, 0))
      /* GL_ARB_es2_compatibility is requried for GL3 contexts */
      if (version < GST_GLSL_VERSION_150 && version != GST_GLSL_VERSION_100)
        return FALSE;

    if (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0)
        && version < GST_GLSL_VERSION_110)
      return FALSE;
  }

  return TRUE;
}

gboolean
_gst_glsl_funcs_fill (GstGLSLFuncs * vtable, GstGLContext * context)
{
  GstGLFuncs *gl = context->gl_vtable;

  if (vtable->initialized)
    return TRUE;

  if (gl->CreateProgram) {
    vtable->CreateProgram = gl->CreateProgram;
    vtable->DeleteProgram = gl->DeleteProgram;
    vtable->UseProgram = gl->UseProgram;

    vtable->CreateShader = gl->CreateShader;
    vtable->DeleteShader = gl->DeleteShader;
    vtable->AttachShader = gl->AttachShader;
    vtable->DetachShader = gl->DetachShader;

    vtable->GetAttachedShaders = gl->GetAttachedShaders;

    vtable->GetShaderInfoLog = gl->GetShaderInfoLog;
    vtable->GetShaderiv = gl->GetShaderiv;
    vtable->GetProgramInfoLog = gl->GetProgramInfoLog;
    vtable->GetProgramiv = gl->GetProgramiv;
  } else if (gl->CreateProgramObject) {
    vtable->CreateProgram = gl->CreateProgramObject;
    vtable->DeleteProgram = gl->DeleteObject;
    vtable->UseProgram = gl->UseProgramObject;

    vtable->CreateShader = gl->CreateShaderObject;
    vtable->DeleteShader = gl->DeleteObject;
    vtable->AttachShader = gl->AttachObject;
    vtable->DetachShader = gl->DetachObject;

    vtable->GetAttachedShaders = gl->GetAttachedObjects;

    vtable->GetShaderInfoLog = gl->GetInfoLog;
    vtable->GetShaderiv = gl->GetObjectParameteriv;
    vtable->GetProgramInfoLog = gl->GetInfoLog;
    vtable->GetProgramiv = gl->GetObjectParameteriv;
  } else {
    vtable->initialized = FALSE;
    return FALSE;
  }

  vtable->initialized = TRUE;
  return TRUE;
}
