/* GStreamer
 * Copyright (C) 2012 Andol Li <andol@andol.info>
 *
 *  gsthanddetect_test: gsteramer handdetect plugin demo application,
 *  part work of GSoc 2012 project
 *
 * 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.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gst/gst.h>

GstElement *playbin, *pipeline;
GstElement *v4l2src, *videoscale, *videoconvert_in, *handdetect,
    *videoconvert_out, *xvimagesink;

static GstBusSyncReply
bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
  const GstStructure *structure;
  gint64 position, length;
  GstFormat format = GST_FORMAT_TIME;
  const GValue *x_value, *y_value;
  gint x, i, y;
  /* select msg */
  if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT ||
      !gst_structure_has_name (gst_message_get_structure (message),
          "hand-gesture"))
    return GST_BUS_PASS;

  /* parse msg structure */
  structure = gst_message_get_structure (message);

  /* if PALM gesture detected */
  if (structure &&
      strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
      strcmp (gst_structure_get_string (structure, "gesture"), "palm") == 0) {
    /* media operation - closed palm to stop media play */
    gst_element_set_state (playbin, GST_STATE_PAUSED);
  }

  /* if FIST gesture detected */
  if (structure &&
      strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 &&
      strcmp (gst_structure_get_string (structure, "gesture"), "fist") == 0) {
    /* print message type and structure name */
    g_print ("%s{{%s}}\n", gst_message_type_get_name (message->type),
        gst_structure_get_name (structure));
    /* print msg structure names&values */
    for (i = 0; i < gst_structure_n_fields (structure); i++) {
      const gchar *name = gst_structure_nth_field_name (structure, i);
      GType type = gst_structure_get_field_type (structure, name);
      const GValue *value = gst_structure_get_value (structure, name);
      type == G_TYPE_STRING ?
          g_print ("-%s[%s]{%s}\n", name, g_type_name (type),
          g_value_get_string (value)) : g_print ("-%s[%s]{%d}\n", name,
          g_type_name (type), g_value_get_uint (value));
    }
    g_print ("\n");

    /* get X,Y positions in frame */
    x_value = gst_structure_get_value (structure, "x");
    x = g_value_get_uint (x_value);
    y_value = gst_structure_get_value (structure, "y");
    y = g_value_get_uint (y_value);

    /* set object volumes [0-10] based on Y */
    g_object_set (G_OBJECT (playbin), "volume", (gdouble) (10 - y / 24), NULL);

    /* seek playback positions */
    gst_element_query_duration (playbin, format, &length);
    /* Width = 320 is specified in caps */
    position = (gint64) length *x / 320;
    gst_element_set_state (playbin, GST_STATE_PAUSED);
    gst_element_seek (GST_ELEMENT (playbin),
        1.0,
        format,
        GST_SEEK_FLAG_FLUSH,
        GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
    gst_element_set_state (GST_ELEMENT (playbin), GST_STATE_PLAYING);
  }

  gst_message_unref (message);
  return GST_BUS_DROP;
}

int
main (gint argc, gchar ** argv)
{
  static GMainLoop *loop;
  GstCaps *caps;
  GstBus *bus;
  gchar *uri;

  const gchar *video_device = "/dev/video0";

  if (argc < 2) {
    fprintf (stderr, "oops, please give a file to play\n");
    return -1;
  }

  uri = g_filename_to_uri (argv[1], NULL, NULL);
  if (!uri) {
    fprintf (stderr, "failed to create the uri\n");
    return -1;
  }

  /* init gst */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);
  /* init elements */
  playbin = gst_element_factory_make ("playbin", "app_playbin");
  pipeline = gst_pipeline_new ("app_pipeline");
  v4l2src = gst_element_factory_make ("v4l2src", "app_v4l2src");
  videoscale = gst_element_factory_make ("videoscale", "app_videoscale");
  videoconvert_in =
      gst_element_factory_make ("videoconvert", "app_videoconvert_in");
  handdetect = gst_element_factory_make ("handdetect", "app_handdetect");
  videoconvert_out =
      gst_element_factory_make ("videoconvert", "app_videoconvert_out");
  xvimagesink = gst_element_factory_make ("xvimagesink", "app_xvimagesink");

  /* check init results */
  if (!playbin || !pipeline || !v4l2src || !videoscale || !videoconvert_in
      || !handdetect || !videoconvert_out || !xvimagesink)
    g_error ("ERROR: element init failed.\n");

  /* set values */
  g_object_set (G_OBJECT (playbin), "uri", uri, NULL);
  g_object_set (G_OBJECT (v4l2src), "device", video_device, NULL);

  /* set caps */
  caps =
      gst_caps_from_string
      ("video/x-raw, format=(string)RGB, width=320, height=240, framerate=(fraction)30/1");

  /* set bus */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, pipeline,
      NULL);
  gst_object_unref (bus);

  /* add elements to pipeline */
  gst_bin_add_many (GST_BIN (pipeline),
      v4l2src,
      videoscale,
      videoconvert_in, handdetect, videoconvert_out, xvimagesink, NULL);

  /* negotiate caps */
  if (!gst_element_link_filtered (v4l2src, videoscale, caps)) {
    g_printerr ("ERROR:v4l2src -> videoscale caps\n");
    return 0;
  }
  gst_caps_unref (caps);

  /* link elements */
  gst_element_link_many (videoscale,
      videoconvert_in, handdetect, videoconvert_out, xvimagesink, NULL);

  /* change states */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* start main loop */
  g_main_loop_run (loop);

  /* clean all */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (pipeline));
  gst_element_set_state (playbin, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (playbin));

  return 0;
}
