/** xmarkup.c - (c) 1994 Copyright by John R. Punin
 *
 * ASHE HTML Editor
 * 
 * This file has the routines to make additional markup tags for HTML document.
 * 
 * John R. Punin      April -29 - 1994
 *
*/

#include "xhtml.h"
#include "xmarkup.h"
#include "xheader.h"

static int ismap = 0;
static int align = TOP_AL;
/*
   
   NAME : create_linker
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates the Dialog Window that 
                 ask for the URL name of the document to be pointed
		 and the reference name, also it shows the selected text
		 that is going to be the link


*/
void 
create_linker(Widget w,HTMLED *he)
{
   Widget dialog,name_box,text_name,label_name;
   XmString l = XmStringCreateSimple("Reference Name :");
   XmString t = XmStringCreateLtoR("\n\nURL Name :",XmSTRING_DEFAULT_CHARSET); 
   XmString u = 
      XmStringCreateLtoR("Link Name :\n\t",XmSTRING_DEFAULT_CHARSET);
   XmString label,tu;
   XmString clear = XmStringCreateSimple("Clear");
   char *selection_linker=NULL;

   dialog = XmCreatePromptDialog(he->textarea,"Linker",NULL,0);
   if(selection_linker = XmTextGetSelection(he->textarea))
   {
      tu = XmStringCreateLtoR(selection_linker,XmSTRING_DEFAULT_CHARSET);
      XtFree(selection_linker);
      label = XmStringConcat(u,tu);
      XmStringFree(u);
      u = XmStringConcat(label,t);
      XmStringFree(tu);
   }
   else
   {
      label = XmStringConcat(u,t);
      XmStringFree(u);
      u = XmStringCopy(label);
   }

   XtVaSetValues(dialog, XmNselectionLabelString,u,
		         XmNapplyLabelString,clear,NULL);
   XmStringFree(label);   XmStringFree(t);
   XmStringFree(u);    XmStringFree(clear); 

   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   label_name = XmCreateLabel(name_box,"label_name",NULL,0);
   XtVaSetValues(label_name,XmNlabelString,l,NULL);
   XmStringFree(l);
   XtManageChild(label_name);
   text_name = XmCreateText(name_box,"text_name",NULL,0);
   XtVaSetValues(text_name, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget, label_name,
		 XmNcolumns,25,
		 NULL);
   
   XtManageChild(text_name);
   XtManageChild(name_box);

   he->user_data = (XtPointer)text_name;
   /* When the user types the URL name, call linker_name()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)linker_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);
}

/* 
   NAME : linker_name
   PARAMETERS : Widget text_name
                Widget where the reference name is saved
                XmSelectionBoxCallbackStruct *cbs
		value of the function that have the URL name
   RETURN : void
   DESCRIPTION : This function set the link using the URL name
                 and the reference name and it is inserted to the
		 selected text
*/


void 
linker_name(Widget w,
		 HTMLED *he, 
		 XmSelectionBoxCallbackStruct *cbs)
{
   Widget text_name = (Widget)he->user_data;
   XmTextPosition left=0,right=0;
   int lnam=0,len=0,lsel=0;
   char *ssel = NULL;
   char *str=NULL,*value=NULL,*sel=NULL;


   he->last_command = LINKER;
   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);
   }
   sel = XmTextGetString(text_name);
   if(sel)
      lnam = strlen(sel);

   str = XtMalloc(lnam+len+20);

   if(value!=NULL)
   {
      XmTextInsert(he->textarea,right,"</A>");
      if(strlen(sel)==0)
	 sprintf(str,"<A HREF=\"%s\">",value);
      else
	 sprintf(str,"<A HREF=\"%s#%s\">",value,sel);

      XmTextInsert(he->textarea,left,str);
      if(lsel==0)
      {
	 if (!strlen(sel))
		XmTextSetInsertionPosition(he->textarea,
				    left+strlen(sel)+strlen(value)+11);
	 else
		XmTextSetInsertionPosition(he->textarea,
				    left+strlen(sel)+strlen(value)+12);
      }
      else
      {
	 if (!strlen(sel))
		XmTextSetInsertionPosition(he->textarea,
				    left+strlen(sel)+strlen(value)+lsel+15);
	 else
		XmTextSetInsertionPosition(he->textarea,
				    left+strlen(sel)+strlen(value)+lsel+16);
      }
   }
   else
   {
      XmTextInsert(he->textarea,left,"<A HREF=\"\"></A> ");
      XmTextSetInsertionPosition(he->textarea,left + 10);
   }

   XtFree(str); 
   XtFree(sel);
   XtFree(ssel);
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}
/*
   
   NAME : create_reference
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates the dialog widget title 
                 to enter the reference name

*/

void 
create_reference(Widget w,HTMLED *he)
{
  Widget dialog;
  XmString rt =
     XmStringCreateLtoR("Referenced text :\n\t",XmSTRING_DEFAULT_CHARSET); 
  XmString sr,r = 
     XmStringCreateLtoR("\n\nReference Name :",XmSTRING_DEFAULT_CHARSET);
  XmString label,clear =XmStringCreateSimple("Clear");
  char *sel_reference=NULL;
  dialog = XmCreatePromptDialog(he->textarea,"Reference",NULL,0);

  if(sel_reference = XmTextGetSelection(he->textarea))
  {
     sr = XmStringCreateLtoR(sel_reference,XmSTRING_DEFAULT_CHARSET);
     XtFree(sel_reference);
     label = XmStringConcat(rt,sr);
     XmStringFree(rt);
     rt= XmStringConcat(label,r);
     XmStringFree(sr);
  }
  else
  {
     label = XmStringConcat(rt,r);
     XmStringFree(rt);
     rt = XmStringCopy(label);
  }
  XtVaSetValues(dialog, 
		XmNselectionLabelString,rt,
		XmNapplyLabelString,clear,NULL);
  XmStringFree(label);   XmStringFree(r); XmStringFree(clear);
  
  /* When the user types the Reference name, call linker_name()... */
  XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)reference_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);
}

/*
   
   NAME : reference_name
   PARAMETERS : XmSelectionBoxCallbackStruct *cbs
                This has the value of the reference name
   RETURN : void
   DESCRIPTION : This function sets the tags of the reference
                 name to the selected text

*/
void 
reference_name(Widget w,
		    XtPointer client_data,
		    XmSelectionBoxCallbackStruct *cbs)
{
   HTMLED *he = (HTMLED *)client_data;
   XmTextPosition left=0,right=0;
   int len,lsel=0;
   char *sel=NULL;
   char *str=NULL,*value=NULL;

   he->last_command = REFER;
   if(XmTextGetSelectionPosition(he->textarea,&left,&right))
   {
      if(right<=left)
	 left = right = XmTextGetInsertionPosition(he->textarea);
   }
   else
      left = right = XmTextGetInsertionPosition(he->textarea);
   
   if(left!=right)
   {
      sel = XmTextGetSelection(he->textarea);
      lsel = strlen(sel);
   }

   if(cbs->value!=NULL)
   {
      XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&value);
      len = strlen(value);
      str = XtMalloc(len+20);
   }
   if(value!=NULL)
   {
      if((len==0)&&(lsel==0))
      {
	 sprintf(str,"<A NAME=\"\"></A>");
	 XmTextInsert(he->textarea,left,str); 
	 XmTextSetInsertionPosition(he->textarea,left +11);
      }
      else
      {
	 XmTextInsert(he->textarea,right,"</A>");
	 sprintf(str,"<A NAME=\"%s\">",value);
	 XmTextInsert(he->textarea,left,str);
	 if(lsel==0)
	    XmTextSetInsertionPosition(he->textarea,left+len+ 11);
	 else
	    XmTextSetInsertionPosition(he->textarea,left +lsel+len+ 15);
      }
   }
   XtFree(sel);
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
   XtFree(str);
}
/*
   
   NAME : create_figure
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates the dialog widget image
                 to enter the name of the URL  of the image file.
		 It has a toggle button to select top or bottom
		 aligning with the text.

*/
void
create_figure(Widget w,HTMLED *he)
{
   Widget dialog,name_box,option_align,togglebutton;
   XmString t = XmStringCreateLtoR("Image Name: \n",XmSTRING_DEFAULT_CHARSET);
   XmString clear =XmStringCreateSimple("Clear");
   XmString bottomal =XmStringCreateSimple("Bottom");
   XmString topal =XmStringCreateSimple("Top");
   XmString middleal =XmStringCreateSimple("Middle");

   XmString align_label = XmStringCreateSimple("Alignment :");
   XmString ismapstr =XmStringCreateLtoR("ISMAP\n",XmSTRING_DEFAULT_CHARSET);

   ismap = 0; align = TOP_AL;
   dialog = XmCreatePromptDialog(he->textarea,"Image",NULL,0);
   XtVaSetValues(dialog, 
		 XmNselectionLabelString,t,
		 XmNapplyLabelString,clear,NULL);
   XmStringFree(clear);   XmStringFree(t);

   name_box = XmCreateForm(dialog,"namebox",NULL,0);
   
   option_align = XmVaCreateSimpleOptionMenu(name_box,"option_align",
	        align_label,'\0',0 /* initial menu selection */,align_cb,
		XmVaPUSHBUTTON,topal,'\0',NULL,NULL,
		XmVaPUSHBUTTON,middleal,'\0',NULL,NULL,
		XmVaPUSHBUTTON,bottomal,'\0',NULL,NULL,
	        XmNuserData,he,
		NULL);
   XmStringFree(align_label);   XmStringFree(topal);   
   XmStringFree(bottomal);XmStringFree(middleal);

   XtManageChild(option_align);
   
   togglebutton = XmCreateToggleButton(name_box,"toggletop",NULL,0);
   XtManageChild(togglebutton);
   XtVaSetValues(togglebutton,
		 XmNlabelString,ismapstr,NULL);
   XtAddCallback(togglebutton,XmNvalueChangedCallback,(XtCallbackProc)ismap_check,NULL);

   XmStringFree(ismapstr);

   XtVaSetValues(option_align, XmNtopAttachment, XmATTACH_WIDGET, 
		 XmNtopWidget,togglebutton,
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 
   XtVaSetValues(togglebutton, XmNtopAttachment, XmATTACH_FORM, 
		 XmNleftAttachment, XmATTACH_FORM,
		 NULL); 

   /* When the user types the Reference name, call linker_name()... */
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)image_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(name_box);
   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
		0,0,800,800,0,0);
}
void 
ismap_check(Widget w,
	   XtPointer client_data, XtPointer call_data)
{  
   if(ismap == 0)
      ismap = 1;
   else
      ismap = 0;
}
void 
align_cb(Widget w,
	   XtPointer client_data, XtPointer call_data)
{
   int item_no = (int)client_data;
   align = item_no;
}

/*
   
   NAME : image_name
   PARAMETERS : XmSelectionBoxCallbackStruct *cbs
                It has the URL image name 
   RETURN : void
   DESCRIPTION : This function insert the image tag to the
                  current position of the cursor

*/
void 
image_name(Widget w, 
	   XtPointer client_data,
	   XmSelectionBoxCallbackStruct *cbs)
{
   HTMLED *he = (HTMLED *)client_data;
   char *imagefile=NULL;
   char *imagename=NULL;
   int len=0;
   XmTextPosition left;

   if(cbs->value!=NULL)
   {
      XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&imagefile);
      len = strlen(imagefile);
      imagename = XtMalloc(len+50);
   }
   else
      imagename = XtMalloc(50);
   
   if(imagefile!=NULL)
   {
      if(align==TOP_AL)
	 sprintf(imagename,"<IMG ALIGN=\"TOP\" SRC = \"%s\" ",imagefile);
      else if (align == MIDDLE_AL)
	 sprintf(imagename,"<IMG ALIGN=\"MIDDLE\" SRC = \"%s\" ",imagefile);
      else
	 sprintf(imagename,"<IMG ALIGN=\"BOTTOM\" SRC = \"%s\" ",imagefile);
   }
   else
   {
      printf("Image Error\n");
   }
   if(ismap)
      strcat(imagename," ISMAP");
   strcat(imagename,">");
   len = strlen(imagename);
   left = XmTextGetInsertionPosition(he->textarea);
   XmTextInsert(he->textarea,left,imagename);
   XmTextSetInsertionPosition(he->textarea,left+len);
   XtFree(imagename);
   XtFree(imagefile);
   ismap = 0; align = TOP_AL;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}
/*
   
   NAME : create_pre
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates a message dialog widget 
                 to show the selected text to be in preformatted way

*/

void 
create_pre(Widget w,HTMLED *he)
{
   Widget dialog;
   XmString mstring,u,t,t2;

   char *mstr;
    mstr = XmTextGetSelection(he->textarea);

   if(strcmp(XtName(w),"button_6"))
      he->user_data = (XtPointer)PRE;
   else
      he->user_data = (XtPointer)COMMENT;

   if(mstr)
   {
      t = XmStringCreateLtoR("Preformatted text is : \n",
			     XmSTRING_DEFAULT_CHARSET);
      t2 = XmStringCreateLtoR("Commentary text is : \n",
			      XmSTRING_DEFAULT_CHARSET);
      dialog = XmCreatePromptDialog(he->textarea,"notice_header",NULL,0);
      mstring = XmStringCreateLtoR(mstr,XmSTRING_DEFAULT_CHARSET);
      if(he->user_data == (XtPointer)PRE)
	 u = XmStringConcat(t,mstring);
      else
      	 u = XmStringConcat(t2,mstring);
      XmStringFree(mstring);XmStringFree(t);XmStringFree(t2);
      XtVaSetValues(dialog,
		    XmNselectionLabelString,u,NULL);
      XmStringFree(u);
      /* When the user choose a size of the header, call set_header */
      XtAddCallback(dialog, XmNokCallback,(XtCallbackProc)set_pre,(XtPointer)he);
      
      /* If the user selects cancel, just destroy the header dialog */
      XtAddCallback(dialog, XmNcancelCallback,(XtCallbackProc)XtDestroyWidget,NULL);
      
      /* Nor help neither text is available.... */
      XtUnmanageChild(XmSelectionBoxGetChild(dialog,XmDIALOG_HELP_BUTTON));
      XtUnmanageChild(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT));
      XtManageChild(dialog);
      XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		   XtWindow(dialog),
                   0,0,800,800,20,20);
   }
   else
      set_pre(w,he);
   XtFree(mstr);
}
/*
   
   NAME : set_pre
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function sets the preformatted tags
                 to the selected text
*/
void 
set_pre(Widget w,HTMLED *he)
{   
   XmTextPosition left=0,right=0;
   int len;
   enum commands flag = (enum commands)he->user_data;
   
   if(flag==PRE)
      he->last_command = PRE;
   else
      he->last_command = COMMENT;

   if(XmTextGetSelectionPosition(he->textarea,&left,&right))
   {
      if(right<=left)
	 left = right = XmTextGetInsertionPosition(he->textarea);
   }
   else
      left = right = XmTextGetInsertionPosition(he->textarea);
   len = right -left;
   
   if(flag==PRE)
   {
      XmTextInsert(he->textarea,right,"\n</PRE>\n");
      XmTextInsert(he->textarea,left,"\n<PRE>\n");
   }
   else
   {
      XmTextInsert(he->textarea,right," -->");
      XmTextInsert(he->textarea,left,"<!-- ");
   }
   if(len == 0)
   {
      if(flag == PRE)
	 XmTextSetInsertionPosition(he->textarea,left + 7);
      else
	 XmTextSetInsertionPosition(he->textarea,left + 5);
   }
   else
   {
      if(flag == PRE)
	 XmTextSetInsertionPosition(he->textarea,left +len + 15);
      else
	 XmTextSetInsertionPosition(he->textarea,left +len + 9);
   }
   he->user_data = NULL;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT); 
}








