/* 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, 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 <sys/time.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, RGBx, 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_pad_template (gstelement_class,
      gst_static_pad_template_get (&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:
      bpp = 24;
      red_mask = 0xff0000;
      green_mask = 0x00ff00;
      blue_mask = 0x0000ff;
      break;
    case GST_VIDEO_FORMAT_RGBx:
      bpp = 32;
      red_mask = 0xff000000;
      green_mask = 0x00ff0000;
      blue_mask = 0x0000ff00;
      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)
