# FrameSet.pm - The FrameSet Class derived from the Base HTML object.
# Created by James Pattie, 04/28/2000.

# Copyright (c) 2000 PC & Web 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 02/24/2001 - Converted to new naming convention.

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

require Exporter;

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

$VERSION = '1.09';

# new
sub new
{
  my $class = shift;
  my $self = $class->SUPER::new(@_);

  $self->setErrorMessage(code => '2000', message => 'FrameSet must be defined');
  $self->setErrorMessage(code => '2001', message => 'Invalid Value for scrolling');
  $self->setErrorMessage(code => '2002', message => 'Invalid Value for frameborder');
  $self->setErrorMessage(code => '2003', message => 'Invalid Content-Type for FrameSet Object');

  $self->setTitle("HTMLObject::FrameSet");

  $self->{frameSet} = "";

  return $self;
}

#reset
sub reset
{
  my $self = shift;

  $self->SUPER::reset(@_);
  $self->setErrorMessage(code => '2000', message => 'FrameSet must be defined');
  $self->setErrorMessage(code => '2001', message => 'Invalid Value for scrolling');
  $self->setErrorMessage(code => '2002', message => 'Invalid Value for frameborder');
  $self->setErrorMessage(code => '2003', message => 'Invalid Content-Type for FrameSet Object');

  $self->setTitle("HTMLObject::FrameSet");

  $self->{frameSet} = "";
}

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

  $doc->setTitle($args{'title'});
  $doc->setFocus("body");
  $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->display();

  exit 0;
}

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

  #make sure that all output is properly indented, this way the user doesn't have to do any indentation to fit our output indentation.
  my ($tempHeadString, $tempFrameSet);
  my $headString = $self->getHeadString();
  my $contentTypeString = $self->getContentType();
  my $titleString = $self->getTitle();
  my $language = $self->getLanguage();

  ($tempHeadString = $headString) =~ s/^(.*)$/    $1/mg;  # currently 4 spaces.
  ($tempFrameSet = $self->{frameSet}) =~ s/^(.*)$/  $1/mg;

  # make sure that we have a frame set to display
  if (length $self->{frameSet} == 0)
  {
    $self->setError(code => '2000');
    $self->displayError(title => 'display', message => 'You must define a FrameSet!');
  }

  if ($contentTypeString =~ /text\/html/i)
  {
    # display Cookies if needed (they must be displayed before Content-Type).
    my $tempStr = $self->displayCookies();
    $output .= $tempStr if (length $tempStr > 0);

    $output .= "Content-Type: $contentTypeString\n\n";

    # output the Document Type header.
    $output .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\" \"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n";
    $output .= "<html lang=\"$language\">\n";
    $output .= "  <head>\n";

    # display Meta Tags if needed.
    $tempStr = $self->displayMetaTags();
    $output .= $tempStr if (length $tempStr > 0);

    $output .= "    <title>$titleString</title>\n";
    $output .= "    $tempHeadString" if (length $headString > 0);
    $output .= "  </head>\n\n";
    $output .= $tempFrameSet;
    $output .= "</html>\n";
  }
  else
  {
    $self->setError(code => '2003');
    $self->displayError(title => 'display', message => 'Only Content-Type = "text/html" is valid in a FrameSet document!');
  }

  print $output;
}

# outer_frameset
# parameters: rows, cols, content, frameborder, border, bordercolor
sub outer_frameset
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'content'})
  {
    $self->doRequiredParameterError('outer_frameset', 'content');
  }

  my $rows = $args{'rows'};
  my $cols = $args{'cols'};
  my $content = $args{'content'};
  my $frameborder = $args{'frameborder'};
  my $bordercolor = $args{'bordercolor'};

  if (length $rows == 0 && length $cols == 0)
  {
    $self->doRequiredParameterError('outer_frameset', 'rows and/or cols');
  }
  if (length $content == 0)
  {
    $self->doRequiredParameterError('outer_frameset', 'content');
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'outer_frameset', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  $content =~ s/^(.*)$/  $1/mg;  #Indent the content by 2 spaces.

  $self->{frameSet} = "<frameset";
  if (length $rows > 0)
  {
    $self->{frameSet} .= " rows=\"$rows\"";
  }
  if (length $cols > 0)
  {
    $self->{frameSet} .= " cols=\"$cols\"";
  }
  if (length $frameborder > 0)
  {
    $self->{frameSet} .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $self->{frameSet} .= " border=\"$args{'border'}\"";
  }
  if (length $bordercolor > 0)
  {
    $self->{frameSet} .= " bordercolor=\"$bordercolor\"";
  }
  $self->{frameSet} .= ">\n$content</frameset>\n";
}

# outerFrameset
# parameters: rows, cols, content, frameborder, border, bordercolor
sub outerFrameset
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'content'})
  {
    $self->doRequiredParameterError('outerFrameset', 'content');
  }

  my $rows = $args{'rows'};
  my $cols = $args{'cols'};
  my $content = $args{'content'};
  my $frameborder = $args{'frameborder'};
  my $bordercolor = $args{'bordercolor'};

  if (length $rows == 0 && length $cols == 0)
  {
    $self->doRequiredParameterError('outerFrameset', 'rows and/or cols');
  }
  if (length $content == 0)
  {
    $self->doRequiredParameterError('outerFrameset', 'content');
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'outerFrameset', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  $content =~ s/^(.*)$/  $1/mg;  #Indent the content by 2 spaces.

  $self->{frameSet} = "<frameset";
  if (length $rows > 0)
  {
    $self->{frameSet} .= " rows=\"$rows\"";
  }
  if (length $cols > 0)
  {
    $self->{frameSet} .= " cols=\"$cols\"";
  }
  if (length $frameborder > 0)
  {
    $self->{frameSet} .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $self->{frameSet} .= " border=\"$args{'border'}\"";
  }
  if (length $bordercolor > 0)
  {
    $self->{frameSet} .= " bordercolor=\"$bordercolor\"";
  }
  $self->{frameSet} .= ">\n$content</frameset>\n";
}

# inner_frameset
# parameters: rows, cols, content, frameborder, border, bordercolor
sub inner_frameset
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'content'})
  {
    $self->doRequiredParameterError('inner_frameset', 'content');
  }

  my $rows = $args{'rows'};
  my $cols = $args{'cols'};
  my $content = $args{'content'};
  my $frameborder = $args{'frameborder'};
  my $bordercolor = $args{'bordercolor'};

  if (length $rows == 0 && length $cols == 0)
  {
    $self->doRequiredParameterError('inner_frameset', 'rows and/or cols');
  }
  if (length $content == 0)
  {
    $self->doRequiredParameterError('inner_frameset', 'content');
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'inner_frameset', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  $content =~ s/^(.*)$/  $1/mg;  # Indent the content by 2 spaces.

  my $output = "<frameset";
  if (length $rows > 0)
  {
    $output .= " rows=\"$rows\"";
  }
  if (length $cols > 0)
  {
    $output .= " cols=\"$cols\"";
  }
  if (length $frameborder > 0)
  {
    $output .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $output .= " border=\"$args{'border'}\"";
  }
  if (length $bordercolor > 0)
  {
    $output .= " bordercolor=\"$bordercolor\"";
  }
  $output .= ">\n$content</frameset>\n";

  return $output;
}

# innerFrameset
# parameters: rows, cols, content, frameborder, border, bordercolor
sub innerFrameset
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'content'})
  {
    $self->doRequiredParameterError('innerFrameset', 'content');
  }

  my $rows = $args{'rows'};
  my $cols = $args{'cols'};
  my $content = $args{'content'};
  my $frameborder = $args{'frameborder'};
  my $bordercolor = $args{'bordercolor'};

  if (length $rows == 0 && length $cols == 0)
  {
    $self->doRequiredParameterError('innerFrameset', 'rows and/or cols');
  }
  if (length $content == 0)
  {
    $self->doRequiredParameterError('innerFrameset', 'content');
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'innerFrameset', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  $content =~ s/^(.*)$/  $1/mg;  # Indent the content by 2 spaces.

  my $output = "<frameset";
  if (length $rows > 0)
  {
    $output .= " rows=\"$rows\"";
  }
  if (length $cols > 0)
  {
    $output .= " cols=\"$cols\"";
  }
  if (length $frameborder > 0)
  {
    $output .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $output .= " border=\"$args{'border'}\"";
  }
  if (length $bordercolor > 0)
  {
    $output .= " bordercolor=\"$bordercolor\"";
  }
  $output .= ">\n$content</frameset>\n";

  return $output;
}

# create_frame
# parameters: src, name, marginwidth, marginheight, scrolling, noresize, bordercolor, frameborder, border
sub create_frame
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'src'})
  {
    $self->doRequiredParameterError('create_frame', 'src');
  }

  my $src = $args{'src'};
  my $scrolling = $args{'scrolling'};
  my $frameborder = $args{'frameborder'};

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

  if (length $scrolling > 0)
  {
    # make sure it is yes, no, or auto
    if ($scrolling !~ /yes|no|auto/i)
    {
      $self->setError(2001);
      $self->displayError(title => 'create_frame', message => "'$scrolling' is invalid for <b>scrolling</b>.");
    }
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'create_frame', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  my $output = "<frame src=\"$src\"";
  if (length $args{'name'} > 0)
  {
    $output .= " name=\"$args{'name'}\"";
  }
  if (length $args{'marginwidth'} > 0)
  {
    $output .= " marginwidth=\"$args{'marginwidth'}\"";
  }
  if (length $args{'marginheight'} > 0)
  {
    $output .= " marginheight=\"$args{'marginheight'}\"";
  }
  if (length $scrolling > 0)
  {
    $output .= " scrolling=\"$scrolling\"";
  }
  if (exists $args{'noresize'})
  {
    $output .= " noresize";
  }
  if (length $args{'bordercolor'} > 0)
  {
    $output .= " bordercolor=\"$args{'bordercolor'}\"";
  }
  if (length $frameborder > 0)
  {
    $output .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $output .= " border=\"$args{'border'}\"";
  }
  $output .= ">\n";

  return $output;
}

# createFrame
# parameters: src, name, marginwidth, marginheight, scrolling, noresize, bordercolor, frameborder, border
sub createFrame
{
  my $self = shift;
  my %args = ( @_, );

  if (!exists $args{'src'})
  {
    $self->doRequiredParameterError('createFrame', 'src');
  }

  my $src = $args{'src'};
  my $scrolling = $args{'scrolling'};
  my $frameborder = $args{'frameborder'};

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

  if (length $scrolling > 0)
  {
    # make sure it is yes, no, or auto
    if ($scrolling !~ /yes|no|auto/i)
    {
      $self->setError(2001);
      $self->displayError(title => 'createFrame', message => "'$scrolling' is invalid for <b>scrolling</b>.");
    }
  }
  if (length $frameborder > 0)
  {
    # make sure it is yes or no
    if ($frameborder !~ /yes|no/i)
    {
      $self->setError(2002);
      $self->displayError(title => 'createFrame', message => "'$frameborder' is invalid for <b>frameborder</b>.");
    }
  }

  my $output = "<frame src=\"$src\"";
  if (length $args{'name'} > 0)
  {
    $output .= " name=\"$args{'name'}\"";
  }
  if (length $args{'marginwidth'} > 0)
  {
    $output .= " marginwidth=\"$args{'marginwidth'}\"";
  }
  if (length $args{'marginheight'} > 0)
  {
    $output .= " marginheight=\"$args{'marginheight'}\"";
  }
  if (length $scrolling > 0)
  {
    $output .= " scrolling=\"$scrolling\"";
  }
  if (exists $args{'noresize'})
  {
    $output .= " noresize";
  }
  if (length $args{'bordercolor'} > 0)
  {
    $output .= " bordercolor=\"$args{'bordercolor'}\"";
  }
  if (length $frameborder > 0)
  {
    $output .= " frameborder=\"$frameborder\"";
  }
  if (length $args{'border'} > 0)
  {
    $output .= " border=\"$args{'border'}\"";
  }
  $output .= ">\n";

  return $output;
}

# create_noframe
# takes a string
sub create_noframe
{
  my $self = shift;

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

  my $content = shift;
  $content =~ s/^(.*)$/  $1/mg;  # Indent the content by 2 spaces.

  my $output = "<noframes>\n$content\n</noframes>\n";

  return $output;
}

# createNoframe
# takes a string
sub createNoframe
{
  my $self = shift;

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

  my $content = shift;
  $content =~ s/^(.*)$/  $1/mg;  # Indent the content by 2 spaces.

  my $output = "<noframes>\n$content\n</noframes>\n";

  return $output;
}

1;
__END__
# Below is the stub of documentation for your module. You better edit it!

=head1 NAME

HTMLObject::FrameSet - Perl extension for HTMLObject.

=head1 SYNOPSIS

  use HTMLObject::FrameSet;
  my $frameSet = HTMLObject::FrameSet->new();

  my $innerFrameset = $frameSet->createFrame(src => 'tester2.cgi',
                                   noresize => '', frameborder => 'no',
                                   scrolling => 'auto');
  $innerFrameset .= $frameSet->createFrame(src => 'tester2.cgi');

  $frameSet->outerFrameset(rows => "*,*", content => $innerFrameset);

  $frameSet->display();  # display the frameset document.

=head1 DESCRIPTION

The HTMLObject::Frameset Object builds upon the HTMLObject::Base object to
provide the user with a quick and easy way to create Dynamic FrameSets.  See
the documentation.html file for more info.

=head1 Exported FUNCTIONS

  scalar new()
    Creates a new instance of the HTMLObject::Frameset document type.

  void reset()
    Resets the HTMLObject::Frameset document back to the defaults.

  void display()
    This function generates the Frameset Document displaying any cookies,
    This function prints the generated document to standard out which is
    then hopefully being sent to a web server to process.

  void displayError(title => '', message => '')
    Creates a HTML document that displays the user specified error
    message along with the error message generated by the program. The
    user specified title is used also. The program is exited after the
    document is displayed. Uses display() to generate the actual document.

  void outer_frameset(rows => '', cols => '', frameborder => 'yes|no',
                      bordercolor => '', border => '', content => '')
    This function creates the <frameset>$content</frameset> tags with the
    specified rows and cols. Modifies $frameSet.

  void outerFrameset(rows => '', cols => '', frameborder => 'yes|no',
                     bordercolor => '', border => '', content => '')
    This function creates the <frameset>$content</frameset> tags with the
    specified rows and cols. Modifies $frameSet.

  scalar inner_frameset(rows => '', cols => '', frameborder => 'yes|no',
                        bordercolor => '', border => '', content => '')
    This function creates the string with <frameset>$content</frameset>
    with the specified rows and cols and then returns it to be used as
    the arguments for outerFrameset().

  scalar innerFrameset(rows => '', cols => '', frameborder => 'yes|no',
                       bordercolor => '', border => '', content => '')
    This function creates the string with <frameset>$content</frameset>
    with the specified rows and cols and then returns it to be used as
    the arguments for outerFrameset().

  scalar create_frame(src => '', name => '', marginwidth => '',
                      marginheight => '', scrolling => 'yes|no|auto',
                      noresize => '', bordercolor => '',
                      frameborder => 'yes|no', border => '')
    This function returns the string of text that would be necessary to
    have the specified frame displayed within the current <frameset>
    context.  If noresize is defined then it is included in the output
    else it is left out. The value does not matter as it is a tag and not
    a name=value item in the <frame> tag.

  scalar createFrame(src => '', name => '', marginwidth => '',
                     marginheight => '', scrolling => 'yes|no|auto',
                     noresize => '', bordercolor => '',
                     frameborder => 'yes|no', border => '')
    This function returns the string of text that would be necessary to
    have the specified frame displayed within the current <frameset>
    context.  If noresize is defined then it is included in the output
    else it is left out. The value does not matter as it is a tag and not
    a name=value item in the <frame> tag.

  scalar create_noframe(content) (scalar value)
    This function returns the string of text that defines a
    <noframes>$content</noframes> sequence that would go within the
    current <frameset> context.

  scalar createNoframe(content) (scalar value)
    This function returns the string of text that defines a
    <noframes>$content</noframes> sequence that would go within the
    current <frameset> context.

=head1 AUTHOR

James A. Pattie, htmlobject@pcxperience.com

=head1 SEE ALSO

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

=cut
