#!/usr/local/bin/perl -I.
use XML::ValidatingElement;
#use strict;
##########################################################################################
package Webpage::webpage;
@ISA = qw( XML::ValidatingElement );
@okids  = qw( section intro );
@oattrs  = qw( showlinkcount stylesheet rand title author description showhitcount  );
sub output
{
	my $self = shift;
    my $type = ref $self;

# get modified date and todays date
	my @months = ("January","February","March","April","May","June","July",
	      "August","September","October","November","December");
	my @days = ("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
	my @daysinmonth = (31,28,31,30,31,30,31,31,30,31,30,31);

#	my $mtime = (stat("$xmlfile"))[9];
#	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime);
#	$year += 1900;
#	my $moddate ="$days[$wday], $mday $months[$mon] $year";

	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	$year += 1900;
	my $curdate = "$days[$wday], $mday $months[$mon] $year";

	$mday -= 7;
	if($mday <1) { $mday += $daysinmonth[$mon]; $mon --; }
	if($mon < 0) { $mon = 11; $year --; }

	my $olddate = sprintf("%4d%02d%02d\n",$year,$mon+1,$mday);

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            # Allow for outputting of char data unless overridden
            if ((ref $_) =~ /::section$/o)
            {
                $_->output($olddate);
            }
		}

		# also must output
			# favourites.html
				open(OUTPUT,">favourites.html");
				my $output = \*OUTPUT;

				print $output "<html><head><title>Tom Paton's Homepage - Favourites</title>";

				open(BOILERPLATE,"<child_pre.html");
				while(<BOILERPLATE>) { print $output $_; }
				close(BOILERPLATE);
				print $output "\n<!-- BEGIN CONTENT	-->\n";
				print $output "<h1>Favourites</h1>\n";
				print $output "<p class=\"desc\">The following links are one's I enjoy and/or frequently visit.</p>\n";

			    my @kids = @{ $self->{Kids} };
			    if ($#kids >= 0)
			    {
			        foreach (@kids)
					{
			            # Allow for outputting of char data unless overridden
			            if ((ref $_) =~ /::section$/o)
						{
			                print $output $_->favourites();
						}
					}
				}
				print $output "<!-- END CONTENT -->\n";
				open(BOILERPLATE,"<child_post.html");
				while(<BOILERPLATE>) { print $output $_; }
				close(BOILERPLATE);
				close(OUTPUT);

			# new.html
				open(OUTPUT,">new.html");
				$output = \*OUTPUT;

				print $output "<html><head><title>Tom Paton's Homepage - New Links</title>";

				open(BOILERPLATE,"<child_pre.html");
				while(<BOILERPLATE>) { print $output $_; }
				close(BOILERPLATE);
				print $output "\n<!-- BEGIN CONTENT	-->\n";
				print $output "<h1>New Links</h1>\n";
				print $output "<p class=\"desc\">The following links have been added in the week prior to the most recent generation of these pages.</p>\n";

			    @kids = @{ $self->{Kids} };
			    if ($#kids >= 0)
			    {
			        foreach (@kids)
					{
			            # Allow for outputting of char data unless overridden
			            if ((ref $_) =~ /::section$/o)
						{
			                print $output $_->newlinks($olddate);
						}
					}
				}
				print $output "<!-- END CONTENT -->\n";
				open(BOILERPLATE,"<child_post.html");
				while(<BOILERPLATE>) { print $output $_; }
				close(BOILERPLATE);
				close(OUTPUT);


			# statistics.html
#				system "perl statistics.pl > _statistics.html";

	}
}
##########################################################################################
package Webpage::Element;
use HTML::Entities;
@ISA = qw( XML::ValidatingElement );
@oattrs = qw( );
@rattrs = qw( );
@okids  = qw( );
@rkids  = qw( );
$pre = '';
$post = '';
$seperator = '';
sub pre
{
	my $self = shift;
    my $type = ref $self;
	return ${"$type\::pre"};
}
sub post
{
	my $self = shift;
    my $type = ref $self;
	return ${"$type\::post"};
}
sub output
{
	my $self = shift;
    my $type = ref $self;

	my $output = "";

	$output .= $self->pre();

	if(defined $self->{Kids})
	{
	    my @kids = @{ $self->{Kids} };
	    if ($#kids >= 0)
	    {
			my $first = 1;
	        foreach (@kids)
			{
	            # Allow for outputting of char data unless overridden
	            if ((ref $_) =~ /::Characters$/o)
	            {
					$char = $_->{Text};
					for ($char)		# remove preceeding and trailing white space
					{
						s/^\s+//;
						s/\s+$//;
					}
					$output .= encode_entities( $char );
	            }
	            else
	            {
					if($first==0)
					{
						$output .= $seperator;
					}
					$first = 0;
	                $output .= $_->output();
	            }
			}
		}
	}
	$output .= $self->post();

	return $output;
}
##########################################################################################
package Webpage::intro;
sub rvalidate { return 1; }
sub output { return ''; };
##########################################################################################
package Webpage::cds;
@ISA = qw( Webpage::Element );
@oattrs = qw( title );
@okids  = qw( desc artist );
sub output
{
	my $self = shift;
	my $olddate = shift;
    my $type = ref $self;

	my $output = '';

	my $first = 1;
	$output .= "<h2>$self->{title}</h2>\n<div class=\"subsection\">";

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
		my $printedartist=0;
        foreach (@kids)
		{
            if ((ref $_) =~ /::desc$/o)
            {
                $output .= $_->output();
            }
            if ((ref $_) =~ /::artist$/o)
            {
				$printedartist=1;
                $output .= $_->output();
            }
		}
		if($printedartist==1)
		{
			$output .= ' | ';
		}
	}
	$output .= "</div>\n";

	return $output;
}

package Webpage::artist;
@ISA = qw( Webpage::Element );
@rattrs = qw( name );
@okids  = qw( disc url );
sub output
{
	my $self = shift;
	my $output = '';

	my $urlnum = 0;

	$output .= "| <b>$self->{name}</b> <font size=-1>\n";
    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::disc$/o)
            {
                $output .= $_->output();
            }
            if ((ref $_) =~ /::url$/o)
            {
				my $url = $_->output();
				$urlnum++;
				$output .= "[<a href=\"$url\">$urlnum</a>]\n";
            }
		}
	}
	$output .= '</font>';

	return $output;
}

package Webpage::disc;
@ISA = qw( Webpage::Element );
@rattrs = qw( title );
@okids  = qw( url );
sub output
{
	my $self = shift;
	my $output = '';

	my $urlnum = 0;

	$output .= "\t\t\t-- $self->{title}\n";

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::url$/o)
            {
				my $url = $_->output();
				$urlnum++;
				$output .= "[<a href=\"$url\">$urlnum</a>]\n"
            }
		}
	}

	return $output;
}
##########################################################################################
package Webpage::raw;
@ISA = qw( Webpage::Element );
@okids  = qw( p a );
sub rvalidate { return 1; }
$pre = "<div class=\"desc\">\n";
$post = "</div>\n";
##########################################################################################
package Webpage::section;
@ISA = qw( Webpage::Element );
@rattrs = qw( title );
@oattrs = qw( menu menuid );
@okids  = qw( subsection cds desc raw form );
sub file
{
	my $self = shift;
    my $type = ref $self;
	if(defined $self->{menuid} and $self->{menuid} gt " ")
	{
		return $self->{menuid};
	} else
	{
		return $self->{title};
	}
}
sub output
{
	my $self = shift;
	my $olddate = shift;
    my $type = ref $self;

	my $file = $self->file();

	open(OUTPUT,">$file.html");
	my $output = \*OUTPUT;

	print $output "<html><head><title>Tom Paton's Homepage - $self->{title}</title>";

	open(BOILERPLATE,"<child_pre.html");
	while(<BOILERPLATE>)
	{
		print $output $_;
	}
	close(BOILERPLATE);
	print $output "\n<!-- BEGIN CONTENT	-->\n";
	print $output "<h1>$self->{title}</h1>\n";

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
		my @subsections = ();
		my $ss = 1;
        foreach (@kids)
		{
            if ((ref $_) =~ /::subsection$/o)
            {
                push(@subsections, "<a href=\"#$ss\">$_->{title}</a>");
				$ss++;
			}
		}
		print $output "<div class=\"menu\">\n\t<span class=\"menuitem\">";
		print $output join("</span>\n\t<span class=\"menuitem\">", @subsections);
		print $output "</span>\n</div>\n";


		$ss = 1;
		foreach (@kids)
		{
            # Allow for outputting of char data unless overridden
            if ((ref $_) =~ /::Character$/o)
            {
				# don't print characters
            } elsif ((ref $_) =~ /::subsection$/o)
			{
                print $output $_->output($olddate,$ss++);
			} else
			{
                print $output $_->output();
			}
		}
	}

	print $output "<!-- END CONTENT -->\n";

	open(BOILERPLATE,"<child_post.html");
	while(<BOILERPLATE>)
	{
		print $output $_;
	}
	close(BOILERPLATE);

	close(OUTPUT);
}
sub newlinks
{
	my $self = shift;
	my $olddate = shift;
	my $output = '';

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
		my @newlinks = ();

        foreach (@kids)
		{
            # Allow for outputting of char data unless overridden
            if ((ref $_) =~ /::subsection$/o)
			{
				my $n = $_->newlinks($olddate);
				if($n gt " ")
				{
		               push(@newlinks, $n);
				}
			}
		}
		my $newlinks = join(" ~ ", @newlinks);

		if($newlinks gt " ")
		{

			my $file = $self->file();
			$output .= "<h2><a href=\"_$file.html\">$self->{title}</a></h2>\n";
			$output .= $newlinks;
		}
	}
	return $output;
}
sub favourites
{
	my $self = shift;
    my $output = '';

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
		my @favourites= ();
        foreach (@kids)
		{
            # Allow for outputting of char data unless overridden
            if ((ref $_) =~ /::subsection/o)
			{
				my $f = $_->favourites();
				if($f gt " ")
				{
		                push(@favourites, $f);
				}
			}
		}
		my $favourites = join( " ~ ", @favourites);

		if($favourites gt " ")
		{
			my $file = $self->file();
			$output .= "<h2><a href=\"_$file.html\">$self->{title}</a></h2>\n";
			$output .= $favourites;
		}
	}

	return $output;
}

##########################################################################################
package Webpage::subsection;
@ISA = qw( Webpage::Element );
@oattrs = qw( title );
@okids  = qw( link desc );
sub output
{
	my $self = shift;
	my $olddate = shift;
	my $anchor = shift;
    my $type = ref $self;
	my $output = '';
	my $first = 1;
	$output .= "<h2><a name=\"$anchor\">$self->{title}</a></h2>\n<div class=\"subsection\">";

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
		my $somehasdesc = 0;

        foreach (@kids)
		{
            if ((ref $_) =~ /::link$/o)
            {
				if ($_->hasdesc()==1)
	            {
					$somehasdesc = 1;
				}
            }
		}
		# first pass -- output descriptions
        foreach (@kids)
		{
            if ((ref $_) =~ /::desc$/o)
            {
                $output .= $_->output();
            }
		}
		if($somehasdesc == 1)
		{
			$output .= "<div class=\"link2\">\n";
		}
		# second pass -- output links with no descriptions
        foreach (@kids)
		{
            if ((ref $_) =~ /::link$/o)
            {
				if ($_->hasdesc() == 0)
				{
					if($first==0)
					{
						if($somehasdesc==1)
						{
							$output .= '<br>';
						} else {
							$output .= ' ~ ';
						}
					}
					$first = 0;
	                $output .= $_->output($olddate);
				}
            }
		}
		if($somehasdesc == 1)
		{
			$output .= "</div>\n";
		}
		# third pass -- output links with descriptions
        foreach (@kids)
		{
            if ((ref $_) =~ /::link$/o)
            {
				if ($_->hasdesc()==1)
	            {
				    $output .= $_->output($olddate);
				}
            }
		}
	}
	$output .= "</div>\n";

	return $output;
}
sub newlinks
{
	my $self = shift;
	my $olddate = shift;

	my @newlinks = ();
    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::link$/o)
			{
				my $nl = $_->newlinks($olddate);
				if($nl gt ' ')
				{
					push(@newlinks, $nl);
				}
			}
		}
	}
	return join(' ~ ', @newlinks);
}
sub favourites
{
	my $self = shift;

	my @favourites= ();

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::link/o)
			{
				my $f = $_->favourites();
				if($f gt ' ')
				{
					push(@favourites, $f);
				}
			}
		}
	}
	return join(' ~ ', @favourites);
}

##########################################################################################
package Webpage::link;
@ISA = qw( Webpage::Element );
@oattrs = qw( date status );
@rkids  = qw( title url );
@okids  = qw( desc );
sub output
{
	my $self = shift;
	my $olddate = shift;

	my $title = '';	# link title <title>...</title>
	my @otherurl = ();	# links within description <url linktext="">...</url>
	my @linktext = ();	# text to highlight for links within description
	my $url = '';	# link for title <url>...</url>
	my $desc = '';	# description <desc>...</desc>

# get text in child elements
    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::title$/o)
            {
                $title = $_->output();
            } elsif ((ref $_) =~ /::url$/o)
            {
				my $lt = $_->getlinktext();
				my $u = $_->output();

				if($lt gt ' ')
				{
					# has linktext, so add to list of other urls
					push(@otherurl,$u);
					push(@linktext,$lt);
				} else
				{
					if($url gt ' ')
					{
						# already have a main url
						push(@otherurl,$u);
						push(@linktext,'');
					} else
					{
						# must be the main url
						$url = $u;
					}
				}
            } elsif ((ref $_) =~ /::desc$/o)
            {
                $desc = $_->output();
            }
		}
	}

	my $new = '';
	my $hit1 = '';
	my $hit2 = '';
	if( (defined $self->{status}) and ($self->{status} eq "hit"))
	{
		# make title bold if it is a hit
		$hit1 = '<b>';
		$hit2 = '</b>';
	}
	if( (defined $self->{date}) and ($self->{date} gt $olddate))
	{
		# put in a + gif to indicate newly added items
		$new = "<img src=\"images/new.gif\" border=\"0\">";
	}
	# make the title bold/have a + new icon
	$title = "$hit1$new$title$hit2";

	# if we have a $url, then the title is a link
	if($url gt ' ')
	{
		$title = "<a href=\"$url\">$title</a>";
	}
	# if we have some other links and a desc, then "link 'em"
	if($desc gt ' ')
	{
	    if ($#otherurl >= 0)
    	{
        	foreach (@otherurl)
			{
				my $lt = shift(@linktext);
				if( $lt gt ' ')
				{
					my $linkwithurl = "<a href=\"$_\">$lt</a>";
					$desc =~ s/$lt/$linkwithurl/i;
				}
			}
		}
	}

	if($desc gt ' ')
	{
		return "<div class=\"link\">\n\t<h3>$title</h3>\n\t$desc\n</div>\n";
	} else
	{
		return "$title\n";
	}
}
sub newlinks
{
	my $self = shift;
	my $olddate = shift;

	if( defined $self->{date} and $self->{date} gt $olddate)
	{
		my $title = '';
		my $url = '';
	    my @kids = @{ $self->{Kids} };
	    if ($#kids >= 0)
	    {
	        foreach (@kids)
			{
	            # Allow for outputting of char data unless overridden
	            if ((ref $_) =~ /::title$/o)
	            {
	                $title = $_->output();
	            } elsif ((ref $_) =~ /::url$/o)
	            {
	                $url = $_->output();
	            }
			}
		}

		return "<a href=\"$url\">$title</a>\n";
	}
	return '';
}
sub favourites
{
	my $self = shift;

	if( defined $self->{status} and $self->{status} eq "hit")
	{
		my $title = '';
		my $url = '';
	    my @kids = @{ $self->{Kids} };
	    if ($#kids >= 0)
	    {
	        foreach (@kids)
			{
	            if ((ref $_) =~ /::title$/o)
				{
					$title = $_->output();
	            } elsif ((ref $_) =~ /::url$/o)
				{
					$url = $_->output();
				}
			}
		}

		return "<a href=\"$url\">$title</a>\n";
	}

	return '';
}
sub hasdesc
{
	my $self = shift;

    my @kids = @{ $self->{Kids} };
    if ($#kids >= 0)
    {
        foreach (@kids)
		{
            if ((ref $_) =~ /::desc$/o)
			{
				return 1;
			}
		}
	}

	return 0;
}
##########################################################################################
package Webpage::url;
@ISA = qw( Webpage::Element );
@oattrs = qw( linktext );
$pre='';
$post='';
sub getlinktext
{
	my $self = shift;

	if(defined $self->{linktext})
	{
		return $self->{linktext};
	} else
	{
		return '';
	}
}
##########################################################################################
package Webpage::title;
@ISA = qw( Webpage::Element );
@okids = qw( q );
$pre='';
$post='';
##########################################################################################
package Webpage::q;
@ISA = qw( Webpage::Element );
@okids  = qw(  );
$pre = ' &quot;';
$post = '&quot; ';
##########################################################################################
package Webpage::desc;
@ISA = qw( Webpage::Element );
@okids  = qw( q em a img br cite );
$pre = '<p class="desc">';
$post = "</p>\n";
##########################################################################################
# HTML ELEMENTS
#------------------------------------------------------------------------------------------
package Webpage::p;
@ISA = qw( Webpage::Element );
$pre = "<p>";
$post = "</p>\n";
package Webpage::em;
@ISA = qw( Webpage::Element );
$pre = " <em>";
$post = "</em> ";
package Webpage::cite;
@ISA = qw( Webpage::Element );
$pre = " <cite>";
$post = "</cite> ";
package Webpage::br;
@ISA = qw( Webpage::Element );
$pre = "<br>";
$post = "\n";
##########################################################################################
package Webpage::a;
use HTML::Entities;
@ISA = qw( Webpage::Element );
@rattrs  = qw( href );
sub pre
{
	my $self = shift;

	return " <a href=\"$self->{href}\">";
}
$post = '</a> ';
##########################################################################################
package Webpage::img;
use HTML::Entities;
@ISA = qw( Webpage::Element );
@rattrs  = qw( src );
@oattrs  = qw( width height border alt align );
sub output
{
	my $self = shift;
	my $type = ref $self;
	my $output = '';

	$output .= " <img src=\"$self->{src}\"";
	if(defined $self->{width}) {
		$output .= " width=\"$self->{width}\"";
	}
	if(defined $self->{height}) {
		$output .= " height=\"$self->{height}\"";
	}
	if(defined $self->{border}) {
		$output .= " border=\"$self->{border}\"";
	}
	if(defined $self->{alt}) {
		$output .= " alt=\"$self->{alt}\"";
	}
	if(defined $self->{align}) {
		$output .= " align=\"$self->{align}\"";
	}
	$output .= '> ';
	return $output;
}
##########################################################################################
package Webpage::form;
use HTML::Entities;
@ISA = qw( Webpage::Element );
@rattrs  = qw( method action );
@okids = qw( input );
sub pre
{
	my $self = shift;
	my $type = ref $self;
	return "<form method=\"$self->{method}\" action=\"$self->{action}\">\n";
}
$post = "</form>\n";
##########################################################################################
package Webpage::input;
use HTML::Entities;
@ISA = qw( Webpage::Element );
@oattrs  = qw( type name size maxlength value  );
sub output
{
	my $self = shift;
	my $output = '';

	$output .= '<input ';
	if(defined $self->{type}) {
		$output .= " type=\"$self->{type}\"";
	}
	if(defined $self->{name}) {
		$output .= " name=\"$self->{name}\"";
	}
	if(defined $self->{size}) {
		$output .= " size=\"$self->{size}\"";
	}
	if(defined $self->{maxlength}) {
		$output .= " maxlength=\"$self->{maxlength}\"";
	}
	if(defined $self->{value}) {
		$output .= " value=\"$self->{value}\"";
	}
	$output .= ">\n";
	return $output;
}
##########################################################################################
package Webpage::Characters;
use HTML::Entities;
sub output
{
	my $self = shift;
	my $output = '';

	if(defined $self->{Text})
	{
		my $char = $self->{Text};
		for ($char)		# remove preceeding and trailing white space
		{
			s/^\s+//;
			s/\s+$//;
		}
		if( defined $char )
		{
			$output .= encode_entities( $char );
		}
	}
	return $output;
}
##########################################################################################
1;  # so the require or use succeeds
