/** xheader.c - (c) 1994 Copyright by John R. Punin
 *
 * ASHE Editor of the HTML. 
 * 
 * This file has the routines to implement the options in the HTML Menu.
 * 
 * John R. Punin      March -12 - 1994
 *
*/
#include "xhtml.h"
#include "xfile.h"
#include "xheader.h"
#include "xmarkup.h"
#include "xviewer.h"

static char *str[6] = {
   "Header 1","Header 2",
   "Header 3","Header 4",
   "Header 5","Header 6"};

/*
   
   NAME : routines_html
   PARAMETERS : int item_no
                Item number of the menu HTML
   RETURN : void
   DESCRIPTION :This is a Callback function that is called when
                one of the items of the HTML menu is selected.

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

   XtVaGetValues(parent,XmNuserData,&he,NULL);
   if(item_no==0)
      create_title(w,(XtPointer)he);
   else if(item_no==1)
      create_header(w,he);
   else if(item_no==2)
      create_paragraph(w,he);
   else if(item_no==3)
      create_line_break(w,he);
   else if(item_no==4)
      create_hor_rule(w,he);
   else if(item_no==5)
      create_pre(w,he);
   else if(item_no==6)
      create_pre(w,he);
   else if(item_no==7)
      create_linker(w,he);
   else if(item_no==8)
      create_reference(w,he);
   else if(item_no==9)
      create_figure(w,he);  
}
/*
   
   NAME : create_title
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates the dialog widget title 
                 to enter the name of the title of the HTML Document

*/

void
create_title(Widget w,XtPointer client_data)
{
   HTMLED *he = (HTMLED *)client_data; 
   Display *display = XtDisplay(he->textarea);
   Widget dialog;
   XmString st,t = XmStringCreateSimple("Title Name :");
   XmString clear =XmStringCreateSimple("Clear"); 
   Arg args[5];
   char *selection_title=NULL ;

   /* Create the dialog for Title in the HTML Document *
    * The textarea is the parent of the Dialog Shell   *
    * The "userData" is used to store the value string */
   
   XtSetArg(args[0], XmNselectionLabelString, t); 
   XtSetArg(args[1], XmNuserData,0); 
   XtSetArg(args[2],XmNapplyLabelString,clear);
   dialog = XmCreatePromptDialog(he->textarea,"Title",args,3);
   if(selection_title=XmTextGetSelection(he->textarea)) 
   {
      st = XmStringCreateLtoR(selection_title,XmSTRING_DEFAULT_CHARSET);
      XtVaSetValues(dialog, 
		    XmNtextString,st, 
		    NULL);
      XmStringFree(st);
      XtFree(selection_title);
   }
   XmStringFree(t);   XmStringFree(clear);

   /* When the user types the title name, call title_name()... */
   XtAddCallback(dialog, XmNokCallback, (XtCallbackProc)title_name,(XtPointer)he);
   
   /* If the user selects cancel, just destroy 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(display,XtWindow(he->textarea),
		XtWindow(XmSelectionBoxGetChild(dialog,XmDIALOG_TEXT)),
                   0,0,800,800,0,0);

}
 
/*
   
   NAME : title_name
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 title of the HTML document when the Ok button
		 is selected from the dialog widget.

*/
void 
title_name( Widget w, 
	   XtPointer client_data, 
	   XmSelectionBoxCallbackStruct *cbs)
{
   HTMLED *he = (HTMLED *)client_data;
   XmTextPosition left,right;
   char *text_title=NULL;
   char *value=NULL;
   char *str=NULL,*title=NULL;
   int len;
   he->last_command = TITLE;

   if(XmStringGetLtoR(cbs->value,XmSTRING_DEFAULT_CHARSET,&value))
      len = strlen(value);
   text_title= XtMalloc(len+20);
   title = remove_title(&left,&right,he);
   strcpy(text_title,"<TITLE>");
   if(value != NULL) 
   {
      strcat(text_title,value);
      Set_label(he->title_output,value);
   }
   strcat(text_title,"</TITLE>");
   if(left!=0)
   {
      XmTextSetSelection(he->textarea,right-7,left,cbs->event->xbutton.time);
      str = XmTextGetSelection(he->textarea);
      if((str)&&(strlen(str)<(BUFSIZE - 10)))
	 strcpy(he->undo_buffer.ubuffer,str);
      else
	 printf("Error :No title was selected\n");
      XtFree(str);
      XmTextReplace(he->textarea,right-7,left,text_title);
      left = right-7; /* BKi */
   }
   else
   {
      left = XmTextGetInsertionPosition(he->textarea);
      XmTextInsert(he->textarea,left,text_title);
   }

   if(len==0)
      XmTextSetInsertionPosition(he->textarea,left+7); 
   else
      XmTextSetInsertionPosition(he->textarea,left+len+15); 

   XtFree(text_title);
   XtFree(title);
}
/*
   
   NAME : remove_title
   PARAMETERS : XmTextPosition *left,
                XmTextPosition *right
		Positions where the old title and returns the new
		position of the new title
   RETURN : char *title
            Returns the title of the Document
   DESCRIPTION : This function removes the old title and replace it
                 with the new title

*/
char *
remove_title(XmTextPosition *left,XmTextPosition *right,HTMLED *he)
{
   int i;
   int flag=0;
   int title_found=0;
   char *text = XmTextGetString(he->textarea);
   char *title=NULL;
   *left = *right = 0;

   for(i=0;i<strlen(text);i++)
   {
      if(flag)
	 break;
      if(!title_found)
      {
	 if(!strncasecmp(&(text[i]),"<TITLE>",7))
	 {
	    *right = i+7;
	    title_found=1;
	    flag=0;
	 }
      }
      else
	 if(!strncasecmp(&(text[i]),"</TITLE>",8))
	 {
	    *left=i+8;
	    flag=1;
	 }
   }

   if(!(flag&&title_found))
   {
      *left = 0;
      *right = 0;
   }
   if(*left != 0)
   {
      title = XtMalloc((int)(*left-*right+5));
      strncpy(title,&(text[*right]),*left-*right-8);
      title[*left-*right-8]='\0';
   }
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
   XtFree(text);
   return(title);
}

void 
clear_title(
   Widget  w,
   XtPointer client_data,XtPointer call_data)
{
   XmString s = XmStringCreateSimple("");
   XtVaSetValues(w, XmNtextString, s, NULL);
}
/*
   
   NAME : create_paragraph
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 tag paragraph where the cursor is.

*/

void 
create_paragraph(Widget w,HTMLED *he)
{
   XmTextPosition pos;  
   pos = XmTextGetInsertionPosition(he->textarea);
   he->last_command = PARAG;
   XmTextInsert(he->textarea,pos,"<P>\n");
   XmTextSetInsertionPosition(he->textarea,pos + 4); 
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}
/*
   
   NAME : create_line_break
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 tag line break where the cursor is.

*/

void 
create_line_break(Widget w,HTMLED *he)
{
   XmTextPosition pos;  
   pos = XmTextGetInsertionPosition(he->textarea);
   he->last_command = LINEBREAK;
   XmTextInsert(he->textarea,pos,"<BR>\n");
   XmTextSetInsertionPosition(he->textarea,pos + 5); 
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}
/*
   
   NAME : create_hor_rule
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 tag horizontal rule where the cursor is.

*/

void 
create_hor_rule(Widget w,HTMLED *he)
{
   XmTextPosition pos;  
   pos = XmTextGetInsertionPosition(he->textarea);
   he->last_command = HR;
   XmTextInsert(he->textarea,pos,"<HR>\n");
   XmTextSetInsertionPosition(he->textarea,pos + 5); 
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
}
/*
   
   NAME : create_header
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This function creates the  dialog widget to
                 select a Header between 1-6 and show the
		 selected text as a Header.

*/
void 
create_header(Widget w,HTMLED *he)
{
   Widget dialog,radiobox;
   XmString t = XmStringCreateLtoR("Header is : \n",XmSTRING_DEFAULT_CHARSET);
   char *mstr;
   XmString mstring,u,strtable[6];
   int i;

   dialog = XmCreatePromptDialog(he->textarea,"notice_header",NULL,0);
   
   mstr = XmTextGetSelection(he->textarea);
   if(mstr)
   {
      mstring = XmStringCreateLtoR(mstr,XmSTRING_DEFAULT_CHARSET);
      u = XmStringConcat(t,mstring);
      XmStringFree(mstring); 
   }
   else
      u = XmStringCopy(t);
   XtFree(mstr);
   XmStringFree(t);
   XtVaSetValues(dialog,
		 XmNselectionLabelString,u,NULL);
   XmStringFree(u);
   /* When the user choose a size of the header, call set_header */
   XtAddCallback(dialog, XmNokCallback,(XtCallbackProc)set_header,(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));
   
   /* Create a radio box -- callback routine is toggled()  */
   for(i=0;i<6;i++)
      strtable[i]=XmStringCreateSimple(str[i]);
   radiobox = 
      XmVaCreateSimpleRadioBox(dialog,"radiob",
			       0, /* the initial choice */
			       toggled, /* the callback routine */
			       XmVaRADIOBUTTON,strtable[0],NULL,NULL,NULL,
			       XmVaRADIOBUTTON,strtable[1],NULL,NULL,NULL,
			       XmVaRADIOBUTTON,strtable[2],NULL,NULL,NULL,
			       XmVaRADIOBUTTON,strtable[3],NULL,NULL,NULL,
			       XmVaRADIOBUTTON,strtable[4],NULL,NULL,NULL,
			       XmVaRADIOBUTTON,strtable[5],NULL,NULL,NULL,
			       XmNuserData,he,
			       NULL);

   XtManageChild(radiobox);

   for(i=0;i<6;i++)
      XmStringFree(strtable[i]);

   XtManageChild(dialog);
   XWarpPointer(XtDisplay(he->textarea),XtWindow(he->textarea),
		XtWindow(dialog),0,0,800,800,20,20);
}
/*
   
   NAME : set_header
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 Header tags to the selected text.
*/
void 
set_header(Widget w,XtPointer client_data)
{
   
   HTMLED *he = (HTMLED *)client_data;
   XmTextPosition left,right;
   char *sel=NULL;
   char str[20];
   int len = 0;
   int header_num = he->header_num;
   he->last_command = HEADER;
   if(XmTextGetSelectionPosition(he->textarea,&left,&right))
   {
      sel = XmTextGetSelection(he->textarea);
      if(sel) len = strlen(sel);
   }

   if(len)
   {
      sprintf(str,"</H%d>\n",header_num+1);
      XmTextInsert(he->textarea,right,str);
      sprintf(str,"<H%d>",header_num+1);
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left+len+10); 
   }
   else
   {
      left = XmTextGetInsertionPosition(he->textarea);
      sprintf(str,"<H%d></H%d>\n",header_num+1,header_num+1);
      XmTextInsert(he->textarea,left,str);
      XmTextSetInsertionPosition(he->textarea,left+4); 
   }
   XtFree(sel);
   he->header_num = 0;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT); 
}   
/*
   
   NAME : toggled
   PARAMETERS : XmToggleButtonCallbackStruct *state
                Shows which radio button changed the state
   RETURN : void
   DESCRIPTION : This is a Callback function and sets the
                 Header number of the selected text

*/
void
toggled(
	Widget w,
	XtPointer client_data, XtPointer call_data)
{
   XmToggleButtonCallbackStruct *state = 
      (XmToggleButtonCallbackStruct *)call_data;
   int which = (int)client_data;
   HTMLED *he;
   XtVaGetValues(XtParent(w),XmNuserData,&he,NULL);
   if(state->set)
      he->header_num = which;
   else
      he->header_num = 0;

}
/*
   
   NAME : create_undo
   PARAMETERS : Widget w
                From what widget this function is called.
   RETURN : void
   DESCRIPTION : This is a Callback function and retrieves
                 the value that was saved in the structure
		 undo_buffer to undo the last command

*/

void
create_undo(Widget w,HTMLED *he)
{
   undo_struct *undo_buffer = &(he->undo_buffer);
  
   if(he->last_command == CLEAR)
   {
      char *title;
      XmTextSetString(he->textarea, he->text_cleared);
      HTMLSetText(he->html_text,he->text_cleared,NULL,NULL,0,NULL,NULL);
      title = get_title(he->html_text);
      if(title!=NULL)
	 Set_label(he->title_output,title);
      else
	 Set_label(he->title_output,"");
      XtFree(he->text_cleared);
      he->text_cleared = NULL;
      he->last_command = NONE;
      XtFree(title);
      return;
   }
   if(he->last_command == TITLE)
   {
      XmTextReplace(he->textarea,undo_buffer->left,
		  undo_buffer->left+undo_buffer->lenleft,undo_buffer->ubuffer);
      undo_buffer->lenright = 0;
      he->last_command = NONE;
      undo_buffer->lenleft = 0;
      undo_buffer->ubuffer[0]='\0';
      return;
   }
   if(he->last_command != NONE)
   {
      XmTextReplace(he->textarea,undo_buffer->left,
		    undo_buffer->left+undo_buffer->lenleft,"");
      if((he->last_command!=PARAG)&&
	 (he->last_command!=LINEBREAK)&&
	 (he->last_command!=IMAGE)&&
	 (he->last_command!=INPUT)&&
	 (he->last_command!=OPTION)&&
	 (he->last_command!=HR)&&
	 (he->last_command!=ITEM)&&
	 (he->last_command!=TERM)&&
	 (he->last_command!=DEFLIST)&&
	 (he->last_command!=CARAC))
	 XmTextReplace(he->textarea,undo_buffer->right,
		       undo_buffer->right+undo_buffer->lenright,"");
   }
   undo_buffer->lenright = 0;
   he->last_command = NONE;
   undo_buffer->lenleft = 0;
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);    
}
/*
   
   NAME : verify_text
   PARAMETERS : XmTextVerifyCallbackStruct *cbs
                This pointer give you the value of the string
		to be inserted in the text widget and also
		give the current position of the cursor
   RETURN : void
   DESCRIPTION : This is a Callback function and verifyes
                 what kind of information is inserted in the
		 text widget with the purpose to save them in
		 in the undo_buffer and set the underlining of
		 the tags.

*/
void 
verify_text(
	    Widget tx, 
	    XtPointer client_data, 
	    XmTextVerifyCallbackStruct *cbs)
{
   HTMLED *he = (HTMLED *)client_data;
   undo_struct *undo_buffer = &(he->undo_buffer);
   char *t;
   he->modified_file=TRUE;/* File is modified */
   if((he->text_cleared)&&(he->last_command != CLEAR))
   {
      XtFree(he->text_cleared);
      he->text_cleared = NULL;
   }
   if(cbs->text->ptr == NULL)/* backspace */
      return;
   undo_buffer->right = undo_buffer->left;
   undo_buffer->lenright = undo_buffer->lenleft;
   undo_buffer->lenleft = cbs->text->length;
   undo_buffer->left = cbs->startPos;
   undo_buffer->com_html = he->last_command;
   if(he->toggle_mark_tag==True)
   {
      t = XmTextGetString(he->textarea);
      parsing_hightlight(t,cbs->startPos,cbs->text->length,he);
      XtFree(t);
   }
}

