#include <X11/Xaw/Table.h>
#include <X11/Wc/WcCreate.h>

#include <ctype.h>

#include "xznol.h"
#include "mymalloc.h"
#include "util.h"

/* Wcl has magic so that you can pass a single string arg to a
   callback.  If specified, it replaces client_data. */

/* scan off next token from str.  return pointer to token, put a '\0'
   at the end of the token, and advance *str to after '\0', or to '\0'
   if the last token.  Return NULL if no more tokens, *str doesn't
   change. */

/* because I'm lazy, only leading spaces to each field are ignored */

/* XXXX This can probably be easily reimplemented with WcInvokeNamedAction()
   */

char *next_arg(char **str)
{
   char *ptr, *ret;

   ptr = *str;

   /* skip leading spaces */
   while(*ptr && isspace(*ptr)) ptr++;
   if (!*ptr) return(NULL);

   ret = ptr;

   /* scan until comma */

   while(*ptr && *ptr != ',') ptr++;
   if (!*ptr) {
      *str = ptr;
   } else {
      *ptr = '\0';
      *str = ptr+1;
   }
   return(ret);
}   

/*ARGSUSED*/
void action_cb(Widget w, XtPointer client_data, XtPointer call_data)
{
   char *str, *tmp;
   static String argv[20];
   Cardinal argc;

   if (!client_data) return;

   str = strdup((char *) client_data);
   tmp = str;
   argc = 0;
   while(argv[argc++] = next_arg(&tmp)) ;
   argc--; /* NULL doesn't count */

   if (argc > 0)
      XtCallActionProc(w, argv[0], NULL, argv+1, argc-1);

   myfree(str);
}

#if 0
/*ARGSUSED*/
void WcCreateAndPopupACT(Widget w, XEvent *event, String *params,
			 Cardinal *num_params)
{
   Widget parent, popup;

   if (*num_params != 2) return;

   parent = WcFullNameToWidget(w, params[0]);
   if (parent) {
      popup = WcCreateDatabasePopup(parent, params[1]);
      if (popup)
	 XtPopup(popup, XtGrabNone);
   }
}

XtActionsRec wcl_actions[] = {
   {"WcCreateAndPopupACT", WcCreateAndPopupACT},
};
#endif

#define num_wcl_actions sizeof(wcl_actions)/sizeof(XtActionsRec)

void wcl_init(XtAppContext app)
{
   WcRegisterClassPtr(app, "Table", tableWidgetClass);
   WcRegisterClassPtr(app, "tableWidgetClass", tableWidgetClass);

   WcRegisterConstructor(app, "createUserList", user_list_constructor);
   WcRegisterConstructor(app, "createZnol", table_constructor);
   WcRegisterConstructor(app, "createUserTableText",
			 user_table_text_constructor);
   WcRegisterConstructor(app, "createAddUserText",
			 adduser_text_constructor);

#if 0
   XtAppAddActions(app, wcl_actions, num_wcl_actions);
#endif
   WcRegisterCallback(app, "ActionCB", action_cb, NULL);

   WcRegisterCallback(app, "SetLabelToField", set_label_to_field, NULL);
}

/* This is necessary because of some ordering difficulties with Xaw.
Don't see a better solution. */

Boolean XmuNewCvtStringToWidget(Display *dpy, XrmValue *args,
				Cardinal *num_args, XrmValue *fromVal, 
				XrmValue *toVal, 
				XtPointer *converter_data)
{
   return(WcCvtStringToWidget(dpy, args, num_args, fromVal, toVal,
			      converter_data));
}

#if 0 && !defined(ultrix) && !defined(ibm032)

/* this is used to avoid some naming conflicts between the R4 Wcl and
   R5 Intrinsics */

/*ARGSUSED*/
Boolean XmuNewCvtStringToWidget(dpy, args, num_args, fromVal, toVal, 
				converter_data)
     Display *dpy;
     XrmValue *args;		/* parent */
     Cardinal *num_args;	/* 1 */
     XrmValue *fromVal;
     XrmValue *toVal;
     XtPointer *converter_data;
{
   XrmValue arg = *toVal;

   /* This will call the Wc replacement, not the Xmu version */
   XmuCvtStringToWidget(args, num_args, fromVal, toVal);

   /* now, fix the Wc braindamage */

   if (arg.addr && arg.addr != toVal->addr) {
      if (arg.size < toVal->size) {
	 toVal->addr = arg.addr;
	 return(False);
      } else {
	 /* this should be 'bcopy(toVal->addr, arg.addr, toVal->size);' but
	    Wc is broken */
	 *((Widget *) arg.addr) = (Widget) toVal->addr;
	 *toVal = arg;
	 return(True);
      }
   } else if (toVal->addr == NULL) {
      return(False);
   } else {
      return(True);
   }
}

#endif
