#include "config.h"
#include "misc.h"
#include "lisp.h"
#include "imf.h"

#include <tcl.h>
#include <tk.h>

#include "../tcltk/tkimf.h"

int imfsample_cmd PARAMS ((ClientData client_data, Tcl_Interp *interp,
			 int argc, char **argv));

int my_rid;
int numremotes;

Tk_Window tkwin;

Display *dpy;
int depth, screen;

char *read_suggest="", *write_suggest="";

void usage PARAMS ((void));

Tcl_Interp *interp;

/* MAXROWS, MAXCOLS, MINROWS, and MINCOLS can be changed safely */
#define MAXROWS 50
#define MAXCOLS 16
#define MINROWS 2
#define MINCOLS 8

#define MAXFAMS (MAXROWS*MAXCOLS)

int numfamilies;
extern char *outdirname;

extern int tmp_valid;

extern Tk_Window tmp_root_window;

int
load_imf_file_cmd(client_data, interp, argc, argv)
ClientData client_data;
Tcl_Interp *interp;
int argc;
char *argv[];
{
    load_imf_file(argv[1], NULL);
    sort_all_images();
    return TCL_OK;
}

int
get_imf_status_cmd(client_data, interp, argc, argv)
ClientData client_data;
Tcl_Interp *interp;
int argc;
char *argv[];
{
    sprintf(interp->result, "%d image families", numimages);
    return TCL_OK;
}

int
get_imf_name_cmd(ClientData cldata, Tcl_Interp *interp, int argc, char *argv[])
{
    int n;

    n = strtol(argv[1], NULL, 10);
    sprintf(interp->result, "%s", images[n]->name);
    return TCL_OK;
}

int
get_imf_numsizes_cmd(ClientData cldata, Tcl_Interp *interp, int argc, char *argv[])
{
    int n;

    n = strtol(argv[1], NULL, 10);
    sprintf(interp->result, "%d", images[n]->numsizes);
    return TCL_OK;
}

main(argc, argv)
int argc;
char *argv[];
{
    char *arg, *mask_color_name = NULL;
    char *stype;
    int i, nfsave;

    tk_init();

    init_lisp();

    imf_interp_hook = tk_interp_imf;
    imf_load_hook = tk_load_imf;

    dpy = Tk_Display(tkwin);
    tmp_root_window = tkwin;
    tmp_valid = TRUE;

    /* process non-X argument */
    for (i = 1; i < argc; ++i) {
	arg = argv[i];
	if (arg && !strcmp(arg, "-mc")) {
	    if (i + 1 < argc) {
		mask_color_name = xmalloc((2 + strlen(argv[i + 1])) * sizeof(char));
		strcpy(mask_color_name, argv[i + 1]);
		argv[i] = NULL;
		argv[i + 1] = NULL;
	    } else {
		low_init_error("No color following -mc");
		usage();
	    }
	} else if (arg && (!strcmp(arg, "-help") || !strcmp(arg, "--help"))) {
	    usage();
	} else if (arg && !strcmp(arg, "-o")) {
	    if (i+1 < argc) {
		outdirname = argv[i+1];
		/* Blast the arg because we'll be scanning the args again
		   and we want to ignore it then. */
		argv[i] = NULL;
		argv[i+1] = NULL;
		++i;
	    } else {
		low_init_error("No output directory following -o");
		usage();
	    }
	}
    }
    
    /* read the files */
    for (i = 1; i < argc; ++i) {
	if (argv[i] != NULL) {
	    read_suggest = write_suggest = argv[i];
	    /* try to guess the format and read the file */
	    if (!read_any_file(argv[i], NULL)) {
		run_warning("Couldn't read \"%s\"", argv[i]);
	    }
	}
    }

    sort_all_images();

    Tk_MakeWindowExist(tkwin);

    {
      int i;
      ImageFamily *imf;

      for (i = 0; i < numimages; ++i) {
	imf = images[i];
	if (imf->numsizes > 0 && imf_interp_hook != NULL)
	  imf = (*imf_interp_hook)(imf, NULL, FALSE);
	if (imf_load_hook != NULL)
	  imf = (*imf_load_hook)(imf);
	images[i] = imf;
      }
    }
    {
      char tclbuf[100];
      int i;

      strcpy(tclbuf, "set_initial_view");
      Tcl_Eval(interp, tclbuf);

      for (i = 0; i < numimages; ++i) {
	sprintf(tclbuf, ".images.content add imf \"%s\"", images[i]->name);
	Tcl_Eval(interp, tclbuf);
      }
    }

    Tk_MainLoop();
}

tk_init()
{
    Tcl_FindExecutable("imftk");

    interp = Tcl_CreateInterp();

    if (Tcl_Init(interp) == TCL_ERROR)
      return TCL_ERROR;

    if (Tk_Init(interp) == TCL_ERROR)
      return TCL_ERROR;

    Tcl_CreateCommand(interp, "load_imf_file", load_imf_file_cmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    Tcl_CreateCommand(interp, "get_imf_status", get_imf_status_cmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    Tcl_CreateCommand(interp, "get_imf_name", get_imf_name_cmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    Tcl_CreateCommand(interp, "get_imf_numsizes", get_imf_numsizes_cmd,
		      (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);

    tkwin = Tk_MainWindow(interp);

    Tcl_CreateCommand(interp, "imfsample", imfsample_cmd,
		      (ClientData) tkwin, (Tcl_CmdDeleteProc *) NULL);

    Tcl_EvalFile(interp, "../../xc7.2.x/tcltk/imftk.tcl");
}

void
usage()
{
    fprintf(stderr,
	  "usage: xshowimf [-mc mask color] [-o outdir] imfile ...\n");
    exit(1);
}

ImageFamily *
hack_find_imf(char *name)
{
  int i;

  for (i = 0; i < numimages; ++i)
    if (strcmp(images[i]->name, name) == 0)
      return images[i];
  return NULL;
}

extern void syntax_error PARAMS ((Obj *x, char *msg));

extern int numimages;

char *outdirname = NULL;
char *imflib = "";

LibraryPath *xconq_libs;

char spbuf[BUFSIZE];

char readerrbuf[1000];

/* This is needed because error handling refers to it. */

void
close_displays()
{
}

/* This is needed because error handling refers to it. */

int
write_entire_game_state(fname)
char *fname;
{
    return 0;
}

/* Need these so we can link in Lisp reader code. */

void
announce_read_progress()
{
}

void  
syntax_error(x, msg)
Obj *x;
char *msg;
{
    sprintlisp(readerrbuf, x, BUFSIZE);
    init_warning("syntax error in `%s' - %s", readerrbuf, msg);
}

void
low_init_error(str)
char *str;
{
    fprintf(stderr, "Error: %s.\n", str);
    fflush(stderr);
}

/* A warning just gets displayed, no other action is taken. */

void
low_init_warning(str)
char *str;
{
    fprintf(stdout, "Warning: %s.\n", str);
    fflush(stdout);
}

/* A run error is fatal. */

void
low_run_error(str)
char *str;
{
    fprintf(stderr, "Error: %s.\n", str);
    fflush(stderr);
    exit(1);
}

void
low_run_warning(str)
char *str;
{
    fprintf(stdout, "Warning: %s.\n", str);
    fflush(stdout);
}

/* Fake definitions of unneeded routines called by lisp.c. */

int
keyword_code(str)
char *str;
{
    run_warning("fake keyword_code being called");
    return 0;
}

/* Make the table so keyword lookup works. */

struct a_key {
    char *name;
} keywordtable[] = {

#undef  DEF_KWD
#define DEF_KWD(NAME,code)  { NAME },

#include "keyword.def"

    { NULL }
};

char *
keyword_name(k)
enum keywords k;
{
    return keywordtable[k].name;
}

void
init_predefined_symbols()
{
}

int
lazy_bind(sym)
Obj *sym;
{
    run_warning("fake lazy_bind being called");
    return FALSE;
}

void
prealloc_debug()
{
}

int
read_any_file(filename, hook)
char *filename;
readimf_hook hook;
{
    ImageFamily *imf;
    char *ext;
    int rc;

    /* Find the extension. */
    for (ext = filename + strlen(filename) - 1; ext > filename; ext--) {
	if (*ext == '.') {
	    ext++;
	    break;
	}
    }
    if (ext == filename)
      ext = "";
#if 0 /*def HAVE_XPM*/
    if (strcmp(ext, "xpm") == 0) {
	/* try a XPM file */
	imf = get_imf(find_imf_name(filename));
	if (imf == NULL)
	  return 0;
	rc = !!read_xpm_file(filename, imf, hook);
	if (hook && rc)
	  hook(imf, 0);
	return rc;
    }
#endif /* HAVE_XPM */
#if 0
    if (strcmp(ext, "b") == 0 || strcmp(ext, "m") == 0) {
	/* try a XBM file */
	imf = get_imf(find_imf_name(filename));
	if (!imf)
	  return 0;
	rc = !!read_xbm_file(filename, imf, hook);
	if (hook && rc)
	  hook(imf,0);
	return rc;
    } else
#endif
    if (strcmp(ext, "imf") == 0) {
	return load_imf_file(filename, hook);
    }
    return 0;
}
