/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) <2005> Tim-Philipp Müller <tim@centricular.net>
 *
 * 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-clockoverlay
 * @see_also: #GstBaseTextOverlay, #GstTimeOverlay
 *
 * This element overlays the current clock time on top of a video
 * stream. You can position the text and configure the font details
 * using the properties of the #GstBaseTextOverlay class. By default, the
 * time is displayed in the top left corner of the picture, with some
 * padding to the left and to the top.
 *
 * <refsect2>
 * <title>Example launch lines</title>
 * |[
 * gst-launch-1.0 -v videotestsrc ! clockoverlay ! autovideosink
 * ]| Display the current wall clock time in the top left corner of the video picture
 * |[
 * gst-launch-1.0 -v videotestsrc ! clockoverlay halignment=right valignment=bottom text="Edge City" shaded-background=true font-desc="Sans, 36" ! videoconvert ! autovideosink
 * ]| Another pipeline that displays the current time with some leading
 * text in the bottom right corner of the video picture, with the background
 * of the text being shaded in order to make it more legible on top of a
 * bright video background.
 * </refsect2>
 */

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

#include "gstclockoverlay.h"
#include <gst/video/video.h>
#include <time.h>


#define DEFAULT_PROP_TIMEFORMAT 	"%H:%M:%S"

enum
{
  PROP_0,
  PROP_TIMEFORMAT,
  PROP_LAST
};

#define gst_clock_overlay_parent_class parent_class
G_DEFINE_TYPE (GstClockOverlay, gst_clock_overlay, GST_TYPE_BASE_TEXT_OVERLAY);

static void gst_clock_overlay_finalize (GObject * object);
static void gst_clock_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_clock_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gchar *
gst_clock_overlay_render_time (GstClockOverlay * overlay)
{
  struct tm *t;
  time_t now;
  gchar buf[256];

#ifdef HAVE_LOCALTIME_R
  struct tm dummy;
#endif

  now = time (NULL);

#ifdef HAVE_LOCALTIME_R
  /* Need to call tzset explicitly when calling localtime_r for changes
     to the timezone between calls to be visible.  */
  tzset ();
  t = localtime_r (&now, &dummy);
#else
  /* on win32 this apparently returns a per-thread struct which would be fine */
  t = localtime (&now);
#endif

  if (t == NULL)
    return g_strdup ("--:--:--");

  if (strftime (buf, sizeof (buf), overlay->format, t) == 0)
    return g_strdup ("");
  return g_strdup (buf);
}

/* Called with lock held */
static gchar *
gst_clock_overlay_get_text (GstBaseTextOverlay * overlay,
    GstBuffer * video_frame)
{
  gchar *time_str, *txt, *ret;
  GstClockOverlay *clock_overlay = GST_CLOCK_OVERLAY (overlay);

  txt = g_strdup (overlay->default_text);

  time_str = gst_clock_overlay_render_time (clock_overlay);
  if (txt != NULL && *txt != '\0') {
    ret = g_strdup_printf ("%s %s", txt, time_str);
  } else {
    ret = time_str;
    time_str = NULL;
  }

  if (g_strcmp0 (ret, clock_overlay->text)) {
    overlay->need_render = TRUE;
    g_free (clock_overlay->text);
    clock_overlay->text = g_strdup (ret);
  }

  g_free (txt);
  g_free (time_str);

  return ret;
}

static void
gst_clock_overlay_class_init (GstClockOverlayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseTextOverlayClass *gsttextoverlay_class;
  PangoContext *context;
  PangoFontDescription *font_description;

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

  gobject_class->finalize = gst_clock_overlay_finalize;
  gobject_class->set_property = gst_clock_overlay_set_property;
  gobject_class->get_property = gst_clock_overlay_get_property;

  gst_element_class_set_static_metadata (gstelement_class, "Clock overlay",
      "Filter/Editor/Video",
      "Overlays the current clock time on a video stream",
      "Tim-Philipp Müller <tim@centricular.net>");

  gsttextoverlay_class->get_text = gst_clock_overlay_get_text;

  g_object_class_install_property (gobject_class, PROP_TIMEFORMAT,
      g_param_spec_string ("time-format", "Date/Time Format",
          "Format to use for time and date value, as in strftime.",
          DEFAULT_PROP_TIMEFORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_mutex_lock (gsttextoverlay_class->pango_lock);
  context = gsttextoverlay_class->pango_context;

  pango_context_set_language (context, pango_language_from_string ("en_US"));
  pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);

  font_description = pango_font_description_new ();
  pango_font_description_set_family_static (font_description, "Monospace");
  pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
  pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL);
  pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
  pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL);
  pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
  pango_context_set_font_description (context, font_description);
  pango_font_description_free (font_description);
  g_mutex_unlock (gsttextoverlay_class->pango_lock);
}


static void
gst_clock_overlay_finalize (GObject * object)
{
  GstClockOverlay *overlay = GST_CLOCK_OVERLAY (object);

  g_free (overlay->format);
  g_free (overlay->text);
  overlay->format = NULL;

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


static void
gst_clock_overlay_init (GstClockOverlay * overlay)
{
  GstBaseTextOverlay *textoverlay;

  textoverlay = GST_BASE_TEXT_OVERLAY (overlay);

  textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
  textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;

  overlay->format = g_strdup (DEFAULT_PROP_TIMEFORMAT);
}


static void
gst_clock_overlay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstClockOverlay *overlay = GST_CLOCK_OVERLAY (object);

  GST_OBJECT_LOCK (overlay);
  switch (prop_id) {
    case PROP_TIMEFORMAT:
      g_free (overlay->format);
      overlay->format = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (overlay);
}


static void
gst_clock_overlay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstClockOverlay *overlay = GST_CLOCK_OVERLAY (object);

  GST_OBJECT_LOCK (overlay);
  switch (prop_id) {
    case PROP_TIMEFORMAT:
      g_value_set_string (value, overlay->format);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  GST_OBJECT_UNLOCK (overlay);
}
