/*===========================================================================
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
  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 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY

.VERSION
 090825         last modif
 
===========================================================================*/

#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
#include <UxLib.h>

#include <proto_xech.h>


extern int  AppendDialogText(), StringToIndex(), CallbackList();
extern int  AppendDialogTextNoWait();

extern void  InitField(), ImageOpen(), ImageClose();


/* Extended Help Initialisations */

struct exthelp {

char   comm[20];
char   swid[30];
char   text[5000];

} ehelp[] = {

{"ROTATE", "pb_search_plot2", "Spectra must be at standard orientation\n\
The wavelength must increase from left to right\n\
and from bottom to top."},

{"SEARCH", "pb_search_plot6", 
"search for calibration lines in a wavelength calibration echelle \n\
 frame in the space pixel-order. The positions the detected lines \n\
 are stored in the auxiliary table line.tbl"},

{"CALIBR", "pb_calib_disper", 

"           1. Presentation of the methods. \n\
  \n\
            The methods PAIR, ANGLE and TWO-D are interactive and  \n\
            use the command CENTER/MOMENT with option CURSOR to point the \n\
            lines. It is recommended to beginners to read the \n\
            related help and use this command before identify/echelle. \n\
            The three methods can be used if the disperser is a grating. \n\
            Only the method TWO-D can apply if the disperser is a grism. \n\
            In case of initial misidentifications, methods PAIR and \n\
            ANGLE invoke a wavelength calibration diagnosis (see Note 3). \n\
  \n\
            In interactive modes, one must first point all the positions  \n\
            to identify, then provide order number and wavelengths. \n\
  \n\
            In method PAIR, one must recognize two pairs of \n\
            lines in overlapped regions of the spectrum and \n\
            provide the absolute order number of the first \n\
            pointed line and wavelengths for each of the two \n\
            pairs. The geometry of the pairs provide the angle of \n\
            orientation of the spectrum. \n\
  \n\
            In method ANGLE, one identify at least four \n\
            lines anywhere and provide absolute order number of the \n\
            first pointed line and the wavelengths of all lines. The \n\
            angle of orientation of the spectrum is computed analytically. \n\
  \n\
            At the difference of PAIR and ANGLE which involve \n\
            the echelle relation (product order by wavelength as \n\
            a function of the x position), the method TWO-D \n\
            fits from the beginning a bivariate polynomial to \n\
            the identifications. Therefore, it requires more initial \n\
            identifications than the above methods. The minimum number \n\
            is given by (dc + 1)**2 + 1, where dc is the degree of \n\
            the polynomial used to fit the dispersion relation. \n\
  \n\
            Method RESTART must be used only IMMEDIATELY AFTER the \n\
            methods PAIR, ANGLE or TWO-D. It avoids the interactive \n\
            pointing of the lines and enters the program at the step  \n\
            of the identifications. \n\
  \n\
            Method GUESS is not interactive and can be used after \n\
            any calibration by an interactive method. The method GUESS \n\
            requires the name of a previously saved echelle session, which  \n\
            process tables will be used to start automatically the \n\
            lines identification. The shift between the two sets of  \n\
            calibration lines is estimated by cross-correlation, unless  \n\
            its value is provided (see parameter guess). \n\
  \n\
            Method ORDER allows to restart only the single-order \n\
            solutions with a different parameter wlctol. "},

{"REBINS", "pb_search_plot17",
"Rebin extracted orders into linear wavelength steps. The \n\
frame is converted from the space pixel-order into the space \n\
wavelength-order"},

{"ORDERS", "pb_search_plot5", 
"Search for order positions in a 2-D echelle spectrum. The positions  \n\
 of points located in order and in interorder space are stored  \n\
 in an auxiliary table, named order. The order definition by  \n\
 Hough transform is more automatic and requires for simple cases \n\
 no parameters"},

{"BACKGR", "pb_search_plot1", 
"Compute the background of the echelle raw spectrum in the \n\
 sampling space pixel-pixel. This command requires the table \n\
 Background values are estimated at reference positions  \n\
 between the orders and interpolated either by smoothing  \n\
 spline or bivariate polynomial interpolation. Commands \n\
 SCAN/ECHELLE and SELECT/BACKGROUND can be used before."},

{"EXTRAS", "pb_search_plot18", 
"Extract echelle orders. Position of the orders are defined \n\
 in the auxiliary table order.tbl, generated by the methods \n\
 STD, COMPLEMENT or HOUGH (panel Order Definition). The extraction \n\
 can be performed in mode Average or Optimal"},

{"SKYBKG", "pb_search_plot20", 
" 1. Definition of sky limits \n\
   \n\
  The limits of the sky window(s) are defined directly \n\
  or interactively. 1 or 2 sky windows can be defined.  \n\
  A cross-order profile is plotted in the graphic window \n\
  and the program expects two position clicked for 1 window \n\
  and four position cliked for two windows. The position \n\
  of the cross-order profile plotted is set automatically \n\
  (POSSKY=AUTO), indicated numerically (POSSKY=order,column) \n\
  or defined interactively by a click in the display window \n\
  (POSSKY=CURSOR). The cross-order profile is plotted over \n\
  one order width on each side (parameter half-width). \n\
 \n\
  2. Extraction of the sky and correction \n\
 \n\
  An extracted sky spectrum is provided, similar to extracted echelle spectra. \n\
  This extracted can be subtracted from the extracted object spectrum for \n\
  sky background correction. "},

{"FLAT",   "pb_search_plot21", 
" 1. Preparation of the flat-field \n\
 \n\
     a) optionally subtract background from flat-field image \n\
        If the descriptor BACKGROUND exists in flat-field image, \n\
        the background step will be skipped. \n\
        The corrected image, i.e. the flat-field corrected \n\
        from its background, is stored as [correct] \n\
  \n\
     b) compute an approximation to the blaze profile for the  \n\
        flat-field. The order-by-order blaze profiles are stored  \n\
        as [blaze] \n\
  \n\
     The output images are used for flat-field correction. \n\
  \n\
     The background is approximated by spline polynomials \n\
     fitted to points located in the interorder space. \n\
     These points are defined by the command DEFINE/ECHELLE \n\
     Parameters can be defaulted to the current session values, \n\
     as displayed by SHOW/ECHELLE. \n\
 \n\
  2. Flat-Field Correction \n\
 \n\
     The flat-field correction is performed in wavelength space during \n\
     the reduction. "}, 

{"RESPON", "pb_search_plot22", 
" Compute instrument response by comparing the extracted \n\
 orders of the standard star to a table of fluxes."},

{"MERGER", "pb_search_plot29", 
"Produces a 1-D spectrum, from the order by order file generated \n\
 by the Resampling command"},

};

void GetExtendedHelp(w)
Widget w;
{
int i;

UxPopupInterface(UxFindSwidget("HelpShell"), no_grab);

for(i=0; i<10; i++) {
  if (w == UxGetWidget(UxFindSwidget(ehelp[i].swid)))
      UxPutText(UxFindSwidget("tx_extended_help"), ehelp[i].text);
  }
}

void MidasCommand(sw)
Widget sw;

{
char command[100];

  /* Scan Limits  */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search2"))) {
      strcpy(command, "SCAN/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha7")));
      strcat(command, " CURSOR");
      AppendDialogText(command);
      AppendDialogText("SYNCHRO/ECHELLE");
      ImageOpen();
      InitField(StringToIndex("tf_alpha2"));
      InitField(StringToIndex("tf_alpha4"));
      InitField(StringToIndex("tf_thres3"));
      ImageClose();
  }

  /* Order Definition */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search3"))) {
      strcpy(command, "CALIBRATE/ECHELLE ? ? ORDER");
      AppendDialogText(command);
      AppendDialogText("SYNCHRO/ECHELLE");
      ImageOpen();
      InitField(StringToIndex("tf_thres1"));
      InitField(StringToIndex("tf_thres5"));
      ImageClose();
  }

  /* Load Echelle */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot3"))) {
      strcpy(command, "LOAD/ECHELLE");
      AppendDialogTextNoWait(command);       
  }

  /* Save Echelle */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot4"))) {
      strcpy(command, "SAVE/ECHELLE sess");
      AppendDialogTextNoWait(command);       
  }

  /* Arc Line Extraction and Search */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search1"))) {
      strcpy(command, "EXTRACT/ECHELLE {WLC} &e; SEARCH/ECHEL &e");
      AppendDialogTextNoWait(command);
  }

  /* Load Search  */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot7"))) {
       sprintf (command, "DISPLAY/ECHE {WLC} ; LOAD/SEARCH");
      AppendDialogTextNoWait(command);       
  }

  /* Search Save  */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot8"))) {
      strcpy(command, "SAVE/ECHELLE sess");
      AppendDialogTextNoWait(command);       
  }


  /* WLC Calibration  */
  if (sw == UxGetWidget(UxFindSwidget("pb_calib_calibrate"))) {
      strcpy(command, "IDENT/ECHELLE ");
      AppendDialogTextNoWait(command);       
  }

  /* Plot Residuals */
  if (sw == UxGetWidget(UxFindSwidget("pb_calib_resid"))) {
       sprintf (command, "PLOT/RESIDUALS");
      AppendDialogTextNoWait(command);       
  }

  /* Rebinned WLC */
  if (sw == UxGetWidget(UxFindSwidget("pb_calib_spec"))) {
      strcpy(command, "EXTRACT/ECHELLE {WLC} &w; REBIN/ECHELLE &w &r; DISPLAY/ECHELLE &r");
      AppendDialogTextNoWait(command);       
  }

  /* Background Panel : Subtract Background */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search6"))) {
      strcpy(command, "SUBTRACT/BACK ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha17")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha18")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha19")));
      AppendDialogTextNoWait(command);       
  }

  /* Show Positions */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot9"))) {
      strcpy(command, "DISPLAY/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha17")));
      strcat(command, " ; SET/ECHE BKGVISU = YES; LOAD/ECHELLE");
      AppendDialogTextNoWait(command);       
  }

  /* Select Positions */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot10"))) {
      strcpy(command, "SELECT/BACKGR ");
      AppendDialogTextNoWait(command);       
  }

  /* Plot Background */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot12"))) {
      sprintf(command, "GRAPH/SPEC; SET/GRAPH YAXIS=%s,%s;",
         UxGetText(UxFindSwidget("tf_alpha21")), UxGetText(UxFindSwidget("tf_alpha20")));
      strcat(command, "PLOT/COLUMN ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha17")));
      strcat(command, " @500 ; OVER/COLUMN  ");
      strcat(command, UxGetText(UxFindSwidget("tf_alpha18")));
      strcat(command, " @500");
      AppendDialogTextNoWait(command);       
  }

  /* Extract Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search7"))) {
      strcpy(command, "EXTRACT/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres6")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres7")));
      AppendDialogTextNoWait(command);       
  }

  /* Plot Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot13"))) {
      strcpy(command, "PLOT/ECHELLE  ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres7")));
      strcat(command, " 1,{echord(1)}");
      AppendDialogTextNoWait(command);       
  }

  /* Defines interactively the limits of the sky window */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search8"))) {
      strcpy(command, "DEFINE/SKY ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres9")));
      if (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("toggleButton16"))) == TRUE)  strcat(command," 1 ");
      else strcat(command, " 2 ");
      strcat(command, " CURSOR");
      AppendDialogText(command);       
      AppendDialogText("SYNCHRO/ECHELLE");
      ImageOpen();
      InitField(StringToIndex("tf_alpha22"));
      InitField(StringToIndex("tf_alpha23"));
      InitField(StringToIndex("tf_alpha24"));
      InitField(StringToIndex("tf_alpha25"));
      ImageClose();
  }


  /* Extract Sky  */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search9"))) {
      strcpy(command, "EXTRACT/SKY  ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres9")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres10")));
      if (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("toggleButton19"))) == TRUE)  strcat(command," FILTER");
      else strcat(command," AVERAGE");
      AppendDialogTextNoWait(command);       
  }


  /* Plot Sky Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot13"))) {
      strcpy(command, "PLOT/ECHELLE  ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres10")));
      strcat(command, " 1,{echord(1)}");
      AppendDialogTextNoWait(command);       
  }

  /* Rebin Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_rebin_rbr"))) {
      strcpy(command, "REBIN/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_rebstrt")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_rebend")));
      AppendDialogTextNoWait(command);       
  }

  /* Plot Rebinned Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_rebin_plot"))) {
      strcpy(command, "PLOT/ECHELLE  ");
      strcat(command, UxGetText(UxFindSwidget("tf_rebend")));
      strcat(command, " 1,{echord(1)}");
      AppendDialogTextNoWait(command);       
  }


  /* Flat-Field Computation */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search10"))) {
      strcpy(command, "FLAT/ECHELLE ");
      AppendDialogText(command); 
      AppendDialogText("SYNCHRO/ECHELLE");
      ImageOpen();
      InitField(StringToIndex("toggleButton2"));
      ImageClose();
  }

  /* Plot Blaze Function */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot24"))) {
      strcpy(command, "PLOT/ECHELLE {BLAZE} 1,{ECHORD(1)}");
      AppendDialogTextNoWait(command);       
  }


  /* Chromatic Response */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search12"))) {
      strcpy(command, "RESPONSE/ECHELLE ");
      AppendDialogTextNoWait(command);       
  }

  /* Plot Blaze Function */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot23"))) {
      strcpy(command, "PLOT/ECHELLE {RESPONSE} 1,{ECHORD(1)}");
      AppendDialogTextNoWait(command);       
  }


  /* Merge Orders */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_search13"))) {
      strcpy(command, "MERGE/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres8")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres11")));
      AppendDialogTextNoWait(command);       
  }

  /* Plot Overlaps */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot25"))) {
      strcpy(command, "MERGE/ECHELLE ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres8")));
      strcat(command, " ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres11")));
      AppendDialogTextNoWait(command);       
  }

  /* Plot Spectrum */
  if (sw == UxGetWidget(UxFindSwidget("pb_search_plot28"))) {
      strcpy(command, "SET/GRAPH; PLOT ");
      strcat(command, UxGetText(UxFindSwidget("tf_thres11")));
      AppendDialogTextNoWait(command);       
  }


  /* Reduce Main Batch  */
  if (sw == UxGetWidget(UxFindSwidget("pb_main_batch"))) {
       WGet_selection();
       WProcess_table("EProcess.tbl");
       sprintf(command,"EXECUTE/TABLE EProcess.tbl REDUCE/ECHELLE [:INPUT] [:OUTPUT]");
       AppendDialogTextNoWait(command);
   }


  /* Rotate Main Batch */
  if (sw == UxGetWidget(UxFindSwidget("pb_main_ident"))) {
       if (WGet_selection() > 0) {
          WProcess_table("EProcess.tbl");
          sprintf(command,"EXECUTE/TABLE EProcess.tbl ROTATE/ECHELLE [:INPUT] [:OUTPUT]");
          AppendDialogTextNoWait(command);       
	}
       else
          UxPutText(UxFindSwidget("shelp_main"), "*** No File Selected: No Action ***");
  }

  /* Load Orders Main Batch */
  if (sw == UxGetWidget(UxFindSwidget("pb_main_batch1"))) {
       if (WGet_selection() > 0) { 
          sprintf(command, "DISPLAY/ECHELLE %s; LOAD/ECHELLE", WGet_First());
          AppendDialogTextNoWait(command);       
	}
       else
          UxPutText(UxFindSwidget("shelp_main"), "*** No File Selected: No Action ***");
  }


  /* Plot Spectrum Main Batch */
  if (sw == UxGetWidget(UxFindSwidget("pb_main_batch2"))) {
      strcpy(command, "SAVE/ECHELLE sess");
      AppendDialogTextNoWait(command);       
  }

}






















