/*
 * GStreamer
 * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
 * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
 * Copyright 2008, 2009 Vincent Penquerc'h <ogg.k.ogg.k@googlemail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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-katedec
 * @see_also: oggdemux
 *
 * <refsect2>
 * <para>
 * This element decodes Kate streams
 * <ulink url="http://libkate.googlecode.com/">Kate</ulink> is a free codec
 * for text based data, such as subtitles. Any number of kate streams can be
 * embedded in an Ogg stream.
 * </para>
 * <para>
 * libkate (see above url) is needed to build this plugin.
 * </para>
 * <title>Example pipeline</title>
 * <para>
 * This explicitely decodes a Kate stream:
 * <programlisting>
 * gst-launch filesrc location=test.ogg ! oggdemux ! katedec ! fakesink silent=TRUE
 * </programlisting>
 * </para>
 * <para>
 * This will automatically detect and use any Kate streams multiplexed
 * in an Ogg stream:
 * <programlisting>
 * gst-launch playbin uri=file:///tmp/test.ogg
 * </programlisting>
 * </para>
 * </refsect2>
 */

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

#include <string.h>

#include <gst/gst.h>

#include "gstkate.h"
#include "gstkatespu.h"
#include "gstkatedec.h"

GST_DEBUG_CATEGORY_EXTERN (gst_katedec_debug);
#define GST_CAT_DEFAULT gst_katedec_debug

/* Filter signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  ARG_REMOVE_MARKUP = DECODER_BASE_ARG_COUNT
};

/* We don't accept application/x-kate here on purpose for now, since we're
 * only really interested in subtitle-like things for playback purposes, not
 * cracktastic complex overlays or presentation images etc. - those should be
 * fed into a tiger overlay plugin directly */
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("subtitle/x-kate")
    );

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("text/x-raw, format = { pango-markup, utf8 }; "
        GST_KATE_SPU_MIME_TYPE)
    );

#define gst_kate_dec_parent_class parent_class
G_DEFINE_TYPE (GstKateDec, gst_kate_dec, GST_TYPE_ELEMENT);

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

static GstFlowReturn gst_kate_dec_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static GstStateChangeReturn gst_kate_dec_change_state (GstElement * element,
    GstStateChange transition);
static gboolean gst_kate_dec_sink_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_kate_dec_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_kate_dec_sink_handle_event (GstPad * pad,
    GstObject * parent, GstEvent * event);
static gboolean gst_kate_dec_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);

/* initialize the plugin's class */
static void
gst_kate_dec_class_init (GstKateDecClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  gobject_class->set_property = gst_kate_dec_set_property;
  gobject_class->get_property = gst_kate_dec_get_property;

  gst_kate_util_install_decoder_base_properties (gobject_class);

  g_object_class_install_property (gobject_class, ARG_REMOVE_MARKUP,
      g_param_spec_boolean ("remove-markup", "Remove markup",
          "Remove markup from decoded text ?", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_kate_dec_change_state);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_factory));

  gst_element_class_set_static_metadata (gstelement_class,
      "Kate stream text decoder", "Codec/Decoder/Subtitle",
      "Decodes Kate text streams",
      "Vincent Penquerc'h <ogg.k.ogg.k@googlemail.com>");
}

/* initialize the new element
 * instantiate pads and add them to element
 * set functions
 * initialize structure
 */
static void
gst_kate_dec_init (GstKateDec * dec)
{
  GST_DEBUG_OBJECT (dec, "gst_kate_dec_init");

  dec->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
  gst_pad_set_chain_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_kate_dec_chain));
  gst_pad_set_query_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_kate_dec_sink_query));
  gst_pad_set_event_function (dec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_kate_dec_sink_event));
  gst_pad_use_fixed_caps (dec->sinkpad);
  gst_pad_set_caps (dec->sinkpad,
      gst_static_pad_template_get_caps (&sink_factory));
  gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);

  dec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_set_query_function (dec->srcpad,
      GST_DEBUG_FUNCPTR (gst_kate_dec_src_query));
  gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);

  gst_kate_util_decode_base_init (&dec->decoder, TRUE);

  dec->src_caps = NULL;
  dec->output_format = GST_KATE_FORMAT_UNDEFINED;
  dec->remove_markup = FALSE;
}

static void
gst_kate_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_kate_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstKateDec *kd = GST_KATE_DEC (object);

  switch (prop_id) {
    case ARG_REMOVE_MARKUP:
      g_value_set_boolean (value, kd->remove_markup);
      break;
    default:
      if (!gst_kate_util_decoder_base_get_property (&kd->decoder, object,
              prop_id, value, pspec)) {
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      }
      break;
  }
}

static GstFlowReturn
gst_kate_dec_handle_kate_event (GstKateDec * kd, const kate_event * ev)
{
  GstFlowReturn rflow = GST_FLOW_OK;
  GstKateFormat format = GST_KATE_FORMAT_UNDEFINED;
  gchar *escaped;
  GstBuffer *buffer;
  size_t len;
  gboolean plain = TRUE;

  if (kd->remove_markup && ev->text_markup_type != kate_markup_none) {
    size_t len0 = ev->len + 1;
    escaped = g_strdup (ev->text);
    if (escaped) {
      kate_text_remove_markup (ev->text_encoding, escaped, &len0);
    }
    plain = TRUE;
  } else if (ev->text_markup_type == kate_markup_none) {
    /* no pango markup yet, escape text */
    /* TODO: actually do the pango thing */
    escaped = g_strdup (ev->text);
    plain = TRUE;
  } else {
    escaped = g_strdup (ev->text);
    plain = FALSE;
  }

  if (G_LIKELY (escaped)) {
    len = strlen (escaped);
    if (len > 0) {
      GST_DEBUG_OBJECT (kd, "kate event: %s, escaped %s", ev->text, escaped);
      buffer = gst_buffer_new_and_alloc (len + 1);
      if (G_LIKELY (buffer)) {
        GstCaps *caps;
        if (plain)
          format = GST_KATE_FORMAT_TEXT_UTF8;
        else
          format = GST_KATE_FORMAT_TEXT_PANGO_MARKUP;
        if (format != kd->output_format) {
          caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
              (format == GST_KATE_FORMAT_TEXT_UTF8) ? "utf8" : "pango-markup",
              NULL);
          gst_pad_push_event (kd->srcpad, gst_event_new_caps (caps));
          gst_caps_unref (caps);
          kd->output_format = format;
        }
        /* allocate and copy the NULs, but don't include them in passed size */
        gst_buffer_fill (buffer, 0, escaped, len + 1);
        gst_buffer_resize (buffer, 0, len);
        GST_BUFFER_TIMESTAMP (buffer) = ev->start_time * GST_SECOND;
        GST_BUFFER_DURATION (buffer) =
            (ev->end_time - ev->start_time) * GST_SECOND;
        rflow = gst_pad_push (kd->srcpad, buffer);
        if (rflow == GST_FLOW_NOT_LINKED) {
          GST_DEBUG_OBJECT (kd, "source pad not linked, ignored");
        } else if (rflow != GST_FLOW_OK) {
          GST_WARNING_OBJECT (kd, "failed to push buffer: %s",
              gst_flow_get_name (rflow));
        }
      } else {
        GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL),
            ("Failed to create buffer"));
        rflow = GST_FLOW_ERROR;
      }
    } else {
      GST_WARNING_OBJECT (kd, "Empty string, nothing to do");
      rflow = GST_FLOW_OK;
    }
    g_free (escaped);
  } else {
    GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL),
        ("Failed to allocate string"));
    rflow = GST_FLOW_ERROR;
  }

  /* if there's a background paletted bitmap, construct a DVD SPU for it */
  if (ev->bitmap && ev->palette) {
    GstBuffer *buffer = gst_kate_spu_encode_spu (kd, ev);
    if (buffer) {
      GstCaps *caps;

      GST_BUFFER_TIMESTAMP (buffer) = ev->start_time * GST_SECOND;
      GST_BUFFER_DURATION (buffer) =
          (ev->end_time - ev->start_time) * GST_SECOND;

      if (kd->output_format != GST_KATE_FORMAT_SPU) {
        caps = gst_caps_new_empty_simple (GST_KATE_SPU_MIME_TYPE);
        gst_pad_push_event (kd->srcpad, gst_event_new_caps (caps));
        gst_caps_unref (caps);
        kd->output_format = GST_KATE_FORMAT_SPU;
      }

      rflow = gst_pad_push (kd->srcpad, buffer);
      if (rflow == GST_FLOW_NOT_LINKED) {
        GST_DEBUG_OBJECT (kd, "source pad not linked, ignored");
      } else if (rflow != GST_FLOW_OK) {
        GST_WARNING_OBJECT (kd, "failed to push buffer: %s",
            gst_flow_get_name (rflow));
      }
    } else {
      GST_ELEMENT_ERROR (kd, STREAM, DECODE, (NULL),
          ("failed to create SPU from paletted bitmap"));
      rflow = GST_FLOW_ERROR;
    }
  }
  return rflow;
}

/* GstElement vmethod implementations */

/* chain function
 * this function does the actual processing
 */

static GstFlowReturn
gst_kate_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstKateDec *kd = GST_KATE_DEC (parent);
  const kate_event *ev = NULL;
  GstFlowReturn rflow = GST_FLOW_OK;

  if (!gst_kate_util_decoder_base_update_segment (&kd->decoder,
          GST_ELEMENT_CAST (kd), buf)) {
    GST_WARNING_OBJECT (kd, "Out of segment!");
    goto not_in_seg;
  }

  rflow =
      gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
      GST_ELEMENT_CAST (kd), pad, buf, kd->srcpad, kd->srcpad, &kd->src_caps,
      &ev);
  if (G_UNLIKELY (rflow != GST_FLOW_OK)) {
    gst_buffer_unref (buf);
    return rflow;
  }

  if (ev) {
    rflow = gst_kate_dec_handle_kate_event (kd, ev);
  }

not_in_seg:
  gst_buffer_unref (buf);
  return rflow;
}

static GstStateChangeReturn
gst_kate_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstKateDec *kd = GST_KATE_DEC (element);

  ret = gst_kate_decoder_base_change_state (&kd->decoder, element,
      parent_class, transition);

  if (transition == GST_STATE_CHANGE_PAUSED_TO_READY) {
    gst_caps_replace (&kd->src_caps, NULL);
  }

  return ret;
}

gboolean
gst_kate_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstKateDec *kd = GST_KATE_DEC (parent);
  gboolean res =
      gst_kate_decoder_base_sink_query (&kd->decoder, GST_ELEMENT_CAST (kd),
      pad, parent, query);
  return res;
}

static gboolean
gst_kate_dec_set_caps (GstKateDec * kd, GstCaps * caps)
{
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  GstFlowReturn rflow = GST_FLOW_OK;

  if (gst_structure_has_field (structure, "streamheader")) {
    const GValue *value;
    GstBuffer *buf;
    const kate_event *ev;

    value = gst_structure_get_value (structure, "streamheader");

    if (GST_VALUE_HOLDS_BUFFER (value)) {
      buf = gst_value_get_buffer (value);

      gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
          GST_ELEMENT_CAST (kd), kd->sinkpad, buf, kd->srcpad, kd->srcpad,
          &kd->src_caps, &ev);

      if (ev) {
        rflow = gst_kate_dec_handle_kate_event (kd, ev);
      }
    } else if (GST_VALUE_HOLDS_ARRAY (value)) {
      gint i, size = gst_value_array_get_size (value);

      for (i = 0; i < size; i++) {
        const GValue *v = gst_value_array_get_value (value, i);

        buf = gst_value_get_buffer (v);
        gst_kate_util_decoder_base_chain_kate_packet (&kd->decoder,
            GST_ELEMENT_CAST (kd), kd->sinkpad, buf, kd->srcpad, kd->srcpad,
            &kd->src_caps, &ev);

        if (ev) {
          rflow = gst_kate_dec_handle_kate_event (kd, ev);
          if (rflow != GST_FLOW_OK && rflow != GST_FLOW_NOT_LINKED)
            break;
        }
      }
    } else {
      GST_WARNING_OBJECT (kd, "Unhandled streamheader type: %s",
          G_VALUE_TYPE_NAME (value));
    }
  }

  return rflow == GST_FLOW_OK || rflow == GST_FLOW_NOT_LINKED;
}

static gboolean
gst_kate_dec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstKateDec *kd = GST_KATE_DEC (parent);
  gboolean res = TRUE;

  GST_LOG_OBJECT (pad, "Event on sink pad: %" GST_PTR_FORMAT, event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      gst_kate_dec_set_caps (kd, caps);
      break;
    }
    default:
      break;
  }

  /* Delay events till we've set caps */
  if (gst_kate_util_decoder_base_queue_event (&kd->decoder, event,
          &gst_kate_dec_sink_handle_event, parent, pad)) {
    return TRUE;
  }

  res = gst_kate_dec_sink_handle_event (pad, parent, event);

  return res;
}

static gboolean
gst_kate_dec_sink_handle_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstKateDec *kd = GST_KATE_DEC (parent);

  GST_LOG_OBJECT (pad, "Handling event on sink pad: %s",
      GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      break;

    case GST_EVENT_FLUSH_START:
      gst_kate_util_decoder_base_set_flushing (&kd->decoder, TRUE);
      break;

    case GST_EVENT_FLUSH_STOP:
      gst_kate_util_decoder_base_set_flushing (&kd->decoder, FALSE);
      break;

    case GST_EVENT_TAG:{
      GstTagList *tags;
      gst_event_parse_tag (event, &tags);
      gst_kate_util_decoder_base_add_tags (&kd->decoder, tags, FALSE);
      gst_event_unref (event);
      event = gst_kate_util_decoder_base_get_tag_event (&kd->decoder);
      break;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}

static gboolean
gst_kate_dec_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstKateDec *kd = GST_KATE_DEC (parent);
  gboolean res = TRUE;

  GST_LOG_OBJECT (pad, "Handling query on src pad: %s",
      GST_QUERY_TYPE_NAME (query));

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:{
      GstCaps *caps;

      if (kd->src_caps) {
        GST_DEBUG_OBJECT (kd, "We have src caps %" GST_PTR_FORMAT,
            kd->src_caps);
        caps = gst_caps_copy (kd->src_caps);
      } else {
        GST_DEBUG_OBJECT (kd, "We have no src caps, using template caps");
        caps = gst_static_pad_template_get_caps (&src_factory);
      }

      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

  return res;
}
