/*===========================================================================
  Copyright (C) 1993-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
===========================================================================*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* .IDENT       callback.c                                 */
/* .AUTHORS     Cristian Levin   (ESO/La Silla)            */
/* .KEYWORDS    XIrspec                                    */
/* .PURPOSE                                                */
/* .VERSION     1.0  Package Creation  27-OCT-1993         

    090828	last modif				   */
/* ------------------------------------------------------- */

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

#include <gl_defs.h>
#include <xm_defs.h>
#include <UxLib.h>
#include <irspec_defs.h>
#include <irspec_comm.h>

#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>

#include <midas_def.h>



#define BADPIX_OBJ	0
#define BADPIX_SKY	1
#define BADPIX_STSTAR	2
#define BADPIX_STSKY	3


extern int AppendDialogText();
extern int GetRespCoords(), GetCoords();

extern void IrspecSave(), WriteKeyword();




static char CalibObj[MAXLINE]; 

static char CoordsTable[MAXLINE] = "dummy_extr.tbl";
static int Lowsky[2], Uppsky[2], Objlim[2];

void PopupIrspec();
 
/******************************************************************
                      Callback procedures
 ******************************************************************/

void MainBadpixCallback()
{
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_badpix_table")), BADPIX_TABLE);
    strcpy(BadpixTable, BADPIX_TABLE);
    WriteKeyword(BadpixTable, K_BADPIX);

    TOGGLE_STATE("rb_badpix_obj", True, False);
    TOGGLE_STATE("rb_badpix_sky", False, False);
    TOGGLE_STATE("rb_badpix_ststar", False, False);
    TOGGLE_STATE("rb_badpix_stsky", False, False);
}

void MainFlatCallback()
{
    char *input;
    char output[MAXLINE];
    int i;

    input = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_flat")));
    for ( i = 0; input[i] != '.' && input[i] != '\0'; i++ )
	;
    input[i] = '\0';
    sprintf(output, "%s_flat", input);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_file_dialog")), output);

    DialogType = DIALOG_FLAT;
    SET_DIALOG_PROMPT("Normalized flat frame :");
    PopupIrspec("file_dialog");

    XtFree(input);
}

void MainStandardCallback()
{
    char *ststar, *object, *flux_table;
    char s[MAXLINE], resp[MAXLINE], ref[MAXLINE];
    int i;

    ststar = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_ststar")));
    for ( i = 0; ststar[i] != '.' && ststar[i] != '\0'; i++ )
	;
    ststar[i] = '\0';
    object = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_object")));
    for ( i = 0; object[i] != '.' && object[i] != '\0'; i++ )
	;
    object[i] = '\0';

    sprintf(resp, "%s_resp", ststar);
    sprintf(ref, "%s_ref", object);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_std_resp")), resp);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_std_ref")), ref);

    flux_table = XmTextGetString(UxGetWidget(UxFindSwidget("tf_flux_out")));
    if ( flux_table[0] != '\0' )
    	XmTextSetString(UxGetWidget(UxFindSwidget("tf_std_flux")), flux_table);

    sprintf(s, "%s %s %s", C_COPY_IMA, object, ref);
    AppendDialogText(s);

    PopupIrspec("StandardShell");

    XtFree(ststar);
    XtFree(object);
    XtFree(resp);
}

void MainObjectCallback()
{
    char *resp, *object;
    char s[MAXLINE], ref[MAXLINE], out_flux[MAXLINE];
    int i;

    object = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_object")));
    for ( i = 0; object[i] != '.' && object[i] != '\0'; i++ )
	;
    object[i] = '\0';

    sprintf(ref, "%s_ref", object);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_obj_ref")), ref);
    sprintf(CalibObj, "%s_cal", object);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_obj_finput")), CalibObj);
    sprintf(out_flux, "%s_flux", object);
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_obj_foutput")), out_flux);


    resp = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_resp")));
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_obj_resp")), resp);

    sprintf(s, "%s %s %s", C_COPY_IMA, object, ref);
    AppendDialogText(s);

    PopupIrspec("ObjectShell");

    XtFree(object);
    XtFree(resp);
}

void BadpixInputCallback( str )
{
/************
char *filename, out[80];
int i;

if ( XmToggleButtonGetState(UxWidget) ) {
    filename = XmTextGetString(UxGetWidget(UxFindSwidget(str)));
    for ( i = 0; filename[i] != '.' && filename[i] != '\0'; i++ )
	;
    filename[i] = '\0';
    sprintf(out, "%s_b", filename); 
    XmTextSetString(UxGetWidget(UxFindSwidget("tf_badpix_out")), out);    
    XtFree(filename);
****************/
}

int get_badpix_input( fname )
char fname[];
{
    int type, i;
    char *input;

    if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_badpix_obj"))) ) {
        input = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_object")));
	type = BADPIX_OBJ;
    }
    else if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_badpix_sky"))) ) {
        input = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_sky")));
	type = BADPIX_SKY;
    }
    else if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_badpix_ststar"))) ) {
        input = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_ststar")));
	type = BADPIX_STSTAR;
    }
    else {
        input = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_stsky")));
	type = BADPIX_STSKY;
    }
    for ( i = 0; input[i] != '.' && input[i] != '\0'; i++ )
	;
    input[i] = '\0';
    strcpy(fname, input);
    XtFree(input);

    return(type);
}

void BadpixDefineCallback()
{
    char *out, *thres1, *thres2, *nframes;
    char cmode;
    char mode[MAXLINE], in[MAXLINE], cmd[2*MAXLINE], cmd1[MAXLINE];
    int i, load;

    get_badpix_input(in);
    out = XmTextGetString(UxGetWidget(UxFindSwidget("tf_badpix_table")));
    for ( i = 0; out[i] != '.' && out[i] != '\0'; i++ )
	;
    out[i] = '\0';

    strcpy(mode, UxGetMenuHistory(UxFindSwidget("mn_mode")));
    if ( !strcmp(mode, "mn_mode_abs") )
	cmode = 'a';
    else /* relative */
	cmode = 'r';

    load = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_badpix_display"))) ? 1 : 0);
	
    thres1 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_badpix_thres1")));
    thres2 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_badpix_thres2")));
    nframes = XmTextGetString(UxGetWidget(UxFindSwidget("tf_badpix_frames")));

    sprintf(cmd, "%s %s %s mode=%c load=%d", C_DEFINE, in, out, cmode, load);

    if ( thres1[0] != '\0' ) {
	sprintf(cmd1, " t=%s", thres1);
	strcat(cmd, cmd1);
        if ( thres2[0] != '\0' ) {
	    sprintf(cmd1, ",%s", thres2);
	    strcat(cmd, cmd1);
        }
    }
    if ( nframes[0] != '\0' ) {
	sprintf(cmd1, " n=%s", nframes);
	strcat(cmd, cmd1);
    }

    AppendDialogText(cmd);

    XtFree(thres1);
    XtFree(thres2);
    XtFree(nframes);
}

void BadpixApplyCallback()
{
    char cmethod;
    char in[MAXLINE], out[MAXLINE], cmd[2*MAXLINE], method[MAXLINE];
    int load, input_type;

    input_type = get_badpix_input(in);
    sprintf(out, "%s_b", in);
    switch( input_type ) {
	case BADPIX_OBJ: 	strcpy(InObj, out);	break;
	case BADPIX_SKY: 	strcpy(InSky, out);	break;
	case BADPIX_STSTAR: 	strcpy(InStstar, out);	break;
	case BADPIX_STSKY: 	strcpy(InStsky, out);	break;
    }
    strcpy(method, UxGetMenuHistory(UxFindSwidget("mn_clean")));
    if ( !strcmp(method, "mn_clean_xy") )
	cmethod = 'b';
    else if ( !strcmp(method, "mn_clean_x") )
	cmethod = 'x';
    else if ( !strcmp(method, "mn_clean_y") )
	cmethod = 'y';
    else /* automatic */
	cmethod = 'a';

    load = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_badpix_display"))) ? 1 : 0);

    sprintf(cmd, "%s %s %s load=%d clean=%c", C_BADPIX, in, out, load, cmethod);

    AppendDialogText(cmd);
}

void FluxTableApplyCallback()
{
    char *flux_in, *flux_out, *fitdeg, *step;
    char interp;
    char cmd[MAXLINE];

    SCTPUT("*** Flux table generation ***");

    flux_in = XmTextGetString(UxGetWidget(UxFindSwidget("tf_flux_in")));
    flux_out = XmTextGetString(UxGetWidget(UxFindSwidget("tf_flux_out")));
    fitdeg = XmTextGetString(UxGetWidget(UxFindSwidget("tf_fitdeg")));
    step = XmTextGetString(UxGetWidget(UxFindSwidget("tf_step")));

    if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_interp_black"))) )
	interp = 'b';
    else if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_interp_poly"))) )
	interp = 'p';
    else /* spline */
	interp = 's';

    sprintf(cmd, "%s %s %s %c degree=%s step=%s", C_STANDARD, flux_in, 
	    flux_out, interp, fitdeg, step);
    AppendDialogText(cmd);

    XtFree(flux_in);
    XtFree(flux_out);
    XtFree(fitdeg);
    XtFree(step);
}

void StandardReduceCallback()
{
    char sky_out[MAXLINE], rect_out[MAXLINE], cmd[2*MAXLINE], cmd1[MAXLINE], 
	 s[MAXLINE], interact[MAXLINE], unit[MAXLINE], ststar_cal[MAXLINE],
	 sky_params[MAXLINE];
    char obs_menu[MAXLINE], obs_mode[5];
    char *ststar, *response, *ref, *factor, *deltax, *deltay, *shift;
    char *sky_table, *sky_cuts1, *sky_cuts2;
    char *flux_table;
    char *y1, *y2, *y3, *y4;
    char cunit;
    float ydata[4];
    int i, sky_zero, sky_debug, response_norm;

    for ( i = 0; InStstar[i] != '.' && InStstar[i] != '\0'; i++ )
        ;
    InStstar[i] = '\0';
    for ( i = 0; InStsky[i] != '.' && InStsky[i] != '\0'; i++ )
        ;
    InStsky[i] = '\0';

    SCTPUT("*** Sky subtraction ***");
    factor = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_factor")));
    shift = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_shift")));
    deltax = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_deltax")));
    deltay = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_deltay")));
    sky_table = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_sky_table")));
    sky_cuts1 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_cuts1")));
    sky_cuts2 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_cuts2")));
    sky_zero = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_std_sky_zero"))) ? 1 : 0);
    sky_debug = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_std_debug"))) ? 1 : 0);
    
    sprintf(sky_params, "%s", factor);
    if ( shift[0] != '\0' )
	sprintf(sky_params, "%s,%s", factor, shift);
    if ( deltax[0] != '\0' && deltay[0] != '\0' )
	sprintf(sky_params, "%s,%s,%s,%s", factor, shift, deltax, deltay);

    sprintf(sky_out, "%s_s", InStstar);
    sprintf(cmd, "%s %s %s %s %s sky=%s force=%d cuts=%s,%s debug=%d", 
                 C_SKYSUB, InStstar, InStsky, sky_out, sky_params, sky_table,
                 sky_zero, sky_cuts1, sky_cuts2, sky_debug);

    AppendDialogText(cmd);

    SCTPUT("*** Rectification ***");
    sprintf(rect_out, "%s_r", sky_out);
    sprintf(cmd, "%s %s %s", C_RECTIFY, sky_out, rect_out);
    AppendDialogText(cmd);

    strcpy(unit, UxGetMenuHistory(UxFindSwidget("mn_unit")));
    if ( !strcmp(unit, "mn_unit_angstrom") )
	cunit = 'a';
    else /* microns */
	cunit = 'm';

    if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_calib_std"))) ) {
        SCTPUT("*** Wavelength calibration ***");
    	sprintf(cmd, "%s %s units=%c", C_CALIB, rect_out, cunit);
    	AppendDialogText(cmd);
    }
    else {
	SCTPUT("*** Reference frame generation ***");
    	ref = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_ref")));
    	sprintf(cmd, "%s %s mode=d units=%c", C_CALIB, ref, cunit);
    	AppendDialogText(cmd);
        SCTPUT("*** Wavelength calibration ***");
    	sprintf(cmd, "%s %s ref=%s units=%c", C_CALIB, rect_out, ref, cunit);
    	AppendDialogText(cmd);
        XtFree(ref);
    }
    ststar = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_ststar")));
    for ( i = 0; ststar[i] != '.' && ststar[i] != '\0'; i++ )
	;
    ststar[i] = '\0';
    sprintf(ststar_cal, "%s_cal", ststar);
    sprintf(cmd, "%s %s %s", C_COPY_IMA, rect_out, ststar_cal);
    AppendDialogText(cmd);
    sprintf(s, "*** The wavelength calibrated frame is: %s ***", ststar_cal);
    SCTPUT(" ");
    SCTPUT(s);
    SCTPUT(" ");

    SCTPUT("*** Response frame generation ***");

    response = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_resp")));
    flux_table = XmTextGetString(UxGetWidget(UxFindSwidget("tf_std_flux")));
    response_norm = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_std_normalize"))) ? 1 : 0);
    strcpy(obs_menu, UxGetMenuHistory(UxFindSwidget("mn_obs_mode")));
    if ( !strcmp(obs_menu, "mn_obs_mode_single") )
	strcpy(obs_mode, "os");
    else
	strcpy(obs_mode, "ab");
    for ( i = 0; flux_table[i] != '.' && flux_table[i] != '\0'; i++ )
	;
    flux_table[i] = '\0';

    sprintf(cmd, "%s %s %s %s obs=%s norm=%d", C_RESPONSE, ststar_cal, 
            flux_table, response, obs_mode, response_norm);

    strcpy(interact, UxGetMenuHistory(UxFindSwidget("mn_ypos")));
    if ( !strcmp(interact, "mn_ypos_noint") ) {
    	y1 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_yresp1")));
    	y2 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_yresp2")));
    	y3 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_yresp3")));
    	y4 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_yresp4")));
        sprintf(cmd1, " yrows=%s,%s,%s,%s", y1, y2, y3, y4);
	strcat(cmd, cmd1);
        AppendDialogText(cmd);
    }
    else {
        AppendDialogText(cmd);
	if ( GetRespCoords(response, ydata) ) {
	    sprintf(s, "%d", (int)ydata[0]);
    	    UxPutText(UxFindSwidget("tf_yresp1"), s);
	    sprintf(s, "%d", (int)ydata[1]);
    	    UxPutText(UxFindSwidget("tf_yresp2"), s);
	    sprintf(s, "%d", (int)ydata[2]);
    	    UxPutText(UxFindSwidget("tf_yresp3"), s);
	    sprintf(s, "%d", (int)ydata[3]);
    	    UxPutText(UxFindSwidget("tf_yresp4"), s);
	}
        else {
    	  /*** Error: keyword IRS_YROWS is not present in response frame ***/;
	}
    }
    XtFree(ststar);
    XtFree(response);
    XtFree(factor);
    XtFree(shift);
    XtFree(deltax);
    XtFree(deltay);
    XtFree(sky_table);
    XtFree(sky_cuts1);
    XtFree(sky_cuts2);
}

void ObjectReduceCallback()
{
    char sky_out[MAXLINE], rect_out[MAXLINE], cmd[2*MAXLINE],
         s[MAXLINE], unit[MAXLINE],
         sky_params[MAXLINE];

    char *ref;
    char *factor, *deltax, *deltay, *shift;
    char *sky_table, *sky_cuts1, *sky_cuts2;
    char cunit;
    int i, sky_zero, sky_debug;

    for ( i = 0; InObj[i] != '.' && InObj[i] != '\0'; i++ )
        ;
    InObj[i] = '\0';
    for ( i = 0; InSky[i] != '.' && InSky[i] != '\0'; i++ )
        ;
    InSky[i] = '\0';

    SCTPUT("*** Sky subtraction ***");
    factor = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_factor")));
    shift = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_shift")));
    deltax = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_deltax")));
    deltay = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_deltay")));
    sky_table = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_sky_table")));
    sky_cuts1 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_cuts1")));
    sky_cuts2 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_cuts2")));
    sky_zero = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_obj_sky_zero"))) ? 1 : 0);
    sky_debug = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_obj_debug"))) ? 1 : 0);
    
    sprintf(sky_params, "%s", factor);
    if ( shift[0] != '\0' )
	sprintf(sky_params, "%s,%s", factor, shift);
    if ( deltax[0] != '\0' && deltay[0] != '\0' )
	sprintf(sky_params, "%s,%s,%s,%s", factor, shift, deltax, deltay);

    sprintf(sky_out, "%s_s", InObj);
    sprintf(cmd, "%s %s %s %s %s sky=%s force=%d cuts=%s,%s debug=%d", 
                 C_SKYSUB, InObj, InSky, sky_out, sky_params, sky_table,
                 sky_zero, sky_cuts1, sky_cuts2, sky_debug);
    AppendDialogText(cmd);

    SCTPUT("*** Rectification ***");
    sprintf(rect_out, "%s_r", sky_out);
    sprintf(cmd, "%s %s %s", C_RECTIFY, sky_out, rect_out);
    AppendDialogText(cmd);

    strcpy(unit, UxGetMenuHistory(UxFindSwidget("mn_obj_unit")));
    if ( !strcmp(unit, "mn_obj_angstrom") )
	cunit = 'a';
    else /* microns */
	cunit = 'm';

    if ( XmToggleButtonGetState(UxGetWidget(UxFindSwidget("rb_obj_std"))) ) {
        SCTPUT("*** Wavelength calibration ***");
    	sprintf(cmd, "%s %s units=%c", C_CALIB, rect_out, cunit);
    	AppendDialogText(cmd);
    }
    else {
    	ref = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_ref")));
    	sprintf(cmd, "%s %s mode=d units=%c", C_CALIB, ref, cunit);
    	AppendDialogText(cmd);
        SCTPUT("*** Wavelength calibration ***");
    	sprintf(cmd, "%s %s ref=%s units=%c", C_CALIB, rect_out, ref, cunit);
    	AppendDialogText(cmd);
	XtFree(ref);
    }
    sprintf(cmd, "%s %s %s", C_COPY_IMA, rect_out, CalibObj);
    AppendDialogText(cmd);
    sprintf(s, "*** The wavelength calibrated frame is: %s ***", CalibObj);
    SCTPUT(" ");
    SCTPUT(s);
    SCTPUT(" ");

    XtFree(factor);
    XtFree(shift);
    XtFree(deltax);
    XtFree(deltay);
    XtFree(sky_table);
    XtFree(sky_cuts1);
    XtFree(sky_cuts2);
}

void ObjectFluxCallback()
{
    char *response, *out_flux, *in_flux;
    char s[2*MAXLINE];

    response = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_resp")));
    in_flux = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_finput")));
    out_flux = XmTextGetString(UxGetWidget(UxFindSwidget("tf_obj_foutput")));
    SCTPUT("*** Flux calibration ***");
    sprintf(s, "%s %s %s %s", C_FLUX, in_flux, response, out_flux);
    AppendDialogText(s);

    sprintf(s, "*** The flux calibrated frame is: %s ***", out_flux);
    SCTPUT(" ");
    SCTPUT(s);
    SCTPUT(" ");
}

void MergeApplyCallback()
{
    char *prefix, *i1, *i2, *step, *out, *pixels, *digits, *ref;
    char s[2*MAXLINE];
    int plot, correct;

    prefix = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_prefix")));
    i1 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_i1")));
    i2 = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_i2")));
    step = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_step")));
    out = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_out")));

    pixels = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_pixels")));
    ref = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_ref")));
    digits = XmTextGetString(UxGetWidget(UxFindSwidget("tf_merge_digits")));
    plot = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_merge_plot"))) ? 1 : 0);
    correct = (XmToggleButtonGetState(UxGetWidget(UxFindSwidget("tg_merge_correct"))) ? 1 : 0);

    if ( step[0] != '\0' )
    	sprintf(s, "%s %s %s,%s,%s %s excl=%s corr=%d ref=%s plot=%d format=i%s",
                C_MERGE, prefix, i1, i2, step, out, pixels, correct, ref, 
                plot, digits);
    else
    	sprintf(s, "%s %s %s,%s %s excl=%s corr=%d ref=%s plot=%d format=i%s",
                C_MERGE, prefix, i1, i2, out, pixels, correct, ref, 
                plot, digits);

    AppendDialogText(s);
}

void ExtractSkyCallback()
{
    char command[128], s[10];
    int sky[4];
    
    sprintf(command, "%s 4 %s", C_EXTR_GCOOR, CoordsTable);
    AppendDialogText(command);
    
    if ( !GetCoords(CoordsTable, sky, 4) )
        return;
    
    sprintf(s, "%d", sky[0]);
    UxPutValue(UxFindSwidget("tf_lowsky1"), s);
    sprintf(s, "%d", sky[1]);
    UxPutValue(UxFindSwidget("tf_lowsky2"), s);
    sprintf(s, "%d", sky[2]);
    UxPutValue(UxFindSwidget("tf_uppsky1"), s);
    sprintf(s, "%d", sky[3]);
    UxPutValue(UxFindSwidget("tf_uppsky2"), s);
    
    Lowsky[0] = sky[0]; Lowsky[1] = sky[1];
    Uppsky[0] = sky[2]; Uppsky[1] = sky[3];
}

void ExtractObjectCallback()
{
    char command[128], s[10];

    sprintf(command, "%s 2 %s", C_EXTR_GCOOR, CoordsTable);
    AppendDialogText(command);

    if ( !GetCoords(CoordsTable, Objlim, 2) )
        return;

    sprintf(s, "%d", Objlim[0]);
    UxPutValue(UxFindSwidget("tf_object1"), s);
    sprintf(s, "%d", Objlim[1]);
    UxPutValue(UxFindSwidget("tf_object2"), s);
}

void FileSaveCallback()
{
    char *flat, *dark, *obj, *sky, *ststar, *stsky;

    obj = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_object")));
    sky = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_sky")));
    ststar = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_ststar")));
    stsky = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_stsky")));
    flat = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_flat")));
    dark = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_dark")));

    IrspecSave(ParametersFile, obj, sky, ststar, stsky, dark, flat);

    XtFree(obj);
    XtFree(sky);
    XtFree(ststar);
    XtFree(stsky);
    XtFree(dark);
    XtFree(flat);
}

void FileSaveAsCallback()
{
    DialogType = DIALOG_SAVE_AS;
    SET_DIALOG_PROMPT("Enter parameters file :");
    UxPutValue(UxFindSwidget("tf_file_dialog"), ParametersFile);
    UxPopupInterface(UxFindSwidget("file_dialog"), exclusive_grab);
}

void QuitCallback()
{
    char command[MAXLINE];
    char *obj, *ststar, *sky, *stsky;

    obj = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_object")));
    ststar = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_ststar")));
    sky = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_sky")));
    stsky = XmTextGetString(UxGetWidget(UxFindSwidget("tf_main_stsky")));

    if ( XmToggleButtonGadgetGetState(UxGetWidget(UxFindSwidget("tg_options_exit"))) )
	sprintf(command, "%s ALL %s %s %s %s", C_CLEAN, obj, ststar, sky, stsky);
    else
	sprintf(command, "%s MID", C_CLEAN);
    AppendDialogText(command);
 
    AppendDialogText("clear/context irspec");

    XtFree(obj);
    XtFree(ststar);
    XtFree(sky);
    XtFree(stsky);
    SCSEPI();
    exit(0);
}

void PopupIrspec( interface )
char *interface;
{
    UxPopdownInterface(UxFindSwidget("BadpixShell"));
    UxPopdownInterface(UxFindSwidget("StandardShell"));
    UxPopdownInterface(UxFindSwidget("ObjectShell"));
    UxPopdownInterface(UxFindSwidget("ExtractShell"));
    UxPopdownInterface(UxFindSwidget("MergeShell"));

    UxPopupInterface(UxFindSwidget(interface), no_grab);
}

