# Template.pm - The Template Class derived from the Base HTML object.
# Created by James Pattie, 06/05/2001.

# Copyright (c) 2000-2004 Xperience, Inc. http://www.pcxperience.com/
# All rights reserved.  This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.

# updated 11/20/2001 - Fixed the DOCTYPE urls being used and updated to be HTML 4.01 specific.

package HTMLObject::Template;
use HTMLObject::Base;
use HTMLObject::Normal;
use strict;
use vars qw($AUTOLOAD $VERSION @ISA @EXPORT @EXPORT_OK);

require Exporter;

@ISA = qw(HTMLObject::Normal Exporter AutoLoader);
@EXPORT = qw(
);

$VERSION = '2.30';

# new
sub new
{
  my $class = shift;
  my %args = ( file => "", @_ );
  my $self = $class->SUPER::new(@_);
  my $file = $args{file};

  $self->setErrorMessage(code => '4000', message => 'Parameters and Options are both required if they are to be used');
  $self->setErrorMessage(code => '4002', message => 'Value must be specified');
  $self->setErrorMessage(code => '4005', message => "Invalid variable or function");
  $self->setErrorMessage(code => '4006', message => "You must specify the HTML file to work with");
  $self->setErrorMessage(code => '4007', message => "HTML File is not readable");
  $self->setErrorMessage(code => '4008', message => "Error Opening HTML File");
  $self->setErrorMessage(code => '4009', message => "Method no longer valid");
  $self->setErrorMessage(code => '4010', message => "Tag not found");
  $self->setErrorMessage(code => '4011', message => "Method not currently available");

  if (length $file == 0)
  {
    $self->setError(code => "4006");
    $self->displayError(title => "HTMLObject::Template - new()", message => "file must be specified!");
  }
  if (! -r $file)
  {
    $self->setError(code => "4007");
    $self->displayError(title => "HTMLObject::Template - new()", message => "file = <b>$file</b> is not readable or does not exist!");
  }

  $self->{file} = $file;

  my $result = open(DOCUMENT, $file);
  if (!$result)
  {
    $self->setError(code => "4008");
    $self->displayError(title => "HTMLObject::Template - new()", message => "error = '$!'");
  }

  my $document = "";
  while (<DOCUMENT>)
  {
    $document .= $_;
  }

  $self->{document} = $document;

  close (DOCUMENT);

  # these variables will tell me if the Template tags are available to provide the desired support.
  $self->{useJavaScript} = ($document =~ /(<JAVASCRIPTTAG>)/ ? 1 : 0);
  $self->{useBodyTagOptions} = ($document =~ /(<BODYARGSTAG>)/ ? 1 : 0);
  $self->{useBodyJavaScriptTagOptions} = ($document =~ /(<BODYJAVASCRIPTTAG>)/ ? 1 : 0);
  $self->{useMetaTags} = ($document =~ /(<METATAG>)/ ? 1 : 0);
  $self->{useBaseTag} = ($document =~ /(<BASETAG>)/ ? 1 : 0);
  $self->{useLanguage} = ($document =~ /(<LANGTAG>)/ ? 1 : 0);
  $self->{useLinkTag} = ($document =~ /(<LINKTAG>)/ ? 1 : 0);
  $self->{useStyleSheet} = ($document =~ /(<STYLESHEETTAG>)/ ? 1 : 0);
  $self->{useTitle} = ($document =~ /(<TITLETAG>)/ ? 1 : 0);
  $self->{provideDocType} = ($document =~ /(<DOCTYPE )(HTML|XHTML|FRAME|XFRAME)(>)/ ? $2 : "NONE");

  $self->setTitle("HTMLObject::Template") if ($self->{useTitle});

  # validate that we have the JAVASCRIPTTAG for BODYJAVASCRIPTTAG to be valid.
  if ($self->{useBodyJavaScriptTagOptions} && !$self->{useJavaScript})
  {
    $self->setError(code => "4010");
    $self->displayError(title => "Error:  new", message => "&lt;JAVASCRIPTTAG&gt; must be defined for &lt;BODYJAVASCRIPTTAG&gt; to be valid!");
  }

  if ($self->{useJavaScript})
  {
    $self->{currentSection} = "javascript";  # force the section to be javascript (as that is the only valid section now).
  }

  return $self;
}

# reset
sub reset
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  reset', message => 'reset is invalid now!');
}

# display
sub display
{
  my $self = shift;
  my $output = "";

  my ($tempJavascriptBody);
  my $contentTypeString = $self->getContentType();
  my $titleString = $self->getTitle();
  my $language = $self->getLanguage();

  if ($contentTypeString =~ /^(text\/html)/i)
  {
    #make sure that all output is properly indented, this way the user doesn't have to do any indentation to fit our output indentation.
    ($tempJavascriptBody = $self->{javascriptBody}) =~ s/^(.*)$/    $1/mg;

    # display Cookies if needed (They apparently must come before the Content-Type: header.)
    my $tempStr = $self->displayCookies();
    $output .= $tempStr if (length $tempStr > 0);

    $output .= "Content-Type: $contentTypeString\n\n"; # Display the Content-Type block.

    # now do any fixup work to allow it to have JavaScript, Base, Links, etc.

    # output the Document Type header.
    if ($self->{provideDocType} ne "NONE")
    {
      if ($self->{provideDocType} eq "HTML")
      {
        $output .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/REC-html4/loose.dtd\">\n";
      }
      elsif ($self->{provideDocType} eq "XHTML")
      {
        $output .= "<?xml version=\"1.0\" encoding=\"$self->{docEncoding}\"?>\n";
        $output .= "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
      }
      elsif ($self->{provideDocType} eq "FRAME")
      {
        $output .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/REC-html4/frameset.dtd\">\n";
      }
      elsif ($self->{provideDocType} eq "XFRAME")
      {
        $output .= "<?xml version=\"1.0\" encoding=\"$self->{docEncoding}\"?>\n";
        $output .= "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
      }
      $self->{document} =~ s/(<DOCTYPE (HTML|XHTML|FRAME|XFRAME)>\n?)//m;
    }

    # now append the sucked in document (with any body substitutions already done) to the end of output.
    $output .= $self->{document};

    # fixup the <html> tag if in XHTML or XFRAME mode.
    if ($self->{provideDocType} =~ /^(XHTML|XFRAME)$/)
    {
      $output =~ s/<html/<html xmlns="http:\/\/www.w3.org\/1999\/xhtml" xml:lang="$language"/;
    }

    # fixup the Language support.
    if ($self->{useLanguage})
    {
      $output =~ s/(<LANGTAG>)/lang=\"$language\"/g;  # replace all instances of <LANGTAG> so that the user can do a global language update.  :)
    }

    # display Meta Tags if needed.
    if ($self->{useMetaTags})
    {
      $tempStr = $self->displayMetaTags();
      if (length $tempStr > 0)
      {
        $output =~ s/(<METATAG>)/$tempStr/;
      }
      else
      {
        $output =~ s/(<METATAG>\n?)//m;
      }
    }

    # display Base if needed.
    if ($self->{useBaseTag})
    {
      $tempStr = $self->displayBase();
      if (length $tempStr > 0)
      {
        $output =~ s/(<BASETAG>)/$tempStr/;
      }
      else
      {
        $output =~ s/(<BASETAG>\n?)//m;
      }
    }

    if ($self->{useTitle})
    {
      if (length $titleString > 0)
      {
        $output =~ s/(<TITLETAG>)/$titleString/;
      }
      else
      {
        $output =~ s/(<TITLETAG>\n?)//m;
      }
    }

    # display Links if needed.
    if ($self->{useLinkTag})
    {
      $tempStr = $self->displayLinks();
      if (length $tempStr > 0)
      {
        $output =~ s/(<LINKTAG>)/$tempStr/;
      }
      else
      {
        $output =~ s/(<LINKTAG>\n?)//m;
      }
    }

    # display Link Attributes if needed.
    if ($self->{useStyleSheet})
    {
      $tempStr = $self->displayCSS();
      if (length $tempStr > 0)
      {
        $output =~ s/(<STYLESHEETTAG>\n?)/$tempStr/m;
      }
      else
      {
        $output =~ s/(<STYLESHEETTAG>\n?)//m;
      }
    }

    # Take care of the JavaScript related head stuff.
    if ($self->{useJavaScript})
    {
      my $javaScriptHeadCode = "";

      # display the JavaScript related code.
      $tempStr = $self->displayJavaScriptHead();
      $javaScriptHeadCode .= "$tempStr\n" if (length $tempStr > 0);

      if (length $javaScriptHeadCode > 0)
      {
        $output =~ s/(<JAVASCRIPTTAG>\n?)/$javaScriptHeadCode/m;
      }
      else
      {
        $output =~ s/(<JAVASCRIPTTAG>\n?)//m;
      }
    }

    if ($self->{useBodyTagOptions})
    {
      my $tempBodyTag = "bgcolor=\"$self->{bodyBgcolor}\" text=\"$self->{bodyFgcolor}\" link=\"$self->{bodyLinkColor}\" vlink=\"$self->{bodyVlinkColor}\" alink=\"$self->{bodyAlinkColor}\"";
      $tempBodyTag .= " background=\"$self->{bodyImage}\"" if (length $self->{bodyImage} > 0);
      $tempBodyTag .= " class=\"$self->{bodyClass}\"" if (length $self->{bodyClass} > 0);
      $tempBodyTag .= " id=\"$self->{bodyID}\"" if (length $self->{bodyID} > 0);
      $tempBodyTag .= " style=\"$self->{bodyStyle}\"" if (length $self->{bodyStyle} > 0);
      $tempBodyTag .= " title=\"$self->{bodyTitle}\"" if (length $self->{bodyTitle} > 0);
      $tempBodyTag .= $self->{bodyCustomArgs} if (length $self->{bodyCustomArgs} > 0);

      $output =~ s/(<BODYARGSTAG>)/$tempBodyTag/;
    }
    if ($self->{useBodyJavaScriptTagOptions})
    {
      my $tempBodyJavaScriptTag = "";
      # display the JavaScript body attributes.
      $tempStr = $self->displayJavaScriptBody();
      $tempBodyJavaScriptTag .= $tempStr if (length $tempStr > 0);

      if (length $tempBodyJavaScriptTag > 0)
      {
        $output =~ s/(<BODYJAVASCRIPTTAG>)/$tempBodyJavaScriptTag/;
      }
      else
      {
        $output =~ s/(<BODYJAVASCRIPTTAG>)//;
      }
    }
  }
  else
  {
    $output .= "Content-Type: $contentTypeString\n\n";
    $output .= $self->{document};  # don't want to possibly corrupt anything so we put the original out.
  }

  # do any replacement for the tagBuffers that have been defined.
  foreach my $tag (keys %{$self->{tagBuffers}})
  {
    if ($self->{tagBufferModes}->{$tag} eq "single")
    {
      $output =~ s/($tag)/$self->{tagBuffers}->{$tag}/;
    }
    else
    {
      $output =~ s/($tag)/$self->{tagBuffers}->{$tag}/g;
    }
  }

  print $output;
}

# displayError - Displays the specified error document and then exits.
sub displayError
{
  my $self = shift;
  my %args = (  title => 'Error: HTMLObject::Base',
    message => 'An Error Occurred!',
    @_ # arguments passed in go here.
        );

  my $doc = HTMLObject::Base->new();

  my $document = $self->{document};
  $document =~ s/</&lt;/g;
  $document =~ s/>/&gt;/g;
  $document =~ s/ /&nbsp;/g;
  $document =~ s/\t/&nbsp;&nbsp;&nbsp;&nbsp;/g;  # replace each tab with 4 spaces for now.
  $document =~ s/\n/<br \/>\n/gm;  # make all line breaks be <br />'s.

  # now make our special tags stand out!
  $document =~ s/(&lt;DOCTYPE&nbsp;)(HTML|FRAME)(&gt;)/<font color=\"red\">$1$2$3<\/font>/;
  $document =~ s/(&lt;LANGTAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;TITLETAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;METATAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;BASETAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;LINKTAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;STYLESHEETTAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;JAVASCRIPTTAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;BODYJAVASCRIPTTAG&gt;)/<font color=\"red\">$1<\/font>/;
  $document =~ s/(&lt;BODYARGSTAG&gt;)/<font color=\"red\">$1<\/font>/;

  # now indent by 2 spaces so it looks better in the table.
  $document =~ s/^(.*)$/&nbsp;&nbsp;$1/mg;
  $document =~ s/^(.*)$/      $1/mg;

  $doc->setTitle($args{'title'});
  $doc->setFocus("body");
  $doc->print("<center><h1>HTMLObject</h1></center><br />\n");
  $doc->print("<h1>Error: &nbsp;<b>" . $self->getErrorCode() . "</b> Occurred!</h1>\n");
  $doc->print("Message: &nbsp;" . $self->getErrorMessage() . "\n<br />\n");
  $doc->print("<br />\n<br />\n$args{'message'}\n<br />\n");
  $doc->print("<br />\n<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" bgcolor=\"lightgreen\">\n");
  $doc->print("  <tr>\n");
  $doc->print("    <td bgcolor=\"cyan\">Your Template Document is: &nbsp;&nbsp;<i>Special tags in <font color=\"red\">red</font></i></td>\n");
  $doc->print("  </tr>\n");
  $doc->print("  <tr>\n");
  $doc->print("    <td>\n      <font color=\"blue\">\n$document      </font>\n    </td>\n");
  $doc->print("  </tr>\n");
  $doc->print("</table>\n");

  $doc->display();

  exit 0;
}

# startDisplaying
sub startDisplaying
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  startDisplaying', message => 'startDisplaying is invalid now!');
}

# endDisplaying
sub endDisplaying
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  endDisplaying', message => 'endDisplaying is invalid now!');
}

# setFocus
sub setFocus
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  setFocus', message => 'setFocus is invalid now!');
}

# print
sub print
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  print', message => 'print is invalid now! &nbsp;See <b>javascriptPrint</b> and <b>substitute</b>.');
}

# printTag
# requires: tag
# optional: value, mode (global or single replace)
# appends the contents of value to the tagBuffers->{tag} string.
# The tagBufferMode is set for the tag
# based upon the value of mode.  If no mode is specified and a mode has not
# yet been set for the tag, then it is defaulted to single replacement
# mode, not global replacement.
sub printTag
{
  my $self = shift;
  my %args = ( tag => "", value => "", @_ );
  my $tag = $args{tag};
  my $value = $args{value};
  my $mode = $args{mode};

  if (length $tag == 0)
  {
    $self->doRequiredParameterError('printTag', 'tag');
  }

  # now append to the tagBuffers the string passed in.
  $self->{tagBuffers}->{$tag} .= $value;

  # check on the status of the mode
  if (length $mode > 0)
  {
    if ($mode !~ /^(single|global)$/)
    {
      $self->setError(code => 1014);
      $self->displayError(title => "Base::printTag", message => "tag replacement mode = '$mode' is invalid!");
    }
  }
  else
  {
    # make sure we have a mode set.
    $self->{tagBufferModes}->{$tag} = "single" if (! exists $self->{tagBufferModes}->{$tag});
  }
}

# javascriptPrint
sub javascriptPrint
{
  my $self = shift;

  if (!defined $_[0])
  {
    $self->doRequiredParameterError('javascriptPrint', 'text');
  }

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  javascriptPrint', message => 'JavaScript Tag not defined!');
  }

  my $text = shift;
  $self->{javascriptBody} .= $text;
}

# substitute
# requires: tag, value, global
# replaces tag with value in the document.  If global = 1, then it does a global replace.
sub substitute
{
  my $self = shift;
  my %args = ( tag => "", value => "", global => 0, @_ );
  my $tag = $args{tag};
  my $value = $args{value};
  my $global = $args{global};

  if (length $tag == 0)
  {
    $self->doRequiredParameterError('substitute', 'tag');
  }
  if (length $value == 0)
  {
    $self->doRequiredParameterError('substitute', 'value');
  }
  if ($self->{document} !~ /($tag)/)
  {
    $self->setError(code => "3010");
    $self->displayError(title => "Template::substitute", message => "tag = <b>$tag</b> not found in document!");
  }
  if ($global == 1)
  {
    $self->{document} =~ s/($tag)/$value/g;
  }
  else
  {
    $self->{document} =~ s/($tag)/$value/;
  }
}

# read
sub read
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  read', message => 'read is invalid now!');
}

# delete
sub delete
{
  my $self = shift;

  if ($self->{currentSection} eq "javascript")
  {
    if (!$self->{useJavaScript})
    {
      $self->setError(code => '4011');
      $self->displayError(title => 'Error:  delete', message => 'JavaScript Tag not defined!');
    }

    $self->{javascriptBody} = "";
  }
  else
  {
    $self->setError(code => '4009');
    $self->displayError(title => 'Error:  delete', message => 'delete with section = <b>$self->{currentSection}</b> is invalid now!');
  }
}

# setJavascriptInclude
# parameters: version, file
sub setJavascriptInclude
{
  my $self = shift;
  my %args = ( @_, );

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setJavascriptInclude', message => 'JavaScript Tag not defined!');
  }
  $self->SUPER::setJavascriptInclude(%args);
}

# setJavascriptVersion
# takes the string for the version
sub setJavascriptVersion
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setJavascriptVersion', message => 'JavaScript Tag not defined!');
  }
  $self->SUPER::setJavascriptVersion(@_);
}

# getJavascriptVersion
sub getJavascriptVersion
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getJavascriptVersion', message => 'JavaScript Tag not defined!');
  }

  return $self->SUPER::getJavascriptVersion;
}

# printJavascriptRequired
# parameters: version, message
sub printJavascriptRequired
{
  my $self = shift;
  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  printJavascriptRequired', message => 'JavaScript Tag not defined!');
  }
  $self->SUPER::printJavascriptRequired(@_);
}

# disableJavascriptErrorHandler
# takes nothing
sub disableJavascriptErrorHandler
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  disableJavascriptErrorHandler', message => 'JavaScript Tag not defined!');
  }
  $self->SUPER::disableJavascriptErrorHandler(@_);
}

# isJavascriptErrorHandlerEnabled
# returns the state of the disable flag.
sub isJavascriptErrorHandlerEnabled
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  isJavascriptErrorHandlerEnabled', message => 'JavaScript Tag not defined!');
  }

  return $self->SUPER::isJavascriptErrorHandlerEnabled(@_);
}

# setJavascriptErrorHandlerEmail
# parameters: email
sub setJavascriptErrorHandlerEmail
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setJavascriptErrorHandlerEmail', message => 'JavaScript Tag not defined!');
  }

  $self->SUPER::setJavascriptErrorHandlerEmail(@_);
}

# getJavascriptErrorHandlerEmail
sub getJavascriptErrorHandlerEmail
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getJavascriptErrorHandlerEmail', message => 'JavaScript Tag not defined!');
  }

  return $self->SUPER::getJavascriptErrorHandlerEmail(@_);
}

# setJavascriptErrorHandlerWindow
# parameters: name
sub setJavascriptErrorHandlerWindow
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setJavascriptErrorHandlerWindow', message => 'JavaScript Tag not defined!');
  }

  $self->SUPER::setJavascriptErrorHandlerWindow(@_);
}

# getJavascriptErrorHandlerWindow
sub getJavascriptErrorHandlerWindow
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getJavascriptErrorHandlerWindow', message => 'JavaScript Tag not defined!');
  }

  return $self->SUPER::getJavascriptErrorHandlerWindow(@_);
}

# setJavascriptErrorHandler
# parameters: code
sub setJavascriptErrorHandler
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setJavascriptErrorHandler', message => 'JavaScript Tag not defined!');
  }

  $self->SUPER::setJavascriptErrorHandler(@_);
}

# onload
# parameters: replace, code
sub onload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  onload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::onload(@_);
}

# setOnload
# parameters: replace, code
sub setOnload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setOnload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::setOnload(@_);
}

# onunload
# parameters: replace, code
sub onunload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  onunload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::onunload(@_);
}

# setOnunload
# parameters: replace, code
sub setOnunload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setOnunload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::setOnunload(@_);
}

# onbeforeunload
# parameters: replace, code
sub onbeforeunload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  onbeforeunload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::onbeforeunload(@_);
}

# setOnbeforeunload
# parameters: replace, code
sub setOnbeforeunload
{
  my $self = shift;

  if (!$self->{useJavaScript})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setOnbeforeunload', message => 'Body JavaScript Tag not defined!');
  }

  $self->SUPER::setOnbeforeunload(@_);
}

# setBase
# parameters: href, target
sub setBase
{
  my $self = shift;

  if (!$self->{useBaseTag})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBase', message => 'Base Tag not defined!');
  }

  $self->SUPER::setBase(@_);
}

# setLink
# parameters: href, name, rel, rev, target, title, type
sub setLink
{
  my $self = shift;

  if (!$self->{useLinkTag})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setLink', message => 'Link Tag not defined!');
  }

  $self->SUPER::setLink(@_);
}

# setStyleEntry
# requires: tag, attributes
sub setStyleEntry
{
  my $self = shift;

  if (!$self->{useStyleSheet})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setStyleEntry', message => 'StyleSheet Tag not defined!');
  }

  $self->SUPER::setStyleEntry(@_);
}

# setLinkDecorations
# parameters: link, alink, vlink, hover
sub setLinkDecorations
{
  my $self = shift;

  if (!$self->{useStyleSheet})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setLinkDecorations', message => 'StyleSheet Tag not defined!');
  }

  $self->SUPER::setLinkDecorations(@_);
}

sub DESTROY
{
  my $self = shift;
}

# Base Methods overriden for validity or to make them not available.

# setLanguageEncoding - Sets the language and charset encoding to work with.
sub setLanguageEncoding
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setLanguageEncoding', message => 'Language Tag not defined!');
  }

  $self->SUPER::setLanguageEncoding(@_);
}

# getLanguage
sub getLanguage
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getLanguage', message => 'Language Tag not defined!');
  }

  return $self->SUPER::getLanguage(@_);
}

# getLanguageName
sub getLanguageName
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getLanguageName', message => 'Language Tag not defined!');
  }

  return $self->SUPER::getLanguageName(@_);
}

# lookupLanguageName
sub lookupLanguageName
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  lookupLanguageName', message => 'Language Tag not defined!');
  }

  return $self->SUPER::lookupLanguageName(@_);
}

# getCharEncoding
sub getCharEncoding
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getCharEncoding', message => 'Language Tag not defined!');
  }

  return $self->SUPER::getCharEncoding(@_);
}

# lookupCharEncoding
sub lookupCharEncoding
{
  my $self = shift;

  if (!$self->{useLanguage})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  lookupCharEncoding', message => 'Language Tag not defined!');
  }

  return $self->SUPER::lookupCharEncoding(@_);
}

# setTitle
sub setTitle
{
  my $self = shift;

  if (!$self->{useTitle})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  HTMLObject::Template->setTitle', message => 'Title Tag not defined!');
  }

  $self->SUPER::setTitle(@_);
}

# getTitle
sub getTitle
{
  my $self = shift;

  if (!$self->{useTitle})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getTitle', message => 'Title Tag not defined!');
  }

  return $self->SUPER::getTitle(@_);
}

# getHeadString
sub getHeadString
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  getHeadString', message => 'Not valid!');
}

# getBodyString
sub getBodyString
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  getHeadString', message => 'Not valid!');
}

# setMetaTag
# parameters:  http-equiv, content
sub setMetaTag
{
  my $self = shift;

  if (!$self->{useMetaTags})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setMetaTag', message => 'Meta Tag not defined!');
  }

  $self->SUPER::setMetaTag(@_);
}

# getFocus
sub getFocus
{
  my $self = shift;

  $self->setError(code => '4009');
  $self->displayError(title => 'Error:  getFocus', message => 'Not valid!');
}

=item void setBodyAttribute(name => value)

 Arguments: hash style html attributes.
 Ex: onblur => "do something", onclick => "something else"

 Builds up name="value" to append to the <body> tag when the
 document is displayed.  name must be a valid html attribute.

 Requires <BODYARGSTAG>.

=cut
sub setBodyAttribute
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyAttribute', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyAttribute(@_);
}

# setBodyBgcolor
sub setBodyBgcolor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyBgcolor', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyBgcolor(@_);
}

# getBodyBgcolor
sub getBodyBgcolor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyBgcolor', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyBgcolor(@_);
}

# setBodyFgcolor
sub setBodyFgcolor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyFgcolor', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyFgcolor(@_);
}

# getBodyFgcolor
sub getBodyFgcolor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyFgcolor', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyFgcolor(@_);
}

# setBodyLinkColor
sub setBodyLinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyLinkColor', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyLinkColor(@_);
}

# getBodyLinkColor
sub getBodyLinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyLinkColor', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyLinkColor(@_);
}

# setBodyVlinkColor
sub setBodyVlinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyFgcolor', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyVlinkColor(@_);
}

# getBodyVlinkColor
sub getBodyVlinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyVlinkColor', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyVlinkColor(@_);
}

# setBodyAlinkColor
sub setBodyAlinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyAlinkColor', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyAlinkColor(@_);
}

# getBodyAlinkColor
sub getBodyAlinkColor
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyAlinkColor', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyAlinkColor(@_);
}

=item void setBodyClass(class)

See the HTMLObject::Base manpage for more details.

=cut
sub setBodyClass
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyClass', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyClass(@_);
}

=item scalar getBodyClass()

See the HTMLObject::Base manpage for more details.

=cut
sub getBodyClass
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyClass', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyClass(@_);
}

=item void setBodyID(id)

See the HTMLObject::Base manpage for more details.

=cut
sub setBodyID
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyID', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyID(@_);
}

=item scalar getBodyID()

See the HTMLObject::Base manpage for more details.

=cut
sub getBodyID
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyID', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyID(@_);
}

=item void setBodyStyle(style)

See the HTMLObject::Base manpage for more details.

=cut
sub setBodyStyle
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyStyle', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyStyle(@_);
}

=item scalar getBodyStyle()

See the HTMLObject::Base manpage for more details.

=cut
sub getBodyStyle
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyStyle', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyStyle(@_);
}

=item void setBodyTitle(title)

See the HTMLObject::Base manpage for more details.

=cut
sub setBodyTitle
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyTitle', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyTitle(@_);
}

=item scalar getBodyTitle()

See the HTMLObject::Base manpage for more details.

=cut
sub getBodyTitle
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  getBodyTitle', message => 'Body Args Tag not defined!');
  }

  return $self->SUPER::getBodyTitle(@_);
}

# setBodyImage
sub setBodyImage
{
  my $self = shift;

  if (!$self->{useBodyTagOptions})
  {
    $self->setError(code => '4011');
    $self->displayError(title => 'Error:  setBodyImage', message => 'Body Args Tag not defined!');
  }

  $self->SUPER::setBodyImage(@_);
}

1;
__END__

=head1 NAME

HTMLObject::Template - Perl extension for HTMLObject.

=head1 SYNOPSIS

  use HTMLObject::Template;
  my $doc = HTMLObject::Template->new(file => "/var/www/html/templates/index.html");

  $doc->setTitle("Test of HTMLObject::Template");
  $doc->substitute(tag => "<BODYTAG>", value => <<"END_OF_BODY");
  <center>
  <h1>HTMLObject::Template</h1>
  <br />
  This is cool!
  END_OF_BODY

  $doc->setCookie(name => 'cookie name', value => 'This rocks!');

  $doc->javascriptPrint(<<"END_OF_JAVASCRIPT");
    function helloWorld()
    {
      document.write("Hello World");
    }
  END_OF_JAVASCRIPT  # This must be left aligned all the way.

  # cause the helloWorld function to be called when the page has been
  # loaded!
  $doc->setOnload(code => "helloWorld();");

  # Actually generate the entire document!
  $doc->display();

=head1 DESCRIPTION

HTMLObject::Template builds on the HTMLObject::Normal object and provides
JavaScript support that facilitates making Dynamic HTML documents much
easier than before.  See the documentation.html file for more details.
All core methods in the HTMLObject::Normal module are available for use
in this module unless specified as being invalid.

=head1 Exported FUNCTIONS

  scalar new(file)
    Creates a new instance of the HTMLObject::Template document type.
    You must specify the file to work with.  It should be a complete
    path to the file or just the name if it is in the same directory.

  void display()
    This function generates the Template Document displaying any cookies,
    JavaScript, Base, Links, etc. that were specified by the user plus
    the contents of the Body that the user created.  This function prints
    the generated document to standard out which is then hopefully being
    sent to a web server to process.  If you used print() then the tags
    that you specified content for will have their substitution done
    now.  This allows you to create content without having to store it
    yourself and then do a substitute before calling display().

  void startDisplaying()
    This function is not valid.

  void endDisplaying()
    This function is not valid.

  void setFocus(section) (scalar value)
    This function is not valid.

  void print(string) (scalar value)
    This function is not valid.  See javascriptPrint and substitute.

  void printTag(tag, value, mode)
    requires: tag
    optional: value, mode (global or single replace)
    appends the contents of value to the tagBuffers->{tag} string.
    The tagBufferMode is set for the tag based upon the value of mode.
    If no mode is specified and a mode has not yet been set for the tag,
    then it is defaulted to single replacement mode, not global
    replacement.

  void javascriptPrint(string) (scalar value)
    This function appends the value passed in into the javascript body.
    Requires <JAVASCRIPTTAG>.

  void substitute(tag, value, global)
    This function validates that the specified tag exists in the
    document and then substitutes it for the contents of value.
    If global is specified and equals 1, then the substitution is done
    globally instead of just replacing the first instance of the tag.

  scalar read()
    This function is not valid.

  scalar readTag(tag)
    requires: tag
    returns the string from tagBuffers identified by tag

  void delete()
    Deletes the contents of the currently specified section. This is only
    valid with "javascript".
    Requires <JAVASCRIPTTAG>.

  void deleteTag(tag)
    required: tag
    We remove the contents from tagBuffers for the tag.

  void setJavascriptInclude(version => '', file => '')
    This function creates an entry in the @javascriptIncludes array that
    will create the code to include the specified javascript file and run
    it at the specified language version. If the version is not
    specified, then "JavaScript" is the default language and version.
    Modifies @javascriptIncludes.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptVersion(version) (scalar value)
    This function sets what the Javascript version should be for the
    JavaScript body section. If not specified before the user calls
    display(), then the version will be JavaScript1.1. Modifies
    $javascriptVersion.
    Requires <JAVASCRIPTTAG>.

  scalar getJavascriptVersion()
    This function returns the current JavaScript version that is set in
    javascriptVersion.
    Requires <JAVASCRIPTTAG>.

  void printJavascriptRequired(version => '', message => '')
    This function will create the <noscript>$message</noscript> tags in
    the head that will be run if the browser does not support scripting
    at all and will also generate the code to display the message if the
    specified version of scripting is not supported. Modifies
    $javascriptRequiredMessage, $javascriptRequiredVersion.
    Requires <JAVASCRIPTTAG>.

  void disableJavascriptErrorHandler()
    This function sets the variable $javascriptErrorHandler to 0 so
    that I know not to generate that block of code when displaying the
    document.
    Requires <JAVASCRIPTTAG>.

  scalar isJavascriptErrorHandlerEnabled()
    This function returns the value of the javascriptErrorHandler to
    see if it is enabled or disabled.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptErrorHandlerEmail(email => '')
    This function will set the value of $javascriptErrorHandlerEmail
    to the value specified.  This is used in the generic JavaScript error
    handler.
    Requires <JAVASCRIPTTAG>.

  scalar getJavascriptErrorHandlerEmail()
    This function returns the email address that will be used by the
    builtin error handling code.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptErrorHandlerPrgName(name => '')
    This function will set the value of $javascriptErrorHandlerPrgName
    to the value specified.  This is used in the generic JavaScript error
    handler to specify the name of the Program we are generating an
    error handler for.
    Requires <JAVASCRIPTTAG>.

  scalar getJavascriptErrorHandlerPrgName()
    This function returns the name of the program that we are generating
    a JavaScript error handler for.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptErrorHandlerPrgVersion(version => '')
    This function will set the value of $javascriptErrorHandlerPrgVersion
    to the value specified.  This is used in the generic JavaScript error
    handler to specify the version of the Program we are generating an
    error handler for.
    Requires <JAVASCRIPTTAG>.

  scalar getJavascriptErrorHandlerPrgVersion()
    This function returns the version of the program that we are generating
    a JavaScript error handler for.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptErrorHandler(code => '')
    This function will set the code to use for the JavaScript error
    handler and will assign it to $javascriptErrorHandlerCode.  It is
    up to the user to properly set the return value so that JavaScript
    does not continue to process the error message.  The user must also
    create their own JavaScript window, etc.
    Requires <JAVASCRIPTTAG>.

  void setJavascriptErrorHandlerWindow(name => '')
    This function will set the base window name to prepend to the
    window creation code used by the builtin error handler.
    Requires <JAVASCRIPTTAG>.

  scalar getJavascriptErrorHandlerWindow()
    This function returns the window name that will be used by the
    builtin error handler.
    Requires <JAVASCRIPTTAG>.

  void onload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the onload() method in HTMLObject::Normal.

  void setOnload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the setOnload() method in HTMLObject::Normal.

  void onunload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the onunload() method in HTMLObject::Normal.

  void setOnunload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the setOnunload() method in HTMLObject::Normal.

  void onbeforeunload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the onbeoreunload() method in HTMLObject::Normal.

  void setOnbeforeunload(replace => bool, code => '')
    Requires <JAVASCRIPTTAG> and <BODYJAVASCRIPTTAG>.

    Calls the setOnbeforeunload() method in HTMLObject::Normal.

  void setBase(href => '', target => '')
    This function allows the user to specify the base url of the webpage
    or more importantly the default target that all links should point to
    if not explicitly specified. This is mainly used in web pages that
    are in a frameset. Modifies $baseHrefString, $baseTargetString.
    Requires <BASETAG>.

  void setLink(href => '', name => '', rel => '', rev => '',
               target => '', title => '')
    This function allows the user to specify a <link> tag item that is
    stored in the @linkTag array to be displayed in the <head> when the
    document is created. Modifies @linkTag.
    Requires <LINKTAG>.

  void setStyleEntry(tag => '', attributes => undef)
    requires: tag,
      attributes (ref to hash of name, value pairs to apply to this tag)
    This generates a CSS entry to specify the style for the tag you
    specified.  Requires <STYLESHEETTAG>.

  void setLinkDecorations(link => 'none', alink => 'none',
                          vlink => 'none', hover => '')
    This function allows the user to specify the decorations that the link,
    visited link, active link and hover link have.  If you specify nothing,
    then by default it turns off all decorations (no underline).  This
    generates a CSS section to specify the link decorations you desire.
    Requires <STYLESHEETTAG>.  (The tag changed from <LINKSTYLESHEETTAG>
    to <STYLESHEETTAG> in 2.06.)

  void setLanguageEncoding(language => 'en', encoding => 'iso-8859-1')
    Sets the language and encoding values to the specified values after
    validating that they exist and are valid together.
    Requires <LANGTAG>.

  scalar getLanguage()
    Returns the value of $language.
    Requires <LANGTAG>.

  scalar getLanguageName()
    Returns the name of the language we are using.
    Requires <LANGTAG>.

  scalar lookupLanguageName(code => 'en')
    Returns the name of the language code that is specified.  Defaults
    to looking up english if nothing specified.  Returns an empty string
    if the language code is not defined in our hash.
    Requires <LANGTAG>.

  scalar getCharEncoding()
    Returns the value of $charsetEncoding.
    Requires <LANGTAG>.

  (scalar or @ ref) lookupCharEncoding(code => 'en')
    Returns the array ref or string that represents the valid charset
    encodings that this language code supports.  Defaults to looking up
    english if nothing specified.
    Requires <LANGTAG>.

  void setTitle(title)  (scalar value)
    Uses the specified string to set the title with. Modifies
    $titleString.
    Requires <TITLETAG>.

  scalar getTitle()
    Returns $titleString.
    Requires <TITLETAG>.

  scalar getHeadString()
    Invalid now.

  scalar getBodyString()
    Invalid now.

  void setMetaTag('http-equiv' => '', content => '')
    Creates an entry in the meta_tags array that specifies the http-equiv
    and content values for the specified Meta tag to be created when
    display is called. Modifies @metaTags.
    Requires <METATAG>.

  void setBodyBgcolor(color)  (scalar value)
    This function sets the background color for the body. Modifies
    $bodyBgcolor.
    Requires <BODYARGSTAG>.

  scalar getBodyBgcolor()
    This function returns the background color for the body.
    Requires <BODYARGSTAG>.

  void setBodyFgcolor(color)  (scalar value)
    This function sets the text color for the body. Modifies
    $bodyFgcolor.
    Requires <BODYARGSTAG>.

  scalar getBodyFgcolor()
    This function returns the text color for the body.
    Requires <BODYARGSTAG>.

  void setBodyLinkColor(color)  (scalar value)
    This function sets the default link color for the body. Modifies
    $bodyLinkColor.
    Requires <BODYARGSTAG>.

  scalar getBodyLinkColor()
    This function returns the default link color for the body.
    Requires <BODYARGSTAG>.

  void setBodyVlinkColor(color)  (scalar value)
    This function sets the visited link color for the body. Modifies
    $bodyVlinkColor.
    Requires <BODYARGSTAG>.

  scalar getBodyVlinkColor()
    This function returns the visited link color for the body.
    Requires <BODYARGSTAG>.

  void setBodyAlinkColor(color)  (scalar value)
    This function sets the active link color for the body. Modifies
    $bodyAlinkColor.
    Requires <BODYARGSTAG>.

  scalar getBodyAlinkColor()
    This function returns the active link color for the body.
    Requires <BODYARGSTAG>.

  void setBodyImage(image)  (scalar value)
    This function sets the background image for the body. Modifies
    $bodyImage.
    Requires <BODYARGSTAG>.

=head1 AVAILABLE TAGS

  The tags that are available and what they do are as follows:
  (They can only be specified once.  The first instance is what will be
  substituted on by the HTMLObject display code.  If you define them
  but do not define anything that the HTMLObject would generate, the
  tag will be removed from the final document.)

  <DOCTYPE HTML|XHTML|FRAME|XFRAME> - Instructs the <!DOCTYPE ...> tag to be
                                created and is output at the top of your
                                document.  HTML will generate a normal
                                tag while FRAME will generate a tag
                                suitable for a FRAMESET.
                                XHTML and XFRAME generate the XHTML version
                                of HTML and FRAMESET DocTypes.
                                All generated DocTypes are transitional.
                                HTML = 4.01
                                XHTML = 1.0
  <LANGTAG>                   - This should be used in the <html> tag to
                                set the LANGUAGE of the document.
  <TITLETAG>                  - This should be put between
                                <title></title> to allow you to
                                dynamically change the title of the page.
  <METATAG>                   - This should be in the <head> of your
                                document and will be replaced with any
                                Meta Tags you defined via the HTMLObject.
  <BASETAG>                   - This should be in the <head> of your
                                document and will be replaced with the
                                Base Tag you defined via the HTMLObject.
  <LINKTAG>                   - This should be in the <head> of your
                                document and will be replaced with the
                                Link Tags you defined via the HTMLObject.
  <STYLESHEETTAG>             - This should be in the <head> of your
                                document and will be replaced with the
                                style sheet created.
  <JAVASCRIPTTAG>             - This should be in the <head> of your
                                document and will be replaced with all
                                javaScript code (error Handler, onLoad,
                                onUnLoad and any code you wrote via
                                javascriptPrint()).
  <BODYARGSTAG>               - This must be in your <body> tag and will
                                be replaced with the bgColor and link
                                tags that the HTMLObject defines or you
                                specified.
  <BODYJAVASCRIPTTAG>         - This must be in your <body> tag and will
                                be replaced with the code necessary to
                                do the onload, onunload and onbeforeunload
                                events if you defined them.

  You can define any other tag you want and use the substitute command to
  replace them anywhere in your document.

  See examples/template.cgi for a sample CGI script using this module.
  See examples/templates/index.html for a sample Template HTML file.

=head1 AUTHOR

James A. Pattie, htmlobject@pcxperience.com

=head1 SEE ALSO

perl(1), HTMLObject::Base(3), HTMLObject::Normal(3), HTMLObject::FrameSet(3), HTMLObject::ReadCookie(3), HTMLObject::Form(3).

=cut
