/* GStreamer EBML I/O
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * (c) 2005 Michal Benes <michal.benes@xeris.cz>
 *
 * ebml-write.c: write EBML data to file/stream
 *
 * 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.
 */

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

#include <string.h>

#include "ebml-write.h"
#include "ebml-ids.h"


GST_DEBUG_CATEGORY_STATIC (gst_ebml_write_debug);
#define GST_CAT_DEFAULT gst_ebml_write_debug

#define _do_init \
      GST_DEBUG_CATEGORY_INIT (gst_ebml_write_debug, "ebmlwrite", 0, "Write EBML structured data")
#define parent_class gst_ebml_write_parent_class
G_DEFINE_TYPE_WITH_CODE (GstEbmlWrite, gst_ebml_write, GST_TYPE_OBJECT,
    _do_init);

static void gst_ebml_write_finalize (GObject * object);

static void
gst_ebml_write_class_init (GstEbmlWriteClass * klass)
{
  GObjectClass *object = G_OBJECT_CLASS (klass);

  object->finalize = gst_ebml_write_finalize;
}

static void
gst_ebml_write_init (GstEbmlWrite * ebml)
{
  ebml->srcpad = NULL;
  ebml->pos = 0;
  ebml->last_pos = G_MAXUINT64; /* force segment event */

  ebml->cache = NULL;
  ebml->streamheader = NULL;
  ebml->streamheader_pos = 0;
  ebml->writing_streamheader = FALSE;
  ebml->caps = NULL;
}

static void
gst_ebml_write_finalize (GObject * object)
{
  GstEbmlWrite *ebml = GST_EBML_WRITE (object);

  gst_object_unref (ebml->srcpad);

  if (ebml->cache) {
    gst_byte_writer_free (ebml->cache);
    ebml->cache = NULL;
  }

  if (ebml->streamheader) {
    gst_byte_writer_free (ebml->streamheader);
    ebml->streamheader = NULL;
  }

  if (ebml->caps) {
    gst_caps_unref (ebml->caps);
    ebml->caps = NULL;
  }

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


/**
 * gst_ebml_write_new:
 * @srcpad: Source pad to which the output will be pushed.
 *
 * Creates a new #GstEbmlWrite.
 *
 * Returns: a new #GstEbmlWrite
 */
GstEbmlWrite *
gst_ebml_write_new (GstPad * srcpad)
{
  GstEbmlWrite *ebml =
      GST_EBML_WRITE (g_object_new (GST_TYPE_EBML_WRITE, NULL));

  ebml->srcpad = gst_object_ref (srcpad);
  ebml->timestamp = GST_CLOCK_TIME_NONE;

  gst_ebml_write_reset (ebml);

  return ebml;
}


/**
 * gst_ebml_write_reset:
 * @ebml: a #GstEbmlWrite.
 *
 * Reset internal state of #GstEbmlWrite.
 */
void
gst_ebml_write_reset (GstEbmlWrite * ebml)
{
  ebml->pos = 0;
  ebml->last_pos = G_MAXUINT64; /* force segment event */

  if (ebml->cache) {
    gst_byte_writer_free (ebml->cache);
    ebml->cache = NULL;
  }

  if (ebml->caps) {
    gst_caps_unref (ebml->caps);
    ebml->caps = NULL;
  }

  ebml->last_write_result = GST_FLOW_OK;
  ebml->timestamp = GST_CLOCK_TIME_NONE;
}


/**
 * gst_ebml_last_write_result:
 * @ebml: a #GstEbmlWrite.
 *
 * Returns: GST_FLOW_OK if there was not write error since the last call of
 *          gst_ebml_last_write_result or code of the error.
 */
GstFlowReturn
gst_ebml_last_write_result (GstEbmlWrite * ebml)
{
  GstFlowReturn res = ebml->last_write_result;

  ebml->last_write_result = GST_FLOW_OK;

  return res;
}


void
gst_ebml_start_streamheader (GstEbmlWrite * ebml)
{
  g_return_if_fail (ebml->streamheader == NULL);

  GST_DEBUG ("Starting streamheader at %" G_GUINT64_FORMAT, ebml->pos);
  ebml->streamheader = gst_byte_writer_new_with_size (1000, FALSE);
  ebml->streamheader_pos = ebml->pos;
  ebml->writing_streamheader = TRUE;
}

GstBuffer *
gst_ebml_stop_streamheader (GstEbmlWrite * ebml)
{
  GstBuffer *buffer;

  if (!ebml->streamheader)
    return NULL;

  buffer = gst_byte_writer_free_and_get_buffer (ebml->streamheader);
  ebml->streamheader = NULL;
  GST_DEBUG ("Streamheader was size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));

  ebml->writing_streamheader = FALSE;
  return buffer;
}

/**
 * gst_ebml_write_set_cache:
 * @ebml: a #GstEbmlWrite.
 * @size: size of the cache.
 * Create a cache.
 *
 * The idea is that you use this for writing a lot
 * of small elements. This will just "queue" all of
 * them and they'll be pushed to the next element all
 * at once. This saves memory and time for buffer
 * allocation and init, and it looks better.
 */
void
gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size)
{
  g_return_if_fail (ebml->cache == NULL);

  GST_DEBUG ("Starting cache at %" G_GUINT64_FORMAT, ebml->pos);
  ebml->cache = gst_byte_writer_new_with_size (size, FALSE);
  ebml->cache_pos = ebml->pos;
}

static gboolean
gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
{
  GstSegment segment;
  gboolean res;

  GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);

  gst_segment_init (&segment, GST_FORMAT_BYTES);
  segment.start = new_pos;
  segment.stop = -1;
  segment.position = 0;

  res = gst_pad_push_event (ebml->srcpad, gst_event_new_segment (&segment));

  if (!res)
    GST_WARNING ("seek to %" G_GUINT64_FORMAT "failed", new_pos);

  return res;
}

/**
 * gst_ebml_write_flush_cache:
 * @ebml:      a #GstEbmlWrite.
 * @timestamp: timestamp of the buffer.
 *
 * Flush the cache.
 */
void
gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe,
    GstClockTime timestamp)
{
  GstBuffer *buffer;

  if (!ebml->cache)
    return;

  buffer = gst_byte_writer_free_and_get_buffer (ebml->cache);
  ebml->cache = NULL;
  GST_DEBUG ("Flushing cache of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buffer));
  GST_BUFFER_TIMESTAMP (buffer) = timestamp;
  GST_BUFFER_OFFSET (buffer) = ebml->pos - gst_buffer_get_size (buffer);
  GST_BUFFER_OFFSET_END (buffer) = ebml->pos;
  if (ebml->last_write_result == GST_FLOW_OK) {
    if (GST_BUFFER_OFFSET (buffer) != ebml->last_pos) {
      gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buffer));
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
    } else {
      GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
    }
    if (ebml->writing_streamheader) {
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
    } else {
      GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_HEADER);
    }
    if (!is_keyframe) {
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
    }
    ebml->last_pos = ebml->pos;
    ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer);
  } else {
    gst_buffer_unref (buffer);
  }
}


/**
 * gst_ebml_write_element_new:
 * @ebml: a #GstEbmlWrite.
 * @size: size of the requested buffer.
 *
 * Create a buffer for one element. If there is
 * a cache, use that instead.
 *
 * Returns: A new #GstBuffer.
 */
static GstBuffer *
gst_ebml_write_element_new (GstEbmlWrite * ebml, GstMapInfo * map, guint size)
{
  /* Create new buffer of size + ID + length */
  GstBuffer *buf;

  /* length, ID */
  size += 12;

  buf = gst_buffer_new_and_alloc (size);
  GST_BUFFER_TIMESTAMP (buf) = ebml->timestamp;

  /* FIXME unmap not possible */
  gst_buffer_map (buf, map, GST_MAP_WRITE);

  return buf;
}


/**
 * gst_ebml_write_element_id:
 * @data_inout: Pointer to data pointer
 * @id: Element ID that should be written.
 * 
 * Write element ID into a buffer.
 */
static void
gst_ebml_write_element_id (guint8 ** data_inout, guint32 id)
{
  guint8 *data = *data_inout;
  guint bytes = 4, mask = 0x10;

  /* get ID length */
  while (!(id & (mask << ((bytes - 1) * 8))) && bytes > 0) {
    mask <<= 1;
    bytes--;
  }

  /* if invalid ID, use dummy */
  if (bytes == 0) {
    GST_WARNING ("Invalid ID, voiding");
    bytes = 1;
    id = GST_EBML_ID_VOID;
  }

  /* write out, BE */
  *data_inout += bytes;
  while (bytes--) {
    data[bytes] = id & 0xff;
    id >>= 8;
  }
}


/**
 * gst_ebml_write_element_size:
 * @data_inout: Pointer to data pointer
 * @size: Element length.
 *
 * Write element length into a buffer.
 */
static void
gst_ebml_write_element_size (guint8 ** data_inout, guint64 size)
{
  guint8 *data = *data_inout;
  guint bytes = 1, mask = 0x80;

  if (size != GST_EBML_SIZE_UNKNOWN) {
    /* how many bytes? - use mask-1 because an all-1 bitset is not allowed */
    while (bytes <= 8 && (size >> ((bytes - 1) * 8)) >= (mask - 1)) {
      mask >>= 1;
      bytes++;
    }

    /* if invalid size, use max. */
    if (bytes > 8) {
      GST_WARNING ("Invalid size, writing size unknown");
      mask = 0x01;
      bytes = 8;
      /* Now here's a real FIXME: we cannot read those yet! */
      size = GST_EBML_SIZE_UNKNOWN;
    }
  } else {
    mask = 0x01;
    bytes = 8;
  }

  /* write out, BE, with length size marker */
  *data_inout += bytes;
  while (bytes-- > 0) {
    data[bytes] = size & 0xff;
    size >>= 8;
    if (!bytes)
      *data |= mask;
  }
}


/**
 * gst_ebml_write_element_data:
 * @data_inout: Pointer to data pointer
 * @write: Data that should be written.
 * @length: Length of the data.
 *
 * Write element data into a buffer.
 */
static void
gst_ebml_write_element_data (guint8 ** data_inout, guint8 * write,
    guint64 length)
{
  memcpy (*data_inout, write, length);
  *data_inout += length;
}


/**
 * gst_ebml_write_element_push:
 * @ebml: #GstEbmlWrite
 * @buf: #GstBuffer to be written.
 * @buf_data: Start of data to push from @buf (or NULL for whole buffer).
 * @buf_data_end: Data pointer positioned after the last byte in @buf_data (or
 * NULL for whole buffer).
 * 
 * Write out buffer by moving it to the next element.
 */
static void
gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf,
    guint8 * buf_data, guint8 * buf_data_end)
{
  GstMapInfo map;
  guint data_size;

  map.data = NULL;

  if (buf_data_end)
    data_size = buf_data_end - buf_data;
  else
    data_size = gst_buffer_get_size (buf);

  ebml->pos += data_size;

  /* if there's no cache, then don't push it! */
  if (ebml->writing_streamheader) {
    if (!buf_data) {
      gst_buffer_map (buf, &map, GST_MAP_READ);
      buf_data = map.data;
    }
    if (!buf_data)
      GST_WARNING ("Failed to map buffer");
    else if (!gst_byte_writer_put_data (ebml->streamheader, buf_data,
            data_size))
      GST_WARNING ("Error writing data to streamheader");
  }
  if (ebml->cache) {
    if (!buf_data) {
      gst_buffer_map (buf, &map, GST_MAP_READ);
      buf_data = map.data;
    }
    if (!buf_data)
      GST_WARNING ("Failed to map buffer");
    else if (!gst_byte_writer_put_data (ebml->cache, buf_data, data_size))
      GST_WARNING ("Error writing data to cache");
    if (map.data)
      gst_buffer_unmap (buf, &map);
    gst_buffer_unref (buf);
    return;
  }

  if (buf_data && map.data)
    gst_buffer_unmap (buf, &map);

  if (ebml->last_write_result == GST_FLOW_OK) {
    buf = gst_buffer_make_writable (buf);
    GST_BUFFER_OFFSET (buf) = ebml->pos - data_size;
    GST_BUFFER_OFFSET_END (buf) = ebml->pos;
    if (ebml->writing_streamheader) {
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    } else {
      GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_HEADER);
    }
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);

    if (GST_BUFFER_OFFSET (buf) != ebml->last_pos) {
      gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buf));
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
    } else {
      GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
    }
    ebml->last_pos = ebml->pos;
    ebml->last_write_result = gst_pad_push (ebml->srcpad, buf);
  } else {
    gst_buffer_unref (buf);
  }
}


/**
 * gst_ebml_write_seek:
 * @ebml: #GstEbmlWrite
 * @pos: Seek position.
 * 
 * Seek.
 */
void
gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos)
{
  if (ebml->writing_streamheader) {
    GST_DEBUG ("wanting to seek to pos %" G_GUINT64_FORMAT, pos);
    if (pos >= ebml->streamheader_pos &&
        pos <= ebml->streamheader_pos + ebml->streamheader->parent.size) {
      gst_byte_writer_set_pos (ebml->streamheader,
          pos - ebml->streamheader_pos);
      GST_DEBUG ("seeked in streamheader to position %" G_GUINT64_FORMAT,
          pos - ebml->streamheader_pos);
    } else {
      GST_WARNING
          ("we are writing streamheader still and seek is out of bounds");
    }
  }
  /* Cache seeking. A bit dangerous, we assume the client writer
   * knows what he's doing... */
  if (ebml->cache) {
    /* within bounds? */
    if (pos >= ebml->cache_pos &&
        pos <= ebml->cache_pos + ebml->cache->parent.size) {
      GST_DEBUG ("seeking in cache to %" G_GUINT64_FORMAT, pos);
      ebml->pos = pos;
      gst_byte_writer_set_pos (ebml->cache, ebml->pos - ebml->cache_pos);
      return;
    } else {
      GST_LOG ("Seek outside cache range. Clearing...");
      gst_ebml_write_flush_cache (ebml, FALSE, GST_CLOCK_TIME_NONE);
    }
  }

  GST_INFO ("scheduling seek to %" G_GUINT64_FORMAT, pos);
  ebml->pos = pos;
}


/**
 * gst_ebml_write_get_uint_size:
 * @num: Number to be encoded.
 * 
 * Get number of bytes needed to write a uint.
 *
 * Returns: Encoded uint length.
 */
static guint
gst_ebml_write_get_uint_size (guint64 num)
{
  guint size = 1;

  /* get size */
  while (size < 8 && num >= (G_GINT64_CONSTANT (1) << (size * 8))) {
    size++;
  }

  return size;
}


/**
 * gst_ebml_write_set_uint:
 * @data_inout: Pointer to data pointer
 * @num: Number to be written.
 * @size: Encoded number length.
 *
 * Write an uint into a buffer.
 */
static void
gst_ebml_write_set_uint (guint8 ** data_inout, guint64 num, guint size)
{
  guint8 *data = *data_inout;

  *data_inout += size;

  while (size-- > 0) {
    data[size] = num & 0xff;
    num >>= 8;
  }
}


/**
 * gst_ebml_write_uint:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write uint element.
 */
void
gst_ebml_write_uint (GstEbmlWrite * ebml, guint32 id, guint64 num)
{
  GstBuffer *buf;
  guint8 *data_start, *data_end;
  guint size = gst_ebml_write_get_uint_size (num);
  GstMapInfo map;

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  /* write */
  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, size);
  gst_ebml_write_set_uint (&data_end, num, size);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_sint:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write sint element.
 */
void
gst_ebml_write_sint (GstEbmlWrite * ebml, guint32 id, gint64 num)
{
  GstBuffer *buf;
  guint8 *data_start, *data_end;
  GstMapInfo map;

  /* if the signed number is on the edge of a extra-byte,
   * then we'll fall over when detecting it. Example: if I
   * have a number (-)0x8000 (G_MINSHORT), then my abs()<<1
   * will be 0x10000; this is G_MAXUSHORT+1! So: if (<0) -1. */
  guint64 unum = (num < 0 ? (-num - 1) << 1 : num << 1);
  guint size = gst_ebml_write_get_uint_size (unum);

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  /* make unsigned */
  if (num >= 0) {
    unum = num;
  } else {
    unum = ((guint64) 0x80) << ((size - 1) * 8);
    unum += num;
    unum |= ((guint64) 0x80) << ((size - 1) * 8);
  }

  /* write */
  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, size);
  gst_ebml_write_set_uint (&data_end, unum, size);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_float:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @num: Number to be written.
 *
 * Write float element.
 */
void
gst_ebml_write_float (GstEbmlWrite * ebml, guint32 id, gdouble num)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, sizeof (num));
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, 8);
  num = GDOUBLE_TO_BE (num);
  gst_ebml_write_element_data (&data_end, (guint8 *) & num, 8);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_ascii:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @str: String to be written.
 *
 * Write string element.
 */
void
gst_ebml_write_ascii (GstEbmlWrite * ebml, guint32 id, const gchar * str)
{
  gint len = strlen (str) + 1;  /* add trailing '\0' */
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, len);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, len);
  gst_ebml_write_element_data (&data_end, (guint8 *) str, len);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_utf8:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @str: String to be written.
 *
 * Write utf8 encoded string element.
 */
void
gst_ebml_write_utf8 (GstEbmlWrite * ebml, guint32 id, const gchar * str)
{
  gst_ebml_write_ascii (ebml, id, str);
}


/**
 * gst_ebml_write_date:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @date: Date in seconds since the unix epoch.
 *
 * Write date element.
 */
void
gst_ebml_write_date (GstEbmlWrite * ebml, guint32 id, gint64 date)
{
  gst_ebml_write_sint (ebml, id, (date - GST_EBML_DATE_OFFSET) * GST_SECOND);
}

/**
 * gst_ebml_write_master_start:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 *
 * Start wiriting mater element.
 *
 * Master writing is annoying. We use a size marker of
 * the max. allowed length, so that we can later fill it
 * in validly. 
 *
 * Returns: Master starting position.
 */
guint64
gst_ebml_write_master_start (GstEbmlWrite * ebml, guint32 id)
{
  guint64 pos = ebml->pos;
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, 0);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  pos += data_end - data_start;
  gst_ebml_write_element_size (&data_end, GST_EBML_SIZE_UNKNOWN);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);

  return pos;
}


/**
 * gst_ebml_write_master_finish_full:
 * @ebml: #GstEbmlWrite
 * @startpos: Master starting position.
 *
 * Finish writing master element.  Size of master element is difference between
 * current position and the element start, and @extra_size added to this.
 */
void
gst_ebml_write_master_finish_full (GstEbmlWrite * ebml, guint64 startpos,
    guint64 extra_size)
{
  guint64 pos = ebml->pos;
  guint8 *data = g_malloc (8);
  GstBuffer *buf = gst_buffer_new_wrapped (data, 8);

  gst_ebml_write_seek (ebml, startpos);

  GST_WRITE_UINT64_BE (data,
      (G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8 + extra_size));

  gst_ebml_write_element_push (ebml, buf, NULL, NULL);
  gst_ebml_write_seek (ebml, pos);
}

void
gst_ebml_write_master_finish (GstEbmlWrite * ebml, guint64 startpos)
{
  gst_ebml_write_master_finish_full (ebml, startpos, 0);
}

/**
 * gst_ebml_write_binary:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @binary: Data to be written.
 * @length: Length of the data
 *
 * Write an element with binary data.
 */
void
gst_ebml_write_binary (GstEbmlWrite * ebml,
    guint32 id, guint8 * binary, guint64 length)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, length);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, length);
  gst_ebml_write_element_data (&data_end, binary, length);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_buffer_header:
 * @ebml: #GstEbmlWrite
 * @id: Element ID.
 * @length: Length of the data
 * 
 * Write header of the binary element (use with gst_ebml_write_buffer function).
 * 
 * For things like video frames and audio samples,
 * you want to use this function, as it doesn't have
 * the overhead of memcpy() that other functions
 * such as write_binary() do have.
 */
void
gst_ebml_write_buffer_header (GstEbmlWrite * ebml, guint32 id, guint64 length)
{
  GstBuffer *buf;
  GstMapInfo map;
  guint8 *data_start, *data_end;

  buf = gst_ebml_write_element_new (ebml, &map, 0);
  data_end = data_start = map.data;

  gst_ebml_write_element_id (&data_end, id);
  gst_ebml_write_element_size (&data_end, length);
  gst_buffer_unmap (buf, &map);
  gst_buffer_set_size (buf, (data_end - data_start));

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
}


/**
 * gst_ebml_write_buffer:
 * @ebml: #GstEbmlWrite
 * @buf: #GstBuffer cointaining the data.
 *
 * Write  binary element (see gst_ebml_write_buffer_header).
 */
void
gst_ebml_write_buffer (GstEbmlWrite * ebml, GstBuffer * buf)
{
  gst_ebml_write_element_push (ebml, buf, NULL, NULL);
}


/**
 * gst_ebml_replace_uint:
 * @ebml: #GstEbmlWrite
 * @pos: Position of the uint that should be replaced.
 * @num: New value.
 *
 * Replace uint with a new value.
 * 
 * When replacing a uint, we assume that it is *always*
 * 8-byte, since that's the safest guess we can do. This
 * is just for simplicity.
 *
 * FIXME: this function needs to be replaced with something
 * proper. This is a crude hack.
 */
void
gst_ebml_replace_uint (GstEbmlWrite * ebml, guint64 pos, guint64 num)
{
  guint64 oldpos = ebml->pos;
  guint8 *data_start, *data_end;
  GstBuffer *buf;

  data_start = g_malloc (8);
  data_end = data_start;
  buf = gst_buffer_new_wrapped (data_start, 8);

  gst_ebml_write_seek (ebml, pos);
  gst_ebml_write_set_uint (&data_end, num, 8);

  gst_ebml_write_element_push (ebml, buf, data_start, data_end);
  gst_ebml_write_seek (ebml, oldpos);
}

/**
 * gst_ebml_write_header:
 * @ebml: #GstEbmlWrite
 * @doctype: Document type.
 * @version: Document type version.
 * 
 * Write EBML header.
 */
void
gst_ebml_write_header (GstEbmlWrite * ebml, const gchar * doctype,
    guint version)
{
  guint64 pos;

  /* write the basic EBML header */
  gst_ebml_write_set_cache (ebml, 0x40);
  pos = gst_ebml_write_master_start (ebml, GST_EBML_ID_HEADER);
#if (GST_EBML_VERSION != 1)
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLVERSION, GST_EBML_VERSION);
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLREADVERSION, GST_EBML_VERSION);
#endif
#if 0
  /* we don't write these until they're "non-default" (never!) */
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXIDLENGTH, sizeof (guint32));
  gst_ebml_write_uint (ebml, GST_EBML_ID_EBMLMAXSIZELENGTH, sizeof (guint64));
#endif
  gst_ebml_write_ascii (ebml, GST_EBML_ID_DOCTYPE, doctype);
  gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEVERSION, version);
  gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEREADVERSION, version);
  gst_ebml_write_master_finish (ebml, pos);
  gst_ebml_write_flush_cache (ebml, FALSE, 0);
}
