/*
 *  WindowMaker window manager
 * 
 *  Copyright (c) 1997 Alfredo K. Kojima
 * 
 *  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 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "wconfig.h"

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

#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include "generic/wwmlib.h"
/* ?? must be below wwmlib.h to avoid definition conflict with libintl.h */
#ifdef HAVE_XLOCALE_H
# include <X11/Xlocale.h>
#else
# include <locale.h>
#endif

#include "WindowMaker.h"
#include "window.h"
#include "funcs.h"
#include "menu.h"
#include "dialog.h"
#include "resource.h"
#include "keybind.h"
#include "version.h"

/****** Global Variables ******/

/* general info */

Display	*dpy;
/* the root window */
char 	*ProgName;

/* locale to use. NULL==POSIX or C */
char *Locale=NULL;

WScreen wScreen;


WPreferences wPreferences;

WResource wResourceDefault;


WShortKey *wKeyBindings[WKBD_LAST];


/* modules */
int ModuleNo;

/* XContexts */
XContext wWinContext;
XContext wAppWinContext;
XContext wStackContext;

/* Atoms */
Atom _XA_WM_STATE;
Atom _XA_WM_CHANGE_STATE;
Atom _XA_WM_PROTOCOLS;
Atom _XA_WM_TAKE_FOCUS;
Atom _XA_WM_DELETE_WINDOW;
Atom _XA_WM_SAVE_YOURSELF;
Atom _XA_WM_CLIENT_LEADER;
Atom _XA_WM_COLORMAP_WINDOWS;

Atom _XA_GNUSTEP_WM_ATTR;
Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
Atom _XA_GNUSTEP_WM_RESIZEBAR;

Atom _XA_GNUSTEP_WM_FUNCTION;

#if 0
Atom _XA_GNUSTEP_WM_RESIZE_WINDOW;
Atom _XA_GNUSTEP_WM_RESIZED_WINDOW;
#endif
Atom _XA_WINDOWMAKER_MENU;
Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
Atom _XA_WINDOWMAKER_STATE;


/* cursors */
Cursor wCursor[WCUR_LAST];

/* last event timestamp for XSetInputFocus */
Time LastTimestamp;

/* paths */
char *MenuConfigPath=NULL;
char *PixmapPath=NULL;


#ifdef SHAPE
int ShapeEventBase;
#endif


/* temporary stuff */
int wVisualID = -1;

/******** End Global Variables *****/

static char **Arguments;
static int ArgCount;

extern void EventLoop();
extern void StartUp();

void
Restart(char *manager)
{
    char *prog=NULL;
    char *argv[MAX_RESTART_ARGS];
    int i;

    if (manager && manager[0]!=0) {
	prog = argv[0] = strtok(manager, " ");
	for (i=1; i<MAX_RESTART_ARGS; i++) {
	    argv[i]=strtok(NULL, " ");
	    if (argv[i]==NULL) {
		break;
	    }
	}
    }

    XCloseDisplay(dpy);
    if (!prog)
      execvp(Arguments[0], Arguments);
    else {
	execvp(prog, argv);
	/* fallback */
	execv(Arguments[0], Arguments);
    }
    wFatal(_("Restart failed!!!"));
    exit(-1);
}

/*
 *---------------------------------------------------------------------
 * wAbort--
 * 	Do a major cleanup and exit the program
 * 
 *---------------------------------------------------------------------- 
 */
void
wAbort()
{
    RestoreDesktop(&wScreen);
    printf(_("%s aborted.\n"), ProgName);
    exit(1);
}


void
print_help()
{
    printf(_("usage: %s [-options]\n"), ProgName);
    puts(_("options:"));
#ifdef USECPP
    puts(_(" -nocpp 		disable preprocessing of configuration files"));
#endif
#ifdef DOCK
    puts(_(" -nodock		do not open the application Dock"));
#endif
    /*
    puts(_(" -locale locale		locale to use"));
     */
    puts(_(" -visualid visualid	visual id of visual to use"));
    puts(_(" -display host:dpy	display to use"));
    puts(_(" -version		print version and exit"));
}

int
main(int argc, char **argv)
{
    int i, restart=0;
    char *display_name="";
    char *tmp;

    ArgCount = argc;
    Arguments = argv;

#if 0
    mcheck(0);
    mpr();
#endif
    
    ProgName = strrchr(argv[0],'/');
    if (!ProgName)
      ProgName = argv[0];
    else
      ProgName++;

    restart = 0;
    
    memset(&wPreferences, 0, sizeof(WPreferences));
    
    if (argc>1) {
	for (i=1; i<argc; i++) {
#ifdef USECPP
	    if (strcmp(argv[i], "-nocpp")==0) {
		wPreferences.flags.nocpp=1;
	    } else
#endif
#ifdef DOCK
	    if (strcmp(argv[i], "-nodock")==0) {
		wPreferences.flags.nodock=1;
	    } else
#endif
	    if (strcmp(argv[i], "-version")==0) {
		printf("WindowMaker %i.%i.%i\n", MAJ_VERSION, MIN_VERSION,
		       SUBMIN_VERSION);
		exit(0);
	/* TODO: fix this */
	    } else if (strcmp(argv[i], "-locale")==0) {
		i++;
		if (i>=argc) {
		    wWarning(_("too few arguments for %s"), argv[i-1]);
		    exit(0);
		}
		Locale = argv[i];
	    } else if (strcmp(argv[i], "-display")==0) {
		i++;
		if (i>=argc) {
		    wWarning(_("too few arguments for %s"), argv[i-1]);
		    exit(0);
		}
		display_name = argv[i];
	    } else if (strcmp(argv[i], "-visualid")==0) {
		i++;
		if (i>=argc) {
		    wWarning(_("too few arguments for %s"), argv[i-1]);
		    exit(0);
		}
		if (sscanf(argv[i], "%i", &wVisualID)!=1) {
		    wWarning(_("bad value for visualid: \"%s\""), argv[i]);
		    exit(0);
		}
	    } else {
		print_help();
		exit(0);
	    }
	}
    }
#if 0
    tmp = getenv("LANG");
    if (tmp) {
    	if (setlocale(LC_ALL,"") == NULL) {
	    wWarning("cannot set locale %s", tmp);
	    wWarning("falling back to C locale");
	    setlocale(LC_ALL,"C");
	    Locale = NULL;
	} else {
	    if (strcmp(tmp, "C")==0 || strcmp(tmp, "POSIX")==0)
	      Locale = NULL;
	    else
	      Locale = tmp;
	}
    } else {
	Locale = NULL;
    }
#endif
    if (!Locale) {
    	tmp = Locale = getenv("LANG");
	setlocale(LC_ALL, "");
    } else {
	setlocale(LC_ALL, Locale);
    }
    if (!Locale || strcmp(Locale, "C")==0 || strcmp(Locale, "POSIX")==0) 
      Locale = NULL;
#ifdef I18N
    if (getenv("NLSPATH"))
      bindtextdomain(PACKAGE, getenv("NLSPATH"));
    else
      bindtextdomain(PACKAGE, NLSDIR);
    textdomain(PACKAGE);
#endif

#ifdef I18N_MB
    if (!XSupportsLocale()) {
	wWarning(_("X server does not support locale"));
    }
    if (XSetLocaleModifiers("") == NULL) {
 	wWarning(_("cannot set locale modifiers"));
    }
#endif
        
    /* pixmap path can be freed later, if the user specified a new
     * path in configuration */
    PixmapPath = strdup(DEF_PIXMAP_PATHS);


    if (display_name && display_name[0]!=0) {
	tmp = wmalloc(strlen(display_name)+64);
	
	sprintf(tmp, "DISPLAY=%s", display_name);
	putenv(tmp);
	wfree(tmp);
    }
    /* open display */
    dpy = XOpenDisplay(display_name);
    if (dpy == NULL) {
	wFatal(_("could not open display \"%s\""), XDisplayName(display_name));
	exit(1);
    }
#ifdef DEBUG
    XSynchronize(dpy, True);
#endif

    wKeyboardInitialize();
    wResourceInitialize();
    wWindowInitialize();
    wMenuInitialize();
    wDialogInitialize();
#ifdef SOUNDS
    wSoundInitialize();
#endif
    StartUp();
    EventLoop();
    return -1;
}
