/* GstInterTest
 * Copyright (C) 2011 David Schleef <ds@schleef.org>
 * Copyright (C) 2010 Entropy Wave Inc
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

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

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

//#define GETTEXT_PACKAGE "intertest"


typedef struct _GstInterTest GstInterTest;
struct _GstInterTest
{
  GstElement *pipeline;
  GstBus *bus;
  GMainLoop *main_loop;

  GstElement *source_element;
  GstElement *sink_element;

  gboolean paused_for_buffering;
  guint timer_id;
};

GstInterTest *gst_inter_test_new (void);
void gst_inter_test_free (GstInterTest * intertest);
void gst_inter_test_create_pipeline_server (GstInterTest * intertest);
void gst_inter_test_create_pipeline_vts (GstInterTest * intertest);
void gst_inter_test_create_pipeline_playbin (GstInterTest * intertest,
    const char *uri);
void gst_inter_test_start (GstInterTest * intertest);
void gst_inter_test_stop (GstInterTest * intertest);

static gboolean gst_inter_test_handle_message (GstBus * bus,
    GstMessage * message, gpointer data);
static gboolean onesecond_timer (gpointer priv);


gboolean verbose;

static GOptionEntry entries[] = {
  {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL},

  {NULL}

};

int
main (int argc, char *argv[])
{
  GError *error = NULL;
  GOptionContext *context;
  GstInterTest *intertest1;
  GstInterTest *intertest2;
  GMainLoop *main_loop;

#if !GLIB_CHECK_VERSION (2, 31, 0)
  if (!g_thread_supported ())
    g_thread_init (NULL);
#endif

  context = g_option_context_new ("- Internal src/sink test");
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
  g_option_context_add_group (context, gst_init_get_option_group ());
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print ("option parsing failed: %s\n", error->message);
    exit (1);
  }
  g_option_context_free (context);

  intertest1 = gst_inter_test_new ();
  gst_inter_test_create_pipeline_server (intertest1);
  gst_inter_test_start (intertest1);

  intertest2 = gst_inter_test_new ();
  gst_inter_test_create_pipeline_playbin (intertest2, NULL);
  gst_inter_test_start (intertest2);

  main_loop = g_main_loop_new (NULL, TRUE);
  intertest1->main_loop = main_loop;
  intertest2->main_loop = main_loop;

  g_main_loop_run (main_loop);
  g_main_loop_unref (main_loop);

  exit (0);
}


GstInterTest *
gst_inter_test_new (void)
{
  GstInterTest *intertest;

  intertest = g_new0 (GstInterTest, 1);

  return intertest;
}

void
gst_inter_test_free (GstInterTest * intertest)
{
  if (intertest->source_element) {
    gst_object_unref (intertest->source_element);
    intertest->source_element = NULL;
  }
  if (intertest->sink_element) {
    gst_object_unref (intertest->sink_element);
    intertest->sink_element = NULL;
  }

  if (intertest->pipeline) {
    gst_element_set_state (intertest->pipeline, GST_STATE_NULL);
    gst_object_unref (intertest->pipeline);
    intertest->pipeline = NULL;
  }
  g_free (intertest);
}

void
gst_inter_test_create_pipeline_playbin (GstInterTest * intertest,
    const char *uri)
{
  GstElement *pipeline;

  if (uri == NULL) {
    gst_inter_test_create_pipeline_vts (intertest);
    return;
  }

  pipeline = gst_pipeline_new (NULL);
  gst_bin_add (GST_BIN (pipeline),
      gst_element_factory_make ("playbin", "source"));

  intertest->pipeline = pipeline;

  gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
  intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);

  intertest->source_element =
      gst_bin_get_by_name (GST_BIN (pipeline), "source");
  g_print ("source_element is %p\n", intertest->source_element);

  g_print ("setting uri to %s\n", uri);
  g_object_set (intertest->source_element, "uri", uri, NULL);
}

void
gst_inter_test_create_pipeline_vts (GstInterTest * intertest)
{
  GString *pipe_desc;
  GstElement *pipeline;
  GError *error = NULL;

  pipe_desc = g_string_new ("");

  g_string_append (pipe_desc, "videotestsrc name=source num-buffers=100 ! ");
  g_string_append (pipe_desc,
      "video/x-raw,format=(string)I420,width=320,height=240 ! ");
  g_string_append (pipe_desc, "timeoverlay ! ");
  g_string_append (pipe_desc, "intervideosink name=sink sync=true ");
  g_string_append (pipe_desc,
      "audiotestsrc samplesperbuffer=1600 num-buffers=100 ! audioconvert ! ");
  g_string_append (pipe_desc, "interaudiosink sync=true ");

  if (verbose)
    g_print ("pipeline: %s\n", pipe_desc->str);

  pipeline = (GstElement *) gst_parse_launch (pipe_desc->str, &error);
  g_string_free (pipe_desc, TRUE);

  if (error) {
    g_print ("pipeline parsing error: %s\n", error->message);
    gst_object_unref (pipeline);
    return;
  }

  intertest->pipeline = pipeline;

  gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
  intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);

  intertest->source_element =
      gst_bin_get_by_name (GST_BIN (pipeline), "source");
  intertest->sink_element = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
}

void
gst_inter_test_create_pipeline_server (GstInterTest * intertest)
{
  GString *pipe_desc;
  GstElement *pipeline;
  GError *error = NULL;

  pipe_desc = g_string_new ("");

  g_string_append (pipe_desc, "intervideosrc ! queue ! ");
  g_string_append (pipe_desc, "xvimagesink name=sink ");
  g_string_append (pipe_desc, "interaudiosrc ! queue ! ");
  g_string_append (pipe_desc, "alsasink ");

  if (verbose)
    g_print ("pipeline: %s\n", pipe_desc->str);

  pipeline = (GstElement *) gst_parse_launch (pipe_desc->str, &error);
  g_string_free (pipe_desc, TRUE);

  if (error) {
    g_print ("pipeline parsing error: %s\n", error->message);
    gst_object_unref (pipeline);
    return;
  }

  intertest->pipeline = pipeline;

  gst_pipeline_set_auto_flush_bus (GST_PIPELINE (pipeline), FALSE);
  intertest->bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (intertest->bus, gst_inter_test_handle_message, intertest);

  intertest->source_element =
      gst_bin_get_by_name (GST_BIN (pipeline), "source");
  intertest->sink_element = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
}

void
gst_inter_test_start (GstInterTest * intertest)
{
  gst_element_set_state (intertest->pipeline, GST_STATE_READY);

  intertest->timer_id = g_timeout_add (1000, onesecond_timer, intertest);
}

void
gst_inter_test_stop (GstInterTest * intertest)
{
  gst_element_set_state (intertest->pipeline, GST_STATE_NULL);

  g_source_remove (intertest->timer_id);
}

static void
gst_inter_test_handle_eos (GstInterTest * intertest)
{
  gst_inter_test_stop (intertest);
}

static void
gst_inter_test_handle_error (GstInterTest * intertest, GError * error,
    const char *debug)
{
  g_print ("error: %s\n", error->message);
  gst_inter_test_stop (intertest);
}

static void
gst_inter_test_handle_warning (GstInterTest * intertest, GError * error,
    const char *debug)
{
  g_print ("warning: %s\n", error->message);
}

static void
gst_inter_test_handle_info (GstInterTest * intertest, GError * error,
    const char *debug)
{
  g_print ("info: %s\n", error->message);
}

static void
gst_inter_test_handle_null_to_ready (GstInterTest * intertest)
{
  gst_element_set_state (intertest->pipeline, GST_STATE_PAUSED);

}

static void
gst_inter_test_handle_ready_to_paused (GstInterTest * intertest)
{
  if (!intertest->paused_for_buffering) {
    gst_element_set_state (intertest->pipeline, GST_STATE_PLAYING);
  }
}

static void
gst_inter_test_handle_paused_to_playing (GstInterTest * intertest)
{

}

static void
gst_inter_test_handle_playing_to_paused (GstInterTest * intertest)
{

}

static void
gst_inter_test_handle_paused_to_ready (GstInterTest * intertest)
{

}

static void
gst_inter_test_handle_ready_to_null (GstInterTest * intertest)
{
  //g_main_loop_quit (intertest->main_loop);

}


static gboolean
gst_inter_test_handle_message (GstBus * bus, GstMessage * message,
    gpointer data)
{
  GstInterTest *intertest = (GstInterTest *) data;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_EOS:
      gst_inter_test_handle_eos (intertest);
      break;
    case GST_MESSAGE_ERROR:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_error (message, &error, &debug);
      gst_inter_test_handle_error (intertest, error, debug);
      g_error_free (error);
      g_free (debug);
    }
      break;
    case GST_MESSAGE_WARNING:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_warning (message, &error, &debug);
      gst_inter_test_handle_warning (intertest, error, debug);
      g_error_free (error);
      g_free (debug);
    }
      break;
    case GST_MESSAGE_INFO:
    {
      GError *error = NULL;
      gchar *debug;

      gst_message_parse_info (message, &error, &debug);
      gst_inter_test_handle_info (intertest, error, debug);
      g_error_free (error);
      g_free (debug);
    }
      break;
    case GST_MESSAGE_TAG:
    {
      GstTagList *tag_list;

      gst_message_parse_tag (message, &tag_list);
      if (verbose)
        g_print ("tag\n");
    }
      break;
    case GST_MESSAGE_STATE_CHANGED:
    {
      GstState oldstate, newstate, pending;

      gst_message_parse_state_changed (message, &oldstate, &newstate, &pending);
      if (GST_ELEMENT (message->src) == intertest->pipeline) {
        if (verbose)
          g_print ("state change from %s to %s\n",
              gst_element_state_get_name (oldstate),
              gst_element_state_get_name (newstate));
        switch (GST_STATE_TRANSITION (oldstate, newstate)) {
          case GST_STATE_CHANGE_NULL_TO_READY:
            gst_inter_test_handle_null_to_ready (intertest);
            break;
          case GST_STATE_CHANGE_READY_TO_PAUSED:
            gst_inter_test_handle_ready_to_paused (intertest);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
            gst_inter_test_handle_paused_to_playing (intertest);
            break;
          case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
            gst_inter_test_handle_playing_to_paused (intertest);
            break;
          case GST_STATE_CHANGE_PAUSED_TO_READY:
            gst_inter_test_handle_paused_to_ready (intertest);
            break;
          case GST_STATE_CHANGE_READY_TO_NULL:
            gst_inter_test_handle_ready_to_null (intertest);
            break;
          default:
            if (verbose)
              g_print ("unknown state change from %s to %s\n",
                  gst_element_state_get_name (oldstate),
                  gst_element_state_get_name (newstate));
        }
      }
    }
      break;
    case GST_MESSAGE_BUFFERING:
    {
      int percent;
      gst_message_parse_buffering (message, &percent);
      //g_print("buffering %d\n", percent);
      if (!intertest->paused_for_buffering && percent < 100) {
        g_print ("pausing for buffing\n");
        intertest->paused_for_buffering = TRUE;
        gst_element_set_state (intertest->pipeline, GST_STATE_PAUSED);
      } else if (intertest->paused_for_buffering && percent == 100) {
        g_print ("unpausing for buffing\n");
        intertest->paused_for_buffering = FALSE;
        gst_element_set_state (intertest->pipeline, GST_STATE_PLAYING);
      }
    }
      break;
    case GST_MESSAGE_STATE_DIRTY:
    case GST_MESSAGE_CLOCK_PROVIDE:
    case GST_MESSAGE_CLOCK_LOST:
    case GST_MESSAGE_NEW_CLOCK:
    case GST_MESSAGE_STRUCTURE_CHANGE:
    case GST_MESSAGE_STREAM_STATUS:
      break;
    case GST_MESSAGE_STEP_DONE:
    case GST_MESSAGE_APPLICATION:
    case GST_MESSAGE_ELEMENT:
    case GST_MESSAGE_SEGMENT_START:
    case GST_MESSAGE_SEGMENT_DONE:
    case GST_MESSAGE_LATENCY:
    case GST_MESSAGE_ASYNC_START:
    case GST_MESSAGE_ASYNC_DONE:
    case GST_MESSAGE_REQUEST_STATE:
    case GST_MESSAGE_STEP_START:
    default:
      if (verbose) {
        g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message));
      }
      break;
    case GST_MESSAGE_QOS:
      break;
  }

  return TRUE;
}



static gboolean
onesecond_timer (gpointer priv)
{
  //GstInterTest *intertest = (GstInterTest *)priv;

  g_print (".\n");

  return TRUE;
}



/* helper functions */

#if 0
gboolean
have_element (const gchar * element_name)
{
  GstPluginFeature *feature;

  feature = gst_default_registry_find_feature (element_name,
      GST_TYPE_ELEMENT_FACTORY);
  if (feature) {
    g_object_unref (feature);
    return TRUE;
  }
  return FALSE;
}
#endif
