/** 
 * 
 * xviewer.c - (c) 1994 Copyright by John R. Punin
 *
 * ASHE
 *
 * This file has the routines to reload the HTML documents
 *
 * Create new frames of ASHE and Local Navigation
 * 
 * John R. Punin     Jul-24- 1994
 *
*/
#include "xhtml.h"	   
#include "xviewer.h"
#include "xfile.h"
/*#include "HTMLP.h"*/


/* 
   NAME : ViewerButtonCallBack
   PARAMETERS : Not used
   RETURN : void
   DESCRIPTION : This Routine creates a new window to browse the
                 html document
*/
extern HTML_LIST *head_html;
extern HTML_LIST *tail_html;
extern MyAppResType myAppRes;
Widget html_help;


Widget 
CreateHTMLwidget(Widget w,HTMLED *he)
{
   Widget html_text;
   String tstring;

   int narg;
   Arg  arglist[MAXARGS];
   /*
     *  Create HTML widget to browse Hypertext documents.
     */

   narg = 0;
   XtSetArg(arglist[narg],XmNwidth ,550 ); narg++;
   XtSetArg(arglist[narg],XmNheight ,300 ); narg++;

   
   html_text = XtVaCreateManagedWidget("texthtml",
				       htmlWidgetClass,w,NULL);

   XtSetValues(html_text,arglist,narg);

   XtManageChild(html_text);


   tstring = XmTextGetString(he->textarea);

   HTMLSetText(html_text,tstring,NULL,NULL,0,NULL,NULL);
   XtFree(tstring);
   return(html_text);
}   



void
Reload_HTML(
    Widget  w,
    XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   String tstring,title;
   int vr,ssr, ir,pir;

   Widget verbar=XtNameToWidget(he->html_text,"Vbar");
   if(verbar)
   {
      XmScrollBarGetValues(verbar,&vr,&ssr,&ir,&pir);
/*      printf("Info is vr=%d,ssr=%d,ir=%d,pir=%d\n",vr,ssr,ir,pir);*/
   }
   
   tstring = XmTextGetString(he->textarea);

   HTMLSetText(he->html_text,tstring,NULL,NULL,0,he->anchor_target,NULL);
   if(verbar)
      XmScrollBarSetValues(verbar,vr,ssr,ir,pir,True);


   title = get_title(he->html_text);
   if(title!=NULL)
      Set_label(he->title_output,title);
   else
      Set_label(he->title_output,"");
 
   XmProcessTraversal(he->textarea,XmTRAVERSE_CURRENT);
 
   XtFree(tstring);   XtFree(title);

}

void 
CreateNewFrame(Widget w,HTMLED *he)
{
   HTMLED *nhe;
   Widget parent = he->textarea;
   Widget shell_frame;
   
   shell_frame = XtVaCreatePopupShell("sframe",
                                     topLevelShellWidgetClass, parent, NULL);

   nhe = create_rest_widgets(shell_frame,he);
   Insert_html_frame(nhe);
/*   Print_Frames();*/

   nhe->shell = shell_frame;

   XtPopup(shell_frame, XtGrabNone);
}
void
CloseFrame(Widget w, HTMLED *he)
{
   Widget wshell = he->shell;
   char buf[BUFSIZ];
   int ask;
   if(strcmp(XtName(wshell),"xhtml"))
   {
     if(he->modified_file)
     {
	char *fname = he->Name_File;
	char *question=XtMalloc(strlen(fname)+50);
	sprintf(question, 
        	"File %s has been modified. \n Do you want to save it?",fname);
	 if((ask = AskUser(he->textarea, question))==YES)
	 {
	    if(save_file_ok(he))
	    {
	       sprintf(buf,"This file %s can not be saved",fname);
	       printf("%s",buf);
	       Set_label(he->text_output,buf);
	       XtFree(question);
	       return;
	    }
	 }
	 else if(ask == CANCEL)
	 {
	    XtFree(question);
	    return;
	 }
	 XtFree(question);
      }
      Delete_html_frame(he);
/*      Print_Frames();*/
      XtFree((char *)he);
      XtPopdown(wshell);
   }
   else
      Set_label(he->text_output,"The main window xhtml can not be closed");
}
   
void 
anchor_call(Widget w, XtPointer client_data, XtPointer call_data)
{
   HTMLED *he = (HTMLED *)client_data;
   WbAnchorCallbackData *ele_ref=(WbAnchorCallbackData *)call_data;
   char *buf;
   char *href=NULL,*name=NULL;
   struct stat statbuf;        /* information on a file */
   
/*   printf("text is %s\n",ele_ref->text);
   printf("href is %s\n",ele_ref->href);
   printf ("id is %d \n",ele_ref->element_id);
   printf("anchor is called\n");
*/
   XtFree(he->href);
   he->href=NULL;
   strip_href(ele_ref->href,&href,&name);
/*   printf("href is %s, name is %s\n",href,name);*/
   if(name!=NULL)
   {
      XtFree(he->anchor_target);
      he->anchor_target = XtMalloc(strlen(name)+1);
      strcpy(he->anchor_target,name);
      XtFree(name);
   }

   if((href!=NULL)&&(href[0]!='\0'))
   {
      XtFree(he->href);
      if(href[0]!='/')
      {
	 he->href=getfile_href(href,he);
	 XtFree(href);
      }
      else
	 he->href = href;

      if(stat(he->href, &statbuf) == 0)
      {
	 if(S_ISDIR(statbuf.st_mode))
	 {
	    buf = XtMalloc(strlen(he->href)+20);
	    sprintf(buf,"%s is a directory",he->href);
	    Set_label(he->text_output,buf);
	    XtFree(buf);
	    XtFree(he->href);
	    he->href = NULL;
	    return;
	 }
      }
      if(open(he->href,O_RDONLY,0)!=-1)
	 CreateNewFrame(w,he);
      else
      {
	 buf = XtMalloc(strlen(he->href)+20);
	 sprintf(buf,"Can't open to %s",he->href);
	 Set_label(he->text_output,buf);
	 XtFree(he->href);
	 he->href = NULL;
	 XtFree(buf);
      }
   }
   else
   {
      if(he->anchor_target!=NULL)
	 Reload_HTML(w,(XtPointer)he,NULL);
   }
}

void 
strip_href(char *ohref,char **href, char**name)
{
   int len=0;
   int i;
   *href = NULL;
   *name = NULL;
   if(ohref!=NULL)
      len = strlen(ohref);

   if(len!=0)
   {
      *href = XtMalloc(len);
      *name = XtMalloc(len);
      (*name)[0]='\0';
      for(i=len-1;i>=0;i--)
	 if(ohref[i]=='#')
	    break;
      strcpy(*href,ohref);
      if((i>=0)||((i==0)&&((*href)[0]=='#')))
      {
	 (*href)[i]='\0';
	 strcpy(*name,&(ohref[i+1]));
      }
   }
}      
	 
char *
getfile_href(char *nhref,HTMLED *he)
{
   char *fname = he->Name_File;
   int len=strlen(fname);
   char *path=NULL;
   char *href = NULL;
   int i,j;
   if(len!=0)
   {
      for(i=len-1;i>=0;i--)
	 if(fname[i]=='/')
	    break;
      if(i!=0)
      {
	 path = XtMalloc(len+2);
	 for(j=0;j<=i;j++)
	    path[j]=fname[j];
	 path[j]='\0';
	 href=XtMalloc(i+strlen(nhref)+5);
	 strcpy(href,path);
	 strcat(href,nhref);
      }
   }   

   return(href);
}

char *
get_title(Widget whtml)
{
   String buffer=NULL;
   char *title=NULL;

/*   HTMLWidget hw = (HTMLWidget) whtml;
   char *wtitle = hw->html.title;
   if(wtitle!=NULL)
   {
      title = XtMalloc(strlen(wtitle));
      strcpy(title,wtitle);
   }
*/

   XtVaGetValues(whtml,WbNtitleText,&buffer,NULL);

   if(buffer != NULL)
   {
      title = XtMalloc(strlen(buffer)+2);
      strcpy(title,buffer);
   }
   /*XtFree(buffer);*/

   return(title);
}

void
Insert_html_frame(HTMLED *he)
{
   HTML_LIST *htemp = (HTML_LIST *)XtMalloc(sizeof(HTML_LIST));
   htemp->fr = he;
   htemp->next = head_html->next;
   head_html->next = htemp;
}
   
void 
Delete_html_frame(HTMLED *he)
{
   HTML_LIST *htemp,*hfound;

   for(htemp = head_html;htemp->next != NULL; htemp = htemp->next)
      if(htemp->next->fr == he)
	 break;

   if(htemp->next)
   {
      hfound = htemp->next;
      htemp->next = hfound->next;
      XtFree((XtPointer)hfound);
   }
   else
      printf("Something is wrong. Your frame was not deleted from memory\n");
}

void
Print_Frames(void)
{
   HTML_LIST *htemp;
   int i=0;

   printf("\n Frame List :\n");
   for(htemp = head_html->next; htemp != tail_html; htemp = htemp->next)
      printf("Fr %d :%s\n",i++,htemp->fr->Name_File);
}
 
void
Exit_ASHE(Widget w)
{
   save_unmodified_files(w);
   exit_dialog(w);
}

void
exit_dialog(Widget w)
{
   Widget dialog;
   XmString text,ok_str,cancel_str;
   char *msg = "Do you really want to exit? \n";
   dialog = XmCreateWarningDialog(w,"warning",NULL,0);
   text = XmStringCreateLtoR(msg,XmFONTLIST_DEFAULT_TAG);
   ok_str = XmStringCreateLocalized("Yes");
   cancel_str = XmStringCreateLocalized("No");
   XtVaSetValues(dialog,
		 XmNmessageString,text,
		 XmNokLabelString,ok_str,
		 XmNcancelLabelString,cancel_str,
		 NULL);

   /* Nor help neither text is available.... */
   XtUnmanageChild(XmMessageBoxGetChild(dialog,XmDIALOG_HELP_BUTTON));
   XtAddCallback(dialog,XmNokCallback,(XtCallbackProc)exit,NULL);



   XmStringFree(text);
   XmStringFree(ok_str);
   XmStringFree(cancel_str);
   
   XtManageChild(dialog);
   XtPopup(XtParent(dialog),XtGrabNone);
}
void
save_unmodified_files(Widget w)
{
   HTML_LIST *htemp;
   HTMLED *he;
   char *fname;
   char buf[BUFSIZ];
   int ask;
   for(htemp = head_html->next; htemp != tail_html; htemp = htemp->next)
   {
      he=htemp->fr;
      fname = he->Name_File;
      if(he->modified_file)
      {
	 char *question=XtMalloc(strlen(fname)+100);
	 sprintf(question, 
        	"File %s has been modified. \n Do you want to save it?",fname);
	 if((ask = AskUser(w, question))==YES)
	 {
	    if(save_file_ok(he))
	    {
	       sprintf(buf,"This file %s can not be saved",he->Name_File);
	       printf("%s",buf);
	       Set_label(he->text_output,buf);
	       XtFree(question);
	       return;
	    }
	 }
	 else if(ask == CANCEL)
	 {
	    XtFree(question);
	    return;
	 }
	 XtFree(question);
      }
   }
}

void 
Create_Shell_Help(Widget w, XtPointer client_data, XtPointer call_data)
{
   /*HTMLED *he = (HTMLED *)client_data;*/
   HTMLED *he=NULL;
   static Widget shell_help = NULL;
   Widget parent = XtParent(w);
   Widget workarea,dismiss,frame;
   int item_no = (int)client_data;
   char *anchor=NULL;
   if(item_no == 0)
   {
      anchor = XtMalloc(8);
      strcpy(anchor,"ASHE");
   }
   if(item_no == 1)
   {
      anchor = XtMalloc(15);
      strcpy(anchor,"Key_Bindings");
   }
   if(item_no == 2)
   {
      anchor = XtMalloc(15);
      strcpy(anchor,"charac_ref");
   }

   XtVaGetValues(parent,XmNuserData,&he,NULL);

   if(!shell_help)
   {
      shell_help = XtVaCreatePopupShell("help_frame",
                                     topLevelShellWidgetClass,he->textarea, NULL);
      workarea = XmCreateForm(shell_help, "workhtml", NULL, 0);
      frame = XtVaCreateManagedWidget("frame_html",xmFrameWidgetClass,workarea,
				      XmNshadowType, XmSHADOW_ETCHED_IN, NULL);

      html_help = CreateHTMLwidget_help(frame,he,anchor);
      dismiss = XmCreatePushButton(workarea,"dismiss",NULL,0);
      XtAddCallback(dismiss,XmNactivateCallback,popdown_help,NULL);
      XtAddCallback(html_help,WbNanchorCallback,anchor_help,he);
      
      XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM, 
		    XmNleftAttachment,XmATTACH_FORM,
		    XmNrightAttachment,XmATTACH_FORM,
		    XmNtopAttachment,XmATTACH_WIDGET, 
		    XmNtopWidget, dismiss, NULL);
      XtVaSetValues(dismiss,XmNtopAttachment,XmATTACH_FORM,
		    NULL);
      XtManageChild(frame);
      XtManageChild(dismiss);
      XtManageChild(workarea);
   }
   else
      if(anchor)
	 HTMLGotoId(html_help,HTMLAnchorToId(html_help,anchor));
   XtFree(anchor);
   XtPopup(shell_help, XtGrabNone);
}

void
BuildHelpMenu(Widget menubar,HTMLED *he)
{
   XmString on_keys,on_index,on_charac,index_acc;

   on_index = XmStringCreateSimple("On Index...");
   index_acc = XmStringCreateSimple("Ctrl-h");
   on_keys = XmStringCreateSimple("On Keys...");
   on_charac = XmStringCreateSimple("On Characters...");
   XmVaCreateSimplePulldownMenu(menubar,"help_menu",0,Create_Shell_Help,
		   XmVaPUSHBUTTON, on_index, 'I',"Ctrl<Key>h",index_acc,
		   XmVaPUSHBUTTON, on_keys, 'K',"",NULL,
		   XmVaPUSHBUTTON, on_charac, 'C',"",NULL,
		   XmNuserData,he,
		   NULL);
   XmStringFree(on_index);XmStringFree(on_keys);XmStringFree(index_acc);
   XmStringFree(on_charac);
   
}
   
Widget 
CreateHTMLwidget_help(Widget w,HTMLED *he,char* anchor)
{
   Widget html_text;
   String tstring;

   int narg;
   Arg  arglist[MAXARGS];

   /*
     *  Create HTML widget to browse Hypertext documents.
     */

   narg = 0;
   XtSetArg(arglist[narg],XmNwidth ,550 ); narg++;
   XtSetArg(arglist[narg],XmNheight ,300 ); narg++;


   
   html_text = XtVaCreateManagedWidget("texthtml",
				       htmlWidgetClass,w,NULL);

   XtSetValues(html_text,arglist,narg);

   XtManageChild(html_text);

   tstring = read_help();

   HTMLSetText(html_text,tstring,NULL,NULL,0,anchor,NULL);

   XtFree(tstring); 
   return(html_text);
}   

String  
read_help(void)
{
   int fd;
   String name = "help.html";
   String fname;
   String mybuf;
   struct stat statbuf;        /* information on a file */
   int file_length=0;
   int i=0;
   long n;
   mybuf = XtMalloc(90);
   strcpy(mybuf,
	  "Error in help.html. \n Please, check in your resources file the htmldir resource");
   printf("Resource directory is %s\n",myAppRes.htmldir);
   if(myAppRes.htmldir)
   {
      fname = XtMalloc(strlen(name)+strlen(myAppRes.htmldir)+2);
      strcpy(fname,myAppRes.htmldir);
      strcat(fname,"/");
      strcat(fname,name);
   }
   else
      fname = name;

   if(stat(fname, &statbuf) == 0)
      file_length = statbuf.st_size;

   /* Opening and Reading the file */
   if((fd = open(fname,O_RDONLY,0)) == -1)
   {
      fprintf(stderr,"File %s does not exist\n\n",name);
      XtFree(fname);
      return mybuf;
    }
   XtFree(mybuf);
   mybuf = (char *)XtMalloc((unsigned)file_length+1);
   while((n = read(fd, mybuf, file_length)) > 0)
   {
      if(n!=file_length)
	  fprintf(stderr,"Warning: did not read entire file!");
      i++;
      if (i==2) fprintf(stderr,"Reading the buffer again\n");
    }

   XtFree(fname);
   return(mybuf);
}


void
popdown_help(Widget w, XtPointer client_data, XtPointer call_data)
{
   XtPopdown(XtParent(XtParent(w)));
}

void
anchor_help(Widget w, XtPointer client_data, XtPointer call_data)
{
   WbAnchorCallbackData *ele_ref=(WbAnchorCallbackData *)call_data;
   

   char *href=NULL,*name=NULL;
   strip_href(ele_ref->href,&href,&name);

   if(href[0]=='\0')
   {
      if((name!=NULL)&&(name[0]!='\0'))
         HTMLGotoId(html_help,HTMLAnchorToId(html_help,name));
   }
}


