

#include "WINGsP.h"

#include <X11/keysym.h>

#ifdef WMAKER
extern void DispatchEvent(XEvent *event);
extern void wNextEvent(XEvent *event);
#endif



typedef struct Panel {
    WMWindow *win;
    WMButton *defBtn;
    WMButton *altBtn;
    WMButton *othBtn;
    WMLabel *iLbl;
    WMLabel *tLbl;
    WMLabel *mLbl;
    WMFrame *line;
    short result;
    short done;
    
    KeyCode retKey;
} Panel;


typedef struct InputBox {
    WMWindow *win;
    WMButton *defBtn;
    WMButton *altBtn;
    WMLabel *tLbl;
    WMLabel *mLbl;
    WMTextField *text;
    short result;
    short done;
    
    KeyCode retKey;
} InputBox;


static void
alertPanelOnClick(void *self, void *clientData)
{
    Panel *panel = clientData;

    panel->done = 1;
    if (self == panel->defBtn) {
	panel->result = WAPRDefault;
    } else if (self == panel->othBtn) {
	panel->result = WAPROther;
    } else if (self == panel->altBtn) {
	panel->result = WAPRAlternate;
    }
}


static void
handleKeyPress(XEvent *event, void *clientData)
{
    Panel *panel = (Panel*)clientData;

    if (event->xkey.keycode == panel->retKey) {
	WMPerformButtonClick(panel->defBtn);
    }
}


#ifdef WMAKER
int
WMRunAlertPanel(WMScreen *scrPtr, Window parent, char *title, char *msg, char *defaultButton,
		char *alternateButton, char *otherButton)
#else
int 
WMRunAlertPanel(WMScreen *scrPtr, char *title, char *msg, char *defaultButton,
		char *alternateButton, char *otherButton)
#endif
{
    WMArgument arg[10];
    Panel *panel;
    int x, dw=0, aw=0, ow=0, w;
    int tmp;
    
    
    panel = wmalloc(sizeof(Panel));
    memset(panel, 0, sizeof(Panel));

    panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
    
    arg[0].argument = WARG_CAPTION;
    arg[0].value = (WMValue)NULL;
    
#ifdef WMAKER
    panel->win = WMCreateWindow(scrPtr, parent, arg, 1);
#else
    panel->win = WMCreateWindow(scrPtr, arg, 1);
#endif

    if (scrPtr->applicationIcon) {
	arg[0].argument = WARG_X;
	arg[0].value = (WMValue)(8 + (64 - scrPtr->applicationIcon->width)/2);
	arg[1].argument = WARG_Y;
	arg[1].value = (WMValue)((75 - scrPtr->applicationIcon->height)/2);
	arg[2].argument = WARG_WIDTH;
	arg[2].value = (WMValue)((long)scrPtr->applicationIcon->width);
	arg[3].argument = WARG_HEIGHT;
	arg[3].value = (WMValue)((long)scrPtr->applicationIcon->height);
	arg[4].argument = WARG_IMAGE;
	arg[4].value = (WMValue)scrPtr->applicationIcon;
	arg[5].argument = WARG_IMAGE_POSITION;
	arg[5].value = (WMValue)WIPImageOnly;
		
	panel->iLbl = WMCreateLabel(panel->win, arg, 6);
    }
    
    if (title) {
	arg[0].argument = WARG_X;
	arg[0].value = (WMValue)80;
	arg[1].argument = WARG_Y;
	arg[1].value = (WMValue)((80 - scrPtr->largeFont->height)/2);
	arg[2].argument = WARG_WIDTH;
	arg[2].value = (WMValue)(400 - 70);
	arg[3].argument = WARG_HEIGHT;
	arg[3].value = (WMValue)(long)scrPtr->largeFont->height;
	arg[4].argument = WARG_CAPTION;
	arg[4].value = (WMValue)title;
	arg[5].argument = WARG_ALIGNMENT;
	arg[5].value = (WMValue)WALeft;
	arg[6].argument = WARG_FONT;
	arg[6].value = (WMValue)scrPtr->largeFont;

	panel->tLbl = WMCreateLabel(panel->win, arg, 7);
    }


    if (msg) {
	arg[0].argument = WARG_X;
	arg[0].value = (WMValue)10;
	arg[1].argument = WARG_Y;
	arg[1].value = (WMValue)95;
	arg[2].argument = WARG_WIDTH;
	arg[2].value = (WMValue)380;
	arg[3].argument = WARG_HEIGHT;
	arg[3].value = (WMValue)(long)(scrPtr->normalFont->height*3);
	arg[4].argument = WARG_CAPTION;
	arg[4].value = (WMValue)msg;
	arg[5].argument = WARG_ALIGNMENT;
	arg[5].value = (WMValue)WACenter;

	panel->mLbl = WMCreateLabel(panel->win, arg, 6);
    }
    
    
    /* create divider line */
    
    arg[0].argument = WARG_X;
    arg[0].value = (WMValue)0;
    arg[1].argument = WARG_Y;
    arg[1].value = (WMValue)80;
    arg[2].argument = WARG_WIDTH;
    arg[2].value = (WMValue)400;
    arg[3].argument = WARG_HEIGHT;
    arg[3].value = (WMValue)2;
    arg[4].argument = WARG_RELIEF;
    arg[4].value = (WMValue)WRGroove;
    panel->line = WMCreateFrame(panel->win, arg, 5);
    
    /* create buttons */
    if (otherButton) 
	ow = XTextWidth(scrPtr->normalFont->font, otherButton, 
			strlen(otherButton));
    
    if (alternateButton)
	aw = XTextWidth(scrPtr->normalFont->font, alternateButton, 
			strlen(alternateButton));
    
    if (defaultButton)
	dw = XTextWidth(scrPtr->normalFont->font, defaultButton,
			strlen(defaultButton));
    
    w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
    if (aw > w)
	w = aw;
    if (ow > w)
	w = ow;

    w += 24;

    arg[0].argument = WARG_CAPTION;
    arg[1].argument = WARG_X;
    
    arg[2].value = (WMValue)145;
    arg[2].argument = WARG_Y;
    arg[2].value = (WMValue)145;
    arg[3].argument = WARG_WIDTH;
    arg[3].value = (WMValue)w;
    arg[4].argument = WARG_HEIGHT;
    arg[4].value = (WMValue)22;
    
    x = 400;

    if (defaultButton) {
	x -= w + 10;
	arg[0].value = (WMValue)defaultButton;
	arg[1].value = (WMValue)x;

	arg[5].argument = WARG_IMAGE;
	arg[5].value = (WMValue)scrPtr->buttonArrow;
	arg[6].argument = WARG_ALT_IMAGE;
	arg[6].value = (WMValue)scrPtr->pushedButtonArrow;
	arg[7].argument = WARG_IMAGE_POSITION;
	arg[7].value = (WMValue)WIPRight;
	
	panel->defBtn = WMCreateCommandButton(panel->win, arg, 8);
	WMBindEvent(panel->defBtn, WEV_CLICK, alertPanelOnClick, panel);
    }
    if (alternateButton) {
	x -= w + 10;
	arg[0].value = (WMValue)alternateButton;
	arg[1].value = (WMValue)x;	
	
	panel->altBtn = WMCreateCommandButton(panel->win, arg, 5);
	WMBindEvent(panel->altBtn, WEV_CLICK, alertPanelOnClick, panel);
    }
    if (otherButton) {
	x -= w + 10;
	arg[0].value = (WMValue)otherButton;
	arg[1].value = (WMValue)x;

	
	panel->othBtn = WMCreateCommandButton(panel->win, arg, 5);
	WMBindEvent(panel->othBtn, WEV_CLICK, alertPanelOnClick, panel);
    }

    panel->done = 0;
    
    WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
			 handleKeyPress, panel);

    WMMapSubwidgets(panel->win);
    WMMapWidget(panel->win);

    while (!panel->done) {
	XEvent event;
	
#ifdef WMAKER
	wNextEvent(&event);
#else
	XNextEvent(scrPtr->display, &event);
#endif
#ifdef WMAKER
	DispatchEvent(&event);
#else
	WMHandleEvent(&event);
#endif
    }
    

    tmp = panel->result;

    WMUnmapWidget(panel->win);
    
    WMDestroyWidget(panel->win);
    
    free(panel);
    
    return tmp;
}





static void
inputBoxOnClick(void *self, void *clientData)
{
    InputBox *panel = clientData;

    panel->done = 1;
    if (self == panel->defBtn) {
	panel->result = WAPRDefault;
    } else if (self == panel->altBtn) {
	panel->result = WAPRAlternate;
    }
}



static void
handleKeyPress2(XEvent *event, void *clientData)
{
    InputBox *panel = (InputBox*)clientData;

    if (event->xkey.keycode == panel->retKey) {
	WMPerformButtonClick(panel->defBtn);
    }
}



#ifdef WMAKER
char*
WMInputBox(WMScreen *scrPtr, Window parent, char *title, char *msg,
	      char *defaultText, char *okButton, char *cancelButton)
#else
char*
WMInputBox(WMScreen *scrPtr, char *title, char *msg, char *defaultText, 
	      char *okButton, char *cancelButton)
#endif
{
    WMArgument arg[10];
    InputBox *panel;
    int x, dw=0, aw=0, w;
    char *tmp;
    
    
    panel = wmalloc(sizeof(InputBox));
    memset(panel, 0, sizeof(InputBox));

    panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
    
    arg[0].argument = WARG_CAPTION;
    arg[0].value = (WMValue)NULL;
    arg[1].argument = WARG_WIDTH;
    arg[1].value = (WMValue)300;
    arg[2].argument = WARG_HEIGHT;
    arg[2].value = (WMValue)150;
    
#ifdef WMAKER
    panel->win = WMCreateWindow(scrPtr, parent, arg, 3);
#else
    panel->win = WMCreateWindow(scrPtr, arg, 3);
#endif
    
    if (title) {
	arg[0].argument = WARG_X;
	arg[0].value = (WMValue)20;
	arg[1].argument = WARG_Y;
	arg[1].value = (WMValue)(long)scrPtr->largeFont->y;
	arg[2].argument = WARG_WIDTH;
	arg[2].value = (WMValue)(300 - 40);
	arg[3].argument = WARG_HEIGHT;
	arg[3].value = (WMValue)(long)scrPtr->largeFont->height;
	arg[4].argument = WARG_CAPTION;
	arg[4].value = (WMValue)title;
	arg[5].argument = WARG_ALIGNMENT;
	arg[5].value = (WMValue)WALeft;
	arg[6].argument = WARG_FONT;
	arg[6].value = (WMValue)scrPtr->largeFont;

	panel->tLbl = WMCreateLabel(panel->win, arg, 7);
    }


    if (msg) {
	arg[0].argument = WARG_X;
	arg[0].value = (WMValue)20;
	arg[1].argument = WARG_Y;
	arg[1].value = (WMValue)65;
	arg[2].argument = WARG_WIDTH;
	arg[2].value = (WMValue)(300-40);
	arg[3].argument = WARG_HEIGHT;
	arg[3].value = (WMValue)(long)scrPtr->normalFont->height;
	arg[4].argument = WARG_CAPTION;
	arg[4].value = (WMValue)msg;
	arg[5].argument = WARG_ALIGNMENT;
	arg[5].value = (WMValue)WALeft;

	panel->mLbl = WMCreateLabel(panel->win, arg, 6);
    }
    
    arg[0].argument = WARG_X;
    arg[0].value = (WMValue)20;
    arg[1].argument = WARG_Y;
    arg[1].value = (WMValue)85;
    arg[2].argument = WARG_WIDTH;
    arg[2].value = (WMValue)(300-40);
    arg[3].argument = WARG_TEXT;
    arg[3].value = (WMValue)defaultText;
    panel->text = WMCreateTextField(panel->win, arg, 4);
    
    /* create buttons */
    if (cancelButton)
	aw = XTextWidth(scrPtr->normalFont->font, cancelButton, 
			strlen(cancelButton));
    
    if (okButton)
	dw = XTextWidth(scrPtr->normalFont->font, okButton,
			strlen(okButton));
    
    w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
    if (aw > w)
	w = aw;

    w += 24;

    arg[0].argument = WARG_CAPTION;
    arg[1].argument = WARG_X;
    
    arg[2].argument = WARG_Y;
    arg[2].value = (WMValue)(150 - 30);
    arg[3].argument = WARG_WIDTH;
    arg[3].value = (WMValue)w;
    arg[4].argument = WARG_HEIGHT;
    arg[4].value = (WMValue)22;
    
    x = 290;

    if (okButton) {
	x -= w + 10;
	arg[0].value = (WMValue)okButton;
	arg[1].value = (WMValue)x;

	arg[5].argument = WARG_IMAGE;
	arg[5].value = (WMValue)scrPtr->buttonArrow;
	arg[6].argument = WARG_ALT_IMAGE;
	arg[6].value = (WMValue)scrPtr->pushedButtonArrow;
	arg[7].argument = WARG_IMAGE_POSITION;
	arg[7].value = (WMValue)WIPRight;
	
	panel->defBtn = WMCreateCommandButton(panel->win, arg, 8);
	WMBindEvent(panel->defBtn, WEV_CLICK, inputBoxOnClick, panel);
    }
    if (cancelButton) {
	x -= w + 10;
	arg[0].value = (WMValue)cancelButton;
	arg[1].value = (WMValue)x;	

	panel->altBtn = WMCreateCommandButton(panel->win, arg, 5);
	WMBindEvent(panel->altBtn, WEV_CLICK, inputBoxOnClick, panel);
    }

    panel->done = 0;
    
    WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
			 handleKeyPress2, panel);

    WMMapSubwidgets(panel->win);
    WMMapWidget(panel->win);

    while (!panel->done) {
	XEvent event;
	
#ifdef WMAKER
	wNextEvent(&event);
#else
	XNextEvent(scrPtr->display, &event);
#endif
#ifdef WMAKER
	DispatchEvent(&event);
#else
	WMHandleEvent(&event);
#endif
    }


    if (panel->result == WAPRDefault)
	tmp = WMGetTextFromTextField(panel->text);
    else
	tmp = NULL;

    WMUnmapWidget(panel->win);
    
    WMDestroyWidget(panel->win);
    
    
    free(panel);
    
    return tmp;
}



