/** 
 * 
 * xform.c - (c) 1994 Copyright by John R. Punin
 *
 * ASHE
 *
 * This file has the routines to create the Form option menu.
 * 
 * John R. Punin      Jul - 24 - 1994
 *
*/
#include "xhtml.h"
#include "xform.h"
#include "xheader.h"
#include "xfile.h"

static int ntype=0;
static int check=0;
static int multi=0;
static int selec=0;

MenuItem type_menu[] = {
{ "Text...", &xmPushButtonWidgetClass, 'T', NULL,NULL, form_text, 0, NULL},
{ "Hidden...", &xmPushButtonWidgetClass, 'H', NULL, NULL,form_text, 0, NULL},
{ "Password...", &xmPushButtonWidgetClass, 'P', NULL,NULL, form_text, 0, NULL},
{ "", &xmSeparatorWidgetClass, (char)NULL, NULL,NULL, NULL, (int)NULL,NULL},
{ "Checkbox...", &xmPushButtonWidgetClass, 'C', NULL, NULL, form_radio, 0, NULL},
{ "Radio...", &xmPushButtonWidgetClass, 'a', NULL,NULL, form_radio, 0, NULL},
{ "", &xmSeparatorWidgetClass, (char)NULL, NULL,NULL, NULL, (int)NULL,NULL},
{ "Reset...", &xmPushButtonWidgetClass, 'R', NULL,NULL, form_reset, 0, NULL},
{ "Submit...", &xmPushButtonWidgetClass, 'S', NULL,NULL, form_reset, 0, NULL},
NULL,
};

MenuItem form_menu[] = {
{ "Form...", &xmPushButtonWidgetClass, 'F', NULL,NULL, set_form, 0, NULL},
{ "Input", &xmCascadeButtonWidgetClass, 'I', NULL, NULL, 0, 0, type_menu},
{ "Select...", &xmPushButtonWidgetClass, 'S', NULL, NULL, form_select, 0, NULL},
{ "Option...", &xmPushButtonWidgetClass, 'O', NULL,NULL , form_option, 0, NULL},
{ "Textarea...", &xmPushButtonWidgetClass, 'T', NULL,NULL,form_textarea,0,NULL},
NULL,};

Widget 
BuildPulldownMenu(Widget w, char *menu_title, char menu_mnemonic,
		 Boolean tear_off, MenuItem *items,HTMLED *he)
{
   Widget PullDown, cascade, widget;
   int i;
   XmString str;
   
   PullDown = XmCreatePulldownMenu(w,"pulldown", NULL,0);
   if (tear_off)
      XtVaSetValues(PullDown, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL);
   str = XmStringCreateLocalized(menu_title);
   cascade = XtVaCreateManagedWidget
      (menu_title,xmCascadeButtonWidgetClass, w,
       XmNsubMenuId, PullDown,
       XmNlabelString,str,
       XmNmnemonic, menu_mnemonic,
       NULL);
   XmStringFree(str);
   
   /* Now add the menu items */
   
   for(i=0; items[i].label != NULL; i++)
   {
      /* If subitems exists, create the pull-right menu by calling this
	 function recursively. Since the function returns a cascade button
	 the widget returned is used..
       */
      if(items[i].subitems)
	 widget = BuildPulldownMenu(PullDown, items[i].label,
				    items[i].mnemonic, tear_off,
				    items[i].subitems,he);
      else
	 widget = XtVaCreateManagedWidget(items[i].label, *items[i].class,
					  PullDown,NULL);
      /* Whether the item is a real item or a cascade button with a menu
	 it can still have a mnemonic.
       */
      if(items[i].mnemonic)
	 XtVaSetValues(widget,XmNmnemonic, items[i].mnemonic,NULL);
      /* any item can have an accelerator, except  cascade menus. But,
	 I don't worry about that */
      if(items[i].accelerator)
      {
	 str = XmStringCreateLocalized (items[i].accel_text);
	 XtVaSetValues(widget, XmNaccelerator,items[i].accelerator,
		       XmNacceleratorText, str, NULL);
	 XmStringFree(str);
      }
      else if(items[i].accel_text)
      {
	 str = XmStringCreateLocalized (items[i].accel_text);
	 XtVaSetValues(widget,
		       XmNacceleratorText, str, NULL);
	 XmStringFree(str);
      }
      
      items[i].callback_data = (XtPointer)he;
      if(items[i].callback)
	 XtAddCallback(widget, 
		       (items[i].class == &xmToggleButtonWidgetClass) ?
		       XmNvalueChangedCallback : /*Toggle Button class */
			XmNactivateCallback, /*PushButton class */
			items[i].callback, items[i].callback_data);
   }
   return cascade;
}

void
set_form(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   Widget dialog,optionmenu,label_form,name_box;

   XmString label = 
      XmStringCreateLtoR("FORM \n",XmSTRING_DEFAULT_CHARSET);
   XmString t = 
      XmStringCreateLtoR("Action (URL) : \n",XmSTRING_DEFAULT_CHARSET);
   XmString clear =XmStringCreateSimple("Clear");

   XmString method = XmStringCreateSimple("Method :");
   XmString get =XmStringCreateSimple("Get");
   XmString post =XmStringCreateSimple("Post");
   XmString none =XmStringCreateSimple("None");

   dialog = XmCreatePromptDialog(he->textarea,"Form_html",NULL,0);
   XtVaSetValues(dialog, 
		 XmNselectionLabelString,t,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(clear);   XmStringFree(t);
   
   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   
   optionmenu = XmVaCreateSimpleOptionMenu(name_box,"option_menu",
	        method,'\0',0 /* initial menu selection */,option_cb,
		XmVaPUSHBUTTON,get,'\0',NULL,NULL,
		XmVaPUSHBUTTON,post,'\0',NULL,NULL,
		XmVaPUSHBUTTON,none,'\0',NULL,NULL,
	        XmNuserData,he,
		NULL);
   XmStringFree(get);   XmStringFree(post);   
   XmStringFree(none);XmStringFree(method);



   label_form = XmCreateLabel(name_box,"label_form",NULL,0);
   XtVaSetValues(label_form,XmNlabelString,label,NULL);
   XmStringFree(label);

   XtVaSetValues(optionmenu, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_form,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 
   XtVaSetValues(label_form, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtManageChild(optionmenu);
   XtManageChild(label_form);
   XtManageChild(name_box);
   

   /* When the user types the Reference name, call form_name()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)form_name,(XtPointer)he);
   
   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL); 
   
   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));
   
   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
   
   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
		0,0,800,800,0,0);
}

void
form_name(Widget w, XtPointer client_data, XtPointer call_data)
{
   XmSelectionBoxCallbackStruct *cbs=(XmSelectionBoxCallbackStruct *)call_data;
   HTMLED *he = (HTMLED *)client_data;
   XmTextPosition left=0,right=0;
   int len=0,lsel = 0;
   char *str,*str2, *value,*ssel = NULL;

   he->last_command = FORM;
   if(XmTextGetSelectionPosition(he->textarea,&left,&right))
   {
      if(right<=left)
	 left = right = XmTextGetInsertionPosition(he->textarea);
   }
   else
      left = right = XmTextGetInsertionPosition(he->textarea);

   if(left!=right)
   {
      ssel = XmTextGetSelection(he->textarea);
      lsel = strlen(ssel);
   }

   if(cbs->value!=NULL)
   {
      XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&value);
      len = strlen(value);
      str = XtMalloc(len+40);
   }
   str2 = XtMalloc(20);
   if(he->method == GET)
      strcpy(str2," METHOD=\"GET\"");
   else if(he->method == POST)
      strcpy(str2," METHOD=\"POST\"");
   else
   {
      XtFree(str2);
      str2=NULL;
   }

   if(left!=right)
   {
      XmTextInsert(he->textarea,right,"\n</FORM>");
      if(str2)
	 sprintf(str,"\n<FORM ACTION=\"%s\" %s>\n ",value,str2);
      else
	 sprintf(str,"\n<FORM ACTION=\"%s\">\n",value);

      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left+strlen(str));
      XtFree(str); 
   }
   else
   {
      XtFree(str);
      str = XtMalloc(50+len);
      sprintf(str,"\n<FORM ACTION=\"%s\" ",value);
      if(str2)
	 strcat(str,str2);
      strcat(str,">\n\n</FORM>");
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left + strlen(str) - 8);
      XtFree(str); XtFree(str2);
   }
   XtFree(ssel);
   he->method = GET;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}

void
option_cb(Widget w, XtPointer client_data, XtPointer call_data)
{
   Widget parent = XtParent(w);
   HTMLED *he;
   int item_no = (int)client_data;

   XtVaGetValues(parent,XmNuserData,&he,NULL);
   he->method = item_no;
}

void
form_text(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,name_box,text_name,label_name;
   Widget label_maxl,text_maxl,label_size,text_size,label_input;

   XmString va = XmStringCreateSimple("Value :");
   XmString na = XmStringCreateSimple("Name :");
   XmString ml = XmStringCreateSimple("MaxLength :");
   XmString si = XmStringCreateSimple("Size :        ");

   XmString label = get_label_input(w);
   XmString clear = XmStringCreateSimple("Clear");

   dialog = XmCreatePromptDialog(he->textarea,"Input_text",NULL,0);

   XtVaSetValues(dialog,XmNselectionLabelString,va,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(va);XmStringFree(clear);

   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   
   label_name = XmCreateLabel(name_box,"label_name",NULL,0);
   XtVaSetValues(label_name,XmNlabelString,na,NULL);
   XmStringFree(na);   

   text_name = XmCreateText(name_box,"text_name",NULL,0);

   label_size = XmCreateLabel(name_box,"label_size",NULL,0);
   XtVaSetValues(label_size,XmNlabelString,si,NULL);
   XmStringFree(si);

   text_size = XmCreateText(name_box,"text_size",NULL,0);

   label_maxl = XmCreateLabel(name_box,"label_maxl",NULL,0);
   XtVaSetValues(label_maxl,XmNlabelString,ml,NULL);
   XmStringFree(ml);

   text_maxl = XmCreateText(name_box,"text_maxl",NULL,0);

   label_input = XmCreateLabel(name_box,"label_input",NULL,0);
   XtVaSetValues(label_input,XmNlabelString,label,NULL);
   XmStringFree(label);


   XtVaSetValues(text_name, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, label_name,
		 XmNleftAttachment, XmATTACH_FORM, 
		 XmNcolumns,26,
		 NULL);
   XtManageChild(text_name);
   
   XtVaSetValues(label_name, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, text_size,
		 XmNleftAttachment, XmATTACH_FORM, 
		 NULL); 
   XtManageChild(label_name);
   XtVaSetValues(text_size, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_size,
		 XmNleftAttachment, XmATTACH_FORM, 
		 XmNcolumns,12,
		 NULL);

   XtVaSetValues(label_size, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_input,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 
   XtVaSetValues(label_input, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtVaSetValues(text_maxl, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_maxl,
		 XmNleftAttachment, XmATTACH_WIDGET, 
		 XmNleftWidget, text_size,
		 XmNcolumns,12,
		 NULL);

   XtVaSetValues(label_maxl, XmNtopAttachment, XmATTACH_WIDGET,
		 XmNtopWidget,label_input,
		 XmNleftAttachment, XmATTACH_WIDGET,
		 XmNleftWidget, label_size,
		 NULL);

   XtManageChild(text_size);
   XtManageChild(label_size); 
   XtManageChild(text_maxl);
   XtManageChild(label_maxl);
   XtManageChild(label_input);

   XtManageChild(name_box);
  
  /* When the user types the Value, call ok_input_text()... */
  XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_input_text,(XtPointer)he);
   
   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   /* verify if these fields are numbers */   
   XtAddCallback(text_size,XmNmodifyVerifyCallback,
		 (XtCallbackProc)check_number, (XtPointer)5);
   XtAddCallback(text_maxl,XmNmodifyVerifyCallback,
		 (XtCallbackProc)check_number, (XtPointer)5);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);

}

void
ok_input_text(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   XmSelectionBoxCallbackStruct *cbs=(XmSelectionBoxCallbackStruct *)call_data;
   Widget dialog,name_box,text_size,text_name,text_maxl;
   char *size,*name,*maxl,*value;
   int lsize, lname,lmaxl;
   int lvalue=0;

   XmTextPosition left = XmTextGetInsertionPosition(he->textarea);
   char *inputcom = NULL;   

   dialog = XtNameToWidget(XtParent(w),"Input_text");
   if(!dialog) dialog = XtNameToWidget(XtParent(w),"Input_check");
   name_box = (dialog ? XtNameToWidget(dialog,"namebox"): NULL);
   text_size = (name_box ? XtNameToWidget(name_box,"text_size") : NULL);
   text_name = (name_box ? XtNameToWidget(name_box,"text_name") : NULL);
   text_maxl = (name_box ? XtNameToWidget(name_box,"text_maxl") : NULL);
   size = (text_size ? XmTextGetString(text_size) : NULL);
   name = (text_name ? XmTextGetString(text_name) : NULL);
   maxl = (text_maxl ? XmTextGetString(text_maxl) : NULL);
   value=NULL;
   lsize = (size ? strlen(size) : 0);
   lname = (name ? strlen(name): 0);
   lmaxl= (maxl ? strlen(maxl): 0);

   if(cbs->value)
      XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&value);

   lvalue = (value ? strlen(value): 0);

   inputcom=XtMalloc(lsize+lname+lmaxl+lvalue+80);

   he->last_command = INPUT;

   sprintf(inputcom,"<INPUT type=\"%s",type_menu[ntype].label);
   inputcom[13]=inputcom[13]+32; /* convert to lower case */
   inputcom[strlen(inputcom)-3]='\0';
   strcat(inputcom,"\" ");
   ntype = 0;
   if(lname!=0)
   {
      strcat(inputcom," name=\"");
      strcat(inputcom,name);
      strcat(inputcom,"\"");
   }
   if(lvalue!=0)
   {
      strcat(inputcom," value=\"");
      strcat(inputcom,value);
      strcat(inputcom,"\"");
   }
   
   if(lsize!=0)
   {
      strcat(inputcom," size=");
      strcat(inputcom,size);
   }
   if(lmaxl!=0)
   {
      strcat(inputcom," maxlength=");
      strcat(inputcom,maxl);
   }
   if(check!=0)
      strcat(inputcom," checked");
      
   strcat(inputcom,">\n");
   XmTextInsert(he->textarea,left,inputcom);
   XmTextSetInsertionPosition(he->textarea,left+strlen(inputcom));
   XtFree(inputcom);XtFree(size);XtFree(name);XtFree(maxl);
   XtFree(value);
   check = 0;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}


void
form_radio(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,name_box,text_name,label_name;
   Widget checked,label_input;

   XmString va = XmStringCreateSimple("Value :");
   XmString na = XmStringCreateSimple("Name :");

   XmString label = get_label_input(w);
   XmString clear = XmStringCreateSimple("Clear");
   
   dialog = XmCreatePromptDialog(he->textarea,"Input_check",NULL,0);
   
   XtVaSetValues(dialog,XmNselectionLabelString,va,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(va);   XmStringFree(clear);
   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   
   label_name = XmCreateLabel(name_box,"label_name",NULL,0);
   XtVaSetValues(label_name,XmNlabelString,na,NULL);
   XmStringFree(na);   

   text_name = XmCreateText(name_box,"text_name",NULL,0);

   checked = XmCreateToggleButton(name_box,"Checked",NULL,0);
   
   label_input = XmCreateLabel(name_box,"label_input",NULL,0);
   XtVaSetValues(label_input,XmNlabelString,label,NULL);
   XmStringFree(label);

  XtVaSetValues(text_name, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, label_name,
		 XmNleftAttachment, XmATTACH_FORM, 
		 XmNcolumns,26,
		 NULL);
   XtManageChild(text_name);
   
   XtVaSetValues(label_name, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, checked,
		 XmNleftAttachment, XmATTACH_FORM, 
		 NULL); 
   XtManageChild(label_name);
   
   XtVaSetValues(checked, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_input,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtVaSetValues(label_input, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtManageChild(checked);
   XtManageChild(label_input);

   XtManageChild(name_box);

   /* When the user types the Value, call ok_input_text()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_input_text,(XtPointer)he);

   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   /* Callback of Check button */
   XtAddCallback(checked,XmNvalueChangedCallback,(XtCallbackProc)checked_input,NULL);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);
}

void
form_reset(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,label_input;
   XmString label = get_label_input(w);
   XmString clear = XmStringCreateSimple("Clear");
   XmString va = XmStringCreateSimple("Value :");

   dialog = XmCreatePromptDialog(he->textarea,"Input_check",NULL,0);
   
   XtVaSetValues(dialog,XmNselectionLabelString,va,
		 XmNapplyLabelString,clear,NULL);

   XmStringFree(va);   XmStringFree(clear);
   
   label_input = XmCreateLabel(dialog,"label_input",NULL,0);
   XtVaSetValues(label_input,XmNlabelString,label,NULL);
   XmStringFree(label);
   XtManageChild(label_input);

  /* When the user types the Value, call ok_input_text()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_input_text,(XtPointer)he);

   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);
}

void
form_select(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,name_box,text_size,label_size;
   Widget multiple,label_select;

   XmString si = XmStringCreateSimple("Size :");
   XmString na = XmStringCreateSimple("Name :");

  XmString label=XmStringCreateLtoR("Select Field\n",XmSTRING_DEFAULT_CHARSET);
   XmString clear = XmStringCreateSimple("Clear");
   
   dialog = XmCreatePromptDialog(he->textarea,"Select_field",NULL,0);
   
   XtVaSetValues(dialog,XmNselectionLabelString,na,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(na);   XmStringFree(clear);
   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   
   label_size = XmCreateLabel(name_box,"label_size",NULL,0);
   XtVaSetValues(label_size,XmNlabelString,si,NULL);
   XmStringFree(si);   

   text_size = XmCreateText(name_box,"text_size",NULL,0);

   multiple = XmCreateToggleButton(name_box,"Multiple",NULL,0);
   
   label_select = XmCreateLabel(name_box,"label_select",NULL,0);
   XtVaSetValues(label_select,XmNlabelString,label,NULL);
   XmStringFree(label);

  XtVaSetValues(text_size, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, label_size,
		 XmNleftAttachment, XmATTACH_FORM, 
		 XmNcolumns,12,
		 NULL);
   XtManageChild(text_size);
   
   XtVaSetValues(label_size, XmNtopAttachment,XmATTACH_WIDGET, 
		 XmNtopWidget, multiple,
		 XmNleftAttachment, XmATTACH_FORM, 
		 NULL); 
   XtManageChild(label_size);
   
   XtVaSetValues(multiple, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_select,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtVaSetValues(label_select, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtManageChild(multiple);
   XtManageChild(label_select);

   XtManageChild(name_box);

   /* When the user types the Value, call ok_input_text()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_select,(XtPointer)he);

   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   /* Callback of Multiple button */
   XtAddCallback(multiple,XmNvalueChangedCallback,(XtCallbackProc)multiple_select,NULL);

   /* verify if these fields are numbers */   
   XtAddCallback(text_size,XmNmodifyVerifyCallback,
		 (XtCallbackProc)check_number, (XtPointer)5);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);
}


void
ok_select(Widget w, XtPointer client_data, XtPointer call_data)
{
   
  XmSelectionBoxCallbackStruct *cbs=(XmSelectionBoxCallbackStruct *)call_data;
  HTMLED *he = (HTMLED *)client_data;
  XmTextPosition left=0,right=0;
  int len=0,lsel = 0;
  char *str, *name=NULL,*ssel = NULL;
  Widget dialog = XtNameToWidget(XtParent(w),"Select_field");
  Widget name_box = (dialog ? XtNameToWidget(dialog,"namebox"): NULL);
  Widget  text_size = (name_box ? XtNameToWidget(name_box,"text_size") : NULL);
  char *size = (text_size ? XmTextGetString(text_size) : NULL);
  int lsize = (size ? strlen(size) : 0);

  he->last_command = FORM;
  if(XmTextGetSelectionPosition(he->textarea,&left,&right))
  {
     if(right<=left)
	left = right = XmTextGetInsertionPosition(he->textarea);
  }
  else
     left = right = XmTextGetInsertionPosition(he->textarea);
  
  if(left!=right)
  {
     ssel = XmTextGetSelection(he->textarea);
     lsel = strlen(ssel);
  }
  if(cbs->value!=NULL)
  {
     XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&name);
     len = strlen(name);
     str = XtMalloc(len+40);
  }
   if(left!=right)
   {
      XmTextInsert(he->textarea,right,"\n</SELECT>");
      sprintf(str,"\n<SELECT name=\"%s\"",name);
      if(lsize != 0)
      {
	 strcat(str," size=");
	 strcat(str,size);
      }
      if(multi!=0)
	 strcat(str," multiple");
      strcat(str,">\n");
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left+strlen(str));
      XtFree(str); 
   }
   else
   {
      XtFree(str);
      str = XtMalloc(50+len);
      sprintf(str,"\n<SELECT name=\"%s\"",name);
      if(lsize != 0)
      {
	 strcat(str," size=");
	 strcat(str,size);
      }
      if(multi!=0)
	 strcat(str," multiple");
      
      strcat(str,">\n\n</SELECT>");
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left + strlen(str) - 10);
      XtFree(str);

   }

  if(size) XtFree(size);
  XtFree(ssel);
  multi=0;
  XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}

void
form_option(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,name_box;
   Widget selected,label_option;

   XmString va = XmStringCreateSimple("Value :");

  XmString label=XmStringCreateLtoR("Option Field\n",XmSTRING_DEFAULT_CHARSET);
   XmString clear = XmStringCreateSimple("Clear");
   
   dialog = XmCreatePromptDialog(he->textarea,"Option_field",NULL,0);
   
   XtVaSetValues(dialog,XmNselectionLabelString,va,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(va);   XmStringFree(clear);
   name_box = XmCreateForm(dialog,"namebox",NULL,0);

   selected = XmCreateToggleButton(name_box,"Selected",NULL,0);
   
   label_option = XmCreateLabel(name_box,"label_option",NULL,0);
   XtVaSetValues(label_option,XmNlabelString,label,NULL);
   XmStringFree(label);

   XtVaSetValues(selected, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_option,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtVaSetValues(label_option, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtManageChild(selected);
   XtManageChild(label_option);

   XtManageChild(name_box);

   /* When the user types the Value, call ok_input_text()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_option,(XtPointer)he); 

   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   /* Callback of Multiple button */
   XtAddCallback(selected,XmNvalueChangedCallback,(XtCallbackProc)selected_check,NULL);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);
}
void
ok_option(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   XmSelectionBoxCallbackStruct *cbs=(XmSelectionBoxCallbackStruct *)call_data;
   int lvalue=0;

   XmTextPosition left = XmTextGetInsertionPosition(he->textarea);
   char *optioncom = NULL;   
   char *value=NULL;

   if(cbs->value)
      XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&value);

   lvalue = (value ? strlen(value): 0);

   optioncom=XtMalloc(lvalue+30);

   he->last_command = OPTION;

   strcpy(optioncom,"<OPTION ");

   if(lvalue!=0)
   {
      strcat(optioncom," value=\"");
      strcat(optioncom,value);
      strcat(optioncom,"\"");
   }
   
   if(selec!=0)
      strcat(optioncom," selected");
      
   strcat(optioncom,"> ");
   XmTextInsert(he->textarea,left,optioncom);
   XmTextSetInsertionPosition(he->textarea,left+strlen(optioncom));
   XtFree(optioncom);
   XtFree(value);
   selec = 0;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}

void
form_textarea(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   
   Widget dialog,name_box;
   Widget label_cols,text_cols,label_rows,text_rows,label_textarea;

   XmString va = XmStringCreateSimple("Name :");
   XmString ro = XmStringCreateSimple("Rows :");
   XmString cl = XmStringCreateSimple("Cols :        ");
   XmString label =
     XmStringCreateLtoR("Textarea Field\n",XmSTRING_DEFAULT_CHARSET);
   XmString clear = XmStringCreateSimple("Clear");

   dialog = XmCreatePromptDialog(he->textarea,"Textarea_field",NULL,0);

   XtVaSetValues(dialog,XmNselectionLabelString,va,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(va);XmStringFree(clear);

   name_box = XmCreateForm(dialog,"namebox",NULL,0);

   label_cols = XmCreateLabel(name_box,"label_cols",NULL,0);
   XtVaSetValues(label_cols,XmNlabelString,cl,NULL);
   XmStringFree(cl);

   text_cols = XmCreateText(name_box,"text_cols",NULL,0);

   label_rows = XmCreateLabel(name_box,"label_rows",NULL,0);
   XtVaSetValues(label_rows,XmNlabelString,ro,NULL);
   XmStringFree(ro);

   text_rows = XmCreateText(name_box,"text_rows",NULL,0);

   label_textarea = XmCreateLabel(name_box,"label_textarea",NULL,0);
   XtVaSetValues(label_textarea,XmNlabelString,label,NULL);
   XmStringFree(label);

   XtVaSetValues(text_cols, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_cols,
		 XmNleftAttachment, XmATTACH_FORM, 
		 XmNcolumns,12,
		 NULL);

   XtVaSetValues(label_cols, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_textarea,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 
   XtVaSetValues(label_textarea, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   XtVaSetValues(text_rows, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,label_rows,
		 XmNleftAttachment, XmATTACH_WIDGET, 
		 XmNleftWidget, text_cols,
		 XmNcolumns,12,
		 NULL);

   XtVaSetValues(label_rows, XmNtopAttachment, XmATTACH_WIDGET,
		 XmNtopWidget,label_textarea,
		 XmNleftAttachment, XmATTACH_WIDGET,
		 XmNleftWidget, label_cols,
		 NULL);

   XtManageChild(text_cols);
   XtManageChild(label_cols); 
   XtManageChild(text_rows);
   XtManageChild(label_rows);
   XtManageChild(label_textarea);

   XtManageChild(name_box);
  
  /* When the user types the Value, call ok_input_text()... */
  XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)ok_textarea,(XtPointer)he);
   
   /* If the user selects cancel, just detroy the dialog */
   XtAddCallback(dialog,XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);

   /* Clear button is available */
   XtAddCallback(dialog,XmNapplyCallback,(XtCallbackProc)clear_title,NULL);
   XtManageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));

   /* No help is available */
   XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));

   /* verify if these fields are numbers */   
   XtAddCallback(text_cols,XmNmodifyVerifyCallback,
		 (XtCallbackProc)check_number, (XtPointer)5);
   XtAddCallback(text_rows,XmNmodifyVerifyCallback,
		 (XtCallbackProc)check_number, (XtPointer)5);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);

}

void
ok_textarea(Widget w, XtPointer client_data, XtPointer call_data)
{
  XmSelectionBoxCallbackStruct *cbs=(XmSelectionBoxCallbackStruct *)call_data;
  HTMLED *he = (HTMLED *)client_data;
  XmTextPosition left=0,right=0;
  int len=0,lsel = 0;
  char *str, *name=NULL,*ssel = NULL;
  Widget dialog = XtNameToWidget(XtParent(w),"Textarea_field");
  Widget name_box = (dialog ? XtNameToWidget(dialog,"namebox"): NULL);
  Widget  text_cols = (name_box ? XtNameToWidget(name_box,"text_cols") : NULL);
  Widget  text_rows = (name_box ? XtNameToWidget(name_box,"text_rows") : NULL);
  char *cols = (text_cols ? XmTextGetString(text_cols) : NULL);
  char *rows = (text_rows ? XmTextGetString(text_rows) : NULL);
  int lrows = (rows ? strlen(rows) : 0);
  int lcols = (cols ? strlen(cols) : 0);

  he->last_command = TEXTAREA;
  if(XmTextGetSelectionPosition(he->textarea,&left,&right))
  {
     if(right<=left)
	left = right = XmTextGetInsertionPosition(he->textarea);
  }
  else
     left = right = XmTextGetInsertionPosition(he->textarea);
  
  if(left!=right)
  {
     ssel = XmTextGetSelection(he->textarea);
     lsel = strlen(ssel);
  }
  if(cbs->value!=NULL)
  {
     XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&name);
     len = strlen(name);
     str = XtMalloc(len+40);
  }
   if(left!=right)
   {
      XmTextInsert(he->textarea,right,"\n</TEXTAREA>");
      sprintf(str,"\n<TEXTAREA name=\"%s\"",name);
      if(lcols != 0)
      {
	 strcat(str," cols=");
	 strcat(str,cols);
      }
      if(lrows != 0)
      {
	 strcat(str," rows=");
	 strcat(str,rows);
      }

      strcat(str,">\n");
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left+strlen(str));
      XtFree(str); 
   }
   else
   {
      XtFree(str);
      str = XtMalloc(60+len);
      sprintf(str,"\n<TEXTAREA name=\"%s\"",name);
      if(lcols != 0)
      {
	 strcat(str," cols=");
	 strcat(str,cols);
      }
      if(lrows != 0)
      {
	 strcat(str," rows=");
	 strcat(str,rows);
      }

      
      strcat(str,">\n\n</TEXTAREA>");
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left + strlen(str) - 12);
      XtFree(str);
   }

  if(cols) XtFree(cols);
  if(rows) XtFree(rows);
  XtFree(ssel);
  XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}


XmString
get_label_input(Widget w)
{
   XmString str;
   char typein[30];
   int i;
   
   strcpy(typein, "Input Type : ");
   for(i=0;type_menu[i].label != NULL;i++)
      if(!strcmp(XtName(w),type_menu[i].label))
      {
	 strcat(typein,type_menu[i].label);
	 strcat(typein,"\n");
	 str = XmStringCreateLtoR(typein,XmSTRING_DEFAULT_CHARSET);
	 ntype = i;
	 return str;	 
      }
   return str;
}

void
check_number(Widget text_w, XtPointer client_data, XtPointer call_data)
{
   char c;
   int ml = (int)client_data;
   int len = XmTextGetLastPosition(text_w);
   XmTextVerifyCallbackStruct *cbs =(XmTextVerifyCallbackStruct *)call_data;
   
   if(cbs->reason == XmCR_MOVING_INSERT_CURSOR)
   {
      if(cbs->newInsert != len)
	 cbs->doit = False;
      return;
   }
   /* no backspacing, typing or stuffing in middle of string */
   if(cbs->currInsert < len)
   {
      cbs->doit = False;
      return;
   }
   if(cbs->text->length == 0)
      return;
   if(cbs->text->length > 1)
   {
      cbs->doit = False;
      return;
   }
   if(!isdigit(c=cbs->text->ptr[0]) || len >= ml)
   {
      cbs->doit = False;
      XBell(XtDisplay(text_w),100);
   }
}
      
void
checked_input(Widget w, XtPointer client_data, XtPointer call_data)
{
   if(check == 0)
      check = 1;
   else
      check = 0;
}
void
multiple_select(Widget w, XtPointer client_data, XtPointer call_data)
{
   if(multi == 0)
      multi = 1;
   else
      multi = 0;
}
void
selected_check(Widget w, XtPointer client_data, XtPointer call_data)
{
   if(selec == 0)
      selec = 1;
   else
      selec = 0;
}
