/* Command decoding, user interface, calls hide */
#include "general.h"
#include "gsurface.h"

#if (defined DJ || defined EMXOS2)       /* a.r. */ 
        #define unix
#endif

#ifdef EMXOS2
        #define ERRFILENAME "GLEOS2.ERR"
        extern FILE *openErrFile(char *fname);
        extern int closeErrFile(FILE *errfile);
        int flagSURFOS2 = 1;
        FILE *ErrFileSURFOS2;
        char outputName[80];
#endif

#ifdef unix
#define VAXC 1
#endif
#ifdef VAXC
#define huge
#define farmalloc malloc
#define farfree free 
#endif
#ifdef unix
char *strlwr(char *);
#endif
char *(*gtxt)[];   /* gtxt is a pointer to an array of poiter to char */
int ngtxt=0;
int gle_debug;
int noscreenio = false;
int nobigfile;

FILE *df;

int hide(float huge *z,int nx, int ny, float minz, float maxz, struct surface_struct *sff);
int scr_end(void);
typedef char *TOKENS[];
int token(char *lin,TOKENS tok,int *ntok,char *outbuff);
int hide_enddefaults(void);

int gle_abort(char *s);
int init_memory(void);
int scr_init(void);
int text_expand(int x);
int token_space(void);
int hide_defaults(void);
int pass_line(void);
char *gletop();
char *getstrv(void);
char *sdup(char *s);
int text_load(char *fname);
int text_free(void);
int do_help(char *s);
int int_edt(char *fname);
int pass_title(void);
int pass_cube(void);
int pass_top(void);
int pass_bot(void);
int pass_marker(void);
int pass_droplines(void);
int pass_riselines(void);
int pass_back(void);
int pass_right(void);
int pass_base(void);
int pass_axis(void);
int pass_anytitle(void);
void cmdline_help(char *s);

int getstr(char *s);
float getf(void);
int geton(void);
FILE *myfopen(char *fname, char *mode);
int pass_data(int *nx, int *ny, float *zmin, float *zmax);
extern int trace_on,this_line;
int ngerror;
char input_file[80];

int batch_only=false;
int draw_it, gotfile = false;
char glearg0[66];
char gleroot[60];
static int xsample,ysample;
#ifdef unix
#include "../../glepath.h"
#endif
main(int argc, char **argv)
{
        char dtype[60];
        char fname[60],*ss;
        int i;

        i=1;
        trace_on = false;

/*---------------------------------------------------------------------------*/
        strcpy(gleroot,argv[0]);
#ifdef unix
        dtype[0] = 0;
        ss = getenv("GLE_TOP");
        if (ss==NULL) ss = GLEPATH;
        strcpy(gleroot,ss);
        strcat(gleroot,"/");
#endif
#ifdef __TURBOC__
        ss = strchr(gleroot,'\\');
        if (ss==NULL) gle_abort("Unable to locate files AGRV[0] wrong");
        for (;strchr(ss+1,'\\')!=NULL;) ss = strchr(ss+1,'\\');
        *(ss+1) = 0;
#endif
        strcpy(fname,"test.sur");
        init_memory(); /* saves some memory for emergencies */
        if (argc>1) {
           strupr( argv[1] );
           strcpy(fname, argv[1]);
           gotfile = true;
        }
        for (i=1;i<argc; i++) {
                strupr(argv[i]);
                if (strncmp(argv[i],"-H",2)==0)  cmdline_help(argv[0]);
                if (strncmp(argv[i],"/H",2)==0)  cmdline_help(argv[0]);
                if (strncmp(argv[i],"-B",2)==0)  batch_only = true;
                if (strncmp(argv[i],"/B",2)==0)  batch_only = true;
                if (strncmp(argv[i],"/D",2)==0)  draw_it = true;
                if (strncmp(argv[i],"-D",2)==0)  draw_it = true;
               #ifdef EMXOS2                                            /* a.r. */
                if (strncmp(argv[i],"/O",2)==0)
                        strcpy(outputName,argv[++i]);
                if (strncmp(argv[i],"-O",2)==0)
                        strcpy(outputName,argv[++i]);
               #endif
        }
        strlwr(fname);
        if (batch_only)
           noscreenio =true;
        else
           scr_init();

        if (strchr(fname,'.')==NULL) strcat(fname,".sur");
        strcpy(input_file,fname);
        text_expand(50); /* Initially allocate 500 lines of text */
        if (gotfile)
           text_load(fname);
        /* IF VAX THEN JUST CALL DRAW_HIDDEN */
        if (draw_it) {
               #ifdef EMXOS2                                    /* a.r. */
                ErrFileSURFOS2 = openErrFile(ERRFILENAME);
                draw_hidden();
                closeErrFile(ErrFileSURFOS2);
                scr_end();
               #else
                draw_hidden();
                scr_end();
               #endif
        } else {
                if (batch_only) 
                   draw_hidden();
                else 
                   int_edt(fname);
                if (!batch_only)
                   scr_end();
        }
#ifdef EMXOS2                                                   /* a.r. */
        unlink("GLEOS2.TMP");
        if (!(draw_it))
                unlink("GLEOS2.ERR");
        unlink("SURFOS2.GLE");
        unlink("SURFOS2.BIG");
        unlink("SURFOS2.TMP");
#endif
}
static char inbuff[200];
static char tkbuff[500];
static char *tk[500];
static int ntok,ct;
static struct surface_struct sf;
static float zmin = 10e10,zmax = -10e10;
static float huge *z;
static int nx,ny;
static int insurf,gotsurf;
static double dxmin,dymin,dxmax,dymax;
double zclipmin,zclipmax;
int zclipminset,zclipmaxset;
draw_hidden()
{
        int i,dri,al;
        int32 li;
        static char *space_str = " ";
        
        xsample = 1; ysample = 1;
        zclipmin = 0;  zclipminset = false;
        zclipmax = 0;  zclipmaxset = false;
        nobigfile = 0;
 
        strcpy(sf.zcolour,"");
        dxmin = dymin = dxmax = dymax = 0;
        zmin = 10e10; zmax = -10e10;
        ngerror = 0;
        token_space();
        for (i=0;i<500;i++) tk[i] = space_str;
        insurf = false; gotsurf = false;
        hide_defaults();
        for (dri=1;dri<=ngtxt;dri++) {
                strcpy(inbuff, (*gtxt)[dri]);
                al = strlen(inbuff);
                if (trace_on) gprint("Source | %s \n",inbuff);
                token(inbuff,tk,&ntok,tkbuff);
                this_line = dri;
                pass_line();
        }
        if (!gotsurf) {
                gprint("Expecting BEGIN SURFACE ... END SURFACE \n");
                return;
        }
        if (nx==0 || ny==0) {
                gprint("No zdata to plot \n");
                return;
        }
        if (zclipminset || zclipmaxset) {
                for (li=0;li< (int32) nx* (int32)ny;li++) {
                        if (zclipminset) if (z[li]<zclipmin) z[li] = zclipmin;
                        if (zclipmaxset) if (z[li]>zclipmax) z[li] = zclipmax;
                }
                if (zclipminset) zmin = zclipmin;
                if (zclipmaxset) zmax = zclipmax;
        }
        hide_enddefaults();

        hide(z,nx,ny,zmin,zmax,&sf);        
}
#define kw(k) if (strcmp(tk[ct],k)==0) 
char *getstrv()
{
        char *s;
        if (ct>=ngtxt) { gprint("Expecting string \n"); return NULL;}
        s = sdup(tk[++ct]);
        if (*s == '"') {        /* remove quotes if exist */
                strcpy(s,tk[ct]+1);
                s[strlen(s)-1] = 0;
        }
        return s;
}                
getstr(char *s)
{
        if (ct>=ngtxt) { gprint("Expecting Color or Lstyle\n"); return;}
        strncpy(s,tk[++ct],11);
}                
float getf()
{
        if (ct>=ngtxt) gprint("Expecting Number\n");
        return atof(tk[++ct]);
}
int geton()
{
        if (ct>=ngtxt) gprint("Expecting ON | OFF\n");
        ct++;
        if (strcmp(tk[ct],"ON")==0) return true;
        if (strcmp(tk[ct],"OFF")==0) return false;
        gprint("Expecting ON | OFF, asuming ON\n");
        return true;
}
pass_line()
{
        int i;
/*        for (i=1; i<ntok; i++) printf("Token {%s} \n",tk[i]); */
        ct = 1;        /* current token */

        if (ntok<1) return;
        kw("BEGIN") {if (strcmp(tk[++ct],"SURFACE")==0) insurf = true; return; }
        if (!insurf) return;
        gotsurf = true;
             kw("END") {if (strcmp(tk[++ct],"SURFACE")==0) insurf = false;}
        else kw("SIZE") {sf.screenx = getf(); sf.screeny = getf();}
        else kw("TITLE") pass_title();
        else kw("CUBE") pass_cube();
        else kw("DATA") {pass_data(&nx,&ny,&zmin,&zmax);        }
        else kw("ROTATE") {sf.xrotate = getf(); sf.yrotate = getf(); sf.zrotate = getf();} 
        else kw("EYE") {sf.eye_x = getf(); sf.eye_y = getf(); sf.vdist = getf();} 
        else kw("VIEW") {sf.eye_x = getf(); sf.eye_y = getf(); sf.vdist = getf();} 
        else kw("HARRAY") sf.maxh = getf();
        else kw("ZCLIP") pass_zclip();
        else kw("SKIRT") sf.skirt_on = geton();
        else kw("XLINES") sf.xlines_on = geton();
        else kw("YLINES") sf.ylines_on = geton();
        else kw("TOP") pass_top();
        else kw("UNDERNEATH") pass_bot();
        else kw("HIDDEN") sf.hidden_on = geton();
        else kw("MARKER") pass_marker();
        else kw("POINTS") pass_points();
        else kw("DROPLINES") pass_droplines();
        else kw("RISELINES") pass_riselines();
        else kw("HIDDEN") sf.hidden_on = geton();
        else kw("BASE") pass_base();
        else kw("BACK") pass_back();
        else kw("RIGHT") pass_right();
        else kw("ZCOLOUR") getstr(sf.zcolour);
        else kw("ZCOLOR") getstr(sf.zcolour);
        else if (strstr(tk[1],"NOBIGFILE")!=NULL) nobigfile = 1;
        else if (strstr(tk[1],"AXIS")!=NULL)  pass_axis();
        else if (strstr(tk[1],"TITLE")!=NULL)  pass_anytitle(); 
 
        if (ct<ntok) {
                gprint("Extra parameters on end of line {%s} \n",tk[ct]);
         }
}
pass_title()
{
        sf.title = getstrv();
        for (ct++;ct<=ntok;ct++) {
                kw("HEI") sf.title_hei = getf();
                else kw("DIST") sf.title_dist = getf();
                else kw("COLOR") getstr(sf.title_color);
                else gprint("Expecting one of HEI, DIST, COLOR , found {%s} \n",tk[ct]);
        }
}
pass_anytitle()
{
        struct axis_struct *ax;
        if (*tk[ct]=='X') ax = &sf.xaxis;
        if (*tk[ct]=='Y') ax = &sf.yaxis;
        if (*tk[ct]=='Z') ax = &sf.zaxis;
        
        ax->title = getstrv();
        for (ct++;ct<=ntok;ct++) {
                kw("HEI") ax->title_hei = getf();
                else kw("DIST") ax->title_dist = getf();
                else kw("COLOR") getstr(ax->title_color);
                else gprint("Expecting one of HEI, DIST, COLOR , found {%s} \n",tk[ct]);
        }
}
pass_cube()
{
        for (ct++;ct<=ntok;ct++) {
                kw("ON") sf.cube_on = true;
                else kw("OFF") sf.cube_on = false;
                else kw("NOFRONT") sf.cube_front_on = false;
                else kw("FRONT") sf.cube_front_on = geton();
                else kw("LSTYLE") getstr(sf.cube_lstyle);
                else kw("COLOR") getstr(sf.cube_color);
                else kw("XLEN") sf.sizex = getf();
                else kw("YLEN") sf.sizey = getf();
                else kw("ZLEN") sf.sizez = getf();
                else gprint("Expecting one of OFF, XLEN, YLEN, ZLEN, FRONT, LSTYLE, COLOR, found {%s} \n",tk[ct]);
        }

}
pass_zclip()
{
        for (ct++;ct<=ntok;ct++) {
                kw("MIN") { zclipmin = getf(); zclipminset = true; }
                else kw("MAX") { zclipmax = getf(); zclipmaxset = true; }
                else gprint("Expecting one of MIN, MAX found {%s} \n",tk[ct]);
        }
}
pass_back()
{
        for (ct++;ct<=ntok;ct++) {
                kw("YSTEP") sf.back_ystep = getf();
                else kw("ZSTEP") sf.back_zstep = getf();
                else kw("LSTYLE") getstr(sf.back_lstyle);
                else kw("COLOR") getstr(sf.back_color);
                else kw("NOHIDDEN") sf.back_hidden = false;
                else gprint("Expecting one of YSTEP, ZSTEP, LSTYLE, COLOR found {%s} \n",tk[ct]);
        }
}
pass_right()
{
        for (ct++;ct<=ntok;ct++) {
                kw("ZSTEP") sf.right_zstep = getf();
                else kw("XSTEP") sf.right_xstep = getf();
                else kw("LSTYLE") getstr(sf.right_lstyle);
                else kw("COLOR") getstr(sf.right_color);
                else kw("NOHIDDEN") sf.right_hidden = false;
                else gprint("Expecting one of ZSTEP, XSTEP, LSTYLE, COLOR found {%s} \n",tk[ct]);
        }
}
pass_base()
{
        for (ct++;ct<=ntok;ct++) {
                kw("XSTEP") sf.base_xstep = getf();
                else kw("YSTEP") sf.base_ystep = getf();
                else kw("LSTYLE") getstr(sf.base_lstyle);
                else kw("COLOR") getstr(sf.base_color);
                else kw("NOHIDDEN") sf.base_hidden = false;
                else gprint("Expecting one of XSTEP, YSTEP, LSTYLE, COLOR found {%s} \n",tk[ct]);
        }
}
pass_droplines() /* toplines lstyle color hidden */
{
        sf.droplines = true;
        for (ct++;ct<=ntok;ct++) {
                kw("LSTYLE") getstr(sf.droplines_lstyle);
                else kw("COLOR") getstr(sf.droplines_color);
                else kw("HIDDEN") sf.droplines_hidden = true;
                else gprint("Expecting one of LSTYLE, COLOR , found {%s} \n",tk[ct]);
        }

}
pass_riselines() /* toplines lstyle color hidden */
{
        sf.riselines = true;
        for (ct++;ct<=ntok;ct++) {
                kw("LSTYLE") getstr(sf.riselines_lstyle);
                else kw("COLOR") getstr(sf.riselines_color);
                else kw("HIDDEN") sf.riselines_hidden = true;
                else gprint("Expecting one of LSTYLE, COLOR , found {%s} \n",tk[ct]);
        }

}
pass_top() /* top lstyle color off */
{
        for (ct++;ct<=ntok;ct++) {
                kw("LSTYLE") getstr(sf.top_lstyle);
                else kw("COLOR") getstr(sf.top_color);
                else kw("ON") sf.top_on = true;
                else kw("OFF") sf.top_on = false;
                else gprint("Expecting one of OFF, LSTYLE, COLOR , found {%s} \n",tk[ct]);
        }
}
pass_bot() 
{
        sf.bot_on = true;
        for (ct++;ct<=ntok;ct++) {
                kw("LSTYLE") getstr(sf.bot_lstyle);
                else kw("COLOR") getstr(sf.bot_color);
                else kw("ON") sf.bot_on = true;
                else kw("OFF") sf.bot_on = false;
                else gprint("Expecting one of ON, OFF, LSTYLE, COLOR , found {%s} \n",tk[ct]);
        }
}
pass_marker() 
{
        getstr(sf.marker);
        for (ct++;ct<=ntok;ct++) {
                kw("COLOR") getstr(sf.marker_color);
                else kw("HEI") sf.marker_hei = getf();
                else gprint("Expecting MARKER markername COLOR c HEI h, found {%s} \n",tk[ct]);
        }
}
pass_axis()
{
        struct axis_struct *ax=NULL;
        if (*tk[ct]=='X') ax = &sf.xaxis;
        if (*tk[ct]=='Y') ax = &sf.yaxis;
        if (*tk[ct]=='Z') ax = &sf.zaxis;
        if (ax==NULL) { gprint("Expecting xaxis,yaxis,zaxis,  \n"); return;}

        for (ct++;ct<=ntok;ct++) {
                     kw("MIN") {ax->min = getf(); ax->minset = true;}
                else kw("MAX") {ax->max = getf(); ax->maxset = true;}
                else kw("DTICKS") ax->step = getf();
                else kw("TICKLEN") ax->ticklen = getf();
                else kw("LEN") ax->ticklen = getf();
                else kw("COLOR") getstr(ax->color);
                else kw("STEP") ax->step = getf();
                else kw("HEI") ax->hei = getf();
                else kw("OFF") ax->on = false;
                else kw("ON") ax->on = true;
                else kw("NOFIRST") ax->nofirst = true;
                else kw("NOLAST") ax->nolast = true;
                 else gprint("Expecting HEI, DIST, COLOR , TICKLEN, MIN, MAX, STEP, found {%s} \n",tk[ct]);
        }
}
static char buff[2032];
FILE *myfopen(char *fname, char *mode);
int alloc_zdata(int nx, int ny);
alloc_zdata(int nx, int ny)
{
        if (z!=NULL) farfree(z);
        z = farmalloc((int32) nx * ((int32) ny+1) * sizeof(float));
        if (z==NULL) {
                gprint("Unable to allocate enough memory for datafile\n");
                return true;
        }
        return false;
}
double getkeyval(char *buff,char *k);
double getkeyval(char *buff,char *k)
{
        char *s;
        s = strstr(buff,k);
        if (s!=NULL) return atof(s+strlen(k));
        return 0.0;
}
pass_data(int *nx, int *ny, float *zmin, float *zmax)        /* data test.z [nx ny] */
{        
        double v;
        int32 x,y,xx,yy;
        int c,b,mx,my,xcnt,ycnt;
        char *s;
        char *fname;
        int i;

        xx = yy = x = y = 0;
        fname = getstrv();
         *nx = 0; *ny = 0;
        for (ct++;ct<=ntok;ct++) {
                kw("NX") *nx = getf();
                else kw("NY") *ny = getf();
                else kw("XSAMPLE") xsample = getf();
                else kw("YSAMPLE") ysample = getf();
                else kw("SAMPLE") {xsample = getf(); ysample = xsample; }
                else gprint("Wanted DATA file.Z  XSAMPLE YSAMPLE SAMPLE NX NY. Found {%s} \n",tk[ct]);
        }
        if (*nx != 0) {
                mx = (*nx - 1)/xsample + 1;
                my = (*ny - 1)/ysample + 1;
        }
        xcnt = xsample; ycnt = ysample;

        if (nx==NULL || ny==0) printf("nx or ny is zero \n");
        if (*nx!=0 && *ny != 0)   if (alloc_zdata(*nx,*ny)) return;
        df = myfopen(fname,"r");
        if (df==NULL) {*nx = 0; *ny = 0; return;}
        for (;!feof(df);) {
          if (fgets(buff,2000,df)!=NULL) {
                if (*nx==0) {
                        strupr(buff);
                        *nx  = getkeyval(buff,"NX");
                        *ny  = getkeyval(buff,"NY");
                        dxmin = getkeyval(buff,"XMIN");
                        dymin = getkeyval(buff,"YMIN");
                        dxmax = getkeyval(buff,"XMAX");
                        dymax = getkeyval(buff,"YMAX");
                        if (*nx==0 || *ny==0) {
                                gprint("Expecting ! NX 10 NY 10  in first line of data file \n");
                                return;
                        }
                        mx = (*nx - 1)/xsample + 1;
                        my = (*ny - 1)/ysample + 1;
                        if (alloc_zdata(mx,my)) return;
                        fgets(buff,2000,df);
                }
check_again:
                b = strlen(buff);
                c = buff[b-1];
                if (strchr(" \n\t",c)==NULL) { /* we're halfway thru a number */
                        buff[b] = getc(df);
                        buff[b+1] = 0;
                        goto check_again;
                }
                s = strchr(buff,'!');
                if (s!=NULL) *s = 0;
                s = strtok(buff," \t\n,");
                for (;s!=NULL;) {
                        v = atof(s);
                        if (isdigit(*s) || *s=='-' || *s=='+' || *s=='.') {
                                if (x>= *nx) {
                                        if (ycnt==ysample) {ycnt = 0; yy++;}
                                        x = 0; y++; ycnt++; xx = 0; xcnt = xsample;
                                        if (abortkey()) goto abort_data;
                                }
                                if (y>= *ny) {
                                        gprint("Too much data in data file %ld %d \n",y,*ny);
                                        return;
                                }
                                if (v < *zmin) *zmin = v;
                                if (v > *zmax) *zmax = v;

                                if (xx<mx && xcnt==xsample && ycnt==ysample) {
                                        z[xx + yy * (int32) mx] = v;        
                                        xx++;        
                                        xcnt = 0; 
                                }
                                xcnt++; 
                                x++;
                        } else gprint("Not a number {%s} \n",s);
                        s = strtok(NULL," \t\n,");
                }        
          }
        }
        fclose(df);
        *ny = my;
        *nx = mx;
        return;
abort_data:
        fclose(df);
        *nx = 0; *ny = 0;
        return;
}
float *pntxyz;
int npnts;
pnt_alloc(int size)
{
        static cursize;
        void *d;
        if (size+10<cursize) return;
        size = size*2;
        d = farmalloc(size*sizeof(float));
        if (d==NULL) {
                gprint("Unable to allocate storage for POINTS data\n");
                gle_abort("memory shortage\n");
        }
        if (cursize>0) memcpy(d,pntxyz,cursize*sizeof(float));
        cursize = size;
        pntxyz = d;
}
pass_points()
{
        double v;
        char *s;
        char *fname;
        int i,nd,nc;
        fname = getstrv();

        pnt_alloc(30);

        if (ct>ngtxt) {
                gprint("Expecting POINTS filename.xyz \n");
                return;
        }
                        
        df = myfopen(fname,"r");
        if (df==NULL) return;
        nd = 0;
        for (;!feof(df);) {
          if (fgets(buff,2000,df)!=NULL) {
                s = strchr(buff,'!');
                if (s!=NULL) *s = 0;
                nc = 0;
                s = strtok(buff," \t\n,");
                for (;s!=NULL;) {
                        v = atof(s);
                        pnt_alloc(nd);
                        if (isdigit(*s) || *s=='-' || *s=='+' || *s=='.') {
                                pntxyz[nd++] = v; nc++;
                        } else gprint("Not a number {%s} \n",s);
                        s = strtok(NULL," \t\n,");
                }
                if (nc>0 && nc!=3) {
                        gprint("Expecting 3 columns in data file, found %d (FATAL ERROR) \n",nc);
                }
          }
        }
        fclose(df);
        npnts = nd;
        sf.pntxyz = pntxyz;
        sf.npnts = npnts;
}
hide_enddefaults() /* defaults after data and commands read */
{
        if (dxmin==dxmax) dxmax = nx-1;
        if (dymin==dymax) dymax = ny-1;
        if (!sf.xaxis.maxset)  sf.xaxis.max = dxmax;
        if (!sf.yaxis.maxset)  sf.yaxis.max = dymax;
        if (!sf.xaxis.minset)  sf.xaxis.min = dxmin;
        if (!sf.yaxis.minset)  sf.yaxis.min = dymin;
        if (!sf.zaxis.minset)  sf.zaxis.min = zmin;
        if (!sf.zaxis.maxset)  sf.zaxis.max = zmax;
        if (sf.zrotate==0 && sf.xrotate==0 && sf.yrotate==0) {
                sf.xrotate = 60;
                sf.yrotate = 50;
                sf.zrotate = 20;        /* not needed as is corrected later*/
        }
        if (sf.eye_x== -1) {
                sf.eye_x = sf.sizex/2.0;
                sf.eye_y = sf.sizex/2.0;
        }

}

hide_defaults()
{
        /* Setup some defaults, */
        memset(&sf,0,sizeof(sf));
        sf.sizey = sf.sizex = 18;
        sf.sizey = sf.sizex = sf.sizez = 18;
        sf.screenx = 18; sf.screeny = 18;
        sf.eye_x = -1;
        sf.zaxis.type = 2;
        sf.yaxis.type = 1;
        sf.xaxis.on = sf.yaxis.on = sf.zaxis.on = true;
        sf.cube_hidden_on = true;
        sf.cube_on = true;
        sf.cube_front_on = false;
        sf.xlines_on = true;
        sf.ylines_on = true;
        sf.hidden_on = true;
        sf.top_on = true;        
        sf.bot_on = false;
        sf.base_hidden = sf.right_hidden = sf.back_hidden = true;
}
FILE *myfopen(char *fname, char *mode)
{
        FILE *f;
        f = fopen(strlwr(fname),mode);
        if (f==NULL) {
                gprint("Unable to open {%s} \n\n",fname); perror("");
                return NULL;
        }
        return f;
}
abortkey()
{
#ifndef EMXOS2                                          /* a.r. */
        if (!kbhit()) return false;
        printf("Press ESC again: \n");
        if (scr_getch()==27) return true;
        else return false;
#else
        extern int peekMsg(void);

        peekMsg();      /* prevents locking PM's single message queue */
        return false;
#endif
}
char *gle_top()
{
        char s[80];
#ifdef __TURBOC__
        return gleroot;
#elif ( defined DJ || defined EMXOS2 || defined unix)
        strcpy(s,gleroot);
        strcat(s, "/");
        return s;
#else
        return "cgle_top:";
#endif
}
char *gledir(char *s);
char *bgidir()
{
#ifdef __TURBOC__
        char *s;
        s = getenv("GLE_BGI");
        if (s==NULL) {
                s = gledir("");
        }
        return s;
#endif
}

char *fontdir(char *fname)
{
        static char fbuff[80];
#ifdef __TURBOC__
        strcpy(fbuff,gle_top());
        strcat(fbuff,"font\\");
#else
        strcpy(fbuff,"cgle_top:");
#endif
#ifdef unix
        strcpy(fbuff,gle_top());
        strcat(fbuff,"font/");
#endif
        strcat(fbuff,fname);
        return &fbuff[0];
}
char *gletopdir(char *fname)
{
        static char fbuff[80];
        strcpy(fbuff,gle_top());
        strcat(fbuff,fname);
        return fbuff;
}
char *gledir(char *fname)
{
        static char fbuff[80];
#ifdef __TURBOC__
        strcpy(fbuff,gle_top());
        strcat(fbuff,"exe\\");
#else
        strcpy(fbuff,"cgle_top:");
#endif
#ifdef unix
        strcpy(fbuff,gle_top());
#endif
        strcat(fbuff,fname);
        return &fbuff[0];
}

void cmdline_help(char *s)
{
fprintf(stderr, "\nUsage:\n");
fprintf(stderr, "%s filename [/b] [/d] [/o filename] [/h]\n", s);
fprintf(stderr, "	or:\n");
fprintf(stderr, "%s filename [-b] [-d] [-o filename] [-h]\n\n", s);
fprintf(stderr, "-b, /b : batch operation\n");
fprintf(stderr, "-o filename, /o filename : specify filename for bigfile (OS/2 only)\n");
fprintf(stderr, "-d, /d : draw-it, wait for keypress, don't edit\n");
fprintf(stderr, "-h, /h : give help for commandline switches\n\n");
exit(0);
}
