/* 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.              */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Light.h"

#ifdef  _WITH_PGPLOT
#ifndef _WITH_GNUPLOT
#include "cpgplot.h"
#endif
#endif



#ifdef  _WITH_PGPLOT

#ifdef _WITH_GTK

static  char the_printer[256+1];
static  char the_file[256+1];
static  int  lpr_flag = 1;
static  GtkWidget   *etr_f;
static  GtkWidget   *etr_p;
static  GtkWidget   *label_f;
static  GtkWidget   *label_p;

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Do the printing an destroy the Printer dialog
 @param     (GtkWidget) *widget  Discarded
 @param     (gpointer)  *data    Widget to destroy
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void printer_doit (GtkWidget *widget, gpointer *data)
{
  char print_command[1024];

  if ( (lpr_flag == 0) && (strcmp(the_file, Out_Plot_File) != 0) ) { 
    sprintf(print_command, "cp %s %s", Out_Plot_File, the_file);
    system(print_command);
  } else if (lpr_flag != 0) {
    sprintf(print_command, "%s %s", the_printer, Out_Plot_File);
    system(print_command);
  }
  gtk_widget_destroy (GTK_WIDGET (data) );
  return;
}

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback for print command entry
 @param     (GtkWidget) *widget  Discarded
 @param     (GtkWidget) *entry      The entry text
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void pent_printer (GtkWidget *widget, GtkWidget *entry)
{
  const gchar *entry_text;

  entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
  if (strlen(entry_text) < 256) sprintf(the_printer, "%s", entry_text);
  return;
}

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Callback for filename entry
 @param     (GtkWidget) *widget  Discarded
 @param     (GtkWidget) *entry      The entry text
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void pent_file (GtkWidget *widget, GtkWidget *entry)
{
  const gchar *entry_text;

  entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
  if (strlen(entry_text) < 256) sprintf(the_file, "%s", entry_text);
  return;
}

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Destroy the Printer dialog
 @param     (GtkWidget) *widget  Discarded
 @param     (gpointer)  *data    Widget to destroy 
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void delete_printer (GtkWidget *widget, gpointer *data)
{
  gtk_widget_destroy (GTK_WIDGET (data) );
  return;
}

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Select file/printer 
 @param     (GtkWidget) *widget     Discarded
 @param     (gpointer)      *data   Flag Printer/File
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void printer_sel (GtkWidget *widget, gpointer *data)
{
  int flag;

  /* toggle one button == toggle the other as well, so only
     act on the active one */
  if (! GTK_TOGGLE_BUTTON(widget)->active)
     return;

  /* 1 = Printer, 0 = File */
  sscanf ((char *) data, "%d", &flag);
  if (flag == 1) {
    lpr_flag = 1;
    gtk_widget_set_sensitive(etr_f,    FALSE);
    gtk_widget_hide(etr_f);
    gtk_widget_show(etr_p);
    gtk_widget_hide(label_f);
    gtk_widget_show(label_p);
    gtk_widget_set_sensitive(etr_p,    TRUE);
  } else {
    lpr_flag = 0;
    gtk_widget_set_sensitive(etr_p,    FALSE);
    gtk_widget_hide(etr_p);
    gtk_widget_show(etr_f);
    gtk_widget_hide(label_p);
    gtk_widget_show(label_f);
    gtk_widget_set_sensitive(etr_f,    TRUE);
  }
  return;
}

/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     Interactive line profile display
 @param     (void) 
 @return    (void) 
 @heading   Plotting
 ****************************************************************************/
static void printer_dialog ()
{
  GtkWidget   *label;
  GtkWidget   *button;
  GtkWidget   *vbox;
  GtkWidget   *hbox;
  GtkWidget   *frame;
  /* GtkWidget   *table; */
  GtkWidget   *separator;
  GtkWidget   *printer_window;
  GSList      *group;

  if (NULL != getenv("PRINTER")) {
    if (strlen(getenv("PRINTER")) < 256) 
	sprintf(the_printer, "lpr -P%s", getenv("PRINTER"));
  } else {
    sprintf(the_printer, "lpr ");
  }

  sprintf(the_file, "%s", Out_Plot_File);
	
  
  printer_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize (printer_window, 360, 240);
  gtk_window_set_position(GTK_WINDOW(printer_window), GTK_WIN_POS_MOUSE); 
  gtk_window_set_policy (GTK_WINDOW(printer_window), TRUE, TRUE, FALSE);  
  gtk_signal_connect (GTK_OBJECT (printer_window), "destroy",
                        (GtkSignalFunc) delete_printer, 
                         GTK_WIDGET (printer_window));
  gtk_window_set_title (GTK_WINDOW (printer_window), _("Print") );
  gtk_container_set_border_width (GTK_CONTAINER (printer_window), 0);

  frame = gtk_frame_new (_("Print") );
  gtk_container_add (GTK_CONTAINER (printer_window), frame);
  gtk_container_set_border_width(GTK_CONTAINER(frame), 2);
  gtk_widget_show (frame);

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (frame), vbox);
  gtk_widget_show (vbox);

  hbox = gtk_hbox_new (TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  gtk_widget_show (hbox);

  label = gtk_label_new (_("Print to:") );
  gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
  gtk_widget_show (label);

  button = gtk_radio_button_new_with_label (NULL, _("Printer") );
  if (lpr_flag == 1) 
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) printer_sel,
                      (gpointer) "1");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  gtk_widget_show (button);
  
  group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
  button = gtk_radio_button_new_with_label(group, _("File") );
  if (lpr_flag == 0) 
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) printer_sel,
                      (gpointer) "0");
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
  gtk_widget_show (button);

  hbox = gtk_hbox_new (TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  gtk_widget_show (hbox);

  label_p = gtk_label_new (_("Print command:") );
  gtk_box_pack_start (GTK_BOX (hbox), label_p, TRUE, TRUE, 0);
  gtk_widget_show (label_p);

  etr_p = gtk_entry_new_with_max_length (256);
  gtk_signal_connect(GTK_OBJECT(etr_p), "changed",
		     GTK_SIGNAL_FUNC(pent_printer),
		     etr_p);
  gtk_entry_set_text (GTK_ENTRY (etr_p), the_printer);
  gtk_entry_select_region (GTK_ENTRY (etr_p),
			   0, 255);
  gtk_box_pack_start (GTK_BOX (hbox), etr_p, TRUE, TRUE, 0);
  gtk_widget_show (etr_p);

  hbox = gtk_hbox_new (TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  gtk_widget_show (hbox);

  label_f = gtk_label_new (_("Filename:") );
  gtk_box_pack_start (GTK_BOX (hbox), label_f, TRUE, TRUE, 0);
  gtk_widget_show (label_f);

  etr_f = gtk_entry_new_with_max_length (256);
  gtk_signal_connect(GTK_OBJECT(etr_f), "changed",
		     GTK_SIGNAL_FUNC(pent_file),
		     etr_f);
  gtk_entry_set_text (GTK_ENTRY (etr_f), the_file);
  gtk_entry_select_region (GTK_ENTRY (etr_f),
			   0, 255);
  gtk_box_pack_start (GTK_BOX (hbox), etr_f, TRUE, TRUE, 0);
  gtk_widget_show (etr_f);

  separator = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (vbox), separator, TRUE, TRUE, 0);
  gtk_widget_show (separator);

  hbox = gtk_hbox_new (TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  gtk_widget_show (hbox);

#ifdef USING_GTK2
  button = gtk_button_new_from_stock(GTK_STOCK_OK);
#else
  button = gtk_button_new_with_label (_("Print"));
#endif
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) printer_doit,
                      GTK_WIDGET (printer_window));
  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);

#ifdef USING_GTK2
  button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
#else
  button = gtk_button_new_with_label (_("Cancel"));
#endif
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) delete_printer,
                      GTK_WIDGET (printer_window));
  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);


  if (lpr_flag == 1) {
    gtk_widget_set_sensitive(etr_f,    FALSE);
    gtk_widget_hide(etr_f);
    gtk_widget_show(etr_p);
    gtk_widget_hide(label_f);
    gtk_widget_show(label_p);
    gtk_widget_set_sensitive(etr_p,    TRUE);
  } else {
    gtk_widget_set_sensitive(etr_p,    FALSE);
    gtk_widget_hide(etr_p);
    gtk_widget_show(etr_f);
    gtk_widget_hide(label_p);
    gtk_widget_show(label_f);
    gtk_widget_set_sensitive(etr_f,    TRUE);
  }

  gtk_widget_show (printer_window);

  return;
}
#endif  /* _WITH_GTK */


/******************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.0
 @short     End plot, redirect to printer if required
 @param     (void)  
 @return    (void)    
 @heading   Plotting
*******************************************************************/
void my_cpgend()
{
    cpgend();
#ifdef _WITH_GTK
    if ( Flags.interactive == ON) printer_dialog();
#endif
    return;
}


/****************************************************************************
 @package   nightfall
 @author    Rainer Wichmann (rwichman@lsw.uni-heidelberg.de)
 @version   1.37
 @short     Visualize the geometry
 @param     (void) 
 @return    (void)   
 @heading   Light Curve
 ****************************************************************************/
void PlotGeometry()
{
  long   i, j, k;                            /* loop counter                */
  float  *Xplot, *Yplot;                     /* plot arrays                 */
  float  RocheXYArray[120][180];             /* 2d potential array          */
  float  x, y;                               /* x,y positions               */ 
  float  q, f = 1.0;                         /* mass ratio, async rotation  */
  float  cont_levels[6];                     /* levels for contour plot     */
  int    Ncont;                              /* # of contour levels         */
  int    ErrCode;                            /* exit status of subroutines  */

  float  transform[6] = {                    /* transformation matrix       */
    -1.0-0.5*(1.0/60.),  
    (1.0/60.),        
    0, 
    -1.0-0.5*(1.0/60.),  
    0, 
    (1.0/60.)
  };
  float  *a_ptr = &RocheXYArray[0][0];       /* pointer to potential array  */

  char   file_out[256+4];                    /* ps output file              */

  sprintf(file_out, "%s%s", Out_Plot_File, "/CPS");

  /* ---------------------- initialize -----------------------------------  */

  Xplot = malloc(2*MAXELEMENTS*sizeof(float));
  Yplot = malloc(2*MAXELEMENTS*sizeof(float));

  if (Xplot == NULL || Yplot == NULL)
#ifdef _WITH_GTK
    {
      if (Flags.interactive == ON) {
        free(Xplot);
        free(Yplot);
        make_dialog(_(errmsg[0]));
        return;
      } else 
	nf_error(_(errmsg[0]));
    }
#else
    nf_error(_(errmsg[0]));
#endif


  /*  if (  Flags.IsComputed == OFF ) { Okt 20 16:47:29 MEST 1999 */

#ifdef _WITH_GTK
    if (Flags.interactive == ON) 
       check_data();
#endif

    if (Flags.fill == OFF) {
       /* THE PRIMARY                                                       */
       ErrCode = DefineParam(Primary);
       if (ErrCode == 8) {
         WARNING(_("Could not define Primary geometry"));
         return;
       }
       /* THE SECONDARY                                                     */
       DefineParam(Secondary);
       if (ErrCode == 8) {
         WARNING(_("Could not define Secondary geometry"));
         return;
       }
    } else {
       /* Overcontact system                                                */
       ErrCode = DefineParamOver();
       if (ErrCode == 8) {
         WARNING(_("Could not define stellar geometry"));
         return;
       }
    }

    EffectiveWavelength(Primary);
    EffectiveWavelength(Secondary);
#ifdef HAVE_DISK
    /* I think it is needed for the Disk here MPR 13.09.01 */
    EffectiveWavelength(Disk);
#endif

    /* THE PRIMARY                                                          */
    ErrCode = DivideSurface(Primary); 
       if (ErrCode == 8) {
         WARNING(_("Could not define Primary surface"));
         return;
       }
    /* THE SECONDARY                                                        */
    ErrCode = DivideSurface(Secondary);
       if (ErrCode == 8) {
         WARNING(_("Could not define Secondary surface"));
         return;
       }
  /*  } Okt 20 16:47:29 MEST 1999 */


  q = Binary[Primary].Mq;
  if (Flags.asynchron1 == ON) f = Binary[Primary].Fratio;
  for (i = 0; i < 120; ++i) {
    for (j = 0; j < 180; ++j) {
       y = -1.0 + (i/60.0);
       x = -1.0 + (j/60.0);
       RocheXYArray[i][j] = -RocheXYPrimary(x, y, q, f);
    }
  }
  cont_levels[0] = -Binary[Primary].RCLag1;
  cont_levels[1] = -Binary[Primary].RCLag2;
  cont_levels[2] = -Binary[Primary].RCLag3;
  cont_levels[3] = -Binary[Primary].RochePot;

  RochePot = 0.0;
  Mq       = Binary[Primary].Mq;
  cont_levels[4] = -RochePerpendSecond(Binary[Secondary].Radius);
  /* cont_levels[4] = -Binary[Secondary].RochePot; */

  Ncont = 5;

  if (Flags.eps == OFF) {
    if(cpgopen("/XSERVE") != 1)
#ifdef _WITH_GTK
      {
        if (Flags.interactive == ON) { 
          free(Xplot);
          free(Yplot);
          make_dialog (_(errmsg[2]));
          return;
	} else 
	  nf_error(_(errmsg[2]));
      }
#else
      nf_error(_(errmsg[2]));
#endif
  } else {
    if(cpgopen(file_out) != 1)
#ifdef _WITH_GTK
      {
        if (Flags.interactive == ON) {
          free(Xplot);
          free(Yplot);
          make_dialog (_(errmsg[1]));
          return;
	} else 
	  nf_error(_(errmsg[1]));
      }
#else
      nf_error(_(errmsg[1]));
#endif
    ++Flags.eps;
  }

#ifdef _WITH_GNUPLOT
  gnu_start();
#endif


  /* ---------------------  the stars           -------------------------- */

  if (Flags.visualize == 1) { 

    cpgscf(2); cpgslw(1); cpgsch(1.6);
    cpgsvp(0.1,0.9,0.1,1.0);
    cpgwnad(-0.7, 1.7, -0.7, 0.7);
#ifdef _WITH_GNUPLOT
    cpgbox("BCNST", 0.5,0, "BCNST", 0.5, 0);
#else
    cpgbox("BCNST", 0, 0, "BCNST", 0, 0);
#endif
    cpgsch(0.1); cpgslw(1);
    k = 0;
    for (i = 0; i < Binary[Primary].NumElem; ++i) {
      if (Surface[Primary][i].mu >= 0) {
	Xplot[k] = Surface[Primary][i].lambda;
	Yplot[k] = Surface[Primary][i].nu;
	++k;
      }
    }

    for (i = 0; i < Binary[Secondary].NumElem; ++i) {
      if (Surface[Secondary][i].mu >= 0) {
	Xplot[k] = 1.0-Surface[Secondary][i].lambda;
	Yplot[k] = Surface[Secondary][i].nu;
	++k;
      }
    }  
    cpgpt(k, Xplot, Yplot, 17);

    if (Flags.eps != OFF) my_cpgend();
    else cpgend();
  }


  /* ---------------------  the contour plot    -------------------------- */

  if (Flags.visualize == 3) { 

    cpgscf(2); cpgslw(1); cpgsch(1.6);
    cpgsvp(0.1,0.9,0.1,1.0);
    cpgwnad(-1., 2., -1.0, 1.0);
    cpglab(_("X"), _("Y"), _("Roche Potential") );
#ifdef _WITH_GNUPLOT
    cpgbox("BCNST", 0.5, 0, "BCNST", 0.5, 0);
#else
    cpgbox("BCNST", 0, 0, "BCNST", 0, 0);
#endif
    cpgcont(a_ptr, 180, 120, 1, 180, 1, 120,
	    cont_levels, (-Ncont), transform); 
    if (Flags.eps != OFF) my_cpgend();
    else cpgend();
    
  }

#ifndef _WITH_GNUPLOT

  /* ---------------------  the potential image    ----------------------- */

  if (Flags.visualize == 2) { 
    cpgscf(2); cpgslw(1); cpgsch(1.6);
    cpgsvp(0.1,0.9,0.1,1.0);
    cpgwnad(-0.7, 1.7, -1.0, 1.0);
    cpglab(_("X"), _("Y"), _("Roche Potential") );
    cpgbox("BCNST", 0,0, "BCNST", 0,0);
    cpgimag(a_ptr, 180, 120, 1, 180, 1, 120,
	    -10., -0., transform);
    cpgwedg("R", 0.5, 4., -0., -10., " ");
    if (Flags.eps != OFF) my_cpgend();
    else cpgend();
  }

  /* ---------------------  three in one    ------------------------------ */

  if (Flags.visualize == 4) {
  
    cpgsubp(1,3); 
    cpgpage();
    cpgscf(2); cpgslw(1); cpgsch(1.6);
    cpgsvp(0.1,0.9,0.0,0.9);
    cpgwnad(-1.0, 2.0, -1.0, 1.0);
    cpgbox("BCST", 0, 0, "BCNST", 0, 0);
    cpgimag(a_ptr, 180, 120, 1, 180, 1, 120,
	    -10., -0., transform);
    cpgwedg("R", 1., 5., -0., -10., " ");

    cpgpage();
    cpgscf(2); cpgslw(1); cpgsch(1.6);
    cpgsvp(0.1,0.9,0.1,1.0);
    cpgwnad(-1.0, 2.0, -1.0, 1.0);
    cpgbox("BCNST", 0,0, "BCNST", 0,0);
    cpgcont(a_ptr, 180, 120, 1, 180, 1, 120,
	    cont_levels, (-Ncont), transform); 

    cpgpage();
    cpgsvp(0.1,0.9,0.1,1.0);
    cpgwnad(-1.0, 2.0, -1.0, 1.0);
    cpgbox("BCNST", 0,0, "BCNST", 0,0);
    cpgsch(0.1); cpgslw(1);
    k = 0;
    for (i = 0; i < Binary[Primary].NumElem; ++i) {
      if (Surface[Primary][i].mu >= 0) {
	Xplot[k] = Surface[Primary][i].lambda;
	Yplot[k] = Surface[Primary][i].nu;
	++k;
      }
    }

    for (i = 0; i < Binary[Secondary].NumElem; ++i) {
      if (Surface[Secondary][i].mu >= 0) {
	Xplot[k] = 1.0-Surface[Secondary][i].lambda;
	Yplot[k] = Surface[Secondary][i].nu;
	++k;
      }
    }  
    cpgpt(k, Xplot, Yplot, 17);
    if (Flags.eps != OFF) my_cpgend();
    else cpgend();
  }

#endif

  free(Xplot);
  free(Yplot);
  return;

}

#endif




syntax highlighted by Code2HTML, v. 0.9.1