/*****************************************************************************/

/*
 *      playlistcb.c -- playlist GTK+ callbacks
 *
 *      Copyright (C) 2001-2002 Sigma Designs
 *                    written by Pascal Cannenterre <pascal_cannenterre@sdesigns.com>
 *
 *      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 of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*****************************************************************************/
#include "define.h"
#include "gtk_callbacks.h"
#include "interface.h"
#include "addfilesbrowser.h"
#include "playlistfile.h"
#include "manageconfig.h"

#include "../pixmaps/fileopen.xpm"


void button_add_clicked( gpointer data )
{
   
  create_add_files_browser(FALSE);
  return;
}

void button_clear_selected_clicked( gpointer data )
{
  GList *node = NULL, *copy_list = NULL;
  gpointer copy_data = NULL;
  GtkCList *clist = GTK_CLIST(data);
  
  node = clist->selection;

  while(node != NULL)
    {
      copy_data = GINT_TO_POINTER(GPOINTER_TO_INT(node->data));
      copy_list = g_list_append(copy_list, copy_data);
      node = g_list_next(node);
    }
  
  copy_list = g_list_sort(copy_list, int_compare_func);
  
  node = g_list_last(copy_list);

  if(node != NULL)
    {
      /* freeze the list */
      playlistwin_prepare_to_update();
      while (node != NULL)
	{
	  gint actual_selected_row = GPOINTER_TO_INT(node->data);
	  gtk_clist_remove(clist, actual_selected_row);
	  GUI.playlist_length--;
	  if(actual_selected_row == (GUI.playlist_selected_row - 1) )
	     GUI.playlist_selected_row--;
	  node = g_list_previous(node);
	}
      /* Apply the changes -> thaw the list */
      playlistwin_update_list();    
    }
  
    return;
}


/* User clicked the "Clear List" button. */
void button_clear_clicked( gpointer data )
{
    gtk_clist_clear( (GtkCList *) data);
    GUI.playlist_length = 0;
    GUI.playlist_selected_row = 0;
    return;
}

/* The user clicked the "Hide/Show titles" button. */
void button_hide_show_clicked( gpointer data )
{
    /* Just a flag to remember the status. 0 = currently visible */
    static short int flag = 0;

    if (flag == 0)
    {
        /* Hide the titles and set the flag to 1 */
	gtk_clist_column_titles_hide((GtkCList *) data);
	flag++;
    }
    else
    {
        /* Show the titles and reset flag to 0 */
	gtk_clist_column_titles_show((GtkCList *) data);
	flag--;
    }

    return;
}

/* If we come here, then the user has selected a row in the list. */
void display_func(gpointer list_data, gpointer user_data)
{
  if(list_data != NULL)
    G_MESSAGE("Element is # %d",GPOINTER_TO_INT(list_data));
}

void selection_made( GtkWidget      *clist,
                     gint            row,
                     gint            column,
		     GdkEventButton *event,
                     gpointer        data )
{
  if(row < 0)
    {
      G_MESSAGE("Wrong row number (selection) !!!");
      return;
    }
  
  if(event != NULL)
    {
      if(event->type == GDK_2BUTTON_PRESS ||
	 event->type == GDK_3BUTTON_PRESS)
	{
	  GUI.playlist_selected_row = row;
	  playlist_play();
	}
    }
  
  return;
}


gint gint_compare_func(gconstpointer a, gconstpointer b)
{
  if (GPOINTER_TO_INT(a) == GPOINTER_TO_INT(b))
    return 0;
  else
    return -1;
}

void unselection_made( GtkWidget      *clist,
		       gint            row,
		       gint            column,
		       GdkEventButton *event,
		       gpointer        data )
{
  
  if(row < 0)
    {
      G_MESSAGE("Wrong row number (unselection) !!!");
      return;
    }

  
  return;
}

void playlist_clear()
{
  GtkCList *clist = NULL;
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
				   "playlist"));
  if(clist != NULL)
    button_clear_clicked((gpointer)clist);
}

void playlistwin_prepare_to_update()
{
  GtkCList *clist = NULL;
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
					 "playlist"));
  if(clist != NULL)
    gtk_clist_freeze(clist);  
}

void playlist_add(gchar *url)
{
  // gchar **fileproperty = g_new0(gchar*, 3);
  gchar **fileproperty = g_new0(gchar*, 1);
  GtkCList *clist = NULL;
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
					 "playlist"));
  
  fileproperty[0] = g_strdup(url);
  // fileproperty[1] = g_strdup("UNKNOWN");
  // fileproperty[2] = g_strdup("00:00:00");
  if(clist != NULL)
    {
      gtk_clist_append(clist, fileproperty);
      GUI.playlist_length++;
    }
  
}

guint playlist_length()
{
  guint playlist_length = 0;
  GList *node = NULL;
  GtkCList *clist = NULL;
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
				   "playlist"));
  if(clist == NULL)
    {
      G_WARNING("CLIST is NULL !!");
      return 0;
    }
  
  gtk_clist_select_all(clist);
  node = clist->selection;
  
  if(node != NULL)
    {
      playlist_length = g_list_length(node);
    }
  
  gtk_clist_undo_selection(clist);
  
  return playlist_length;
}

gint playlist_next(INFO * info)
{
  gchar *text = NULL;
  GtkCList *clist = NULL;
  gint pls_next = -1;
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
				   "playlist"));
   if(clist != NULL && GUI.playlist_length != 0)
    {
      G_WARNING("Playlist length is %d", GUI.playlist_length);
      
      if(GUI.playlist_selected_row >= GUI.playlist_length)
	GUI.playlist_selected_row = 0;

      gtk_clist_get_text(clist, GUI.playlist_selected_row, 0, &text);
      if(text != NULL)
	{
	  DWORD tmp = info->dwStreamtype;
	  if(checkFileValidity(info, text))
	    {
	      pls_next = 1;
	      if(tmp != info->dwStreamtype)
		{
		  usleep(20*TICK);
		  FMPClose();
		  info->playing = CLOSED; 
		  usleep(20*TICK);
		  G_WARNING("OK, FMPClose() realized !");
		}
	      gdk_threads_enter();
	      G_WARNING("GDK_THREAD_ENTER_REALIZED !");
	      handle_Play_Pause(info);
	      gtk_clist_unselect_all(clist);
	      gdk_threads_leave();
	    }
	}
      else
	pls_next = 0;	
    }
   else
     pls_next = 0;
   
   GUI.playlist_selected_row++;
      
   if(pls_next == 1)
     {
       gdk_threads_enter();
       gtk_clist_select_row(clist, GUI.playlist_selected_row-1, 0);
       gdk_threads_leave();
     }

   return pls_next;
}


gint run_playlist_timeout_cb(gpointer data)
{
  if(Info.bDiscType != LOCALFILE)
    {
      GUI.playlist_runner_tag = 0;
      return FALSE;
    }
  if(Info.loop_is_over)
    {
      Info.loop_is_over = 0;
      gdk_threads_enter();
      playlist_play();
      gdk_threads_leave();
    }
  return TRUE;
}

void playlist_play()
{
  gchar *text = NULL;
  GtkCList *clist = NULL;
  gboolean playlist_succeded = FALSE;
  
  if(GUI.playlist_runner_tag == 0)
    {
      GUI.playlist_runner_tag =
	gtk_timeout_add(PLAYLIST_NEXT_FILE_DELAY,
		(GtkFunction)run_playlist_timeout_cb,
		&Info);	
    }
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
				   "playlist"));
  if(clist != NULL && GUI.playlist_length != 0)
    {
      G_WARNING("Playlist length is %d", GUI.playlist_length);
      
      GUI.playlist_selected_row = (GUI.playlist_length + GUI.playlist_selected_row)%(GUI.playlist_length);
      
      gtk_clist_get_text(clist, GUI.playlist_selected_row, 0, &text);
      if(text != NULL)
	{
	  playlist_succeded = playfile(text);
	  if(playlist_succeded)
	    {
	      gtk_clist_unselect_all(clist);
	      G_WARNING("playlist_play succeeded !");
	    }
	  else
	    G_PRINT("\n\n\n\nPlaylist has failed !!!\n\n\n\n");
	}
      else
	{
	  G_WARNING(" Couldn't retrieve file name from cell !!");
	  return;
	}
	
      GUI.playlist_selected_row++;
      
      if(playlist_succeded)
	gtk_clist_select_row(clist, GUI.playlist_selected_row-1, 0);
    }
  else
    G_WARNING("Trouble with clist in playfile_play() !!");
  return;
}

void playlistwin_update_list()
{
  GtkCList *clist = NULL;
  
  clist = 
    GTK_CLIST(gtk_object_get_data (GTK_OBJECT (GUI.playlistwin), 
					 "playlist"));
  if(clist != NULL)
    gtk_clist_thaw(clist);
}

static GtkWidget *fileplaylistw = NULL;

void gtk_destroy_playlist_file_selector(GtkWidget *widget, gpointer data)
{
  if(fileplaylistw != NULL)
    {
      gtk_grab_remove(fileplaylistw);
      gtk_widget_destroy(fileplaylistw);
      fileplaylistw = NULL;
    }
}

void get_playlist_file_selector(gboolean is_save_dialog)
{
/* I test if there is already a visible or an iconified window of the file selector */
 if (fileplaylistw != NULL && fileplaylistw->window != NULL)
   {
     gdk_window_show(fileplaylistw->window);
     gdk_window_raise(fileplaylistw->window);
   }
 else
   {
     
     /* Create a new file selection widget */
     if(is_save_dialog)
       fileplaylistw = gtk_file_selection_new ("Save playlist file as...");
     else
       fileplaylistw = gtk_file_selection_new ("Open a playlist file...");

     gtk_signal_connect(GTK_OBJECT (fileplaylistw), "destroy",
			GTK_SIGNAL_FUNC(gtk_destroy_playlist_file_selector) ,
			NULL);
     /* Connect the ok_button to file_ok_sel function */
     if(is_save_dialog)
       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileplaylistw)->ok_button),
			   "clicked", (GtkSignalFunc) file_ok_save_sel, fileplaylistw );
     else
       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileplaylistw)->ok_button),
			  "clicked", (GtkSignalFunc) file_ok_open_sel, fileplaylistw );
     
     /* Connect the cancel_button to destroy the widget */
     gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
					   (fileplaylistw)->cancel_button),
			       "clicked", 
			       GTK_SIGNAL_FUNC(gtk_destroy_playlist_file_selector),
			       NULL);
     
     /* Lets set the filename, as if this were a save dialog, and we are giving
     a default filename */
     
     gtk_file_selection_set_filename (GTK_FILE_SELECTION(fileplaylistw),
				      playlist_get_default_filename());
  
     if(!is_save_dialog && Info.sFilename != NULL)
       {
	 gtk_file_selection_set_filename (GTK_FILE_SELECTION(fileplaylistw), 
					  Info.sFilename);
       }
     
     set_window_icon(fileplaylistw,fileopen_xpm);
     gtk_window_set_transient_for(GTK_WINDOW(fileplaylistw), GTK_WINDOW(GUI.playlistwin) );
     gtk_grab_add(fileplaylistw);
     gtk_widget_show(fileplaylistw);
     gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(fileplaylistw));
   }
}

gboolean file_ok_save_sel(GtkWidget *widget, gpointer data)
{
  gtk_widget_hide(GTK_WIDGET(fileplaylistw));
  
  G_MESSAGE("file selected is %s", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fileplaylistw)) );
  
  if(save_playlist(gtk_file_selection_get_filename (GTK_FILE_SELECTION (fileplaylistw))))
    G_WARNING("Save playlist OK !!!");
  else
    G_WARNING("Save playlist FAILED !!!");
  
  gtk_destroy_playlist_file_selector(NULL, NULL);
  return TRUE;
}

gboolean file_ok_open_sel(GtkWidget *widget, gpointer data)
{
  gtk_widget_hide(GTK_WIDGET(fileplaylistw));
  if(load_playlist(gtk_file_selection_get_filename (GTK_FILE_SELECTION (fileplaylistw))))
    G_WARNING("Load playlist OK !!!");
  else
    G_WARNING("Load playlist FAILED !!!");
  gtk_destroy_playlist_file_selector(NULL, NULL);
  return TRUE;
}

gboolean load_playlist_file_clicked_cb(GtkWidget *widget, gpointer data)
{
  get_playlist_file_selector(FALSE);
  return TRUE;
}

gboolean save_playlist_file_clicked_cb(GtkWidget *widget, gpointer data)
{
  get_playlist_file_selector(TRUE);
  return TRUE;
}
