/* GStreamer
 * Copyright (C) 2011 David Schleef <ds@entropywave.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 Street, Suite 500,
 * Boston, MA 02110-1335, USA.
 */
/**
 * SECTION:element-gstintersubsink
 *
 * The intersubsink element is a subtitle sink element.  It is used
 * in connection with a intersubsrc element in a different pipeline.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 -v ... ! intersubsink
 * ]|
 * 
 * The intersubsink element cannot be used effectively with gst-launch-1.0,
 * as it requires a second pipeline in the application to send audio.
 * See the gstintertest.c example in the gst-plugins-bad source code for
 * more details.
 * </refsect2>
 */

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

#include <gst/gst.h>
#include <gst/base/gstbasesink.h>
#include "gstintersubsink.h"

GST_DEBUG_CATEGORY_STATIC (gst_inter_sub_sink_debug_category);
#define GST_CAT_DEFAULT gst_inter_sub_sink_debug_category

/* prototypes */
static void gst_inter_sub_sink_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec);
static void gst_inter_sub_sink_get_property (GObject * object,
    guint property_id, GValue * value, GParamSpec * pspec);
static void gst_inter_sub_sink_finalize (GObject * object);

static void gst_inter_sub_sink_get_times (GstBaseSink * sink,
    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
static gboolean gst_inter_sub_sink_start (GstBaseSink * sink);
static gboolean gst_inter_sub_sink_stop (GstBaseSink * sink);
static GstFlowReturn
gst_inter_sub_sink_render (GstBaseSink * sink, GstBuffer * buffer);

enum
{
  PROP_0,
  PROP_CHANNEL
};

#define DEFAULT_CHANNEL ("default")

/* pad templates */
static GstStaticPadTemplate gst_inter_sub_sink_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("text/plain")
    );


/* class initialization */
#define parent_class gst_inter_sub_sink_parent_class
G_DEFINE_TYPE (GstInterSubSink, gst_inter_sub_sink, GST_TYPE_BASE_SINK);

static void
gst_inter_sub_sink_class_init (GstInterSubSinkClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstBaseSinkClass *base_sink_class = GST_BASE_SINK_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_inter_sub_sink_debug_category, "intersubsink", 0,
      "debug category for intersubsink element");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_inter_sub_sink_sink_template));

  gst_element_class_set_static_metadata (element_class,
      "Internal subtitle sink",
      "Sink/Subtitle",
      "Virtual subtitle sink for internal process communication",
      "David Schleef <ds@schleef.org>");

  gobject_class->set_property = gst_inter_sub_sink_set_property;
  gobject_class->get_property = gst_inter_sub_sink_get_property;
  gobject_class->finalize = gst_inter_sub_sink_finalize;
  base_sink_class->get_times = GST_DEBUG_FUNCPTR (gst_inter_sub_sink_get_times);
  base_sink_class->start = GST_DEBUG_FUNCPTR (gst_inter_sub_sink_start);
  base_sink_class->stop = GST_DEBUG_FUNCPTR (gst_inter_sub_sink_stop);
  base_sink_class->render = GST_DEBUG_FUNCPTR (gst_inter_sub_sink_render);

  g_object_class_install_property (gobject_class, PROP_CHANNEL,
      g_param_spec_string ("channel", "Channel",
          "Channel name to match inter src and sink elements",
          DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_inter_sub_sink_init (GstInterSubSink * intersubsink)
{
  intersubsink->channel = g_strdup (DEFAULT_CHANNEL);

  intersubsink->fps_n = 1;
  intersubsink->fps_d = 1;
}

void
gst_inter_sub_sink_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_free (intersubsink->channel);
      intersubsink->channel = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

void
gst_inter_sub_sink_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (object);

  switch (property_id) {
    case PROP_CHANNEL:
      g_value_set_string (value, intersubsink->channel);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
gst_inter_sub_sink_finalize (GObject * object)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (object);

  g_free (intersubsink->channel);
  intersubsink->channel = NULL;

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_inter_sub_sink_get_times (GstBaseSink * sink, GstBuffer * buffer,
    GstClockTime * start, GstClockTime * end)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (sink);

  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
    *start = GST_BUFFER_TIMESTAMP (buffer);
    if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
      *end = *start + GST_BUFFER_DURATION (buffer);
    } else {
      if (intersubsink->fps_n > 0) {
        *end = *start +
            gst_util_uint64_scale_int (GST_SECOND, intersubsink->fps_d,
            intersubsink->fps_n);
      }
    }
  }
}

static gboolean
gst_inter_sub_sink_start (GstBaseSink * sink)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (sink);

  intersubsink->surface = gst_inter_surface_get (intersubsink->channel);

  return TRUE;
}

static gboolean
gst_inter_sub_sink_stop (GstBaseSink * sink)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (sink);

  g_mutex_lock (&intersubsink->surface->mutex);
  if (intersubsink->surface->sub_buffer) {
    gst_buffer_unref (intersubsink->surface->sub_buffer);
  }
  intersubsink->surface->sub_buffer = NULL;
  g_mutex_unlock (&intersubsink->surface->mutex);

  gst_inter_surface_unref (intersubsink->surface);
  intersubsink->surface = NULL;

  return TRUE;
}

static GstFlowReturn
gst_inter_sub_sink_render (GstBaseSink * sink, GstBuffer * buffer)
{
  GstInterSubSink *intersubsink = GST_INTER_SUB_SINK (sink);

  g_mutex_lock (&intersubsink->surface->mutex);
  if (intersubsink->surface->sub_buffer) {
    gst_buffer_unref (intersubsink->surface->sub_buffer);
  }
  intersubsink->surface->sub_buffer = gst_buffer_ref (buffer);
  //intersubsink->surface->sub_buffer_count = 0;
  g_mutex_unlock (&intersubsink->surface->mutex);

  return GST_FLOW_OK;
}
