/* NIGHTFALL Light Curve Synthesis Program                                 */
/* Copyright (C) 1998 Rainer Wichmann                                      */
/*                                                                         */
/*  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.              */

/* ANSI C forbids an empty source file, so put this outside                */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>

#include "Light.h"

#ifdef _WITH_GTK


static   GtkWidget   *exit_dialog;           /* exit confirmation            */

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Handle exit
 @tip       function arguments are not used
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       The button id
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void doQuit()
{
  int os_x, os_y, os_w, os_h;

#ifdef _WITH_GNUPLOT
    if (Flags.plotOpened == ON) { Flags.plotOpened = OFF; cpgend(); }
#endif

  gdk_window_get_position(top_window->window, &os_x, &os_y);
#ifdef USING_GTK2
  gdk_drawable_get_size(top_window->window, &os_w, &os_h);
#else
  gdk_window_get_size(top_window->window, &os_w, &os_h);
#endif

#ifdef HAVE_GNOME  
  gnome_config_push_prefix ("nightfall/");
  if (Flags.GN_rempos) {
    gnome_config_set_int("Geometry/x",  os_x);
    gnome_config_set_int("Geometry/y",  os_y);
    gnome_config_set_int("Geometry/w",  os_w);
    gnome_config_set_int("Geometry/h",  os_h);
  }
  gnome_config_sync();
  gnome_config_pop_prefix();
#endif
  gtk_main_quit ();
  exit(0);
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Handle exit confirmation
 @tip       function arguments are not used
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       The button id
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void do_exit_app (GtkWidget * widget, 
		  gpointer *data)
{
  gint button_number;

  sscanf ((char *) data, "%d", &button_number);

  switch (button_number) {
  case 0: /* NO button  */
    gtk_widget_destroy(GTK_WIDGET(exit_dialog));
    break;
  case 1: /* YES button */
    doQuit();
    break;
  default:
    break;
  };
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Exit confirmation
 @param     (void) 
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void do_exit_confirm ()
{

#ifdef HAVE_GNOME
  exit_dialog = gnome_message_box_new(_("Really exit ?"), 
				 GNOME_MESSAGE_BOX_QUESTION,  
				 GNOME_STOCK_BUTTON_NO, 
				 GNOME_STOCK_BUTTON_YES, NULL);

  gnome_dialog_button_connect (GNOME_DIALOG(exit_dialog), 0,
                                GTK_SIGNAL_FUNC(do_exit_app),
                                (gpointer) "0");  

  gnome_dialog_button_connect (GNOME_DIALOG(exit_dialog), 1,
                                GTK_SIGNAL_FUNC(do_exit_app),
                                (gpointer) "1");  

  gtk_widget_show(GTK_WIDGET(exit_dialog));
#else

  GtkWidget   *label;
  GtkWidget   *button;
  GtkWidget   *box1;
  GtkWidget   *hbox;
  GtkWidget   *separator;

#ifdef USING_GTK2
  exit_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#else
  exit_dialog = gtk_window_new (GTK_WINDOW_DIALOG);
#endif
  gtk_widget_set_usize (exit_dialog, 200, 80);
  /* gtk_window_set_position(GTK_WINDOW(exit_dialog), GTK_WIN_POS_MOUSE); */ 
  gtk_signal_connect (GTK_OBJECT (exit_dialog), "destroy",
		      GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);

  box1 = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (exit_dialog), box1);
  gtk_container_set_border_width (GTK_CONTAINER (box1), 5);

  label = gtk_label_new (_("Really exit ?") );
  gtk_box_pack_start (GTK_BOX (box1), label, FALSE, TRUE, 5);
  gtk_widget_show (label);
   
  separator = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
  gtk_widget_show (separator);    

  hbox = gtk_hbox_new (TRUE, 0);
  gtk_box_pack_start (GTK_BOX (box1), hbox, FALSE, TRUE, 0);
  gtk_widget_show (hbox);

  button = gtk_button_new_with_label (_("No"));
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (do_exit_app), "0");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  (GTK_WIDGET_FLAGS (button)  |= (GTK_CAN_DEFAULT));
  gtk_widget_grab_default (button); 
  gtk_widget_show (button);

  button = gtk_button_new_with_label (_("Yes"));
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      GTK_SIGNAL_FUNC (do_exit_app), "1");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  (GTK_WIDGET_FLAGS (button)  |= (GTK_CAN_DEFAULT));
  gtk_widget_grab_default (button); 
  gtk_widget_show (button);

  gtk_widget_show (box1);
  gtk_widget_show (exit_dialog);
#endif

  return;
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'close application'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
delete_event (GtkWidget *widget, gpointer *data)
{

#ifdef HAVE_GNOME
  if (Flags.GN_exitconfirm)  
    do_exit_confirm();
  else 
    doQuit();
#else
  if ((char *) data == NULL) 
    do_exit_confirm();
  else
    doQuit();
#endif  
  /* only returns if not confirmed */
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'compute lightcurve'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightcurve_event (GtkWidget *widget, gpointer *data)
{
  int    ErrCode = 0;             /* return status                */
  double Merit = 0.;              /* merit observed - computed    */
  
  /* block GUI                                                    */

  gtk_widget_set_sensitive(top_window, FALSE);

  /* validate data                                                */
  check_data();

  /* compute                                                      */
  ErrCode = MainLoop (&Merit);
  if (ErrCode == 0) {
    WriteOutput();
    if (Flags.plot > OFF) {

#ifdef _WITH_PGPLOT
      PlotOutput();
#else
      make_dialog (_(errmsg[14]));
#endif

    }
  } else {
    make_dialog (_(errmsg[12]));
  }

  gtk_progress_bar_update (GTK_PROGRESS_BAR (progress_bar), 0.0);

  /* unblock GUI                                                  */
  gtk_widget_set_sensitive(top_window, TRUE);

  /* ungray menu items                                            */
  gtk_widget_set_sensitive(menu_plot,    TRUE);
  if (Flags.ProComputed == ON) {
    gtk_widget_set_sensitive(menu_profile,    TRUE);
  }

  return;
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'fit data'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightfit_event (GtkWidget *widget, gpointer *data)
{
  int    WasOn = OFF;             /* flag for animation           */
  int    ErrCode = 0;             /* return status                */

  Flags.WantFit = ON;

  /* block GUI                                                    */
  gtk_widget_set_sensitive(top_window, FALSE);

  /* validate data                                                */
  check_data();

  /* unset animation                                              */
  if (Flags.animate == ON) {
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (t_anim_button),
                                     FALSE);
     Flags.animate = OFF;
     WasOn = ON;
     Flags.plot = ON;
  }

  /* compute                                                      */
  ErrCode = Simplex();
  if (ErrCode == 0) {
    WriteOutput();
  } else {
    make_dialog (_(errmsg[15]));
  }

  gtk_progress_bar_update (GTK_PROGRESS_BAR (progress_bar), 0.0);
  
  /* unblock GUI                                                  */
  gtk_widget_set_sensitive(top_window, TRUE);

  Flags.WantFit = OFF;
  Flags.plot    = OFF;

  /* update with fitted data                                      */
  UpdateGui();

  /* ungray menu items                                            */
  gtk_widget_set_sensitive(menu_plot,    TRUE);
  if (Flags.ProComputed == ON) {
    gtk_widget_set_sensitive(menu_profile,    TRUE);
  }

  if (WasOn == ON) {
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (t_anim_button),
                                     TRUE);
     Flags.animate = ON;
  }
    

  return;  
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'map chi square'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void lightmap_event (GtkWidget *widget, gpointer *data)
{
  int    WasOn = OFF;             /* flag for animation           */
  int    ErrCode = 0;             /* return status                */

  Flags.WantMap = ON;

  /* block GUI                                                    */
  gtk_widget_set_sensitive(top_window, FALSE);

  /* validate data                                                */
  check_data();

  /* unset animation                                              */
  if (Flags.animate == ON) {
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (t_anim_button),
                                   FALSE);
     Flags.plot = ON;
     WasOn = ON;
     Flags.animate = OFF;
  }

  /* compute                                                      */
  ErrCode = ChiMap();
  if (ErrCode != 0) {
    make_dialog (_(errmsg[15]));
  }

  gtk_progress_bar_update (GTK_PROGRESS_BAR (progress_bar), 0.0);
  
  /* unblock GUI                                                  */
  gtk_widget_set_sensitive(top_window, TRUE);

  Flags.WantMap = OFF;
  Flags.plot    = OFF;

  /* ungray menu items                                            */
  gtk_widget_set_sensitive(menu_plot,    TRUE);
  if (Flags.ProComputed == ON) {
    gtk_widget_set_sensitive(menu_profile,    TRUE);
  }

  if (WasOn == ON) {
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (t_anim_button),
                                     TRUE);
     Flags.animate = ON;
  }

  return;  
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'Profiler'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
profiler_event (GtkWidget *widget, gpointer *data)
{
  /* check whether profile computed already                       */
  if (Flags.ProComputed == ON) {
#ifdef _WITH_PGPLOT
    Profiler();
#else
    make_dialog (_(errmsg[14]));
#endif
  } else {
    make_dialog (_(errmsg[16]));
  }

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'Plot Lightcurve'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightcurveplot_event (GtkWidget *widget, gpointer *data)
{
  int store;             /* temporary store plot flag             */

  /* check whether already computed                               */
  if (Flags.IsComputed == ON) {

    store = Flags.plot;
    Flags.plot = TG_graphstore;
    if (Flags.plot == OFF) Flags.plot = ON;

#ifdef _WITH_PGPLOT
    PlotOutput(); 
#else
    make_dialog (_(errmsg[14]));
#endif

    Flags.plot = store;

  } else {
    make_dialog (_(errmsg[17]));
  }

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'Reset Memory'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
reset_event (GtkWidget *widget, gpointer *data)
{
  register int Band;         /* loop variable                     */

#ifdef _WITH_GTK
  if ( Flags.interactive == ON && Flags.parseCL == OFF ) 
    my_appbar_push(_("Clearing data memory"));
#endif

  /* set data count for all passbands to zero                     */
  for ( Band = 0;  Band < (NUM_MAG+2); ++ Band) Flags.Passbands[Band] = 0;

  /* clear data file list                                         */
  ClearList();

  updatepage3 ();

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'visualize geometry'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightgeometry_event (GtkWidget *widget, gpointer *data)
{
  int    ErrCode;       /* exit status                            */
  int store;            /* temporary store visualize flag         */

  store = Flags.visualize;
  Flags.visualize = TG_visualstore;

  /* validate input data                                          */
  check_data();

  /* define geometry                                              */

  if (Flags.fill == OFF) {
     /* THE PRIMARY                                               */
     ErrCode = DefineParam(Primary);
     /* THE SECONDARY                                             */
     DefineParam(Secondary);
  } else {
     /* Overcontact system                                        */
     ErrCode = DefineParamOver();
  }

  if (ErrCode < 2 ) {
#ifdef _WITH_PGPLOT
    PlotGeometry();
#else
    make_dialog (_(errmsg[14]));
#endif
  } else {
    make_dialog (_(errmsg[12]));
  }

  Flags.visualize = store;

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'Roche Slicer'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightslice_event (GtkWidget *widget, gpointer *data)
{
  int    ErrCode;                  /* exit status                 */

  
  /* validate input data                                          */
  check_data();

  /* define geometry                                              */

  if (Flags.fill == OFF) {
     /* THE PRIMARY                                               */
     ErrCode = DefineParam(Primary);
     /* THE SECONDARY                                             */
     DefineParam(Secondary);
  } else {
     /* Overcontact system                                        */
     ErrCode = DefineParamOver();
  }

  if (ErrCode < 2) {
#ifdef _WITH_PGPLOT
    MakeSliceBox(); 
#else
    make_dialog (_(errmsg[14]));
#endif
  } else {
    make_dialog (_(errmsg[12]));
  }

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback function for 'StarView'
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void
lightstarview_event (GtkWidget *widget, gpointer *data)
{
  int    ErrCode;                  /* exit status                 */

  /* validate input data                                          */
  check_data();

  /* define geometry                                              */

  if (Flags.fill == OFF) {
     /* THE PRIMARY                                               */
     ErrCode = DefineParam(Primary);
     /* THE SECONDARY                                             */
     DefineParam(Secondary);
     /* The disk                                                  */
#ifdef HAVE_DISK
     if (Flags.disk == ON) 
       ErrCode = DefineParamDisk();
#endif
  } else {
     /* Overcontact system                                        */
     ErrCode = DefineParamOver();
  }

  if (ErrCode < 2 ) {
#ifdef _WITH_PGPLOT
    MakeVbox();
#else
    make_dialog (_(errmsg[14]));
#endif
  } else {
    make_dialog (_(errmsg[12]));
  }

  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle fitting of spot
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       The spot
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_fit_spot (GtkWidget *widget, gpointer *data)
{
  int  i;                      /* number of spot                  */

  sscanf ((char *) data, "%d", &i);
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    /* button is down                                             */
    FitSpotS[i-10] = ON;

    if ((i < 14) && (SpotActive[0] == ON)) Flags.simplex[i] = ON;
    if ((i < 18) && (i > 13) && (SpotActive[1] == ON)) {
       if   (SpotActive[0] == ON) Flags.simplex[i] = ON;
       else Flags.simplex[i-4] = ON;
    }
    if ((i < 22) && (i > 17) && (SpotActive[2] == ON)) Flags.simplex[i] = ON;
    if ((i < 26) && (i > 21) && (SpotActive[3] == ON)) {
       if   (SpotActive[2] == ON) Flags.simplex[i] = ON;
       else Flags.simplex[i-4] = ON;
    }
         
  } else {

    /* button is up                                               */
    FitSpotS[i-10] = OFF;

    if (i < 14 && SpotActive[0] == ON) Flags.simplex[i] = OFF;
    if ((i < 18) && (i > 13) && (SpotActive[1] == ON)) {
       if   (SpotActive[0] == ON) Flags.simplex[i] = OFF;
       else Flags.simplex[i-4] = OFF;
    }
    if ((i < 22) && (i > 17) && (SpotActive[2] == ON)) Flags.simplex[i] = OFF;
    if ((i < 26) && (i > 21) && (SpotActive[3] == ON)) {
       if   (SpotActive[2] == ON) Flags.simplex[i] = OFF;
       else Flags.simplex[i-4] = OFF;
    }
  }
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle spot 1 on primary active
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_p_spot1 (GtkWidget *widget, gpointer *data)
{
  int i;                  /* loop variable                        */

  if(GTK_TOGGLE_BUTTON (widget)->active) {

    /* we had a first spot before                                 */
    if (TG_P1spot == ON) {
      /* shift up spots to make place                             */
      for ( i=Flags.Spots1; i>0; --i) Spot[Primary][i] = Spot[Primary][i-1];  
      /* increase spot count                                      */
      ++Flags.Spots1;
      /* restore spot                                             */
      Spot[Primary][0] =  SpotStore[Primary][0]; 
      /* restore fit params                                       */
      for (i = 0; i < 4; ++i) Flags.simplex[10+i] = FitSpotS[i];
      if (TG_P2spot == ON && SpotActive[1] == ON) { 
           for (i = 4; i < 8; ++i) Flags.simplex[10+i] = FitSpotS[i];
      }  
    } else {
    /* we had no first spot before                                */
      TG_P1spot = ON;
      /* shift up spots to make place                             */
      for ( i=Flags.Spots1; i>0; --i) Spot[Primary][i] = Spot[Primary][i-1]; 
      /* increase spot count                                      */
      ++Flags.Spots1; 
      /* restore spot                                             */
      Spot[Primary][0] =  SpotStore[Primary][0]; 
      /* restore fit params                                       */
      for (i = 0; i < 4; ++i) Flags.simplex[10+i] = FitSpotS[i];   
      if (TG_P2spot == ON && SpotActive[1] == ON) { 
           for (i = 4; i < 8; ++i) Flags.simplex[10+i] = FitSpotS[i];
      }
    }
    SpotActive[0] = ON;
  } else {

      /* shift down spots                                         */
      for ( i=0; i<Flags.Spots1; ++i) Spot[Primary][i] = Spot[Primary][i+1]; 
      /* decrease spot count                                      */
      if (Flags.Spots1 > 0) --Flags.Spots1;
      /* check fit params                                         */
      for (i = 0; i < 4; ++i) {
             Flags.simplex[10+i] = FitSpotS[i+4];
             Flags.simplex[14+i] = 0;
      }
      SpotActive[0] = OFF;     
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle spot 2 on primary active
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_p_spot2 (GtkWidget *widget, gpointer *data)
{
  int i;                  /* loop variable                        */

  if(GTK_TOGGLE_BUTTON (widget)->active) {

    /* we had a second spot before                                */
    if (TG_P2spot == ON) {
      /* put into second slot if first spot active                */
      if (SpotActive[0] == ON) {
        /* shift up spots to make place                           */
        for (i=Flags.Spots1; i>1; --i) Spot[Primary][i] = Spot[Primary][i-1];
        /* increase spot count                                    */
        ++Flags.Spots1;
        /* restore spot                                           */
        Spot[Primary][1] =  SpotStore[Primary][1]; 
        /* restore fit params                                     */
        for (i = 0; i < 4; ++i) Flags.simplex[14+i] = FitSpotS[4+i];
      } else {
        /* shift up spots to make place                           */
        for ( i=Flags.Spots1; i>0; --i) Spot[Primary][i] = Spot[Primary][i-1];
        /* increase spot count                                    */
        ++Flags.Spots1;
        /* restore spot                                           */
        Spot[Primary][0] =  SpotStore[Primary][1]; 
        /* restore fit params                                     */
        for (i = 0; i < 4; ++i) Flags.simplex[10+i] = FitSpotS[4+i];
      }        

    } else {

      /* we had no second spot before                             */
      TG_P2spot = ON;
      /* increase spot count                                      */
      ++Flags.Spots1; 
      if (SpotActive[0] == ON) {
       /* restore spot                                            */
       Spot[Primary][1] =  SpotStore[Primary][1]; 
       /* restore fit params                                      */
       for (i = 0; i < 4; ++i) Flags.simplex[14+i] = FitSpotS[4+i];   
      } else {
       /* restore spot                                            */
       Spot[Primary][0] =  SpotStore[Primary][1]; 
       /* restore fit params                                      */
       for (i = 0; i < 4; ++i) Flags.simplex[10+i] = FitSpotS[4+i];   
      }
    }
    SpotActive[1] = ON;
           
  } else {

      /* decrease spot count                                      */
      if (Flags.Spots1 > 0) --Flags.Spots1;
      if (SpotActive[0] == ON) {
       /* shift down spots to make place                          */
       for ( i=1; i<Flags.Spots1; ++i) Spot[Primary][i] = Spot[Primary][i+1]; 
       /* check fit params                                        */
       for (i = 0; i < 4; ++i) {
              Flags.simplex[14+i] = 0;
       }
      } else {
       /* shift down spots to make place                          */
       for ( i=0; i<Flags.Spots1; ++i) Spot[Primary][i] = Spot[Primary][i+1]; 
       /* check fit params                                        */
       for (i = 0; i < 8; ++i) {
              Flags.simplex[10+i] = 0;
       }
      }
    SpotActive[1] = OFF;

  }
  return;

}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle spot 1 on secondary active
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_s_spot1 (GtkWidget *widget, gpointer *data)
{
  int i;                  /* loop variable                        */

  if(GTK_TOGGLE_BUTTON (widget)->active) {

    /* we had a first spot before                                 */
    if (TG_S1spot == ON) {
      /* shift up spots to make place                             */
      for ( i=Flags.Spots2; i>0; --i) Spot[Secondary][i]=Spot[Secondary][i-1];
      /* increase spot count                                      */
      ++Flags.Spots2;
      /* restore spot                                             */
      Spot[Secondary][0] =  SpotStore[Secondary][0]; 
      /* restore fit params                                       */
      for (i = 0; i < 4; ++i) Flags.simplex[18+i] = FitSpotS[8+i];
      if (TG_S2spot == ON && SpotActive[3] == ON) { 
           for (i = 4; i < 8; ++i) Flags.simplex[18+i] = FitSpotS[8+i];
      }  
    } else {
    /* we had no first spot before                                */
      TG_S1spot = ON;
      /* shift up spots to make place                             */
      for ( i=Flags.Spots2; i>0; --i) Spot[Secondary][i]=Spot[Secondary][i-1];
      /* increase spot count                                      */
      ++Flags.Spots2; 
      /* restore spot                                             */
      Spot[Secondary][0] =  SpotStore[Secondary][0]; 
      /* restore fit params                                       */
      for (i = 0; i < 4; ++i) Flags.simplex[18+i] = FitSpotS[8+i];   
      if (TG_S2spot == ON && SpotActive[3] == ON) { 
           for (i = 4; i < 8; ++i) Flags.simplex[18+i] = FitSpotS[8+i];
      } 
    }
    SpotActive[2] = ON;
           
  } else {

      /* shift down spots                                         */
      for ( i=0; i<Flags.Spots2; ++i) Spot[Secondary][i]=Spot[Secondary][i+1]; 
      /* decrease spot count                                      */
      if (Flags.Spots2 > 0) --Flags.Spots2;
      /* check fit params                                         */
      for (i = 0; i < 4; ++i) {
             Flags.simplex[18+i] = FitSpotS[i+12];
             Flags.simplex[22+i] = 0;
      }
      SpotActive[2] = OFF;     
       
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle spot 2 on secondary active
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_s_spot2 (GtkWidget *widget, gpointer *data)
{
  int i;                  /* loop variable                        */

  if(GTK_TOGGLE_BUTTON (widget)->active) {

    /* we had a second spot before                                */
    if (TG_S2spot == ON) {
      /* put into second slot if first spot active                */
      if (SpotActive[2] == ON) {
        /* shift up spots to make place                           */
        for (i=Flags.Spots2; i>1; --i) Spot[Secondary][i]=Spot[Secondary][i-1];
        /* increase spot count                                    */
        ++Flags.Spots2;
        /* restore spot                                           */
        Spot[Secondary][1] =  SpotStore[Secondary][1]; 
        /* restore fit params                                     */
        for (i = 0; i < 4; ++i) Flags.simplex[22+i] = FitSpotS[12+i];
      } else {
        /* shift up spots to make place                           */
        for (i=Flags.Spots2; i>0; --i) Spot[Secondary][i]=Spot[Secondary][i-1];
        /* increase spot count                                    */
        ++Flags.Spots2;
        /* restore spot                                           */
        Spot[Secondary][0] =  SpotStore[Secondary][1]; 
        /* restore fit params                                     */
        for (i = 0; i < 4; ++i) Flags.simplex[18+i] = FitSpotS[12+i]; 
      }       

    } else {

      /* we had no second spot before                             */
      TG_S2spot = ON;
      /* increase spot count                                      */
      ++Flags.Spots2; 
      if (SpotActive[2] == ON) {
       /* restore spot                                            */
       Spot[Secondary][1] =  SpotStore[Secondary][1]; 
       /* restore fit params                                      */
       for (i = 0; i < 4; ++i) Flags.simplex[22+i] = FitSpotS[12+i];   
      } else {
       /* restore spot                                            */
       Spot[Secondary][0] =  SpotStore[Secondary][1]; 
       /* restore fit params                                      */
       for (i = 0; i < 4; ++i) Flags.simplex[18+i] = FitSpotS[12+i];   
      }

    }    
    SpotActive[3] = ON;     

  } else {

      /* decrease spot count                                      */
      if (Flags.Spots2 > 0) --Flags.Spots2;
      if (SpotActive[2] == ON) {
       /* shift down spots to make place                          */
       for (i=1; i<Flags.Spots2; ++i) Spot[Secondary][i]=Spot[Secondary][i+1]; 
       /* check fit params                                        */
       for (i = 0; i < 4; ++i) {
              Flags.simplex[22+i] = 0;
       }
      } else {
       /* shift down spots to make place                          */
       for (i=0; i<Flags.Spots2; ++i) Spot[Secondary][i]=Spot[Secondary][i+1]; 
       /* check fit params                                        */
       for (i = 0; i < 8; ++i) {
              Flags.simplex[18+i] = 0;
       }
      }

    SpotActive[3] = OFF;     
  }
  return;
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle simulated annealing
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_anneal (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.anneal = ON;
  } else {

    Flags.anneal = OFF;
  }
  return;
}

#ifdef HAVE_DISK
/******************************************************************
 @package   nightfall
 @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
 @version   1.0
 @short     Toggle accretion disk
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_disk (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.disk = ON;
    gtk_widget_show (e_114);
    gtk_widget_show (orad_label);
    gtk_widget_show (e_115);
    gtk_widget_show (irad_label);
    gtk_widget_show (e_116);
    gtk_widget_show (tilt_label);
    if (Flags.warp == ON) {
      gtk_widget_show (e_117);
      gtk_widget_show (warp_label);
    }
    gtk_widget_show (t_warp_button);
    gtk_widget_show (e_118);
    gtk_widget_show (thick_label);
    gtk_widget_show (e_119);
    gtk_widget_show (hr_label);
    gtk_widget_show (e_120);
    gtk_widget_show (disktmp_label);

    gtk_widget_show (td_button_0);
    gtk_widget_show (td_button_1);
    gtk_widget_show (td_button_2);

    gtk_widget_show (e_130);
    gtk_widget_show (hs_temp_label);
    gtk_widget_show (e_131);
    gtk_widget_show (hs_longitude_label);
    gtk_widget_show (e_132);
    gtk_widget_show (hs_extent_label);
    gtk_widget_show (e_133);
    gtk_widget_show (hs_depth_label);

#ifdef _WITH_OPENGL
    if ( GLWindowOpened == ON ) {
      GLUpdate3d(glArea);
      GLDisplay3d(glArea);
    }
#endif 
  } else {

    Flags.disk = OFF;
    gtk_widget_hide (e_114);
    gtk_widget_hide (orad_label);
    gtk_widget_hide (e_115);
    gtk_widget_hide (irad_label);
    gtk_widget_hide (e_116);
    gtk_widget_hide (tilt_label);
    gtk_widget_hide (t_warp_button);
    gtk_widget_hide (e_117);
    gtk_widget_hide (warp_label);
    gtk_widget_hide (e_118);
    gtk_widget_hide (thick_label);
    gtk_widget_hide (e_119);
    gtk_widget_hide (hr_label);
    gtk_widget_hide (e_120);
    gtk_widget_hide (disktmp_label);

    gtk_widget_hide (td_button_0);
    gtk_widget_hide (td_button_1);
    gtk_widget_hide (td_button_2);

    gtk_widget_hide (e_130);
    gtk_widget_hide (hs_temp_label);
    gtk_widget_hide (e_131);
    gtk_widget_hide (hs_longitude_label);
    gtk_widget_hide (e_132);
    gtk_widget_hide (hs_extent_label);
    gtk_widget_hide (e_133);
    gtk_widget_hide (hs_depth_label);

#ifdef _WITH_OPENGL
    if ( GLWindowOpened == ON ) {
      GLUpdate3d(glArea);
      GLDisplay3d(glArea);
    }
#endif 
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
 @version   1.0
 @short     Toggle warped disk
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_warp (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.warp = ON;
    gtk_widget_show (e_117);
    gtk_widget_show (warp_label);

#ifdef _WITH_OPENGL
    if ( GLWindowOpened == ON ) {
      GLUpdate3d(glArea);
      GLDisplay3d(glArea);
    }
#endif 
  } else {

    Flags.warp = OFF;
    gtk_widget_hide (e_117);
    gtk_widget_hide (warp_label);

#ifdef _WITH_OPENGL
    if ( GLWindowOpened == ON ) {
      GLUpdate3d(glArea);
      GLDisplay3d(glArea);
    }
#endif 
  }
  return;
}
#endif 

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle elliptic orbit
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_elliptic (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.elliptic = ON;
    gtk_widget_show (ecc_button);
    gtk_widget_show (ome_button);
    gtk_widget_show (e_107);
    gtk_widget_show (e_108);
  } else {

    Flags.elliptic = OFF;
    gtk_widget_hide (ecc_button);
    gtk_widget_hide (ome_button);
    gtk_widget_hide (e_107);
    gtk_widget_hide (e_108);
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle asynchroneous rotation (Primary)
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_fratio1 (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.asynchron1 = ON;
    gtk_widget_show (as1_button);
    gtk_widget_show (e_109);
  } else {

    Flags.asynchron1 = OFF;
    gtk_widget_hide (as1_button);
    gtk_widget_hide (e_109);
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle asynchroneous rotation (Secondary)
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_fratio2 (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.asynchron2 = ON;
    gtk_widget_show (as2_button);
    gtk_widget_show (e_110);
  } else {

    Flags.asynchron2 = OFF;
    gtk_widget_hide (as2_button);
    gtk_widget_hide (e_110);
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle blackbody/model atmosphere
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_blackbody (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.blackbody = OFF;
    gtk_widget_show (e_121);
    gtk_widget_show (e_122);
  } else {

    Flags.blackbody = ON;
    gtk_widget_hide (e_121);
    gtk_widget_hide (e_122);
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle fractional visbility ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_fractional (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.fractional = ON;
  } else {

    Flags.fractional = OFF;
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle detailed reflection ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_reflect (GtkWidget *widget, gpointer *data)
{
  char InitString[4];           /* entry string                   */

  if(GTK_TOGGLE_BUTTON (widget)->active) {
    
    gtk_widget_show (ref_label);
    gtk_widget_show (e_113);
    if (TG_reflectstore > 0) { 
         Flags.reflect = TG_reflectstore; 
    } else { 
         Flags.reflect = ON;
         sprintf(InitString, "%3d", Flags.reflect);
         gtk_entry_set_text (GTK_ENTRY (e_113), InitString);
    }
  } else {

    gtk_widget_hide (ref_label);
    gtk_widget_hide (e_113);
    Flags.reflect = OFF;
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle line profile computation ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_lineprofile (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {

    Flags.lineprofile = ON;
  } else {

    Flags.lineprofile = OFF;
  }
  return;
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle animated mode ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_animate (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {
    Flags.animate = ON;
  } else {
    Flags.animate = OFF;
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle hardcopy (ps-file) ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_psfile (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {
    Flags.eps = ON;
  } else {
    Flags.eps = OFF;
  }
  return;
}

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.1
 @short     Toggle use OpenGL ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Discarded
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
#ifdef _WITH_OPENGL
void toggle_opengl (GtkWidget *widget, gpointer *data)
{
  if(GTK_TOGGLE_BUTTON (widget)->active) {
    Flags.use_opengl = ON;
    if ( GLWindowOpened == ON && GLWindowHidden == ON) {
      gtk_widget_show(glWindow);
    } 
  } else {
    Flags.use_opengl = OFF;
    if ( GLWindowOpened == ON ) {
      if (GLPrefWinOpened == TRUE) {
	gtk_widget_destroy (GTK_WIDGET (glPrefsWindow) );
	GLPrefWinOpened = OFF;	
      }

      gtk_widget_hide (glWindow);
      GLWindowHidden = ON;
      /*
      gtk_widget_destroy (GTK_WIDGET (glArea) );
      gtk_widget_destroy (GTK_WIDGET (glWindow) );
      GLWindowOpened = OFF;
      */
    }
  }
  return;
}
#endif

/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle data fitting ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Which parameter to fit ?
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_fit (GtkWidget *widget, gpointer *data)
{
  int  i;   /* index on parameter to fit                          */

  if (data != NULL) {
    sscanf ((char *) data, "%d", &i);
    if(GTK_TOGGLE_BUTTON (widget)->active) {
      Flags.simplex[i] = ON;
    } else {
      Flags.simplex[i] = OFF;
    }
  } else {
    WARNING(_("fit parameter is NULL"));
  }
  return;
}


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Toggle debug options ON/OFF
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)  *data       Which parameter to fit ?
 @return    (void)   
 @heading   Graphical User Interface
*******************************************************************/
void toggle_debug (GtkWidget *widget, gpointer *data)
{
  int  i;    /* index on debug option                             */

  sscanf ((char *) data, "%d", &i);

  if(GTK_TOGGLE_BUTTON (widget)->active) {
    if (i == 1) Flags.debug[WARN] = ON;
    if (i == 2) Flags.debug[BUSY] = ON;
    if (i == 3) Flags.debug[VERBOSE] = ON;
  } else {
    if (i == 1) Flags.debug[WARN] = OFF;
    if (i == 2) Flags.debug[BUSY] = OFF;
    if (i == 3) Flags.debug[VERBOSE] = OFF;
  }
  return;
}

#endif







syntax highlighted by Code2HTML, v. 0.9.1