/*============================================================================*
 *============================================================================*
 * Component:           plextor-tool-applet
 * Filename:            properties.c
 *                                                                             
 * Authors:             Georg Huettenegger
 *                                                                             
 * Date of Creation:    Fri Jul 30 16:04:49 1999
 *                                                                             
 * Last Modification:   Fri Jul 30 16:04:49 1999
 *                                                                             
 * Copyright:           Georg Huettenegger                            
 *                                                                             
 *
 * 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 <stdio.h>
#include <gnome.h>
#include "properties.h"
#include "gplextor-tool.h"
#include "utility-functions.h"
#include "scsi-functions.h"

static int prop_cancel (GtkWidget * w, gpointer data);
static void prop_apply (GtkWidget * w, int page, gpointer data);
static void prop_device_changed_callback (GtkWidget * widget, gpointer data);
static void prop_speed_changed_callback (GtkWidget * widget, gpointer data);
static void prop_avail_spindowns_changed_callback (GtkWidget * widget,
                                                   gpointer data);
static void prop_nsd_toggle_value_change (GtkToggleButton * widget,
                                          gpointer data);
static void prop_avoid_vib_toggle_value_change (GtkToggleButton * widget,
                                                gpointer data);
static void prop_waiting_toggle_value_change (GtkToggleButton * widget,
                                              gpointer data);
static void prop_left_volume_change (GtkAdjustment * widget, gpointer data);
static void prop_right_volume_change (GtkAdjustment * widget, gpointer data);
static void prop_lock_volume_change (GtkToggleButton * widget, gpointer data);

void properties_window (AppletWidget * applet, gpointer data)
{
  static GnomeHelpMenuEntry help_entry = { NULL, "properties" };
  GPlextorToolAppletData * gptad = data;
  GtkWidget * table, * vtable, * scale;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr, "Trace: properties_window\n");
#endif

  help_entry.name = gnome_app_id;
  gptad->prop_active = TRUE;

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptad->prop_win)
  {
    gtk_widget_show (GTK_WIDGET (gptad->prop_win));
    gdk_window_raise (GTK_WIDGET (gptad->prop_win)->window);

    if (gptd)
    {
      adjust_prop_toggles (gptad, gptd);
      adjust_prop_volume (gptad, gptd);

      /* common part of page activation */

      /* first set device */
      gtk_signal_handler_block (GTK_OBJECT
                                (GTK_COMBO(gptad->prop_dev_selection_combo)
                                 ->entry), gptad->prop_dev_sel_signal_id);
      gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(gptad->prop_dev_selection_combo)
                                   ->entry), gptad->old_device_selection);
      gtk_signal_handler_unblock (GTK_OBJECT
                                  (GTK_COMBO(gptad->prop_dev_selection_combo)
                                   ->entry), gptad->prop_dev_sel_signal_id);
      /* next set speed combo */
      gtk_signal_handler_block (GTK_OBJECT
                                (GTK_COMBO(gptad->prop_speed_selection_combo)
                                 ->entry), gptad->prop_speed_sel_signal_id);
      gtk_combo_set_popdown_strings (GTK_COMBO
                                     (gptad->prop_speed_selection_combo),
                                     gptd->avail_speeds);
      gtk_entry_set_text (GTK_ENTRY(GTK_COMBO
                                    (gptad->prop_speed_selection_combo)
                                    ->entry),
                          gptad->old_speed_selection);
      gtk_signal_handler_unblock (GTK_OBJECT
                                  (GTK_COMBO
                                   (gptad->prop_speed_selection_combo)->entry),
                                  gptad->prop_speed_sel_signal_id);
    }
    else
    {
      gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
    }

    return;
  }

  gptad->prop_win = GNOME_PROPERTY_BOX (gnome_property_box_new ());

  gnome_dialog_close_hides
    (GNOME_DIALOG (& (gptad->prop_win->dialog)), TRUE);

  gtk_window_set_title
    (GTK_WINDOW (&GNOME_PROPERTY_BOX (gptad->prop_win)->dialog.window),
     _("Plextor-Tool Settings"));

  table = gtk_table_new (3, 4, FALSE);
  gnome_property_box_append_page (GNOME_PROPERTY_BOX (gptad->prop_win),
                                  table, gtk_label_new (_("General")));

  gptad->prop_dev_selection_combo = gtk_combo_new ();

  if (!gptd)
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
    return;
  }

  /* first create device selection combo */
  gtk_combo_set_popdown_strings (GTK_COMBO(gptad->prop_dev_selection_combo),
                                 gptad->device_names);
  gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(gptad->prop_dev_selection_combo)
                               ->entry), gptad->old_device_selection);
  gtk_table_attach_defaults (GTK_TABLE (table),
                             gptad->prop_dev_selection_combo,
                             0, 1, 1, 2);
  /* register tooltip help for device selection combo */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->prop_dev_selection_combo,
                                    _("Currently Selected Device"));

  /* now create speed selection combo */
  gptad->prop_speed_selection_combo = gtk_combo_new ();
  gtk_combo_set_popdown_strings (GTK_COMBO(gptad->prop_speed_selection_combo),
                                 gptd->avail_speeds);
  gtk_entry_set_text (GTK_ENTRY(GTK_COMBO(gptad->prop_speed_selection_combo)
                                ->entry), gptad->old_speed_selection);
  gtk_table_attach_defaults (GTK_TABLE (table),
                             gptad->prop_speed_selection_combo,
                             0, 1, 2, 3);
  /* register tooltip help for speed selection combo */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->prop_speed_selection_combo,
                                    _("Currently Selected Speed"));


  /* now create spindown selection combo */
  gptad->prop_avail_spindowns_combo = gtk_combo_new ();
  gtk_combo_set_popdown_strings (GTK_COMBO(gptad->prop_avail_spindowns_combo),
                                 gptd->avail_spindowns);
  gtk_entry_set_text (GTK_ENTRY(GTK_COMBO(gptad->prop_avail_spindowns_combo)
                                ->entry), gptad->old_spindown_selection);
  gtk_table_attach_defaults (GTK_TABLE (table),
                             gptad->prop_avail_spindowns_combo,
                             0, 1, 3, 4);
  /* register tooltip help for spindown selection combo */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->prop_avail_spindowns_combo,
                                    _("Current Spindown Settings"));

  /* now create the speed mode toggle button */
  gptad->nsd_toggle = gtk_check_button_new_with_label (_("No Speed Down "
                                                         "Toggle"));
  gtk_table_attach_defaults (GTK_TABLE (table), gptad->nsd_toggle, 1, 2, 1, 2);
  /* register tooltip help for the speed mode toggle button */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->nsd_toggle,
                                    _("Disables Speed Down On Read Error"));


  /* create the avoid vibration toggle button */
  gptad->avoid_vib_toggle = gtk_check_button_new_with_label 
    (_("Disable Avoid Vibration"));
  gtk_table_attach_defaults (GTK_TABLE(table),
                             gptad->avoid_vib_toggle, 1, 2, 2, 3);
  /* register tooltip help for the avoid vibration toggle button */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->avoid_vib_toggle,
                                    _("Disables Avoid Vibration Setting"));


  /* create the waiting for max. speed toggle button */
  gptad->waiting_toggle = gtk_check_button_new_with_label
    (_("Disable Waiting for Max. Speed"));
  gtk_table_attach_defaults (GTK_TABLE(table),
                             gptad->waiting_toggle, 1, 2, 3, 4);
  /* register tooltip help for the waiting for max. speed toggle button */
  applet_widget_set_widget_tooltip 
    (APPLET_WIDGET(gptad->applet), gptad->waiting_toggle,
     _("Disables Waiting For Maximum Speed Before Data Transfer"));

  /* inner table for volume setting */
  vtable = gtk_table_new (2, 3, FALSE);

  /* label within inner table above adjusters */
  gtk_table_attach_defaults(GTK_TABLE(vtable), gtk_label_new (_("Vol")),
			    0, 1, 0, 1);
  /* left adjustment for left volume (actually port 0) */
  gptad->left_volume = (GtkAdjustment *) gtk_adjustment_new
    (-gptd->ptd.act_left_volume, -255.0, 0.0, 1.0, 1.0, 0.0);
  scale = gtk_vscale_new (GTK_ADJUSTMENT(gptad->left_volume));
  gtk_range_set_update_policy (GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS);
  gtk_scale_set_draw_value (GTK_SCALE(scale), FALSE);
  gtk_table_attach_defaults(GTK_TABLE(vtable), scale, 0, 1, 1, 2);

  /* right adjustment for right volume (actually port 1) */
  gptad->right_volume = (GtkAdjustment *) gtk_adjustment_new
    (-gptd->ptd.act_right_volume, -255.0, 0.0, 1.0, 1.0, 0.0);
  scale = gtk_vscale_new (GTK_ADJUSTMENT(gptad->right_volume));
  gtk_range_set_update_policy (GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS);
  gtk_scale_set_draw_value (GTK_SCALE(scale), FALSE);
  gtk_table_attach_defaults(GTK_TABLE(vtable), scale, 1, 2, 1, 2);
  
  /* create the lock volume toggle button */
  gptad->lock_volume = gtk_check_button_new_with_label(_("Lock"));
  gtk_table_attach_defaults(GTK_TABLE(vtable), gptad->lock_volume, 0, 2, 2, 3);
  gtk_table_attach_defaults (GTK_TABLE(table), vtable, 2, 3, 0, 4);
  /* register tooltip help for lock volume toggle button */
  applet_widget_set_widget_tooltip (APPLET_WIDGET(gptad->applet),
                                    gptad->lock_volume,
                                    _("Lock Left And Right Volume"));

  /* connect the signals with the handler functions */

  gptad->prop_dev_sel_signal_id = gtk_signal_connect 
    (GTK_OBJECT (GTK_COMBO(gptad->prop_dev_selection_combo)
                 ->entry), "changed",
     GTK_SIGNAL_FUNC (prop_device_changed_callback), gptad);

  gptad->prop_speed_sel_signal_id = gtk_signal_connect 
    (GTK_OBJECT (GTK_COMBO(gptad->prop_speed_selection_combo)
                 ->entry), "changed",
     GTK_SIGNAL_FUNC (prop_speed_changed_callback), gptad);
                      
  gptad->prop_avail_spindwn_signal_id = gtk_signal_connect 
    (GTK_OBJECT (GTK_COMBO(gptad->prop_avail_spindowns_combo)
                 ->entry), "changed",
     GTK_SIGNAL_FUNC (prop_avail_spindowns_changed_callback), gptad);

  gptad->prop_nsd_toggle_signal_id = gtk_signal_connect 
    (GTK_OBJECT (gptad->nsd_toggle), "toggled",
     GTK_SIGNAL_FUNC (prop_nsd_toggle_value_change), gptad);

  gptad->prop_avoid_vib_toggle_signal_id = gtk_signal_connect 
    (GTK_OBJECT (gptad->avoid_vib_toggle), "toggled",
     GTK_SIGNAL_FUNC (prop_avoid_vib_toggle_value_change), gptad);

  gptad->prop_waiting_toggle_signal_id = gtk_signal_connect 
    (GTK_OBJECT (gptad->waiting_toggle), "toggled",
     GTK_SIGNAL_FUNC (prop_waiting_toggle_value_change), gptad);

  gptad->prop_left_volume_signal_id = gtk_signal_connect
     (GTK_OBJECT (gptad->left_volume), "value_changed",
      GTK_SIGNAL_FUNC (prop_left_volume_change), gptad);

  gptad->prop_right_volume_signal_id = gtk_signal_connect
     (GTK_OBJECT (gptad->right_volume), "value_changed",
      GTK_SIGNAL_FUNC (prop_right_volume_change), gptad);

  gptad->prop_lock_volume_signal_id = gtk_signal_connect 
    (GTK_OBJECT (gptad->lock_volume), "toggled",
     GTK_SIGNAL_FUNC (prop_lock_volume_change), gptad);

  /* standard parts */
  gtk_signal_connect (GTK_OBJECT (gptad->prop_win), "destroy",
                      GTK_SIGNAL_FUNC (prop_cancel), gptad);
  gtk_signal_connect (GTK_OBJECT (gptad->prop_win), "delete_event",
                      GTK_SIGNAL_FUNC (prop_cancel), gptad);
  gtk_signal_connect (GTK_OBJECT (gptad->prop_win), "close",
                      GTK_SIGNAL_FUNC (prop_cancel), gptad);
  gtk_signal_connect (GTK_OBJECT (gptad->prop_win), "apply",
                      GTK_SIGNAL_FUNC (prop_apply), gptad);
  gtk_signal_connect (GTK_OBJECT (gptad->prop_win), "help",
                      GTK_SIGNAL_FUNC (gnome_help_pbox_display),
                      &help_entry);

  adjust_prop_toggles (gptad, gptd);
  adjust_prop_volume (gptad, gptd);

  gtk_widget_show_all (GTK_WIDGET (gptad->prop_win));
}

static int prop_cancel (GtkWidget * w, gpointer data)
{
  GPlextorToolAppletData * gptad = data;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr, "Trace: prop_cancel\n");
#endif
  
  gptad->prop_active = FALSE;
  
  return FALSE;
}

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Should never be called (and if called does nothing).
 * All changes take effect immediately.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
static void prop_apply (GtkWidget * w, int page, gpointer data)
{
#ifdef CALL_TRACE
  GPlextorToolAppletData * gptad = data;

  flushed_output_0 (gptad->out_file_ptr, "Trace: prop_appy\n");
#endif
}

static void prop_device_changed_callback (GtkWidget * widget, gpointer data)
{
  GPlextorToolAppletData * gptad = data;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_device_changed_callback\n");
#endif

  g_free (gptad->old_device_selection);
  gptad->old_device_selection = g_strdup
    (gtk_entry_get_text (GTK_ENTRY
                         (GTK_COMBO(gptad->prop_dev_selection_combo)
                          ->entry)));

  device_changed (gptad, TRUE);
}

static void prop_speed_changed_callback (GtkWidget * widget, gpointer data)
{
  GPlextorToolAppletData * gptad = data;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_speed_changed_callback\n");
#endif

  g_free (gptad->old_speed_selection);
  gptad->old_speed_selection = g_strdup
    (gtk_entry_get_text (GTK_ENTRY
                         (GTK_COMBO(gptad->prop_speed_selection_combo)
                          ->entry)));

  speed_changed (gptad, TRUE);
}

static void prop_avail_spindowns_changed_callback (GtkWidget * widget,
                                                   gpointer data)
{
  GPlextorToolAppletData * gptad = data;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_avail_spindowns_changed_callback\n");
#endif

  g_free (gptad->old_spindown_selection);
  gptad->old_spindown_selection = g_strdup
    (gtk_entry_get_text (GTK_ENTRY
                         (GTK_COMBO(gptad->prop_avail_spindowns_combo)
                          ->entry)));

  spindown_changed (gptad);
}

static void prop_nsd_toggle_value_change (GtkToggleButton * widget,
                                          gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;


#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_nsd_toggle_value_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    if (GTK_TOGGLE_BUTTON (widget)->active) 
    { /* toggle button is down */
      gptd->ptd.act_speed_mode = 1;
    }
    else
    {
      gptd->ptd.act_speed_mode = 0;
    }
    change_speed_mode_setting (gptd);
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

static void prop_avoid_vib_toggle_value_change (GtkToggleButton * widget,
                                                gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_avoid_vib_toggle_value_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    if (GTK_TOGGLE_BUTTON (widget)->active) 
    { /* toggle button is down */
      gptd->ptd.act_avoid_vib_setting = 1;
    }
    else
    {
      gptd->ptd.act_avoid_vib_setting = 0;
    }
    change_avoid_vibration_setting (gptd);
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

static void prop_waiting_toggle_value_change (GtkToggleButton * widget,
                                              gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_waiting_toggle_value_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    if (GTK_TOGGLE_BUTTON (widget)->active) 
    { /* toggle button is down */
      gptd->ptd.act_waiting_setting = 1;
    }
    else
    {
      gptd->ptd.act_waiting_setting = 0;
    }
    change_waiting_for_speed_setting (gptd);
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

static void prop_left_volume_change (GtkAdjustment * widget, gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_left_volume_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    float new_vol = -GTK_ADJUSTMENT(gptad->left_volume)->value;
    if (new_vol < 0.0)
      new_vol = 0.0;
    if (new_vol != gptd->ptd.act_left_volume)
    {
      gptd->ptd.act_left_volume = new_vol;
      if ( (gptd->act_lock_volume == TRUE) &&
	   (gptd->ptd.act_left_volume != gptd->ptd.act_right_volume) )
      { /* update right adjuster too */
	GTK_ADJUSTMENT(gptad->right_volume)->value = -new_vol;
	gtk_signal_emit_by_name (GTK_OBJECT(gptad->right_volume),
				 "value_changed");
      }
      else
	change_volume_setting (gptd);
    }
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

static void prop_right_volume_change (GtkAdjustment * widget, gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_right_volume_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    float new_vol = -GTK_ADJUSTMENT(gptad->right_volume)->value;
    if (new_vol < 0.0)
      new_vol = 0.0;
    if (new_vol != gptd->ptd.act_right_volume)
    {
      gptd->ptd.act_right_volume = new_vol;
      if ( (gptd->act_lock_volume == TRUE) &&
	   (gptd->ptd.act_left_volume != gptd->ptd.act_right_volume) )
      { /* update left adjuster too */
	GTK_ADJUSTMENT(gptad->left_volume)->value = -new_vol;
	gtk_signal_emit_by_name (GTK_OBJECT(gptad->left_volume),
				 "value_changed");
      }
      else
	change_volume_setting (gptd);
    }
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

static void prop_lock_volume_change (GtkToggleButton * widget, gpointer data)
{
  GPlextorToolAppletData * gptad = data;
  GPlextorToolData * gptd;

#ifdef CALL_TRACE
  flushed_output_0 (gptad->out_file_ptr,
                    "Trace: prop_lock_volume_change\n");
#endif

  gptd = find_gptd_with_device_name (gptad, gptad->old_device_selection);

  if (gptd)
  {
    if (GTK_TOGGLE_BUTTON (widget)->active) 
    { /* toggle button is down */
      gptd->act_lock_volume = TRUE;
      if (gptd->ptd.act_left_volume != gptd->ptd.act_right_volume)
      { /* if there are differences => update to average */
	float new_vol
	  = (gptd->ptd.act_left_volume + gptd->ptd.act_right_volume)/2.0;
	if (new_vol < 0.0)
	  new_vol = 0.0;
	gptd->ptd.act_left_volume = new_vol;
	gptd->ptd.act_right_volume = new_vol;
	/* update GUI and set new values */
	GTK_ADJUSTMENT(gptad->left_volume)->value = -new_vol;
	gtk_signal_emit_by_name (GTK_OBJECT(gptad->left_volume),
				 "value_changed");
	GTK_ADJUSTMENT(gptad->right_volume)->value = -new_vol;
	gtk_signal_emit_by_name (GTK_OBJECT(gptad->right_volume),
				 "value_changed");
	change_volume_setting (gptd);
      }
    }
    else
    {
      gptd->act_lock_volume = FALSE;
    }
  }
  else
  {
    gnome_error_dialog (_("Internal Error: Could Not Find The Device"));
  }
}

/*============================================================================*
 *============================================================================*
 * EOF properties.c
 *============================================================================*
 *============================================================================*
 */
