// This is primarily the menus associated with FILE pulldown menu
#include <CC/iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <Xm/Form.h>
#include "menu.h"
#include "drawwindow.h"  // the data that needs to be seen by other routines
#include "screen.h"
#include "initialize.h"
#include "pdbtolev.h"
#include "contour.h"
#include "peptide.h"
#include "math.h"
#include "bone.h"
#include "trace.h"

void  CreateActionArea(Widget dialog,ActionAreaItem * actions,int num_actions);


extern struct screenvalue  sc;
extern struct maiddatafile maidfile;
extern struct coredata core[NMAPS];
extern struct bonedata bone[NMAPS];
extern struct geometry geo;
// these variable are used for setting check boxes in readmaidfile
extern char buttonname[MAXPDB][10];// defined in pdbmenu.c++
//extern struct pickpdb picked;
extern struct griddata map[NMAPS]; // all the map (denfile),contour data associated with map
//extern XtAppContext appctx;
extern Widget toplevel;
extern String colors[];
Widget  label;
char cur_bitden[1024] = "xlogo64"; /* make large enough for full pathnames */
Pixel cur_color;
Boolean test_proc(XtPointer clientData);

struct st ss;
//void readmap(char filename[],struct griddata& den1);
void initializemapscreen(struct griddata& den1);
//void saveden(struct griddata den1);
void error_callback(Widget dialog,XtPointer  client_data,XtPointer  call_data);
//void drawpdb(struct pdbfile pdb1);



void unmangechild(Widget child,XtPointer  client_data,XtPointer  call_data) /* need to write
     my own progrm to avoid warning, must hve Xtpointer,etc. in header, eventhough not used*/
{
   XtUnmanageChild(child);
}

void  CreateActionArea(Widget dialog,ActionAreaItem * actions,int num_actions)
{
    Widget widget;
    int i;

    for (i = 0; i < num_actions; i++) {
        widget = XtVaCreateManagedWidget (actions[i].label,
            xmPushButtonWidgetClass, dialog,
	    XmNshowAsDefault, i == 0,
	    XmNdefaultButtonShadowThickness, 1,
            NULL);
	if (actions[i].XtCallbackProc){
            XtAddCallback (widget, XmNactivateCallback,
                actions[i].XtCallbackProc, actions[i].data);
        }
        if (i == 0) 
            XtVaSetValues (dialog, XmNdefaultButton, widget, NULL);
    }
}
/* Custom dialog routine copied from motif man: ch07 - action_area2.c
 * a function that could be invoked by any arbitrary callback.  Here,
 * we demonstrate how one can build a standard customized dialog box.
 * The control area is created here and the action area is created in
 * a separate, generic routine: CreateActionArea().
 */
void  file_new_dialog(Widget w)
{
    Widget dialog, rc;
    XmString string;
    Arg args[5];
    int n = 0;
    static ActionAreaItem action_items[] = {
        { "OK",     new_ok_pushed,     NULL          },
        { "Clear",  clear_pushed,  NULL          },
        { "Cancel", close_dialog,  NULL          },
        { "Help",   help,          "Help Button" },
    };
    /* Create a TemplateDialog that will contain the control area
     * and the action area buttons for the dialog
     */
    string = XmStringCreateLocalized ("Dialog Shell");
    XtSetArg (args[n], XmNdialogTitle, string); n++;
    XtSetArg (args[n], XmNautoUnmanage, False); n++;
    dialog = XmCreateTemplateDialog (toplevel, "dialog", args, n);
    XmStringFree (string);

    /* now that the dialog is created, set the Cancel button's
     * client data, so close_dialog() will know what to destroy.
     */
    action_items[0].data=action_items[2].data = (XtPointer) dialog;

    /* create the control area which contains a
     * Label gadget and a TextField widget.
     */
    ss.num=3; // the number of data entries spaces
    rc = XtVaCreateWidget ("control_area", 
        xmRowColumnWidgetClass, dialog, NULL);
    string = XmStringCreateLocalized ("ENTER NAME FOR THIS DATA SET:");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[0] = XtVaCreateManagedWidget ("text-field",xmTextFieldWidgetClass, rc, NULL);
    string = XmStringCreateLocalized ("ENTER NAME OF PDB FILE (or 'none'):");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[1] = XtVaCreateManagedWidget ("text-field",
        xmTextFieldWidgetClass, rc, NULL);

    string = XmStringCreateLocalized ("ENTER NAME OF XPLOR MAP FILE (or 'none'):");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[2] = XtVaCreateManagedWidget ("text-field",
        xmTextFieldWidgetClass, rc, NULL);
   /* RowColumn is full -- now manage */
    XtManageChild (rc);

#if 0
    /* Set the client data for the "OK" and "Clear" buttons */
      action_items[0].data = (XtPointer) ss.w1;
      action_items[1].data = (XtPointer) ss.w[0];
#endif  
    /* Create the action area. */
    CreateActionArea (dialog, action_items, XtNumber (action_items));

    /* callback for Return in TextField.  Use dialog as client data */
//    XtAddCallback (ss.w[0], XmNactivateCallback, activate_cb, dialog);

    XtManageChild (dialog);
    XtPopup (XtParent (dialog), XtGrabNone);
    glClearColor(backcolv[0],backcolv[1],backcolv[2],0);//background color :red, green, blue, and alpha = black
}



void  file_old_dialog(Widget w)
{
    Widget dialog, rc;
    XmString string;
    Arg args[5];
    int n = 0;
    static ActionAreaItem action_items[] = {
        { "OK",     old_ok_pushed,     NULL          },
        { "Clear",  clear_pushed,  NULL          },
        { "Cancel", close_dialog,  NULL          },
        { "Help",   help,          "Help Button" },
    };
    /* Create a TemplateDialog that will contain the control area
     * and the action area buttons for the dialog
     */
    string = XmStringCreateLocalized ("Dialog Shell");
    XtSetArg (args[n], XmNdialogTitle, string); n++;
    XtSetArg (args[n], XmNautoUnmanage, False); n++;
    dialog = XmCreateTemplateDialog (toplevel, "dialog", args, n);
    XmStringFree (string);

    /* now that the dialog is created, set the Cancel button's
     * client data, so close_dialog() will know what to destroy.
     */
    action_items[0].data=action_items[2].data = (XtPointer) dialog;

    /* create the control area which contains a
     * Label gadget and a TextField widget.
     */
    ss.num=1; // the number of data entries spaces
    rc = XtVaCreateWidget ("control_area", 
        xmRowColumnWidgetClass, dialog, NULL);
    string = XmStringCreateLocalized ("ENTER NAME OF DATA SET (.maid will be added):");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[0] = XtVaCreateManagedWidget ("text-field",xmTextFieldWidgetClass, rc, NULL);
    XtManageChild (rc);

    /* Set the client data for the "OK" and "Clear" buttons */
  
    /* Create the action area. */
    CreateActionArea (dialog, action_items, XtNumber (action_items));

    /* callback for Return in TextField.  Use dialog as client data */
//    XtAddCallback (ss.w[0], XmNactivateCallback, activate_cb, dialog);

    XtManageChild (dialog);
    XtPopup (XtParent (dialog), XtGrabNone);
    glClearColor(backcolv[0],backcolv[1],backcolv[2],0);//background color :red, green, blue, and alpha = black
}


void close_dialog(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    Widget shell = (Widget) client_data;
    XtDestroyWidget (shell);
}


/* The "ok" button was pushed or the user pressed Return */
static void old_ok_pushed(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    char* text[5];
    char text0[100];
    for(int i = 0;i< ss.num;i++)
        text[i] =   XmTextFieldGetString (ss.w[i]);
      
    strcpy(text0,text[0]);
    for( i = 0;i< ss.num;i++)
      XtFree (text[i]);
    strcat(text0,".maid");
    strcpy(maidfile.name,text0);
//    readmaidfile(maidfile,map,core);
    readmaidfile(maidfile,map,bone);
printf(" npdbfile = %d\n",maidfile.npdb);
for(i=1;i<=maidfile.npdb;i++)
   printf("pdbfilename%d = %s\n",i,maidfile.pdb[i].name);
    Widget shell = (Widget) client_data;
    XtDestroyWidget (shell);
    maidfile.start=0;  // This starts routine (as set by RUN command)
#if 0 // Following makes sample peptide, test procedures for finding Ca, etc.
// geo.stpos[0]=6.050;geo.stpos[1]=  32.431;geo.stpos[2]=   1.664;// for endo
geo.stpos[0]=10.372;geo.stpos[1]= -11.671;geo.stpos[2]=  77.670;// for albp
 maketestpep(geo,geo.pos,10,geo.phihel,geo.psihel);
// findphipsierr(map[1],geo);
#endif
}

/* The "ok" button was pushed or the user pressed Return */
static void new_ok_pushed(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    char* text[5];
    char text0[100],ich[10];
    for(int i = 0;i< ss.num;i++)
        text[i] =   XmTextFieldGetString (ss.w[i]);      
    strcpy(text0,text[0]);
    strcat(text0,".maid");
    strcpy(maidfile.name,text0);
    if( (strcasecmp(text[1],"")==0)||(strcasecmp(text[1],"none")==0) ) // Not case sensitive 
       maidfile.nden = 0;
    else{
       maidfile.npdb = 1;
       strcpy(maidfile.pdb[1].name,text[1]);
    }   
    if( (strcasecmp(text[2],"")==0)||(strcasecmp(text[2],"none")==0) ){ // Not case sensitive 
       maidfile.nden = 0;
    }
    else{ // Map file input - read and create binary file
        maidfile.nden = 1;
        readmap(text[2],map[1],maidfile);// read the this map into struct griddata map[1]....
        initializemapscreen(map[1]); 
//        strcpy(map[1].mapname,maidfile.name);
        strcpy(map[1].mapname,text[2]);
        strcat(map[1].mapname,".den");
        itoa(1,ich);
        strcat(map[1].mapname,ich);
        saveden(map[1]);
//        strcpy(core[1].corename,"none"); // indicates no core file created yet
        strcpy(bone[1].bonename,"none"); // indicates no bone file created yet
    }   
    writemaidfile(1,maidfile,map,bone);// "1" indicate create new file names
    readmaidfile(maidfile,map,bone);
    Widget shell = (Widget) client_data;
    XtDestroyWidget (shell);
printf ("Name = %s pdbfile = %s mapfile = %s\n",
      maidfile.name,maidfile.pdb[1].name,text[2]);
    for( i = 0;i< ss.num;i++)
      XtFree (text[i]);
    maidfile.start=0;  // This starts routine (as set by RUN command)
}

void clear_pushed(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    for(int i = 0;i< ss.num;i++)
        XmTextFieldSetString (ss.w[i], "");
}

void help(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    String string = (String) client_data;
    
    puts(string);
}

/* When Return is pressed in TextField widget, respond by getting
 * the designated "default button" in the action area and activate
 * it as if the user had selected it.
 */
void activate_cb(Widget text_w,XtPointer  client_data,XtPointer  call_data)
             /* user pressed Return in this widget */
       /* dialog passed as client data */
{
    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
    Widget dflt, dialog = (Widget) client_data;

    /* get the "default button" from the action area... */
    XtVaGetValues (dialog, XmNdefaultButton, &dflt, NULL);
    if (dflt) /* sanity check -- this better work */
        /* make the default button think it got pushed using
	 * XtCallActionProc().  This function causes the button
	 * to appear to be activated as if the user pressed it.
         */
        XtCallActionProc (dflt, "ArmAndActivate", cbs->event, NULL, 0);
}


Boolean test_proc(XtPointer client_data)
{
   int i;  
   sc.cubecol[0] += 0.01;
   i= sc.cubecol[0];
   sc.cubecol[0]= sc.cubecol[0]-i;;
   draw_screen(client_data);
    return False; // Runs continually
//   return True; // Runs just once
}


/* The OK button was selected from the FileSelectionDialog (or, the user
 * double-clicked on a file selection).  Try to read the file as a bitden.
 * If the user changed colors, we call this function directly from change_color()
 * to reload the pixmap.  In this case, we pass NULL as the callback struct
 * so we can identify this special case.
 */
void load_pixmap(Widget dialog,XtPointer  client_data,XtPointer  call_data)
{
    Pixmap pixmap;
    char *file = NULL;
    XmFileSelectionBoxCallbackStruct *cbs =
        (XmFileSelectionBoxCallbackStruct *) call_data;

    if (cbs) {
        if (!XmStringGetLtoR (cbs->value, XmFONTLIST_DEFAULT_TAG, &file))
            return; /* internal error */
        (void) strcpy (cur_bitden, file);
        XtFree (file); /* free allocated data from XmStringGetLtoR() */
    }

    pixmap = XmGetPixmap (XtScreen (toplevel), cur_bitden,
        cur_color, WhitePixelOfScreen (XtScreen (toplevel)));

    if (pixmap == XmUNSPECIFIED_PIXMAP)
        printf ("Can't create pixmap from %s\n", cur_bitden);
    else {
        Pixmap old;
        XtVaGetValues (label, XmNlabelPixmap, &old, NULL);
        XmDestroyPixmap (XtScreen (toplevel), old);
        XtVaSetValues (label,
            XmNlabelType,   XmPIXMAP,
            XmNlabelPixmap, pixmap,
            NULL);
    }
}

/* called from any of the "Edit" menu items.  Change the color of the
 * current bitden being displayed.  Do this by calling load_pixmap().
 */
void change_color(Widget widget,XtPointer  client_data,XtPointer  call_data)
{
    XColor xcolor, unused;
    Display *dpy = XtDisplay (label);
    Colormap cmap = DefaultColormapOfScreen (XtScreen (label));
    int item_no = (int) client_data;

    if (XAllocNamedColor (dpy, cmap, colors[item_no], &xcolor, &unused) == 0 ||
        cur_color == xcolor.pixel)
        return;

    cur_color = xcolor.pixel;
    load_pixmap (widget, NULL, NULL);
}

#define MSG \
"Use the FileSelection dialog to find bitden files to\n\
display in the scrolling area in the main window.  Use\n\
the edit menu to display the bitden in different colors."

/* The help button in the help menu from the menubar was selected.
 * Display help information defined above for how to use the program.
 * This is done by creating a Motif information dialog box.  Again,
 * make the dialog static so we can reuse it.
 */
void help_cb(Widget widget,XtPointer  client_data,XtPointer  call_data)
{
    static Widget dialog;

    if (!dialog) {
        Arg args[5];
        int n = 0;
        XmString msg = XmStringCreateLtoR (MSG, XmFONTLIST_DEFAULT_TAG);
        XtSetArg (args[n], XmNmessageString, msg); n++;
        dialog = XmCreateInformationDialog (toplevel, "help_dialog", args, n);
    }
    XtManageChild (dialog);
    XtPopup (XtParent (dialog), XtGrabNone);
}

#if 0 // moved to initialize.c++
void writemaidfile(int inew,struct maiddatafile& maidfile,struct griddata map[],
         struct bonedata bone[])
/* if inew = 1; then new - must create default file names,
    if = 0, then old, just use already created names
*/
{ 
    char ich[10],pdbname[10],denname[10],bonename[10];
    int i;
    FILE *fp,*tempfp; 

    fp= fopen(maidfile.name,"w");
    fprintf(fp,"Number of pdbfiles:  %d\n",maidfile.npdb);
    for(i=1;i<=maidfile.npdb;i++){
          itoa(i,ich);
          strcpy(pdbname,"pdbfile");
          strcat(pdbname,ich); 
          fprintf(fp,"%s:  %s\n",pdbname,maidfile.pdb[i].name);
    }    
    fprintf(fp,"Number of denfiles:  %d\n",maidfile.nden);
    for(i=1;i<=maidfile.nden;i++){
         itoa(i,ich);
         strcpy(denname,"denfile");
         strcat(denname,ich);
         fprintf(fp,"%s:   %s\n",denname,map[i].mapname);
#if 0
         strcpy(corename,"corefile");
         strcat(corename,ich);
         core[i].num = i; // Indentity number of corefile
         fprintf(fp,"%s:   %s\n",corename,core[i].corename);
#endif
#if 1
         strcpy(bonename,"bonefile");
         strcat(bonename,ich);
         bone[i].num = i; // Indentity number of bonefile
         fprintf(fp,"%s:   %s\n",bonename,bone[i].bonename);
#endif
    }
    if(inew==1){ // new - create spherefile and write default value to it and create other files
       strcpy(maidfile.spherefile,maidfile.name);
       strcat(maidfile.spherefile,"spherefile");
       tempfp = fopen(maidfile.spherefile,"w");
       fprintf(tempfp,"%d\n",-1);// Input default  = -1 spheres - indicates do not use speres
       fclose(tempfp);
       strcpy(maidfile.fitfile,maidfile.name);
       strcat(maidfile.fitfile,"fit"); 
       strcpy(maidfile.pdbsequence,maidfile.name);
       strcat(maidfile.pdbsequence,"pdbsequence"); 
       strcpy(maidfile.editbones,maidfile.name);
       strcat(maidfile.editbones,"editbones"); 
       strcpy(maidfile.nsym,maidfile.name);
       strcat(maidfile.nsym,"symrottran"); 
       strcpy(maidfile.selenomet,maidfile.name);
       strcat(maidfile.selenomet,"selenomet"); 
    } 
    fprintf(fp,"%s:  %s\n","spherefile",maidfile.spherefile);
    fprintf(fp,"%s:  %s\n","fitfile",maidfile.fitfile);    
    fprintf(fp,"%s:  %s\n","editbonesfile",maidfile.editbones);    
    fprintf(fp,"%s:  %s\n","pdbsequencefile",maidfile.pdbsequence);    
    fprintf(fp,"%s:  %s\n","symrottranfile",maidfile.nsym);    
    fprintf(fp,"%s:  %s\n","selenometfile",maidfile.selenomet);    
    fclose(fp);
}
#endif


void readmaidfile(struct maiddatafile& maidfile,struct griddata map[],
       struct bonedata bone[])
// This file also include some initial PDB settings since it is only
//    called at beginning of reading pdb files
{ 
    int i;
    char junk[200],line[300];
    FILE *fp;
    Widget widget;

    if( (fp=fopen(maidfile.name,"r")) == NULL){
         errormessage(toplevel,"This file cannot be found");
         goto quitread;
    }
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s%s%d",junk,junk,junk,&maidfile.npdb);
    for(i=1;i<= maidfile.npdb;i++){
        fgets(line,200,fp); /* read each line*/
        sscanf(line,"%s%s",junk,maidfile.pdb[i].name);
        maidfile.pdb[i].start=1; // Indicates - just read, pdbtolev not run yet
        maidfile.pdb[i].iset=0; // Indicates have net set geo.set yet
        if(i==1){
           maidfile.pdb[i].onoff = 1; // Default turn on draw for first pdb
           if (widget = XtNameToWidget (sc.pullright[i], buttonname[0]))
              XtVaSetValues (widget, XmNset, True, NULL);
        }
        else{
           maidfile.pdb[i].onoff = -1; // Default turn off draw for rest
           if (widget = XtNameToWidget (sc.pullright[i], buttonname[0]))
              XtVaSetValues (widget, XmNset, FALSE, NULL);
        }
        maidfile.pdb[i].linethick = 1.0; // Default line thickness
        maidfile.pdb[i].sideonoff =1; // Default - turn on side chains,connect all atoms
        maidfile.pdb[i].pickres[0].num = 0; // Initially, no residues picked
        XtSetSensitive(sc.pullright[i],1);//Turn on sensitivitivity  
        // Turn on check box for pdb (button0) and side chain(button1)
        if (widget = XtNameToWidget (sc.pullright[i], buttonname[1]))
            XtVaSetValues (widget, XmNset, True, NULL);
        if (widget = XtNameToWidget (sc.pullright[i], buttonname[2]))
            XtVaSetValues (widget, XmNset, False, NULL);
    }
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s%s%d",junk,junk,junk,&maidfile.nden);
    for(i=1;i<= maidfile.nden;i++){
//       bone[i].minden = 1.4;  // Now define in initializeDefault minimum value of density used in bone calculation
       fgets(line,200,fp); /* read each line*/
       if(maidfile.start!=2){ // if = 2, then have already picked new and read the one map
          sscanf(line,"%s%s",junk,map[i].mapname);
          readbinarymap(map[i]);
          initializemapscreen(map[i]); // This is the screen stuff originally in initializemap
       }
       XtSetSensitive(sc.mappullright[i],1);//Turn on sensitivitivity  
       if (widget = XtNameToWidget (sc.mappullright[i], buttonname[0]))
            XtVaSetValues (widget, XmNset,False, NULL);
       fgets(line,200,fp); /* read bonefile line*/
       sscanf(line,"%s%s",junk,bone[i].bonename);
       if(strcmp("none",bone[i].bonename) == 0) // if bonefile does not exist
          bone[i].iexist = 0;
       else 
          bone[i].iexist = 1; // indicates file exist but not yet read
       bone[i].num = i; // assign number corresponding to map number
       if (widget = XtNameToWidget (sc.mappullright[i], buttonname[1]))
            XtVaSetValues (widget, XmNset, False, NULL);// default - bone off
    }
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.spherefile);
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.fitfile);
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.editbones);
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.pdbsequence);
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.nsym);
    fgets(line,200,fp); /* read each line*/
    sscanf(line,"%s%s",junk,maidfile.selenomet);
// The following file names are created and used but not written in mainfile
    strcpy(maidfile.resqual,maidfile.name);
    strcat(maidfile.resqual,"resqual"); 
    strcpy(maidfile.firstedit,maidfile.name);
    strcat(maidfile.firstedit,"firstedit"); 
    
//    picked.onoff = 0; // Initial defaul - draw entire pdb file
//    picked.range = 10; // default range if pick pdb
    readcubeclass("cubeclass"); // reads array for contouring
   fclose(fp);
   quitread:;
}

void errormessage(Widget widget, char errortext[])
{
    static Widget dialog;
    XmString errorxm; 

     errorxm=   XmStringCreateLocalized (errortext);
    /* See if we've already created this dialog -- if so,
     * we don't need to create it again.  Just re-pop it up.
     */
    if (!dialog) {
        Arg args[5];
        int n = 0;
        XmString ok = XmStringCreateLocalized ("OK");
        XtSetArg(args[n], XmNautoUnmanage, False); n++;
        XtSetArg(args[n], XmNcancelLabelString, ok); n++;
        dialog = XmCreateInformationDialog (widget, "notice", args, n);
        XtAddCallback (dialog, XmNcancelCallback, error_callback, NULL);
        XtUnmanageChild (
            XmMessageBoxGetChild (dialog, XmDIALOG_OK_BUTTON));
        XtUnmanageChild (
            XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
    }
    XtVaSetValues (dialog,
    XmNmessageString,    errorxm,NULL);
    XmStringFree (errorxm);
    XtManageChild (dialog);
    XtPopup  (XtParent (dialog), XtGrabNone);
    XtRealizeWidget (toplevel);
    XtAppMainLoop (sc.appctx);
}

void error_callback(Widget dialog,XtPointer  client_data,XtPointer  call_data)
{
    XtPopdown (XtParent (dialog));
}


void filepulldown(Widget menubar)
{
    XmString  old,start,run,stop,quit,windowonoff,addpdb,addmap,drawgridonoff;
    Widget  filemenu;
    start = XmStringCreateLocalized ("NEW...");
    old = XmStringCreateLocalized ("OLD...");
    run = XmStringCreateLocalized ("RUN...");
    windowonoff= XmStringCreateLocalized ("WINDOW ON/OFF");
    drawgridonoff= XmStringCreateLocalized ("DRAW GRID ON/OFF");
    stop = XmStringCreateLocalized ("STOP...");
    quit = XmStringCreateLocalized ("Quit");
    addpdb = XmStringCreateLocalized ("Add Pdb");
    addmap = XmStringCreateLocalized ("Add Map");
    filemenu= XmVaCreateSimplePulldownMenu (menubar, "file_menu", 0, file_cb,
        XmVaPUSHBUTTON, start, 'N', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, old, 'O', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, run, 'R', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, windowonoff, 'W', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, addpdb, 'P', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, addmap, 'M', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, drawgridonoff, 'D', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, stop, 'S', NULL, NULL,
        XmVaSEPARATOR,
        XmVaPUSHBUTTON, quit, 'Q', NULL, NULL,
        NULL);
    XmStringFree (old);
    XmStringFree (run);
    XmStringFree (stop);
    XmStringFree (start);
    XmStringFree (quit);
    XmStringFree (windowonoff);
    XmStringFree (drawgridonoff);
    XmStringFree (addpdb);
    XmStringFree (addmap);
}

static void pdb_ok_pushed(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    int ipdb;
    char* text[5];
    char text0[100];
    Widget widget;
    FILE *fp;

    for(int i = 0;i< ss.num;i++)
        text[i] =   XmTextFieldGetString (ss.w[i]);      
    strcpy(text0,text[0]);
    for( i = 0;i< ss.num;i++)
      XtFree (text[i]);
    
    if( (fp=fopen(text[0],"r") ) ==NULL) { // check if file exists
         errormessage(toplevel,"ERROR: That PDB file does not exist");
         fclose(fp);
    }
    else{ // else pdbfile exists
      fclose(fp);
      ipdb = maidfile.npdb = maidfile.npdb+1;
      strcpy(maidfile.pdb[ipdb].name,text[0]);
      writemaidfile(0,maidfile,map,bone);  //"0" indicates use old file names
      maidfile.pdb[ipdb].start=1; // Indicates - just read, pdbtolev not run yet
      maidfile.pdb[ipdb].onoff = 1; // Default turn on draw
      maidfile.pdb[ipdb].sideonoff =1; // Default - turn on side chains,connect all atoms
      maidfile.pdb[ipdb].linethick = 1.0; // Default line thickness
      maidfile.pdb[ipdb].pickres[0].num = 0; // Initially, no residues picked
      XtSetSensitive(sc.pullright[ipdb],1);//Turn on sensitivitivity  
      // Turn on check box for pdb (button0) and side chain(button1)
      if (widget = XtNameToWidget (sc.pullright[ipdb], buttonname[0]))
            XtVaSetValues (widget, XmNset, True, NULL);
      if (widget = XtNameToWidget (sc.pullright[ipdb], buttonname[1]))
            XtVaSetValues (widget, XmNset, True, NULL);
      if (widget = XtNameToWidget (sc.pullright[ipdb], buttonname[2]))
            XtVaSetValues (widget, XmNset, False, NULL);
      Widget shell = (Widget) client_data;
      XtDestroyWidget (shell);
   } // pdb file exists
}

void file_addpdb_dialog(Widget w)
{
    Widget dialog, rc;
    XmString string;
    Arg args[5];
    int n = 0;
    static ActionAreaItem action_items[] = {
        { "OK",     pdb_ok_pushed,     NULL          },
        { "Clear",  clear_pushed,  NULL          },
        { "Cancel", close_dialog,  NULL          },
        { "Help",   help,          "Help Button" },
    };
    /* Create a TemplateDialog that will contain the control area
     * and the action area buttons for the dialog
     */
    string = XmStringCreateLocalized ("Dialog Shell");
    XtSetArg (args[n], XmNdialogTitle, string); n++;
    XtSetArg (args[n], XmNautoUnmanage, False); n++;
    dialog = XmCreateTemplateDialog (toplevel, "dialog", args, n);
    XmStringFree (string);

    /* now that the dialog is created, set the Cancel button's
     * client data, so close_dialog() will know what to destroy.
     */
    action_items[0].data=action_items[2].data = (XtPointer) dialog;

    /* create the control area which contains a
     * Label gadget and a TextField widget.
     */
    ss.num=1; // the number of data entries spaces
    rc = XtVaCreateWidget ("control_area", 
        xmRowColumnWidgetClass, dialog, NULL);
    string = XmStringCreateLocalized ("ENTER NAME OF PDB FILE :");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[0] = XtVaCreateManagedWidget ("text-field",xmTextFieldWidgetClass, rc, NULL);
    XtManageChild (rc);

    /* Set the client data for the "OK" and "Clear" buttons */
  
    /* Create the action area. */
    CreateActionArea (dialog, action_items, XtNumber (action_items));

    /* callback for Return in TextField.  Use dialog as client data */
#if 0 // I do not think this should be called if use action_items */
    XtAddCallback (ss.w[0], XmNactivateCallback, activate_cb, dialog);
#endif
    XtManageChild (dialog);
    XtPopup (XtParent (dialog), XtGrabNone);
    glClearColor(backcolv[0],backcolv[1],backcolv[2],0);//background color :red, green, blue, and alpha = black
}

static void map_ok_pushed(Widget w,XtPointer  client_data,XtPointer  call_data)
{
    int iden;
    char* text[5];
    char text0[100],ich[10];
    Widget widget;
    FILE *fp;

    for(int i = 0;i< ss.num;i++)
        text[i] =   XmTextFieldGetString (ss.w[i]);      
    strcpy(text0,text[0]);
    for( i = 0;i< ss.num;i++)
      XtFree (text[i]);

    if( (fp=fopen(text0,"r") ) ==NULL) { // check if file exists
         errormessage(toplevel,"ERROR: That MAP file does not exist");
         fclose(fp);
    }
    else{ // else mapfile exists
      iden = maidfile.nden = maidfile.nden+1;
//    strcpy(maidfile.den[iden].name,text0);
      readmap(text0,map[iden],maidfile);// read the this map into struct griddata map[1]....
//    strcpy(map[iden].mapname,maidfile.name);
printf(" mapname = %s   text[0] = %s\n",map[iden].mapname,text0);
      strcpy(map[iden].mapname,text0);
printf(" mapname = %s   text[0] = %s\n",map[iden].mapname,text0);
      strcat(map[iden].mapname,".den");
      itoa(iden,ich);
      strcat(map[iden].mapname,ich);
      saveden(map[iden]);
      writemaidfile(0,maidfile,map,bone); //"0" indicates use old file names
      XtSetSensitive(sc.mappullright[iden],1);//Turn on sensitivitivity  
      if (widget = XtNameToWidget (sc.mappullright[iden], buttonname[0]))
            XtVaSetValues (widget, XmNset, True, NULL);
      Widget shell = (Widget) client_data;
      XtDestroyWidget (shell);
   } // mapfile exists
}


void file_addmap_dialog(Widget w)
{
    Widget dialog, rc;
    XmString string;
    Arg args[5];
    int n = 0;
    static ActionAreaItem action_items[] = {
        { "OK",     map_ok_pushed,     NULL          },
        { "Clear",  clear_pushed,  NULL          },
        { "Cancel", close_dialog,  NULL          },
        { "Help",   help,          "Help Button" },
    };
    /* Create a TemplateDialog that will contain the control area
     * and the action area buttons for the dialog
     */
    string = XmStringCreateLocalized ("Dialog Shell");
    XtSetArg (args[n], XmNdialogTitle, string); n++;
    XtSetArg (args[n], XmNautoUnmanage, False); n++;
    dialog = XmCreateTemplateDialog (toplevel, "dialog", args, n);
    XmStringFree (string);

    /* now that the dialog is created, set the Cancel button's
     * client data, so close_dialog() will know what to destroy.
     */
    action_items[0].data=action_items[2].data = (XtPointer) dialog;

    /* create the control area which contains a
     * Label gadget and a TextField widget.
     */
    ss.num=1; // the number of data entries spaces
    rc = XtVaCreateWidget ("control_area", 
        xmRowColumnWidgetClass, dialog, NULL);
    string = XmStringCreateLocalized ("ENTER NAME OF MAP FILE :");
    XtVaCreateManagedWidget ("label", xmLabelGadgetClass, rc,
        XmNlabelString,    string,
        NULL);
    XmStringFree (string);
    ss.w[0] = XtVaCreateManagedWidget ("text-field",xmTextFieldWidgetClass, rc, NULL);
    XtManageChild (rc);

    /* Set the client data for the "OK" and "Clear" buttons */
  
    /* Create the action area. */
    CreateActionArea (dialog, action_items, XtNumber (action_items));

    /* callback for Return in TextField.  Use dialog as client data */
#if 0 // I do not think this should be called if use action_items */
    XtAddCallback (ss.w[0], XmNactivateCallback, activate_cb, dialog);
#endif

    XtManageChild (dialog);
    XtPopup (XtParent (dialog), XtGrabNone);
    glClearColor(backcolv[0],backcolv[1],backcolv[2],0);//background color :red, green, blue, and alpha = black
}

void file_cb(Widget widget,XtPointer client_data,XtPointer  call_data)
// maidfile.start = 1 (just beginning); 2 (have created maid file); 3 (have read maidfile)
//        if >0  draw cube  - else drawmodel
{
    int item_no = (int) client_data;
    switch(item_no){
      case 0: //The New item
         maidfile.start = 1;  //Set in main.c++ - This indicates just starting - draw simple cube
         file_new_dialog(toplevel);
         maidfile.start = 2;  // Indicates have created maid file
         break;
      case 1:  // The Old item
         file_old_dialog(toplevel);
         maidfile.start = 3;  // Indicates have read maid file
         break;
      case 2: // The run item
          if(maidfile.start == 1){
             errormessage(toplevel,"ERROR: Must first choose 'OLD' or 'NEW' options");
             goto endrun;
          }
          maidfile.start = 0; //maidfile.start = 2 or 3;  from now on draw pdb, not cube
#if 0 
// simple test routine - slowly changes color of cue 
    int i;
         for(i=0;i<=2;i++)
             sc.cubecol[i]= redv[i];
         sc.run_wpid = XtAppAddWorkProc(sc.appctx, test_proc,&sc.drawwind1);
#endif
         endrun:;
         break;
      case 3: // window on/off
         sc.windowselect = -sc.windowselect;
         break;
      case 4: // addpdb
         file_addpdb_dialog(toplevel);
         break;
      case 5: // addmap
         file_addmap_dialog(toplevel);
         break;
      case 6: // drawgrid
         sc.drawgrid = -sc.drawgrid;
         break;
      case 7: // The stop item
	if (sc.run_wpid) { // If running, kill
	    XtRemoveWorkProc(sc.run_wpid);
	    sc.run_wpid = 0;
        }
        break;
      case 8: // The quit item
        exit (0);
        break;
    }
}

#if 0 // moved to initialize.c++
void readmap(char filename[],struct griddata& den1)
// New 12jul00 - must be sure can read long enough line
//    increase dimension to 2000
{
	char name[2000],order[3];
	int i,j,k,ntitle,nless,nmore;
	float dd,dds;
        FILE *fp;

        if( (fp=fopen(filename,"r")) == NULL){
          printf("error opening file %s\n",filename);
          exit(0);
        } 
        printf("Reading XPLOR map file %s\n",filename);
	fgets(name,200,fp); /* read top blank line */
	fgets(name,200,fp); /* read number of title lines */
	sscanf(name,"%d",&ntitle);
	for(i=1;i<=ntitle;i++)
             fgets(name,1999,fp);  /* read title - discard */
	fgets(name,200,fp); /* read section data */
	sscanf(name,"%d%d%d%d%d%d%d%d%d",&den1.na[0],&den1.amin[0],
                       &den1.amax[0],&den1.na[1],&den1.amin[1],
                       &den1.amax[1], &den1.na[2],&den1.amin[2],
                       &den1.amax[2]);
#if 0
        for(i=0;i<3;i++)
           den1.griddim[i]=den1.amax[i]-den1.amin[i]+2;/* the +2 is needed for iden array*/
        printf("Allocating den array dimensions %d %d %d\n",
                           den1.griddim[0],den1.griddim[1],den1.griddim[2]);
        scmat3(den1.den,den1.griddim[0],den1.griddim[1],den1.griddim[2]);// allocates array 3 dim array (mat)
                     // of type  unsigned char - n1,n2,n3,n4 size of each dimension
#endif
	fgets(name,200,fp); /* read unit cell data */
	sscanf(name,"%f%f%f%f%f%f",&den1.cell[1],&den1.cell[2],&den1.cell[3],
                                   &den1.cell[4],&den1.cell[5],&den1.cell[6]);
        initializemap(den1);
        initializemapscreen(den1);
	fgets(name,200,fp); /* read matrix order */
	sscanf(name,"%3s",order);
	if( (order[0] != 'Z')  || (order[1]!='Y')  || (order[2]!='X') ){
            printf("ERROR: Not a formated XPLOR map\n");
            exit(0);
        }
	/* read matrix map values */
        nless=nmore=0;
	for(k=0;k<=den1.amax[2]-den1.amin[2];k++) {
                printf("Reading k section %d\n",k);
		fscanf(fp,"%s",name); /* read k section name and discard*/
		for(j=0;j<=den1.amax[1]-den1.amin[1];j++) {
	           for(i=0;i<=den1.amax[0]-den1.amin[0];i++) {
                      fscanf(fp,"%12f",&dd);
                      dds=dd*maidfile.denscale;
                      if(dds>MAXCHAR){//maxchar = 127 is maximum real density                         
                         dds=MAXCHAR;
                         nmore=nmore+1;
                      }
                      if(dds< -MAXCHAR+1){ // save dds = -MAXCHAR for use in bones routines
                           nless=nless+1;
                           dds= -MAXCHAR+1;
                      }
                      den1.den[i][j][k]=dds;
		     }
		}
	}
        printf("# of den > maxchar = %d; # < -maxchar = %d\n",nmore,nless);
	fclose(fp);
        printf("Done\n");
}
#endif

#if 0 // moved to intialize.c++
void saveden(struct griddata den1)
{
   long i,j,k;
   FILE *fps;

   printf("Saving the density in file %s\n",den1.mapname);
   fps=fopen(den1.mapname,"wb");
   fwrite(&den1.na[0],sizeof(den1.na[0]),3,fps);
   fwrite(&den1.amin[0],sizeof(den1.amin[0]),3,fps);
   fwrite(&den1.amax[0],sizeof(den1.amax[0]),3,fps);
   fwrite(&den1.cell[1],sizeof(den1.cell[1]),6,fps);
   for(k=0;k<=den1.amax[2]-den1.amin[2];k++) 
       for(j=0;j<=den1.amax[1]-den1.amin[1];j++) 
	    for(i=0;i<=den1.amax[0]-den1.amin[0];i++) 
                fwrite(&den1.den[i][j][k],sizeof(den1.den[i][j][k]),1,fps);
   fclose(fps);
   printf("Done\n");
}
#endif

void initializemapscreen(struct griddata& den1)
/* This is screen stuff originally in initialize map
  New initializemap with this removed is now in bone.c++
*/
{
    int i;

    for(i=0;i<=2;i++) // Use default contour radius
          den1.crange[i]=sc.contourradius/den1.delx[i];
    den1.contonoff = -1;
    den1.selectcontonoff = -1;
    for(i=0;i<3;i++)
       den1.color[i]=bluev[i];
    den1.conlevel = sc.conlevel*maidfile.denscale;  // Set contourleve to default value
    // Allocate arrays for contour routines
    den1.ntri = NTRI/(den1.delx[0]*den1.delx[1]*den1.delx[2]); // Scale ntri relative del = 1
printf("Allocating arrays for contour routines  ntriangles = %d\n",den1.ntri);
    imat2(den1.tri,den1.ntri,9);
printf("   Done\n");
}
