/*		HyperText gateway			HTMLGate.c
**		=================
**
**	expects things like
**		GET /news:alt.hypertext
**	rether than
**		GET news:alt.hypertext
**	because of a weirdness of MidasWWW.
*/

/* #define HELP_BASE "http://slacvx.slac.stanford.edu:80/MidasHelp/Gateway/" */
#define HELP_BASE "http://info.cern.ch/hypertext/WWW/HTMLGate/Help/"

#include "HTAnchor.h"
#include "HText.h"
#include "HTStyle.h"
#include "HTAccess.h" /* tbl */

static char *oldTitle;
static HTStyle *oldStyle;
static HTStyle *normalStyle;
static HTStyle *exampleStyle;
extern HTStyleSheet * styleSheet;

#define BUFFER_SIZE 4096

static char buffer[BUFFER_SIZE];  
static int size;
static int reply_socket;

extern  int  WWW_TraceFlag;         /* Off unless -v option given */
PUBLIC HTParentAnchor * HTMainAnchor = 0;
PUBLIC HText * HTMainText = 0;
extern char * HTClientHost;
					   
PUBLIC void HTMLGateInit()
{
   normalStyle = HTStyleNamed(styleSheet, "Normal"); 
   exampleStyle = HTStyleNamed(styleSheet, "Example");
}
static void flush()
{
    write(reply_socket,buffer,size);
    size = 0;
}
static void reply(const char *message)
{
   for (;  buffer[size++] = *message++ ; ) if (size == BUFFER_SIZE) flush();  
   size--; 
}

/* @@ Dangereous arg passing here ehen int on stack doesn't match pointer size
*/
static void replyf(const char *fmt, const char *arg)

{
   char temp[4096];
   sprintf(temp,fmt,arg);
   reply(temp);
}


/*	Retrieve a file
**	---------------
*/

#ifdef __STDC__
int HTRetrieve(const char * arg, const char * keywords, int soc)
#else
int HTRetrieve(arg, keywords, soc)
    char *arg;
    char *keywords;
    int soc;
#endif
{

  if (normalStyle == 0) HTMLGateInit();
  oldTitle = NULL;
  oldStyle = NULL; 
  size = 0;
  reply_socket = soc; 
  
  arg++;	/* Skip the leading slash */
  
  if (!strncmp(arg,"rlogin",6) || !strncmp(arg,"telnet",6) || !HTLoadAbsolute(arg,FALSE))
    {
      reply("<h2>Error</h2>");
      reply("Gateway was unable to connect to: "); 
      reply(arg);
      reply("<p>For more information see");
      replyf("<a href=\"%scannot_connect.html\">", HELP_BASE);
      reply("help</a>");
    }  

  flush();
  return 1; /* OK */
}
/*			Creation Method
**			---------------
*/
PUBLIC HText *	HText_new ARGS1(HTParentAnchor *,anchor)
{
   return NULL; 
}

void HTAnchor_setTitle
  ARGS2(HTParentAnchor *,this, CONST char *,title)
{
  if (oldTitle) free(oldTitle);
  oldTitle = strcpy(malloc(strlen(title)+1),title);  
}

void HTAnchor_appendTitle
  ARGS2(HTParentAnchor *,this, CONST char *,title)
{
  char *tempTitle = strcat(malloc(strlen(title)+strlen(oldTitle)+1),title);
  free(oldTitle);
  oldTitle = tempTitle;
}
/*			Object Building methods
**			-----------------------
**
**	These are used by a parser to build the text in an object
*/
PUBLIC void HText_beginAppend ARGS1(HText *,text)
{
}

    


/*	New paragraph in current style
**	------------------------------
** See also: setStyle.
*/

PUBLIC void HText_appendParagraph ARGS1(HText *,text)
{
  if (!oldStyle || oldStyle->freeFormat)  reply("<p>\n"); else reply("\n");
}


/*	Set Style
**	---------
**
*/
PUBLIC void HText_setStyle ARGS2(HText *,text, HTStyle *,style)
{
   if (style != oldStyle) 
     { 
       if (oldStyle && oldStyle != normalStyle) replyf("</%s>\n",oldStyle->SGMLTag);
       if (style != normalStyle) replyf("<%s>\n",style->SGMLTag);
     }
   oldStyle = style;
}


/*	Append a character to the text object
**	-------------------------------------
*/
PUBLIC void HText_appendCharacter ARGS2(HText *,text, char,ch)
{
   replyf("%c",ch); 
}

/*		Anchor handling
**		---------------
*/
/*	Start an anchor field
*/
PUBLIC void HText_beginAnchor ARGS2(HText *,text, HTChildAnchor *,anc)
{
/*  if (oldStyle == exampleStyle) reply("</xmp><a"); 
  else
*/
  	reply("\n<a");
  if (anc->name && *anc->name) replyf(" name=%s",anc->name); 
  if (anc->href && *anc->href) replyf(" href=\"%s\"",anc->href); 
  reply(">"); 
}
PUBLIC void HText_endAnchor ARGS1(HText *,text)
{
/*  if (oldStyle == exampleStyle) reply("</a><xmp>"); 
  else
*/
  reply("</a>");
}


PUBLIC void HText_appendText ARGS2(HText *,text, CONST char *,str)
{
  replyf("%s",str);
}


PUBLIC void HText_endAppend ARGS1(HText *,text)
{
 if (oldStyle && oldStyle != normalStyle) replyf("</%s>",oldStyle->SGMLTag);
 if (oldTitle) 
   {
     replyf("\n<title>%s</title>\n",oldTitle);  /* @@@ aaargh! At end! */
     free(oldTitle);
     oldTitle = NULL;
   } 
}



/* 	Dump diagnostics to stderr
*/
PUBLIC void HText_dump ARGS1(HText *,text)
{
    fprintf(stderr,"HText: Dump called\n");
}
	

/*	Return the anchor associated with this node
*/
PUBLIC HTParentAnchor * HText_nodeAnchor ARGS1(HText *,text)
{
    return NULL;
}

 

/*		Editing functions		- NOT IMPLEMENTED
**		=================
**
**	These are called from the application. There are many more functions
**	not included here from the orginal text object.
*/

/*	Style handling:
*/
/*	Apply this style to the selection
*/
PUBLIC void HText_applyStyle ARGS2(HText *, me, HTStyle *,style)
{
    
}


/*	Update all text with changed style.
*/
PUBLIC void HText_updateStyle ARGS2(HText *, me, HTStyle *,style)
{
    
}


/*	Return style of  selection
*/
PUBLIC HTStyle * HText_selectionStyle ARGS2(
	HText *,me,
	HTStyleSheet *,sheet)
{
    return 0;
}


/*	Paste in styled text
*/
PUBLIC void HText_replaceSel ARGS3(
	HText *,me,
	CONST char *,aString, 
	HTStyle *,aStyle)
{
}


/*	Apply this style to the selection and all similarly formatted text
**	(style recovery only)
*/
PUBLIC void HTextApplyToSimilar ARGS2(HText *,me, HTStyle *,style)
{
    
}

 
/*	Select the first unstyled run.
**	(style recovery only)
*/
PUBLIC void HTextSelectUnstyled ARGS2(HText *,me, HTStyleSheet *,sheet)
{
    
}


/*	Anchor handling:
*/
PUBLIC void		HText_unlinkSelection ARGS1(HText *,me)
{
    
}

PUBLIC HTAnchor *	HText_referenceSelected ARGS1(HText *,me)
{
     return 0;   
}


#ifdef CURSES
PUBLIC int HText_getTopOfScreen ARGS1(HText *,text)
{
      return text->top_of_screen;
}

PUBLIC int HText_getLines ARGS1(HText *,text)
{
      return text->lines;
}
#endif
PUBLIC HTAnchor *	HText_linkSelTo ARGS2(HText *,me, HTAnchor *,anchor)
{
    return 0;
}

PUBLIC BOOL HText_select ARGS1(HText *,text)
{
    return YES;
}


PUBLIC BOOL HText_selectAnchor ARGS2(HText *,text, HTChildAnchor *,anchor)
{
    return YES;
}