/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstclock.c: Clock subsystem for maintaining time sync
 *
 * 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.
 */

#include <sys/time.h>

//#define GST_DEBUG_ENABLED
#include "gst_private.h"

#include "gstelement.h"
#include "gstclock.h"


static GstClock *the_system_clock = NULL;

/**
 * gst_clock_new:
 * @name: the name of the new clock
 *
 * create a new clock element
 *
 * Returns: the new clock element
 */
GstClock*
gst_clock_new (gchar *name)
{
  GstClock *clock = (GstClock *) g_malloc(sizeof(GstClock));

  clock->name = g_strdup (name);
  clock->sinkobjects = NULL;
  clock->sinkmutex = g_mutex_new ();
  clock->lock = g_mutex_new ();
  g_mutex_lock (clock->sinkmutex);

  clock->num = 0;
  clock->num_locked = 0;
  clock->locking = FALSE;

  return clock;
}

GstClock*
gst_clock_get_system(void)
{
  if (the_system_clock == NULL) {
    the_system_clock = gst_clock_new ("system_clock");
    gst_clock_reset (the_system_clock);
  }
  return the_system_clock;
}

void
gst_clock_register (GstClock *clock, GstObject *obj)
{
  if ((GST_ELEMENT(obj))->numsrcpads == 0) {
    GST_DEBUG (GST_CAT_CLOCK,"gst_clock: setting registered sink object 0x%p\n", obj);
    clock->sinkobjects = g_list_append (clock->sinkobjects, obj);
    clock->num++;
  }
}

void
gst_clock_set (GstClock *clock, GstClockTime time)
{
  struct timeval tfnow;
  GstClockTime now;

  gettimeofday (&tfnow, (struct timezone *)NULL);
  now = tfnow.tv_sec*1000000LL+tfnow.tv_usec;
  g_mutex_lock (clock->lock);
  clock->start_time = now - time;
  g_mutex_unlock (clock->lock);
  GST_DEBUG (GST_CAT_CLOCK,"gst_clock: setting clock to %llu %llu %llu\n",
             time, now, clock->start_time);
}

GstClockTimeDiff
gst_clock_current_diff (GstClock *clock, GstClockTime time)
{
  struct timeval tfnow;
  GstClockTime now;

  gettimeofday (&tfnow, (struct timezone *)NULL);
  g_mutex_lock (clock->lock);
  now = ((guint64)tfnow.tv_sec*1000000LL+tfnow.tv_usec) - (guint64)clock->start_time;
  g_mutex_unlock (clock->lock);

  return GST_CLOCK_DIFF (time, now);
}

void
gst_clock_reset (GstClock *clock)
{
  struct timeval tfnow;

  gettimeofday (&tfnow, (struct timezone *)NULL);
  g_mutex_lock (clock->lock);
  clock->start_time = ((guint64)tfnow.tv_sec)*1000000LL+tfnow.tv_usec;
  clock->current_time = clock->start_time;
  clock->adjust = 0LL;
  GST_DEBUG (GST_CAT_CLOCK,"gst_clock: setting start clock %llu\n", clock->start_time);
  g_mutex_unlock (clock->lock);
}

void
gst_clock_wait (GstClock *clock, GstClockTime time, GstObject *obj)
{
  struct timeval tfnow;
  GstClockTime now;
  GstClockTimeDiff diff;


  gettimeofday (&tfnow, (struct timezone *)NULL);
  g_mutex_lock (clock->lock);
  now = tfnow.tv_sec*1000000LL+tfnow.tv_usec - clock->start_time;

  diff = GST_CLOCK_DIFF (time, now);
  // if we are not behind wait a bit
  GST_DEBUG (GST_CAT_CLOCK,"gst_clock: %s waiting for time %08llu %08llu %08lld\n",
             GST_OBJECT_NAME (obj), time, now, diff);

  g_mutex_unlock (clock->lock);
  if (diff > 10000 ) {
    tfnow.tv_usec = (diff % 1000000);
    tfnow.tv_sec = diff / 1000000;
    // FIXME, this piece of code does not work with egcs optimisations on, had to use the following line
    if (!tfnow.tv_sec) {
      select(0, NULL, NULL, NULL, &tfnow);
    }
    else GST_DEBUG (GST_CAT_CLOCK,"gst_clock: %s waiting %u %llu %llu %llu seconds\n",
                    GST_OBJECT_NAME (obj), (int)tfnow.tv_sec, now, diff, time);
  }
  GST_DEBUG (GST_CAT_CLOCK,"gst_clock: %s waiting for time %08llu %08llu %08lld done \n", 
             GST_OBJECT_NAME (obj), time, now, diff);
}
