#!/usr/bin/perl
use lib '/home/erealms/ethereal/mgmt/perl';

#################################################################################
# Created       : Martin Foster
# Modified      : 17-Feb-2005
#################################################################################
#
# Gummies  - Script part of Ethereal Realms, designed to view gummies 
#            rights.  Allows to display specific classes and groups.
# Copyright (C) 2000-2006  Martin Foster
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# Author of this script can be contacted at the following:
#       E-Mail  : martin@ethereal-realms.org
#       Address : 29-26503 TWP RD 511
#                 Spruce Grove, Alberta
#                 T7Y 1G4
#
#################################################################################

use CGI;							# Common gateway interface
use CGI::Carp qw(fatalsToBrowser);				# CGI Error logs
use strict;							# Strict variable enforcement

use Ethereal::Database;						# Database handler
use Ethereal::Param;						# Parameter handler
use Ethereal::Template;						# Template handler

#################################################################################
# Gobal override
#################################################################################
$CGI::POST_MAX=1024 * 50;					# Maximum posts
$CGI::DISABLE_UPLOADS = 1;					# Disable uploads

#################################################################################
# Data Members
#################################################################################
my $cgi;							# Common gateway interface handle
my $database;							# Database handle
my $param;							# Parameter handle

my $sname;							# Simply the script name
my $sparam;							# Scripted parameter string

my %sparam;							# Scripted parameters

#################################################################################
# Program Area
#################################################################################

	# Initial handles
	$cgi      = new CGI;
	$database = new Ethereal::Database();

	# Connect and fetch
	$database->Connect($cgi);

	# Parameters
	$param    = new Ethereal::Param($database, $cgi);
	$param->GetParam();

	# Pull script name
	$sname = $cgi->url(-full=>1);
	$sparam = $cgi->url(-path_info=>1);


	# Virtual Directory support
	# Escape
	$sname = quotemeta($sname);

	# Needed addition
	$sparam = ($sparam =~ /\/$/) ? $sparam : "$sparam/";

	# Truncate
	$sparam =~ s/^$sname\///;


	# Retrieve parameters
	($sparam{'CLASS'},
	 $sparam{'IDENT'}) = split(/\//, $cgi->unescape($sparam));

	# Handling
	$sparam{'IDENT'} = undef if (length($sparam{'IDENT'}) < 2);
	

 	# HTML support
	# Document header
	print $cgi->header();
	print $database->DocumentGetHeader(), "\n";

	
	# Display gummy
	GummyDisplay($database, $cgi, $param, \%sparam);

	# Document footer
	print $database->DocumentGetFooter(), "\n";


#################################################################################
# Sub-Routines
#################################################################################

#####################
# Gummy Display
#
# Very simple sub-routine that will simply allow the user to look through the 
# list of gummies to search for.

sub GummyDisplay
{
	#####################
	# Data members
	my $database = shift;					# Database handle
	my $cgi      = shift;					# CGI handle
	my $param    = shift;					# Parameter handle
	my $sparam   = shift;					# Virtual directory parameters

	my $res;						# Results			
	my $tmpl;						# Template handle
	my $statement;						# Database statement

	my $class;						# Gummy class
	my $count;						# Counter
	my $ident;						# Gummy grouping 
	my $oident;						# Old gummy grouping
	my $name;						# Name of script
	my $title;						# Display title

	my $realm    = 'system';				# Realm search
	my $exclude  = 'default';				# Exclusion for class
	my $url      = $cgi->url(-absolute=>1);			# Self-referencing link

	my $list;						# Searching
	my $gummy;						# List of gummies
	my $row;						# Gummy rows
	my $template;						# Templates
	my $warning;						# Warning about injection
	
	my %gummy;						# Configuration hash


	#####################
	# Program area

	# Link with has
	$database->GetHashGummy(\%gummy);

	# Create instance
	$tmpl = new Ethereal::Template(\%gummy);


	# Widget generation
	# Pull list of gummies
	$database->Pull(\$statement, "SELECT GummyClass, GummyIdent
		FROM Gummy
		WHERE GummyClass <> ?
		GROUP BY GummyIdent, GummyClass
		ORDER BY GummyClass, GummyIdent", $exclude); 

	# Initialize
	$list = '';

	# Populate
	# Loop and extract
	while (($class, $ident) = $statement->fetchrow())
	{
		# Properly close list
		if ((defined($oident))
		 && (!defined($ident)))
	 	{
			# Close the entry
			$list .= $tmpl->Pass('TagListOff'); 

		 	# Past history for comparison
			$oident = $ident;

			# Skip the rest
			next;
		}

		# Primary entries
		if ((!defined($oident))
		 && (defined($ident)))
		{
			# Primary entries
			$list .= $tmpl->Pass('TagListPri',
				MCLASS => ucfirst($class),
				MLINK  => $url . '/' . $cgi->escape($class)
			 );	
			
			# Properly open list
			$list .= $tmpl->Pass('TagListOn');

			# Secondary entries
			$list .= $tmpl->Pass('TagListSec',
				MIDENT => ucfirst($ident),
				MCLASS => ucfirst($class),
				MLINK  => $url . '/' . $cgi->escape($class) . '/' . $cgi->escape($ident)
			 );

		 	# Past history for comparison
			$oident = $ident;
			
			# Skip the rest
			next;
		}

		# Depth
		# Go down a level
		if (defined($ident))
		{
			# Secondary entries
			$list .= $tmpl->Pass('TagListSec',
				MIDENT => ucfirst($ident),
				MCLASS => ucfirst($class),
				MLINK  => $url . '/' . $cgi->escape($class) . '/' . $cgi->escape($ident)
			 );	
		}

		# Surface level
		else
		{
			# Primary entries
			$list .= $tmpl->Pass('TagListPri',
				MCLASS => ucfirst($class),
				MLINK  => $url . '/' . $cgi->escape($class)
			 );
		}

		# Past history for comparison
		$oident = $ident;
	}

	# Finish
	$statement->finish();


	# Forced defaults
	$sparam->{'CLASS'} = 'General' unless (defined($sparam->{'CLASS'}));


	# Query management
	# Prepare and execute
	if (defined($sparam->{'IDENT'}))
	{
		# Group specific
		$database->Pull(\$statement, "SELECT 
			 GummyName  AS \"GummyName\",
			 GummyPath  AS \"GummyPath\",
			 GummyIdent AS \"GummyIdent\",
			 GummyMacro AS \"GummyMacro\"
			FROM  Gummy
			WHERE LOWER(GummyClass)=?
			  AND LOWER(RealmName)=?
			  AND LOWER(GummyIdent)=?
			ORDER BY GummyIdent, GummyName",

		 lc($sparam->{'CLASS'}),
		 lc($realm),
		 lc($sparam->{'IDENT'})
		);
	}

	else
	{
		# Non-grouped
		$database->Pull(\$statement, "SELECT 
			 GummyName  AS \"GummyName\",
			 GummyPath  AS \"GummyPath\",
			 GummyIdent AS \"GummyIdent\",
			 GummyMacro AS \"GummyMacro\"
			FROM  Gummy
			WHERE LOWER(GummyClass)=?
			  AND LOWER(RealmName)=?
			  AND GummyIdent IS NULL
			ORDER BY GummyIdent, GummyName",

		 lc($sparam->{'CLASS'}),
		 lc($realm)
		);
	}


	# Title
	# Determine String
	$title = (defined($sparam->{'IDENT'})) 
	  ? ucfirst($sparam->{'CLASS'}) . ' / ' . ucfirst($sparam->{'IDENT'})
	  : ucfirst($sparam->{'CLASS'});


	# Initialize counter
	$count = 0;

	# Initialize template
	$gummy = '';
	$row   = '';
	

	# Cycle through gummies
	while ($res = $statement->fetchrow_hashref())
	{
		# Increment counter
		$count++;

		# Padding
		$ident = (defined($res->{'GummyIdent'})) ? lc($res->{'GummyIdent'}) : $gummy{'TxtRoot'};

		
		# Entry is outside of bounds
		if ($count > $gummy{'SetDisplay'})
		{
			# Append new row
			$gummy .= $tmpl->Pass('TmplRow', MROWS=>$row);

			# Reset row
			$row = '';

			# Reset counter
			$count = 1;
		}

		# Determine name
		$name = (defined($res->{'GummyMacro'})) 
		  ? '::' . uc($res->{'GummyMacro'}) . '::'
		  : ucfirst($res->{'GummyName'});

		# Append additional columns
		$row .= $tmpl->Pass('TmplColFilled',
			MPATH => $res->{'GummyPath'},
			MNAME => $name
		 );
	}

	# Add in spacers
	for ($count; $count < $gummy{'SetDisplay'}; $count++)
	{
		# Fill in with blanks
		$row .= $gummy{'TmplColBlank'};
	}

	# Put in last 
	$gummy .= $tmpl->Pass('TmplRow', MROWS=>$row);

	# Warning
	$warning = ($sparam->{'CLASS'} =~ /inject/i) ? $gummy{'TmplWarning'} : '';

	# Display template
	$tmpl->Show('TmplPage',
		MTITLE   => $title,
		MWARNING => $warning,
		LSTCLASS => $list,
		LSTGUMMY => $gummy
	 );
}
