/*
 * GStreamer gstv4l2object.c: base class for V4L2 elements
 * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2006 Edgard Lima <edgard.lima@indt.org.br>
 *
 * 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 <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

#include "v4l2_calls.h"
#include "gstv4l2tuner.h"
#ifdef HAVE_XVIDEO
#include "gstv4l2xoverlay.h"
#endif
#include "gstv4l2colorbalance.h"

OPEN_V4L2OBJECT_PROPS CLOSE_V4L2OBJECT_PROPS const GList *
gst_v4l2_probe_get_properties (GstPropertyProbe * probe)
{
  GObjectClass *klass = G_OBJECT_GET_CLASS (probe);
  static GList *list = NULL;

  /* well, not perfect, but better than no locking at all.
   * In the worst case we leak a list node, so who cares? */
  GST_CLASS_LOCK (GST_OBJECT_CLASS (klass));

  if (!list) {
    list = g_list_append (NULL, g_object_class_find_property (klass, "device"));
  }

  GST_CLASS_UNLOCK (GST_OBJECT_CLASS (klass));

  return list;
}

static gboolean
gst_v4l2_class_probe_devices (GstElementClass * klass, gboolean check,
    GList ** klass_devices)
{
  static gboolean init = FALSE;
  static GList *devices = NULL;

  if (!init && !check) {
    gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL };
    gint base, n, fd;

    while (devices) {
      GList *item = devices;
      gchar *device = item->data;

      devices = g_list_remove (devices, item);
      g_free (device);
    }

    /*
     * detect /dev entries 
     */
    for (n = 0; n < 64; n++) {
      for (base = 0; dev_base[base] != NULL; base++) {
        struct stat s;
        gchar *device = g_strdup_printf ("%s%d",
            dev_base[base],
            n);

        /*
         * does the /dev/ entry exist at all? 
         */
        if (stat (device, &s) == 0) {
          /*
           * yes: is a device attached? 
           */
          if (S_ISCHR (s.st_mode)) {

            if ((fd = open (device, O_RDWR | O_NONBLOCK)) > 0 || errno == EBUSY) {
              if (fd > 0)
                close (fd);

              devices = g_list_append (devices, device);
              break;
            }
          }
        }
        g_free (device);
      }
    }

    init = TRUE;
  }

  *klass_devices = devices;

  return init;
}

void
gst_v4l2_probe_probe_property (GstPropertyProbe * probe,
    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);

  switch (prop_id) {
    case PROP_DEVICE:
      gst_v4l2_class_probe_devices (klass, FALSE, klass_devices);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
      break;
  }
}

gboolean
gst_v4l2_probe_needs_probe (GstPropertyProbe * probe,
    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
  gboolean ret = FALSE;

  switch (prop_id) {
    case PROP_DEVICE:
      ret = !gst_v4l2_class_probe_devices (klass, TRUE, klass_devices);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
      break;
  }

  return ret;

}

static GValueArray *
gst_v4l2_class_list_devices (GstElementClass * klass, GList ** klass_devices)
{
  GValueArray *array;
  GValue value = { 0 };
  GList *item;

  if (!*klass_devices)
    return NULL;

  array = g_value_array_new (g_list_length (*klass_devices));
  item = *klass_devices;
  g_value_init (&value, G_TYPE_STRING);
  while (item) {
    gchar *device = item->data;

    g_value_set_string (&value, device);
    g_value_array_append (array, &value);

    item = item->next;
  }
  g_value_unset (&value);

  return array;
}

GValueArray *
gst_v4l2_probe_get_values (GstPropertyProbe * probe,
    guint prop_id, const GParamSpec * pspec, GList ** klass_devices)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (probe);
  GValueArray *array = NULL;

  switch (prop_id) {
    case PROP_DEVICE:
      array = gst_v4l2_class_list_devices (klass, klass_devices);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
      break;
  }

  return array;
}

#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ())
GType
gst_v4l2_device_get_type (void)
{
  static GType v4l2_device_type = 0;

  if (v4l2_device_type == 0) {
    static const GFlagsValue values[] = {
      {V4L2_CAP_VIDEO_CAPTURE, "CAPTURE",
          "Device supports video capture"},
      {V4L2_CAP_VIDEO_OUTPUT, "PLAYBACK",
          "Device supports video playback"},
      {V4L2_CAP_VIDEO_OVERLAY, "OVERLAY",
          "Device supports video overlay"},

      {V4L2_CAP_VBI_CAPTURE, "VBI_CAPTURE",
          "Device supports the VBI capture"},
      {V4L2_CAP_VBI_OUTPUT, "VBI_OUTPUT",
          "Device supports the VBI output"},

      {V4L2_CAP_TUNER, "TUNER",
          "Device has a tuner or modulator"},
      {V4L2_CAP_AUDIO, "AUDIO",
          "Device has audio inputs or outputs"},

      {0, NULL, NULL}
    };

    v4l2_device_type =
        g_flags_register_static ("GstV4l2DeviceTypeFlags", values);
  }

  return v4l2_device_type;
}

void
gst_v4l2object_install_properties_helper (GObjectClass * gobject_class)
{

  g_object_class_install_property
      (G_OBJECT_CLASS (gobject_class), PROP_DEVICE,
      g_param_spec_string ("device",
          "Device", "Device location", NULL, G_PARAM_READWRITE));
  g_object_class_install_property
      (G_OBJECT_CLASS (gobject_class),
      PROP_DEVICE_NAME,
      g_param_spec_string ("device_name",
          "Device name", "Name of the device", NULL, G_PARAM_READABLE));
  g_object_class_install_property
      (G_OBJECT_CLASS (gobject_class), PROP_FLAGS,
      g_param_spec_flags ("flags", "Flags",
          "Device type flags",
          GST_TYPE_V4L2_DEVICE_FLAGS, 0, G_PARAM_READABLE));
  g_object_class_install_property
      (gobject_class, PROP_STD,
      g_param_spec_string ("std", "std",
          "standard (norm) to use", NULL, G_PARAM_READWRITE));
  g_object_class_install_property
      (gobject_class, PROP_INPUT,
      g_param_spec_string ("input",
          "input",
          "input/output (channel) to switch to", NULL, G_PARAM_READWRITE));
  g_object_class_install_property
      (gobject_class, PROP_FREQUENCY,
      g_param_spec_ulong ("frequency",
          "frequency",
          "frequency to tune to (in Hz)", 0, G_MAXULONG, 0, G_PARAM_READWRITE));

}

GstV4l2Object *
gst_v4l2object_new (GstElement * element,
    GstV4l2GetInOutFunction get_in_out_func,
    GstV4l2SetInOutFunction set_in_out_func,
    GstV4l2UpdateFpsFunction update_fps_func)
{

  GstV4l2Object *v4l2object;

  /*
   * some default values 
   */

  v4l2object = g_new0 (GstV4l2Object, 1);

  v4l2object->element = element;
  v4l2object->get_in_out_func = get_in_out_func;
  v4l2object->set_in_out_func = set_in_out_func;
  v4l2object->update_fps_func = update_fps_func;

  v4l2object->video_fd = -1;
  v4l2object->buffer = NULL;
  v4l2object->videodev = g_strdup ("/dev/video0");

  v4l2object->stds = NULL;
  v4l2object->inputs = NULL;
  v4l2object->colors = NULL;

  v4l2object->xwindow_id = 0;

  return v4l2object;

}


void
gst_v4l2object_destroy (GstV4l2Object ** v4l2object)
{

  if (*v4l2object) {

    if ((*v4l2object)->videodev) {
      g_free ((*v4l2object)->videodev);
      (*v4l2object)->videodev = NULL;
    }

    g_free (*v4l2object);
    *v4l2object = NULL;

  }

}


gboolean
gst_v4l2object_set_property_helper (GstV4l2Object * v4l2object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{

  switch (prop_id) {
    case PROP_DEVICE:
      if (v4l2object->videodev)
        g_free (v4l2object->videodev);
      v4l2object->videodev = g_strdup (g_value_get_string (value));
      break;
    case PROP_STD:
      if (GST_V4L2_IS_OPEN (v4l2object)) {
        GstTuner *tuner = GST_TUNER (v4l2object->element);
        GstTunerNorm *norm = gst_tuner_find_norm_by_name (tuner,
            (gchar *)
            g_value_get_string (value));

        if (norm) {
          /* like gst_tuner_set_norm (tuner, norm)
             without g_object_notify */
          gst_v4l2_tuner_set_norm (v4l2object, norm);
        }
      } else {
        g_free (v4l2object->std);
        v4l2object->std = g_value_dup_string (value);
      }
      break;
    case PROP_INPUT:
      if (GST_V4L2_IS_OPEN (v4l2object)) {
        GstTuner *tuner = GST_TUNER (v4l2object->element);
        GstTunerChannel *channel = gst_tuner_find_channel_by_name (tuner,
            (gchar *)
            g_value_get_string (value));

        if (channel) {
          /* like gst_tuner_set_channel (tuner, channel)
             without g_object_notify */
          gst_v4l2_tuner_set_channel (v4l2object, channel);
        }
      } else {
        g_free (v4l2object->input);
        v4l2object->input = g_value_dup_string (value);
      }
      break;
    case PROP_FREQUENCY:
      if (GST_V4L2_IS_OPEN (v4l2object)) {
        GstTuner *tuner = GST_TUNER (v4l2object->element);
        GstTunerChannel *channel = gst_tuner_get_channel (tuner);

        if (channel &&
            GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
          /* like
             gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value))
             without g_object_notify */
          gst_v4l2_tuner_set_frequency (v4l2object, channel,
              g_value_get_ulong (value));
        }
      } else {
        v4l2object->frequency = g_value_get_ulong (value);
      }
      break;
    default:
      return FALSE;
      break;
  }

  return TRUE;

}


gboolean
gst_v4l2object_get_property_helper (GstV4l2Object * v4l2object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    case PROP_DEVICE:
      g_value_set_string (value, v4l2object->videodev);
      break;
    case PROP_DEVICE_NAME:
    {
      gchar *new = NULL;

      if (GST_V4L2_IS_OPEN (v4l2object))
        new = (gchar *) v4l2object->vcap.card;
      g_value_set_string (value, new);
      break;
    }
    case PROP_FLAGS:
    {
      guint flags = 0;

      if (GST_V4L2_IS_OPEN (v4l2object)) {
        flags |= v4l2object->vcap.capabilities &
            (V4L2_CAP_VIDEO_CAPTURE |
            V4L2_CAP_VIDEO_OUTPUT |
            V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);
        if (v4l2object->vcap.capabilities & V4L2_CAP_AUDIO)
          flags |= V4L2_FBUF_CAP_CHROMAKEY;
      }
      g_value_set_flags (value, flags);
      break;
    }
    case PROP_STD:
      g_value_set_string (value, v4l2object->std);
      break;
    case PROP_INPUT:
      g_value_set_string (value, v4l2object->input);
      break;
    case PROP_FREQUENCY:
      g_value_set_ulong (value, v4l2object->frequency);
      break;
    default:
      return FALSE;
      break;
  }

  return TRUE;

}

static void
gst_v4l2_set_defaults (GstV4l2Object * v4l2object)
{
  GstTunerNorm *norm = NULL;
  GstTunerChannel *channel = NULL;
  GstTuner *tuner = GST_TUNER (v4l2object->element);

  if (v4l2object->std)
    norm = gst_tuner_find_norm_by_name (tuner, v4l2object->std);
  if (norm) {
    gst_tuner_set_norm (tuner, norm);
  } else {
    norm =
        GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2object->element)));
    if (norm) {
      v4l2object->std = g_strdup (norm->label);
      gst_tuner_norm_changed (tuner, norm);
      g_object_notify (G_OBJECT (v4l2object->element), "std");
    }
  }

  if (v4l2object->input)
    channel = gst_tuner_find_channel_by_name (tuner, v4l2object->input);
  if (channel) {
    gst_tuner_set_channel (tuner, channel);
  } else {
    channel =
        GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER (v4l2object->
                element)));
    v4l2object->input = g_strdup (channel->label);
    gst_tuner_channel_changed (tuner, channel);
    g_object_notify (G_OBJECT (v4l2object->element), "input");
  }

  if (GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
    if (v4l2object->frequency != 0) {
      gst_tuner_set_frequency (tuner, channel, v4l2object->frequency);
    } else {
      v4l2object->frequency = gst_tuner_get_frequency (tuner, channel);
      if (v4l2object->frequency == 0) {
        /* guess */
        gst_tuner_set_frequency (tuner, channel, 1000);
      } else {
        g_object_notify (G_OBJECT (v4l2object->element), "frequency");
      }
    }
  }
}


gboolean
gst_v4l2object_start (GstV4l2Object * v4l2object)
{
  if (gst_v4l2_open (v4l2object))
    gst_v4l2_set_defaults (v4l2object);
  else
    return FALSE;


#ifdef HAVE_XVIDEO
  gst_v4l2_xoverlay_start (v4l2object);
#endif

  return TRUE;
}

gboolean
gst_v4l2object_stop (GstV4l2Object * v4l2object)
{

#ifdef HAVE_XVIDEO
  gst_v4l2_xoverlay_stop (v4l2object);
#endif

  if (!gst_v4l2_close (v4l2object))
    return FALSE;

  return TRUE;
}
