#include <gst/gst.h>

static GstElement *main_thread;
static GstElement *channel_bin;
static GstElement *audiosink;
static GstElement *filesrc, *mad_decoder, *volume;

init_mixer (int argc, char* argv[])
{
    GstPad *temp_pad; /* for connecting to adder */

    gst_init (&argc, &argv);
    gst_control_init (&argc, &argv);

    /* create main thread to process everything.
     * this thread will hold a bin and an osssink.
     * the bin will hold a filesrc, mad, and volume.
     * a ghost pad will connect the volume's output to
     * the osssink. */
    main_thread = gst_thread_new ("mixer_thread");
    g_assert (main_thread != NULL);

    /* create bin to hold filesrc, volume, and mad */
    channel_bin = gst_bin_new ("channel_bin");
    g_assert (channel_bin != NULL);

    /* create a filesrc reader (goes into bin) */
    filesrc = gst_element_factory_make ("filesrc", "filesrc");
    g_assert (filesrc != NULL);
    g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);

    /* create a decoder */
    mad_decoder = gst_element_factory_make ("mad", "mpg123_decoder");
    g_assert (mad_decoder != NULL);

    /* create a volume controller */
    volume = gst_element_factory_make ("volume", "volume");
    g_assert (volume != NULL);

    /* add main part of audio processing to the bin */
    gst_bin_add_many (GST_BIN (channel_bin),
		      filesrc,
		      mad_decoder,
		      volume,
		      NULL);

    /* actually connect the elements */
    gst_element_connect_many (filesrc, mad_decoder, volume, NULL);

    /* add ghost pad to connect bin to osssink which is held
     * in mixer_thread */
    gst_element_add_ghost_pad (channel_bin, 
			       gst_element_get_pad (volume, "src"),
			       "channel_bin_output");

    /* create our audio sink for final output */
    audiosink = gst_element_factory_make ("osssink", "play_audio");
    g_assert (audiosink != NULL);

    temp_pad = gst_element_get_static_pad (audiosink, "sink");
    g_assert (temp_pad != NULL);

    /* try to connect the ghost pad from the channel bin to the
     * audiosink intake pad */
    if (!gst_pad_connect (gst_element_get_pad (channel_bin, 
					       "channel_bin_output"), 
					       temp_pad))
    {
	g_print ("error connecting pads!\n");
    }

    gst_bin_add (GST_BIN (main_thread), GST_ELEMENT (channel_bin));
    gst_bin_add (GST_BIN (main_thread), GST_ELEMENT (audiosink));

    /* we turn on all pipelines/bins/threads */
    gst_element_set_state (main_thread, GST_STATE_PLAYING);
    gst_element_set_state (channel_bin, GST_STATE_PLAYING);

    /* print out the schedule? */
    gst_scheduler_show (GST_ELEMENT_SCHED (main_thread));

}

void
start_channel (void)
{
    g_print ("starting audio\n");
    gst_element_set_state (GST_ELEMENT (channel_bin), GST_STATE_PLAYING);
}

void
pause_channel (void)
{
    g_print ("pausing audio\n");
    gst_element_set_state (GST_ELEMENT (channel_bin), GST_STATE_PAUSED);
}


void
quit_everything(void)
{

  //  gst_object_destroy (GST_OBJECT (main_thread));
    gst_main_quit();
}
