/* vim: set syntax=c: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*/
%at{
 /* bonobo-media-gstreamer: GStreamer player using the Bonobo:Meida interfaces
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyright (c) 2001  Ali Abdin   <aliabdin@aucegypt.edu> and
 *                     ÉRDI Gergõ  <cactus@cactus.rulez.org>
 *                     Wim Taymans <wim.taymans@chello.be>
 */
%}

%header{
#include <bonobo/bonobo-persist-file.h>
#include "bonobo-media/bonobo-media-stream.h"
%}

%privateheader{
#include "bonobo-media-gstreamervideo.h"
#include "bonobo-media/bonobo-media-video.h"
#include <gstplay/gstplay.h>
%}

%{
#include <bonobo/bonobo-exception.h>

#include <bonobo-media/bonobo-media-stream-private.h>

%}

class Bonobo:Media:GStreamer from Bonobo:Media:Stream
{
	private gint 		  length;
	private gint		  current_pos;
	private GstPlay		  *play;
	//private GtkWidget		  *play;

	private guint timeout_id
		destroy
		{
			if (VAR)
				gtk_timeout_remove (VAR);
		} = 0;

	private gboolean update_position (self)
		{
			gint current_time = 0;

			bonobo_media_stream_send_pos_notification (
				BONOBO_MEDIA_STREAM (self),
				current_time);
				
			if (current_time == self->_priv->length)
				bonobo_media_stream_send_end_notification (
					BONOBO_MEDIA_STREAM (self));

			return TRUE;
		}
	
	override (Bonobo:Media:Stream)
		gfloat get_pos_per_sec (BonoboMediaStream *media_stream,
				       CORBA_Environment *ev)
		{
			gfloat ratio = 0;

			/* Since position is in decoded values (to
			   avoid problems with variable bit-rate
			   streams), ratio is effectively the same as
			   the output sampling rate */

			return ratio;
		}

	override (Bonobo:Media:Stream)
		gint get_length (BonoboMediaStream *media_stream,
				 CORBA_Environment *ev)
		{
			return SELF (media_stream)->_priv->length;
		}
		
	override (Bonobo:Media:Stream)
		void seek (BonoboMediaStream *media_stream,
			   gint pos,
			   CORBA_Environment *ev)
		{
			gint seek_success = TRUE;
			BonoboMediaGStreamer *self = SELF (media_stream);

			if (pos < 0 || pos > self->_priv->length) {
				CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
						     ex_Bonobo_Media_Stream_InvalidPosition,
						     NULL);
				return;
			}

			if (!seek_success) {
				CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
						     ex_Bonobo_Media_Stream_InvalidPosition,
						     NULL);
				return;
			}
			update_position (self);
		}

	private gboolean         playing = FALSE;

	private void audio_init (self)
		{
		}
	
	private void* player_func (self)
		{
		   return NULL;
		}
	
	private void audio_cleanup (self)
		{
		}
	
	override (Bonobo:Media:Stream)
		void play (BonoboMediaStream *media_stream,
			   CORBA_Environment *ev)
		{
			BonoboMediaGStreamer *self = SELF (media_stream);
			
			gst_play_play (self->_priv->play);

			self->_priv->playing = TRUE;
			 
			if (!self->_priv->timeout_id)
				self->_priv->timeout_id = 
					gtk_timeout_add (100, (GtkFunction)update_position, self);
		}

	override (Bonobo:Media:Stream)
		void stop (BonoboMediaStream *media_stream,
			   CORBA_Environment *ev)
		{
			BonoboMediaGStreamer *self = SELF (media_stream);
			
			self->_priv->playing = FALSE;
			
			if (self->_priv->timeout_id)
				gtk_timeout_remove (self->_priv->timeout_id);
				
			self->_priv->timeout_id = 0;
		}
		
	private void volume_cb (GtkObject *obj, gfloat vol,
				Bonobo:Media:GStreamer *self (check null type))
		{
			g_print ("Volume changed to %f\n", vol);
		}

	private void speaker_cb (GtkObject *obj,
				 Bonobo:Media:GStreamer *self (check null type))
		{
			audio_cleanup (self);
			audio_init (self);
		}
		
	private void read_file_info (self)
		{	
		}

	public gint PersistFile_load (BonoboPersistFile   *pf,
				      const CORBA_char    *filename,
				      CORBA_Environment   *ev,
				      Bonobo:Media:GStreamer *self (check null type))
		{
			load_file (self, filename);
			
			return 0;
		}

	public gint PersistFile_save (BonoboPersistFile   *pf,
				      const CORBA_char    *filename,
				      CORBA_Environment   *ev,
				      Bonobo:Media:GStreamer *self (check null type))
		{
			CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
					     ex_Bonobo_NotSupported, NULL);
			return 0;
		}
	
	public void load_file (self, const gchar *filename)
		{
		   gst_play_set_uri (self->_priv->play, filename);
		}

	private void construct (self)
		{
			Bonobo_Media_Stream corba_stream;
			BonoboMediaVideo *gstreamer_video;
			BonoboPersistFile *pf;
			
			corba_stream = bonobo_media_stream_corba_object_create (BONOBO_OBJECT (self));

			self->_priv->play = gst_play_new ();
			//self->_priv->play = gtk_button_new ();

			gstreamer_video = BONOBO_MEDIA_VIDEO (bonobo_media_gstreamervideo_new (self->_priv->play));

		 	bonobo_object_add_interface (BONOBO_OBJECT (self), BONOBO_OBJECT (gstreamer_video));

			pf = bonobo_persist_file_new
				((BonoboPersistFileIOFn) PersistFile_load,
				 (BonoboPersistFileIOFn) PersistFile_save,
				 self);
			bonobo_object_add_interface (BONOBO_OBJECT (self),
						     BONOBO_OBJECT (pf));
			
			bonobo_media_stream_construct (BONOBO_MEDIA_STREAM (self), corba_stream);
		}

	public Bonobo:Media:GStreamer* new_from_file (const gchar *filename)
		{
			Self *self;

			self = bonobo_media_gstreamer_new ();

			construct (self);
			load_file (self, filename);

			return self;
		}

	public Bonobo:Media:GStreamer* new (void)
		{
			Self *self;
			
			self = GET_NEW;
			
			construct (self);

			return self;
		}
}
