/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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.
 */
/**
 * SECTION:element-cacasink
 * @see_also: #GstAASink
 *
 * Displays video as color ascii art.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * CACA_GEOMETRY=160x60 CACA_FONT=5x7 gst-launch-1.0 filesrc location=test.avi ! decodebin ! videoconvert ! cacasink
 * ]| This pipeline renders a video to ascii art into a separate window using a
 * small font and specifying the ascii resolution.
 * |[
 * CACA_DRIVER=ncurses gst-launch-1.0 filesrc location=test.avi ! decodebin ! videoconvert ! cacasink
 * ]| This pipeline renders a video to ascii art into the current terminal.
 * </refsect2>
 */

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

#include <string.h>
#include "gstcacasink.h"


//#define GST_CACA_DEFAULT_RED_MASK R_MASK_32_REVERSE_INT
//#define GST_CACA_DEFAULT_GREEN_MASK G_MASK_32_REVERSE_INT
//#define GST_CACA_DEFAULT_BLUE_MASK B_MASK_32_REVERSE_INT

/* cacasink signals and args */
enum
{
  LAST_SIGNAL
};

#define GST_CACA_DEFAULT_SCREEN_WIDTH 80
#define GST_CACA_DEFAULT_SCREEN_HEIGHT 25
#define GST_CACA_DEFAULT_DITHER CACA_DITHERING_NONE
#define GST_CACA_DEFAULT_ANTIALIASING TRUE

enum
{
  PROP_0,
  PROP_SCREEN_WIDTH,
  PROP_SCREEN_HEIGHT,
  PROP_DITHER,
  PROP_ANTIALIASING
};

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
        ("{ RGB, BGR, RGBx, xRGB, BGRx, xBGR, RGB16, RGB15 }"))
    );

static gboolean gst_cacasink_setcaps (GstBaseSink * pad, GstCaps * caps);
static void gst_cacasink_get_times (GstBaseSink * sink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end);
static GstFlowReturn gst_cacasink_render (GstBaseSink * basesink,
    GstBuffer * buffer);

static void gst_cacasink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_cacasink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstStateChangeReturn gst_cacasink_change_state (GstElement * element,
    GstStateChange transition);

#define gst_cacasink_parent_class parent_class
G_DEFINE_TYPE (GstCACASink, gst_cacasink, GST_TYPE_BASE_SINK);

#define GST_TYPE_CACADITHER (gst_cacasink_dither_get_type())
static GType
gst_cacasink_dither_get_type (void)
{
  static GType dither_type = 0;

  static const GEnumValue dither_types[] = {
    {CACA_DITHERING_NONE, "No dithering", "none"},
    {CACA_DITHERING_ORDERED2, "Ordered 2x2 Bayer dithering", "2x2"},
    {CACA_DITHERING_ORDERED4, "Ordered 4x4 Bayer dithering", "4x4"},
    {CACA_DITHERING_ORDERED8, "Ordered 8x8 Bayer dithering", "8x8"},
    {CACA_DITHERING_RANDOM, "Random dithering", "random"},
    {0, NULL, NULL},
  };

  if (!dither_type) {
    dither_type = g_enum_register_static ("GstCACASinkDithering", dither_types);
  }
  return dither_type;
}

static void
gst_cacasink_class_init (GstCACASinkClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSinkClass *gstbasesink_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->set_property = gst_cacasink_set_property;
  gobject_class->get_property = gst_cacasink_get_property;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SCREEN_WIDTH,
      g_param_spec_int ("screen-width", "Screen Width",
          "The width of the screen", 0, G_MAXINT, GST_CACA_DEFAULT_SCREEN_WIDTH,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SCREEN_HEIGHT,
      g_param_spec_int ("screen-height", "Screen Height",
          "The height of the screen", 0, G_MAXINT,
          GST_CACA_DEFAULT_SCREEN_HEIGHT,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DITHER,
      g_param_spec_enum ("dither", "Dither Type", "Set type of Dither",
          GST_TYPE_CACADITHER, GST_CACA_DEFAULT_DITHER,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ANTIALIASING,
      g_param_spec_boolean ("anti-aliasing", "Anti Aliasing",
          "Enables Anti-Aliasing", GST_CACA_DEFAULT_ANTIALIASING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state = gst_cacasink_change_state;

  gst_element_class_set_static_metadata (gstelement_class,
      "A colored ASCII art video sink", "Sink/Video",
      "A colored ASCII art videosink", "Zeeshan Ali <zak147@yahoo.com>");
  gst_element_class_add_static_pad_template (gstelement_class, &sink_template);

  gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_cacasink_setcaps);
  gstbasesink_class->get_times = GST_DEBUG_FUNCPTR (gst_cacasink_get_times);
  gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_cacasink_render);
  gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_cacasink_render);
}

static void
gst_cacasink_get_times (GstBaseSink * sink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  *start = GST_BUFFER_TIMESTAMP (buffer);
  *end = *start + GST_BUFFER_DURATION (buffer);
}

static gboolean
gst_cacasink_setcaps (GstBaseSink * basesink, GstCaps * caps)
{
  GstCACASink *cacasink;
  GstVideoInfo info;
  guint bpp, red_mask, green_mask, blue_mask;

  cacasink = GST_CACASINK (basesink);

  if (!gst_video_info_from_caps (&info, caps))
    goto caps_error;

  switch (GST_VIDEO_INFO_FORMAT (&info)) {
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_xBGR:
      bpp = 8 * info.finfo->pixel_stride[0];
      red_mask = 0xff << (8 * info.finfo->poffset[GST_VIDEO_COMP_R]);
      green_mask = 0xff << (8 * info.finfo->poffset[GST_VIDEO_COMP_G]);
      blue_mask = 0xff << (8 * info.finfo->poffset[GST_VIDEO_COMP_B]);
      break;
    case GST_VIDEO_FORMAT_RGB16:
      bpp = 16;
      red_mask = 0xf800;
      green_mask = 0x07e0;
      blue_mask = 0x001f;
      break;
    case GST_VIDEO_FORMAT_RGB15:
      bpp = 16;
      red_mask = 0x7c00;
      green_mask = 0x03e0;
      blue_mask = 0x001f;
      break;
    default:
      goto invalid_format;
  }

  if (cacasink->bitmap) {
    caca_free_bitmap (cacasink->bitmap);
  }
  cacasink->bitmap = caca_create_bitmap (bpp,
      GST_VIDEO_INFO_WIDTH (&info),
      GST_VIDEO_INFO_HEIGHT (&info),
      GST_ROUND_UP_4 (GST_VIDEO_INFO_WIDTH (&info) * bpp / 8),
      red_mask, green_mask, blue_mask, 0);
  if (!cacasink->bitmap)
    goto no_bitmap;

  cacasink->info = info;

  return TRUE;

  /* ERROS */
caps_error:
  {
    GST_ERROR_OBJECT (cacasink, "error parsing caps");
    return FALSE;
  }
invalid_format:
  {
    GST_ERROR_OBJECT (cacasink, "invalid format");
    return FALSE;
  }
no_bitmap:
  {
    GST_ERROR_OBJECT (cacasink, "could not create bitmap");
    return FALSE;
  }
}

static void
gst_cacasink_init (GstCACASink * cacasink)
{
  cacasink->screen_width = GST_CACA_DEFAULT_SCREEN_WIDTH;
  cacasink->screen_height = GST_CACA_DEFAULT_SCREEN_HEIGHT;

  cacasink->dither = GST_CACA_DEFAULT_DITHER;
  cacasink->antialiasing = GST_CACA_DEFAULT_ANTIALIASING;
}

static GstFlowReturn
gst_cacasink_render (GstBaseSink * basesink, GstBuffer * buffer)
{
  GstCACASink *cacasink = GST_CACASINK (basesink);
  GstVideoFrame frame;

  GST_DEBUG ("render");

  if (!gst_video_frame_map (&frame, &cacasink->info, buffer, GST_MAP_READ))
    goto invalid_frame;

  caca_clear ();
  caca_draw_bitmap (0, 0, cacasink->screen_width - 1,
      cacasink->screen_height - 1, cacasink->bitmap,
      GST_VIDEO_FRAME_PLANE_DATA (&frame, 0));
  caca_refresh ();

  gst_video_frame_unmap (&frame);

  return GST_FLOW_OK;

  /* ERRORS */
invalid_frame:
  {
    GST_ERROR_OBJECT (cacasink, "invalid frame received");
    return GST_FLOW_ERROR;
  }
}

static void
gst_cacasink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCACASink *cacasink;

  g_return_if_fail (GST_IS_CACASINK (object));

  cacasink = GST_CACASINK (object);

  switch (prop_id) {
    case PROP_DITHER:{
      cacasink->dither = g_value_get_enum (value);
      caca_set_dithering (cacasink->dither + CACA_DITHERING_NONE);
      break;
    }
    case PROP_ANTIALIASING:{
      cacasink->antialiasing = g_value_get_boolean (value);
      if (cacasink->antialiasing) {
        caca_set_feature (CACA_ANTIALIASING_MAX);
      } else {
        caca_set_feature (CACA_ANTIALIASING_MIN);
      }
      break;
    }
    default:
      break;
  }
}

static void
gst_cacasink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstCACASink *cacasink;

  cacasink = GST_CACASINK (object);

  switch (prop_id) {
    case PROP_SCREEN_WIDTH:{
      g_value_set_int (value, cacasink->screen_width);
      break;
    }
    case PROP_SCREEN_HEIGHT:{
      g_value_set_int (value, cacasink->screen_height);
      break;
    }
    case PROP_DITHER:{
      g_value_set_enum (value, cacasink->dither);
      break;
    }
    case PROP_ANTIALIASING:{
      g_value_set_boolean (value, cacasink->antialiasing);
      break;
    }
    default:{
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
  }
}

static gboolean
gst_cacasink_open (GstCACASink * cacasink)
{
  cacasink->bitmap = NULL;

  if (caca_init () < 0)
    goto init_failed;

  cacasink->screen_width = caca_get_width ();
  cacasink->screen_height = caca_get_height ();
  cacasink->antialiasing = TRUE;
  caca_set_feature (CACA_ANTIALIASING_MAX);
  cacasink->dither = 0;
  caca_set_dithering (CACA_DITHERING_NONE);

  return TRUE;

  /* ERRORS */
init_failed:
  {
    GST_ELEMENT_ERROR (cacasink, RESOURCE, OPEN_WRITE, (NULL),
        ("caca_init() failed"));
    return FALSE;
  }
}

static void
gst_cacasink_close (GstCACASink * cacasink)
{
  if (cacasink->bitmap) {
    caca_free_bitmap (cacasink->bitmap);
    cacasink->bitmap = NULL;
  }
  caca_end ();
}

static GstStateChangeReturn
gst_cacasink_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      if (!gst_cacasink_open (GST_CACASINK (element)))
        return GST_STATE_CHANGE_FAILURE;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_cacasink_close (GST_CACASINK (element));
      break;
    default:
      break;
  }
  return ret;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  if (!gst_element_register (plugin, "cacasink", GST_RANK_NONE,
          GST_TYPE_CACASINK))
    return FALSE;

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    cacasink,
    "Colored ASCII Art video sink",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
