/*
 * gstannodex.c - GStreamer annodex plugin
 * Copyright (C) 2005 Alessandro Decina
 * 
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *
 * 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.
 */

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

#include <math.h>
#include <string.h>

#include <gst/tag/tag.h>
#include "gstannodex.h"
#include "gstcmmlparser.h"
#include "gstcmmlenc.h"
#include "gstcmmldec.h"

GstClockTime
gst_annodex_granule_to_time (gint64 granulepos, gint64 granulerate_n,
    gint64 granulerate_d, guint8 granuleshift)
{
  gint64 keyindex, keyoffset;
  gint64 granulerate;
  GstClockTime res;

  g_return_val_if_fail (granuleshift <= 64, GST_CLOCK_TIME_NONE);

  if (granulepos == -1)
    return GST_CLOCK_TIME_NONE;

  if (granulepos == 0 || granulerate_n == 0 || granulerate_d == 0)
    return 0;

  if (granuleshift != 0 && granuleshift != 64) {
    keyindex = granulepos >> granuleshift;
    keyoffset = granulepos - (keyindex << granuleshift);
    granulepos = keyindex + keyoffset;
  }

  /* GST_SECOND / (granulerate_n / granulerate_d) */
  granulerate = gst_util_uint64_scale (GST_SECOND,
      granulerate_d, granulerate_n);

  /* granulepos * granulerate */
  res = gst_util_uint64_scale (granulepos, granulerate, 1);

  return res;
}

GValueArray *
gst_annodex_parse_headers (const gchar * headers)
{
  GValueArray *array;
  GValue val = { 0 };
  gchar *header_name = NULL;
  gchar *header_value = NULL;
  gchar *line, *column, *space, *tmp;
  gchar **lines;
  gint i = 0;

  array = g_value_array_new (0);
  g_value_init (&val, G_TYPE_STRING);

  lines = g_strsplit (headers, "\r\n", 0);
  line = lines[i];
  while (line != NULL && *line != '\0') {
    if (line[0] == '\t' || line[0] == ' ') {
      /* WSP: continuation line */
      if (header_value == NULL)
        /* continuation line without a previous value */
        goto fail;

      tmp = g_strjoin (" ", header_value, g_strstrip (line), NULL);
      g_free (header_value);
      header_value = tmp;
    } else {
      if (header_name) {
        g_value_take_string (&val, header_name);
        g_value_array_append (array, &val);
        g_value_take_string (&val, header_value);
        g_value_array_append (array, &val);
      }
      /* search the column starting from line[1] as an header name can't be
       * empty */
      column = g_strstr_len (line + 1, strlen (line) - 1, ":");
      if (column == NULL)
        /* bad syntax */
        goto fail;

      if (*(space = column + 1) != ' ')
        /* bad syntax */
        goto fail;

      header_name = g_strndup (line, column - line);
      header_value = g_strdup (space + 1);
    }

    line = lines[++i];
  }

  if (header_name) {
    g_value_take_string (&val, header_name);
    g_value_array_append (array, &val);
    g_value_take_string (&val, header_value);
    g_value_array_append (array, &val);
  }

  g_value_unset (&val);
  g_strfreev (lines);

  return array;

fail:
  GST_WARNING ("could not parse annodex headers");
  g_free (header_name);
  g_free (header_value);
  g_strfreev (lines);
  g_value_array_free (array);
  g_value_unset (&val);
  return NULL;
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  gst_tag_register (GST_TAG_CMML_STREAM, GST_TAG_FLAG_META,
      GST_TYPE_CMML_TAG_STREAM, "cmml-stream", "annodex CMML stream tag", NULL);

  gst_tag_register (GST_TAG_CMML_HEAD, GST_TAG_FLAG_META,
      GST_TYPE_CMML_TAG_HEAD, "cmml-head", "annodex CMML head tag", NULL);

  gst_tag_register (GST_TAG_CMML_CLIP, GST_TAG_FLAG_META,
      GST_TYPE_CMML_TAG_CLIP, "cmml-clip", "annodex CMML clip tag", NULL);

  gst_cmml_parser_init ();

  if (!gst_cmml_enc_plugin_init (plugin))
    return FALSE;

  if (!gst_cmml_dec_plugin_init (plugin))
    return FALSE;

  return TRUE;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    "annodex",
    "annodex stream manipulation (info about annodex: http://www.annodex.net)",
    plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
