/* 
 * $Id: ox11dlg.c,v 1.5 2003/02/16 12:43:37 isizaka Exp isizaka $
 * 
 * This file is part of "Ngraph for X11".
 * 
 * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
 * 
 * "Ngraph for X11" 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.
 * 
 * "Ngraph for X11" 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

/**
 *
 * $Log: ox11dlg.c,v $
 * Revision 1.5  2003/02/16 12:43:37  isizaka
 * for release 6.13.18
 *
 * Revision 1.4  2002/07/06 08:57:25  isizaka
 * change to GPL.
 *
 * Revision 1.3  2001/03/23 12:17:43  isizaka
 * for 6.3.13
 *
 * Revision 1.2  1999/04/15 12:14:26  isizaka
 * for release 6.03.01
 *
 * Revision 1.1  1999/03/17 13:28:13  isizaka
 * Initial revision
 *
 *
 **/

#include <Xm/XmAll.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "ngraph.h"
#include "object.h"
#include "nstring.h"
#include "jstring.h"
#include "ioutil.h"

#include "x11gui.h"

#define NAME "dialog"
#define PARENT "object"
#define VERSION  "1.00.00"
#define TRUE  1
#define FALSE 0

extern int globallock;

#define ERRDISPLAY 100
#define ERRNODLGINST 101

#define ERRNUM 2

char *dlgerrorlist[ERRNUM]={
  "cannot open display.",
  "no instance for dialog",
};

Widget DLGTopLevel=NULL;

extern XtAppContext Application;
extern int OpenApplication();
extern Display *Disp;
extern char *AppName,*AppClass;
extern int OpenApplication();

void dialogclose(Widget w,XtPointer client_data,XtPointer call_data)
{
}

int dlginit(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  Arg al[20];
  Cardinal ac;
  Atom xa_wm_delete;

  if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
  if (!OpenApplication()) return 1;
  if (DLGTopLevel==NULL) {
    ac=0;
    XtSetArg(al[ac],XmNmappedWhenManaged,False);ac++;
    DLGTopLevel=
    XtAppCreateShell(AppName,AppClass,applicationShellWidgetClass,Disp,al,ac);
    XtVaSetValues(DLGTopLevel,XmNdeleteResponse,XmDO_NOTHING,NULL);
    xa_wm_delete=XmInternAtom(Disp,"WM_DELETE_WINDOW",False);
    XmAddWMProtocolCallback(DLGTopLevel,xa_wm_delete,dialogclose,NULL);
    ac=0;
    XtSetArg(al[ac],XmNwidth,WidthOfScreen(XtScreen(DLGTopLevel))); ac++;
    XtSetArg(al[ac],XmNheight,HeightOfScreen(XtScreen(DLGTopLevel))); ac++;
    XtSetValues(DLGTopLevel,al,ac);
    XtRealizeWidget(DLGTopLevel);
  }
  return 0;
}


int dlgdone(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
  return 0;
}

int dlgconfirm(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  char *mes;
  int rcode,locksave;

  mes=(char *)argv[2];
  locksave=globallock;
  globallock=TRUE;
  if (mes==NULL) mes="";
  rcode=MessageBox(DLGTopLevel,mes,"Select",MB_YESNO);
  globallock=locksave;
  if (rcode==IDYES) *(int *)rval=1;
  else *(int *)rval=0;
  return (rcode==IDYES)?0:1;
}

int dlgmessage(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  char *mes;
  int rcode,locksave;

  mes=(char *)argv[2];
  locksave=globallock;
  globallock=TRUE;
  if (mes==NULL) mes="";
  rcode=MessageBox(DLGTopLevel,mes,"Confirm",MB_OK);
  globallock=locksave;
  return 0;
}

int dlginput(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  char *mes;
  int locksave;
  char *inputbuf;
  char *s;

  locksave=globallock;
  globallock=TRUE;
  mes=(char *)argv[2];
  memfree(*(char **)rval);
  *(char **)rval=NULL;
  inputbuf=NULL;
  if ((DialogInput(DLGTopLevel,"Input",mes,&inputbuf)==IDOK) 
  && (inputbuf!=NULL)) {
    if ((s=memalloc(strlen(inputbuf)+1))!=NULL) {
      strcpy(s,inputbuf);
    }
    XtFree(inputbuf);
    *(char **)rval=s;
  } else {
    XtFree(inputbuf);
    globallock=locksave;
    return 1;
  }
  globallock=locksave;
  return 0;
}

int dlgbeep(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
{
  int locksave;

  locksave=globallock;
  globallock=TRUE;
  MessageBeep(DLGTopLevel);
  globallock=locksave;
  return 0;
}

int dlggetopenfile(struct objlist *obj,char *inst,char *rval,
                   int argc,char **argv)
{
  struct narray *array;
  char **d;
  int anum;
  char *filter;
  int locksave;
  int ret;
  char *file,*file2;

  locksave=globallock;
  globallock=TRUE;
  free(*(char **)rval);
  *(char **)rval=NULL;
  array=(struct narray *)argv[2];
  d=arraydata(array);
  anum=arraynum(array)/2;
  if ((anum>0) && (d[1]!=NULL)) filter=d[1];
  else filter=NULL;
  ret=nGetOpenFileName(DLGTopLevel,"Open file",NULL,NULL,NULL,
                       &file,filter,TRUE,TRUE);
  if (ret==IDOK) {
    if ((file2=memalloc(strlen(file)+1))!=NULL) {
      strcpy(file2,file);
      changefilename(file2);
      *(char **)rval=file2;
    }
  }
  free(file);
  globallock=locksave;
  return (ret==IDOK)?0:1;
}

int dlggetopenfiles(struct objlist *obj,char *inst,char *rval,
                   int argc,char **argv)
{
  struct narray *array;
  char **d;
  int anum;
  char *filter;
  int locksave;
  int ret,len;
  char *file,*s,*name;
  struct narray *farray;

  locksave=globallock;
  globallock=TRUE;
  memfree(*(struct narray **)rval);
  *(char **)rval=NULL;
  array=(struct narray *)argv[2];
  d=arraydata(array);
  anum=arraynum(array)/2;
  if ((anum>0) && (d[1]!=NULL)) filter=d[1];
  else filter=NULL;
  ret=nGetOpenFileNameMulti(DLGTopLevel,"Open files",NULL,NULL,NULL,
                            &file,filter,TRUE);
  if (ret==IDOK) {
    farray=arraynew(sizeof(char *));
    s=file;
    while ((name=getitok2(&s,&len," "))!=NULL) {
      changefilename(name);
      arrayadd(farray,&name);
    }
    *(struct narray **)rval=farray;
  }
  free(file);
  globallock=locksave;
  return (ret==IDOK)?0:1;
}

int dlggetsavefile(struct objlist *obj,char *inst,char *rval,
                   int argc,char **argv)
{
  struct narray *array;
  char **d;
  int anum;
  char *filter;
  int locksave;
  int ret;
  char *file,*file2;

  locksave=globallock;
  globallock=TRUE;
  free(*(char **)rval);
  *(char **)rval=NULL;
  array=(struct narray *)argv[2];
  d=arraydata(array);
  anum=arraynum(array)/2;
  if ((anum>0) && (d[1]!=NULL)) filter=d[1];
  else filter=NULL;
  ret=nGetSaveFileName(DLGTopLevel,"Save file",NULL,NULL,NULL,
                       &file,filter,TRUE);
  if (ret==IDOK) {
    if ((file2=memalloc(strlen(file)+1))!=NULL) {
      strcpy(file2,file);
      changefilename(file2);
      *(char **)rval=file2;
    }
  }
  free(file);
  globallock=locksave;
  return (ret==IDOK)?0:1;
}


#define TBLNUM 10

struct objtable dialog[TBLNUM] = {
  {"init",NVFUNC,NEXEC,dlginit,NULL,0},
  {"done",NVFUNC,NEXEC,dlgdone,NULL,0},
  {"next",NPOINTER,0,NULL,NULL,0},
  {"yesno",NIFUNC,NREAD|NEXEC,dlgconfirm,"s",0},
  {"message",NVFUNC,NREAD|NEXEC,dlgmessage,"s",0},
  {"input",NSFUNC,NREAD|NEXEC,dlginput,"s",0},
  {"beep",NVFUNC,NREAD|NEXEC,dlgbeep,NULL,0},
  {"get_open_file",NSFUNC,NREAD|NEXEC,dlggetopenfile,"sa",0},
  {"get_open_files",NSAFUNC,NREAD|NEXEC,dlggetopenfiles,"sa",0},
  {"get_save_file",NSFUNC,NREAD|NEXEC,dlggetsavefile,"sa",0},
};

void *adddialog()
{
  return addobject(NAME,NULL,PARENT,VERSION,TBLNUM,dialog,ERRNUM,dlgerrorlist,NULL,NULL);
}

