/*
 * Clutter.
 *
 * An OpenGL based 'interactive canvas' library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif

#include <glib.h>
#include <graphene.h>
#include <stdint.h>

#include "clutter/clutter-macros.h"

G_BEGIN_DECLS

#define CLUTTER_D50_X 0.9642f
#define CLUTTER_D50_Y 1.0f
#define CLUTTER_D50_Z 0.8251f

#define CLUTTER_D65_X 0.95047f
#define CLUTTER_D65_Y 1.0f
#define CLUTTER_D65_Z 1.08883f

typedef enum _ClutterColorspace
{
  CLUTTER_COLORSPACE_SRGB,
  CLUTTER_COLORSPACE_BT2020,
  CLUTTER_COLORSPACE_NTSC,
  CLUTTER_COLORSPACE_PAL,
  CLUTTER_COLORSPACE_P3,
} ClutterColorspace;

typedef enum _ClutterTransferFunction
{
  CLUTTER_TRANSFER_FUNCTION_SRGB_PIECEWISE,
  CLUTTER_TRANSFER_FUNCTION_GAMMA22,
  CLUTTER_TRANSFER_FUNCTION_PQ,
  CLUTTER_TRANSFER_FUNCTION_BT1886,
  CLUTTER_TRANSFER_FUNCTION_LINEAR,
} ClutterTransferFunction;

typedef enum _ClutterColorimetryType
{
  CLUTTER_COLORIMETRY_TYPE_COLORSPACE,
  CLUTTER_COLORIMETRY_TYPE_PRIMARIES,
} ClutterColorimetryType;

typedef enum _ClutterEOTFType
{
  CLUTTER_EOTF_TYPE_NAMED,
  CLUTTER_EOTF_TYPE_GAMMA,
} ClutterEOTFType;

typedef enum _ClutterLuminanceType
{
  CLUTTER_LUMINANCE_TYPE_DERIVED,
  CLUTTER_LUMINANCE_TYPE_EXPLICIT,
} ClutterLuminanceType;

typedef struct _ClutterPrimaries
{
  float r_x, r_y;
  float g_x, g_y;
  float b_x, b_y;
  float w_x, w_y;
} ClutterPrimaries;

typedef struct _ClutterColorimetry
{
  ClutterColorimetryType type : 1;
  union
  {
    ClutterColorspace colorspace;
    ClutterPrimaries *primaries;
  };
} ClutterColorimetry;

typedef struct _ClutterEOTF
{
  ClutterEOTFType type : 1;
  union
  {
    ClutterTransferFunction tf_name;
    float gamma_exp;
  };
} ClutterEOTF;

typedef struct _ClutterLuminance
{
  ClutterLuminanceType type : 1;
  float min;
  float max;
  float ref;
  float mastering_max;
} ClutterLuminance;

typedef enum _ClutterCicpPrimaries
{
  CLUTTER_CICP_PRIMARIES_SRGB = 1,
  CLUTTER_CICP_PRIMARIES_PAL = 5,
  CLUTTER_CICP_PRIMARIES_NTSC = 6,
  CLUTTER_CICP_PRIMARIES_NTSC_2 = 7,
  CLUTTER_CICP_PRIMARIES_BT2020 = 9,
  CLUTTER_CICP_PRIMARIES_P3 = 12,
} ClutterCicpPrimaries;

typedef enum _ClutterCicpTransfer
{
  CLUTTER_CICP_TRANSFER_BT709 = 1,
  CLUTTER_CICP_TRANSFER_GAMMA22 = 4,
  CLUTTER_CICP_TRANSFER_GAMMA28 = 5,
  CLUTTER_CICP_TRANSFER_BT601 = 6,
  CLUTTER_CICP_TRANSFER_LINEAR = 8,
  CLUTTER_CICP_TRANSFER_SRGB = 13,
  CLUTTER_CICP_TRANSFER_BT2020 = 14,
  CLUTTER_CICP_TRANSFER_BT2020_2 = 15,
  CLUTTER_CICP_TRANSFER_PQ = 16,
  CLUTTER_CICP_TRANSFER_HLG = 18,
} ClutterCicpTransfer;

typedef struct _ClutterCicp
{
  ClutterCicpPrimaries primaries;
  ClutterCicpTransfer transfer;
  uint8_t matrix_coefficients;
  uint8_t video_full_range_flag;
} ClutterCicp;

CLUTTER_EXPORT
const ClutterPrimaries * clutter_colorspace_to_primaries (ClutterColorspace colorspace);

CLUTTER_EXPORT
void clutter_primaries_ensure_normalized_range (ClutterPrimaries *primaries);

CLUTTER_EXPORT
const ClutterLuminance * clutter_eotf_get_default_luminance (ClutterEOTF eotf);

CLUTTER_EXPORT
const ClutterLuminance * clutter_luminance_get_default_sdr (void);

CLUTTER_EXPORT
const ClutterPrimaries * clutter_colorimetry_get_primaries (const ClutterColorimetry *colorimetry);

CLUTTER_EXPORT
void clutter_colorimetry_clear (ClutterColorimetry *colorimetry);

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (ClutterColorimetry, clutter_colorimetry_clear)

CLUTTER_EXPORT
const char * clutter_colorspace_to_string (ClutterColorspace colorspace);

CLUTTER_EXPORT
char * clutter_colorimetry_to_string (ClutterColorimetry colorimetry);

CLUTTER_EXPORT
const char * clutter_eotf_to_string (ClutterEOTF eotf);

CLUTTER_EXPORT
gboolean clutter_primaries_equal (const ClutterPrimaries *primaries,
                                  const ClutterPrimaries *other_primaries);

CLUTTER_EXPORT
gboolean clutter_colorimetry_equal (const ClutterColorimetry *colorimetry,
                                    const ClutterColorimetry *other_colorimetry);

CLUTTER_EXPORT
gboolean clutter_eotf_equal (const ClutterEOTF *eotf,
                             const ClutterEOTF *other_eotf);

CLUTTER_EXPORT
gboolean clutter_luminance_equal (const ClutterLuminance *lum,
                                  const ClutterLuminance *other_lum);

CLUTTER_EXPORT
void clutter_xyY_to_XYZ (float            x,
                         float            y,
                         float            Y,
                         graphene_vec3_t *XYZ);

CLUTTER_EXPORT
void clutter_colorimetry_to_XYZ (const ClutterColorimetry *colorimetry,
                                 graphene_matrix_t        *to_XYZ);

CLUTTER_EXPORT
void clutter_colorimetry_from_XYZ (const ClutterColorimetry *colorimetry,
                                   graphene_matrix_t        *from_XYZ);

G_END_DECLS
