/*
 * 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-1.0 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-1.0 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_static_pad_template (gstelement_class, &src_factory);
  gst_element_class_add_static_pad_template (gstelement_class, &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;
}
