// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: htmldrv.cpp 
// Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
// Produced By: gaer@nhc.noaa.gov
// File Creation Date: 03/09/1999 
// Date Last Modified: 03/31/1999
// ----------------------------------------------------------- // 
// ------------- Program description and details ------------- // 
// ----------------------------------------------------------- // 
/*
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
  
The HyperTextDrv and HyperText class is used to create HTML
documents. The HyperTextDrv class is a base class that uses
the C++ ostream library to write HTML tags and text to a
specified stream. The HyperText class is used to write
HTML document templates to a specified stream,
*/
// ----------------------------------------------------------- // 
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "htmldrv.h"

// Define program constants
const char *DefaultTitle = "HTML Document";

const char *htmColors[NumHTMLColors] = {
  "\"#000000\"", // htmBLACK       
  "\"#000080\"", // htmDARKBLUE    
  "\"#0000ff\"", // htmBLUE        
  "\"#008000\"", // htmGREEN       
  "\"#008080\"", // htmTEAL        
  "\"#00ff00\"", // htmBRIGHTGREEN 
  "\"#00ffff\"", // htmTURQUOISE   
  "\"#800000\"", // htmDARKRED     
  "\"#800080\"", // htmVIOLET      
  "\"#808000\"", // htmDARKYELLOW  
  "\"#808080\"", // htmDARKGRAY    
  "\"#C0C0C0\"", // htmGRAY        
  "\"#ff0000\"", // htmRED         
  "\"#ff00ff\"", // htmPINK        
  "\"#ffff00\"", // htmYELLOW      
  "\"#ffffff\""  // htmWHITE       
};

const char *htmFonts[NumHTMLFonts] = {
  "Arial",        // htmARIAL,
  "Arial Black",  // htmARIALBLACK
  "Arial Narrow", // htmARIALNARROW
  "Courier New"   // htmCOURIER,
};

HyperTextDrv::HyperTextDrv(ostream &s)
{
  stream = &s;
  dec_precision = DefaultPrecision;
  non_breaking_sp = 0; // Do not use non-breaking spaces by default
}

HyperTextDrv::~HyperTextDrv()
{
  // Destructor provided for virtuality
}

void HyperTextDrv::WriteString(const char *s)
// Write a single line of text to the stream, filtering all
// the characters that have special meaning in HTML documents.
{
 char *p = (char *)s;
 unsigned len = strlen(s);

 while(len--) {
   WriteChar((const unsigned char)*p);
   p++;
 }
}

void HyperTextDrv::WriteChar(const unsigned char c) const
// Write a single character to the stream, filtering all the
// characters that have special meaning in HTML documents.
{
  switch(c) {
    case '<' : // Less than sign
      *(stream) << "&lt;"; 
      break;

    case '>': // Greater then sign
      *(stream) << "&gt;";  
      break;

    case '&' : // Ampersand
      *(stream) << "&amp;"; 
      break;

    case ' ' : // Treat spaces as breaking or non-breaking
      if(non_breaking_sp)
	*(stream) << "&nbsp;";
      else
	*(stream) << c;
      break;

    default:  
      int ex_set = c;
      if(ex_set >= 127) { // Fitler the extended ASCII character set
	*(stream) << "&#" << ex_set;
	break;
      }
      *(stream) << c;
      break;
  }
}

void HyperTextDrv::Write(char c)
{
  WriteChar((const unsigned char)c);
}

void HyperTextDrv::Write(const char c) const
{
  WriteChar((const unsigned char)c);
}

void HyperTextDrv::Write(unsigned char c)
{
  WriteChar((const unsigned char)c);
}

void HyperTextDrv::Write(const unsigned char c) const
{
  WriteChar(c);
}

void HyperTextDrv::Write(char *s)
{
  WriteString((const char *)s);
}

void HyperTextDrv::Write(const char *s)
{
  WriteString(s);
}

void HyperTextDrv::Write(unsigned char *s)
{
  WriteString((const char *)s);
}

void HyperTextDrv::Write(const unsigned char *s)
{
  WriteString((const char *)s);
}

void HyperTextDrv::Write(const long val) const
{
  *(stream) << val;
}

void HyperTextDrv::Write(long val)
{
  *(stream) << val;
}

void HyperTextDrv::Write(const unsigned long val) const
{
  *(stream) << val;
}

void HyperTextDrv::Write(unsigned long val)
{
  *(stream) << val;
}

void HyperTextDrv::Write(const int val) const
{
  *(stream) << val;
}

void HyperTextDrv::Write(int val)
{
  *(stream) << val;
}

void HyperTextDrv::Write(const unsigned int val) const
{
  *(stream) << val;
}

void HyperTextDrv::Write(unsigned int val)
{
  *(stream) << val;
}

void HyperTextDrv::Write(double val)
{
  stream->setf(ios::showpoint | ios::fixed);
  stream->precision(dec_precision);
  *(stream) << val;
}

void HyperTextDrv::Write(const double val) const
{
  stream->setf(ios::showpoint | ios::fixed);
  stream->precision(dec_precision);
  *(stream) << val;
}

void HyperTextDrv::Write(float val)
{
  stream->setf(ios::showpoint | ios::fixed);
  stream->precision(dec_precision);
  *(stream) << val;
}

void HyperTextDrv::Write(const float val) const
{
  stream->setf(ios::showpoint | ios::fixed);
  stream->precision(dec_precision);
  *(stream) << val;
}

ostream& HyperTextDrv::operator<<(ostream & (*_f)(ostream&))
{
  (*_f)(*(stream));
  return *(stream);
}

HyperTextDrv& HyperTextDrv::operator<<(char *s)
{
  Write(s);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(const char *s)
{
  Write(s);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(unsigned char *s)
{
  Write(s);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(const unsigned char *s)
{
  Write(s);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(char c)
{
  Write(c);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const char c) const
{
  Write(c);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(unsigned char c)
{
  Write(c);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const unsigned char c) const
{
  Write(c);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(long val)
{
  Write(val);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const long val) const
{
  Write(val);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(unsigned long val)
{
  Write(val);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const unsigned long val) const
{
  Write(val);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(int val) 
{
  Write(val);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const int val) const
{
  Write(val);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(unsigned int val)
{
  Write(val);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const unsigned int val) const
{
  Write(val);
  return *this;
}
 
const HyperTextDrv& HyperTextDrv::operator<<(const float val) const
{
  Write(val);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(float val)
{
  Write(val);
  return *this;
}

const HyperTextDrv& HyperTextDrv::operator<<(const double val) const
{
  Write(val);
  return *this;
}

HyperTextDrv& HyperTextDrv::operator<<(double val)
{
  Write(val);
  return *this;
}

void HyperText::Prologue(const char *doc_title)
{
  *(stream) << html << endl;
  *(stream) << head << endl;
  if(doc_title)
    *(stream) << title << ' ' << doc_title << ' ' << etitle << endl;
  else
    *(stream) << title << ' ' << DefaultTitle << ' ' << etitle << endl;
  *(stream) << ehead << endl;
}

void HyperText::StartBody(const char *parameters)
{
  if(parameters == 0)
    *(stream) << body;
  else
    BODY(parameters);

  *(stream) << endl;
}

void HyperText::StartBody(htmCOLORS color)
{
  *(stream) << lt << "BODY BGCOLOR=" << htmColors[color] << gt << endl;
  *(stream) << endl;
}


void HyperText::Epilogue()
{
  *(stream) << endl;
  *(stream) << ebody << endl;
  *(stream) << ehtml << endl;
}

void HyperText::DocHeader(const char *doc_title)
{
  if(doc_title)
    *(stream) << h1 << center << doc_title << ecenter << eh1 << endl;
  else
    *(stream) << h1 << center << DefaultTitle << ecenter << eh1 << endl;

  *(stream) << hr << endl;
  *(stream) << endl;
}

void HyperText::DocTrailer()
{
  *(stream) << endl << hr << endl;
  PAR("ALIGN=\"CENTER\"");
  *(stream) << center << endl;
  TABLE("BORDER CELLSPACING=1 BORDERCOLOR=\"#000000\"");
  *(stream) << tr;
  TD("VALIGN=\"MIDDLE\"");
  *(stream) << endl;
  PAR("ALIGN=\"CENTER\"");
  *(stream) << "End Of Document";
  *(stream) << etd << endl;
  *(stream) << etr << etable << ecenter << epar << endl;
}

void HyperText::GenTable(int cell_spacing, int cell_padding, int width,
			 int border, htmCOLORS bordercolor)
{
  *(stream) << otable << "BORDER=" << border <<  ' ' << "CELLSPACING=";
  *(stream) << cell_spacing << ' ' << "BORDERCOLOR=" << htmColors[bordercolor];
  *(stream) << ' ' << "CELLPADDING=" << cell_padding << ' ';
  *(stream)  << "WIDTH=\"%" << width << "\"" << ctag;
  *(stream) << endl;
}

void HyperText::StartTableRow()
{
  *(stream) << tr << endl; 
}

void HyperText::TableHeader(char *valign, int colspan, int rowspan, int width)
{
  *(stream) << lt << "TH ALIGN=" << valign << ' ' << "COLSPAN=" << colspan;
  *(stream) << ' ' << "ROWSPAN=" << rowspan << ' ';
  *(stream) << "WIDTH=\"%" << width << "\"" << gt;
}

void HyperText::TableData(char *valign, int colspan, int rowspan, int width)
{
  *(stream) << lt << "TD ALIGN=" << valign << ' ' << "COLSPAN=" << colspan;
  *(stream) << ' ' << "ROWSPAN=" << rowspan << ' ';
  *(stream) << "WIDTH=\"%" << width << "\"" << gt;
}

void HyperText::GetSystemTime(char *s, int full_month_name)
// Function used to create a custom time string.
{
  time_t STime;
  struct tm *TimeBuffer;
  char month[25]; char day[25]; char year[25];
  char hour[25]; char minutes[25]; char seconds[25];
  time(&STime);
  TimeBuffer = localtime(&STime);
  if(full_month_name)
    strftime(month, 25, "%B", TimeBuffer);
  else
    strftime(month, 25, "%b", TimeBuffer);
  strftime(day, 25, "%d", TimeBuffer);
  strftime(year, 25, "%Y", TimeBuffer);
  strftime(hour, 25, "%H", TimeBuffer);
  strftime(minutes, 25, "%M", TimeBuffer);
  strftime(seconds, 25, "%S", TimeBuffer);

  // Weekday Name Month Day, Year HH:MM:SS
  sprintf(s, "%s %s, %s %s:%s:%s", month, day, year, hour, minutes, seconds);
}
// ----------------------------------------------------------- // 
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //
