#include <stdlib.h>
#include <gtk/gtk.h>
#include <unicap.h>
#include <ucil.h>
#include <unicapgtk.h>
#include <string.h>

ucil_font_object_t *fobj = NULL;


void predisplay_cb( GtkWidget *ugtk, unicap_data_buffer_t *buffer, gpointer user_data )
{
   int cx, cy;
   ucil_color_t color, pixelcolor;
   static int frame_count = 0;
   char text[128];
   int tw, th;
   
   color.colorspace = UCIL_COLORSPACE_RGB24;
   color.rgb24.r = 255;
   color.rgb24.g = 0;
   color.rgb24.b = 0;

   pixelcolor.colorspace = ucil_get_colorspace_from_fourcc( buffer->format.fourcc );
   ucil_convert_color( &pixelcolor, &color );
   
   cx = buffer->format.size.width / 2;
   cy = buffer->format.size.height / 2;

   ucil_draw_line( buffer, &pixelcolor, 
		   cx - buffer->format.size.height / 3, cy, 
		   cx + buffer->format.size.height / 3, cy );
   ucil_draw_line( buffer, &pixelcolor, 
		   cx, cy - buffer->format.size.height / 3, 
		   cx, cy + buffer->format.size.height / 3 );
   
   ucil_draw_circle( buffer, &pixelcolor, 
		     cx, cy, 
		     buffer->format.size.height / 4 );

   color.rgb24.r = 255;
   color.rgb24.g = 255;
   color.rgb24.b = 255;
   ucil_convert_color( &pixelcolor, &color );

   sprintf( text, "Frame: %d", frame_count++ );
   ucil_text_get_size( fobj, text, &tw, &th );
   
   ucil_draw_text( buffer, &pixelcolor, fobj, text, cx - tw/2, cy + buffer->format.size.height / 3 + 2 );
   
   
   
}

/*
  format_change_cb: 
  Callback called when the user selected a new video format
*/
static 
void format_change_cb( GtkWidget *ugtk, unicap_format_t *format, GtkWidget *ugtk_display )
{

   unicapgtk_video_display_stop( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ) );
   unicapgtk_video_display_set_format( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ), format );
   unicapgtk_video_display_start( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ) );

}

static 
void device_change_cb( UnicapgtkDeviceSelection *selection, gchar *device_id, GtkWidget *ugtk_display )
{
   unicap_device_t device;
   unicap_handle_t handle;
   GtkWidget *format_selection;

   format_selection = g_object_get_data( G_OBJECT( ugtk_display ), "format_selection" );
   g_assert( format_selection );

   unicap_void_device( &device );
   strcpy( device.identifier, device_id );
   
   if( !SUCCESS( unicap_enumerate_devices( &device, &device, 0 ) ) ||
       !SUCCESS( unicap_open( &handle, &device ) ) )
   {
      // device is not available anymore
      g_printerr( "*** TODO: device rescan*** device not available!\n" );
      return;
   }
   
   if( unicap_is_stream_locked( &device ) )
   {
      // could not acquire lock
      unicap_close( handle );
      g_printerr( "*** TODO: device rescan*** device is locked\n" );
      return;
   }
		
   unicapgtk_video_display_set_handle( UNICAPGTK_VIDEO_DISPLAY( ugtk_display ), handle );
   unicapgtk_video_format_selection_set_handle( UNICAPGTK_VIDEO_FORMAT_SELECTION( format_selection ), handle );
   unicap_close( handle );
}

int main( int   argc,
          char *argv[] )
{
  GtkWidget *window;
  GtkWidget *ugtk;
  GtkWidget *device_selection;
  GtkWidget *format_selection;
  GtkWidget *vbox;
  GtkWidget *hbox;
  
  gtk_init (&argc, &argv);


  fobj = ucil_create_font_object( 14, NULL );

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  vbox = gtk_vbox_new( FALSE, 0 );
  gtk_container_add( GTK_CONTAINER( window ), vbox );

  hbox = gtk_hbox_new( FALSE, 2 );
  gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
  
  device_selection = unicapgtk_device_selection_new( TRUE );
  gtk_box_pack_start( GTK_BOX( hbox ), device_selection, FALSE, FALSE, 0 );

  format_selection = unicapgtk_video_format_selection_new( );
  gtk_box_pack_start( GTK_BOX( hbox ), format_selection, FALSE, FALSE, 0 );
  
  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (exit), NULL);
  
  ugtk = unicapgtk_video_display_new( );  


  // Activate GTK backend to ensure good overlay quality
  g_object_set( ugtk, "backend", "gtk", "scale-to-fit", FALSE, NULL );

  gtk_box_pack_start( GTK_BOX( vbox ), ugtk, FALSE, FALSE, 0 );
  gtk_widget_show_all (window);

  g_object_set_data( G_OBJECT( ugtk ), "format_selection", format_selection );

  g_signal_connect( device_selection, "unicapgtk-device-selection-changed", (GCallback)device_change_cb, ugtk );
  g_signal_connect( format_selection, "unicapgtk_video_format_changed", (GCallback)format_change_cb, ugtk );
  
  unicapgtk_device_selection_rescan( UNICAPGTK_DEVICE_SELECTION( device_selection ) );

  // register a callback which is called immediately before an image is displayed
  g_signal_connect( G_OBJECT( ugtk ), "unicapgtk_video_display_predisplay", 
					G_CALLBACK( predisplay_cb ), NULL );

  
  gtk_main(); 
  
  return 0;
}
