package Yaala::Report;

use strict;
use warnings;

use Exporter;
use Yaala::Html qw#head foot escape navbar get_filename get_title#;
use Yaala::Data::Core qw#receive get_values#;
use Yaala::Data::Setup qw#$SELECTS#;
use Yaala::Data::Convert qw#convert#;
use Yaala::Config qw#get_config#;
use Yaala::Report::Core qw#$OUTPUTDIR#;
use Yaala::Report::GDGraph qw#generate_graph $GRAPH_WIDTH $GRAPH_HEIGHT#;

@Yaala::Report::EXPORT_OK = qw#generate#;
@Yaala::Report::ISA = ('Exporter');

my $VERSION = '$Id: Combined.pm,v 1.10 2003/12/07 14:53:30 octo Exp $';
print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);

for (@$SELECTS)
{
	my $sel = $_;
	while (scalar (@{$sel->[1]}) > 3)
	{
		my $ignore = pop (@{$sel->[1]});
		print STDERR $/, __FILE__, ": With the combined output only ",
			"three fields are supported. ",
			"Field ``$ignore'' will be ignored.";
	}
}

return (1);

sub generate
{
	for (@$SELECTS)
	{
		my $sel = $_;
		if (scalar (@{$sel->[1]}) == 1)
		{
			generate_1D_page ($sel);
		}
		elsif (scalar (@{$sel->[1]}) == 2)
		{
			generate_2D_page ($sel);
		}
		elsif (scalar (@{$sel->[1]}) == 3)
		{
			generate_3D_page ($sel);
		}
		else
		{
			die;
		}
	}

	generate_index_page ();

	return (1);
}

sub generate_1D_page
{
	my $sel = shift;
	my ($key) = @{$sel->[1]};

	my $filename = get_filename ($sel);
	my $title = get_title ($sel);

	open (FH, '> ' . $OUTPUTDIR . $filename) or die ('open: ' . $!);
	
	print FH head ($title, $title);
	print FH navbar ($sel);

	print FH generate_1D_table ($sel, $key);
	
	print FH foot ();
	close (FH);
}

sub generate_2D_page
{
	my $sel = shift;
	my ($key1, $key2) = @{$sel->[1]};

	my $filename = get_filename ($sel);
	my $title = get_title ($sel);

	open (FH, '> ' . $OUTPUTDIR . $filename) or die ('open: ' . $!);
	
	print FH head ($title, $title);
	print FH navbar ($sel);

	print FH generate_2D_table ($sel, $key1, $key2);
	
	print FH foot ();
	close (FH);
}

sub generate_3D_page
{
	my $sel = shift;
	my ($key1, $key2, $key3) = @{$sel->[1]};

	my $filename = get_filename ($sel);
	my $title = get_title ($sel);

	open (FH, '> ' . $OUTPUTDIR . $filename) or die ('open: ' . $!);
	
	print FH head ($title, $title);
	print FH navbar ($sel);

	print FH generate_1D_table ($sel, $key3, 1);
	
	my @vals3 = get_values ($sel, $key3);
	
	for (sort (@vals3))
	{
		my $val3 = $_;
		print FH generate_2D_table ($sel, $key1, $key2, $key3, $val3);
	}
	
	print FH foot ();
	close (FH);
}

sub generate_index_page
{
	open (FH, '> ' . $OUTPUTDIR . 'index.html') or die ('open: ' . $!);

	print FH head ("yaala $::VERSION", "yaala $::VERSION - Index");
	print FH navbar ();

	if (scalar (keys (%$::EXTRA)))
	{
		print FH "\n<hr>\n<table>\n";
		for (keys (%$::EXTRA))
		{
			my $key = $_;
			my $val = $::EXTRA->{$key};

			print FH qq#  <tr>\n    <th class="top">$key</th>\n    <td>$val</td>\n  </tr>\n#;
		}
		print FH "</table>\n";
	}
	else
	{
		print FH "\n<!-- no \%::EXTRA -->\n";
	}
	
	print FH foot ();
	close (FH);
}

sub generate_1D_table
{
	my $sel = shift;
	my $key = shift;
	
	my $do_links = 0;
	if (@_) { $do_links = shift; }

	my @aggs = @{$sel->[0]};

	my @vals = get_values ($sel, $key);
	@vals = sort (@vals);
	
	my %grand_total = ();
	for (@aggs)
	{
		$grand_total{$_} = receive ($sel, $_, {});
	}
	
	my $text = "\n<hr>\n";

	my $graph_file = generate_graph ($sel, $key);
	if ($graph_file)
	{
		$text .= qq#<p><img src="$graph_file" width="$GRAPH_WIDTH" height="$GRAPH_HEIGHT" alt="[graph]" /></p>\n#;
	}
	
	$text .= "<table>\n  <tr>\n"
	.	'    <th colspan="' . (1 + (2 * scalar (@aggs))) . '">'
	.	ucfirst ($key) . "</th>\n  </tr>\n";

	if (scalar (@aggs) > 1)
	{
		$text .= qq#  <tr>\n    <th class="subhdr">Aggregation</th>\n#;
		$text .= qq#    <th colspan="2" class="subhdr"># . ucfirst ($_) . "</th>\n" for (@aggs);
		$text .= "  </tr>\n";
	}

	for (@vals)
	{
		my $val = $_;
		
		$text .= qq#  <tr>\n    <th class="subhdr">#;
		if ($do_links)
		{
			my $tmpval = $val;
			$tmpval =~ s/\W//g;
			$text .= qq(<a href="#$tmpval">);
		}
		$text .= $val;
		if ($do_links)
		{
			$text .= '</a>';
		}
		$text .= "</th>\n";
		
		for (@aggs)
		{
			my $agg = $_;
			my $sum = receive ($sel, $agg, {$key => $val});
			my $print_sum = convert ($agg, $sum);
		
			$text .= qq#</th>\n    <td>$print_sum</td>\n#
			.	"    <td>" . sprintf ("%.1f%%", 100 * $sum / $grand_total{$agg}) . "</td>\n";
		}
	}

	$text .= qq#  <tr>\n    <th class="subhdr">Total</td>\n#;
	for (@aggs)
	{
		my $agg = $_;
		my $print_sum = convert ($agg, $grand_total{$agg});
		
		$text .= qq#    <td class="total">$print_sum</td>\n#
		.	qq#    <td class="total">100.0%</td>\n#
	}
	$text .= qq#</tr>\n</table>\n#;
	
	return ($text);
}

sub generate_2D_table
{
	my $sel = shift;
	my $key1 = shift;
	my $key2 = shift;
	
	my $text;
	
	my $key3 = '';
	my $val3 = '';
	if (scalar (@_) >= 2)
	{
		$key3 = shift;
		$val3 = shift;
	}

	my @aggs = @{$sel->[0]};
	my $num_aggs = scalar (@aggs);
	
	my @vals1 = get_values ($sel, $key1);
	my @vals2 = get_values ($sel, $key2);

	@vals1 = sort (@vals1);
	@vals2 = sort (@vals2);
	
	my %grand_total = ();
	for (@aggs)
	{
		my $query = {};
		if ($key3 and $val3)
		{
			$query->{$key3} = $val3;
		}
		$grand_total{$_} = receive ($sel, $_, $query);
	}

	my $target = '';
	if ($val3)
	{
		my $tmpval = $val3;
		$tmpval =~ s/\W//g;
		$text = qq#\n<hr id="$tmpval" />\n#;
	}
	else
	{
		$text = qq#\n<hr />\n#;
	}
	
	my $graph_file = generate_graph ($sel, $key1, $key3, $val3);
	if ($graph_file)
	{
		$text .= qq#<p><img src="$graph_file" width="$GRAPH_WIDTH" height="$GRAPH_HEIGHT" alt="[graph]" />\n#;

		$graph_file = generate_graph ($sel, $key2, $key3, $val3);
		$text .= qq#  <img src="$graph_file" width="$GRAPH_WIDTH" height="$GRAPH_HEIGHT" alt="[graph]" /></p>\n#;
	}
	
	$text .= qq#<table>\n#;
	
	if ($key3 and $val3)
	{
		$text .= "  <caption>$val3</caption>\n";
	}

	my $agg_column_width = '';
	if ($num_aggs > 1)
	{
		$agg_column_width = qq# colspan="$num_aggs"#;
	}
	
	# first line
	$text .= qq#  <tr>\n    <td colspan="2" rowspan="# . ($num_aggs > 1 ? '3' : '2')
	. qq#" class="blank"><img src="logo.png" /></td>\n#
	. '    <th colspan="' . ($num_aggs * scalar (@vals2)) . qq#"># . ucfirst ($key2) . "</th>\n"
	. qq#    <th rowspan="2"$agg_column_width>Total</th>\n#
	. qq#    <th rowspan="2"$agg_column_width>Percent</th>\n#
	. "  </tr>\n";
	
	# second line
	$text .= "  <tr>\n";
	for (@vals2)
	{
		$text .= qq#    <th class="subhdr"$agg_column_width>$_</th>\n#;
	}
	$text .= qq#  </tr>\n#;

	# third line (if appropriate only)
	if ($num_aggs > 1)
	{
		$text .= "  <tr>\n";
		
		my $tmp = join ('', map { qq#    <th class="subhdr">$_</th>\n# } (@aggs));
		$text .= $tmp x (2 + scalar (@vals2));
		
		$text .= "  </tr>\n";
	}
	$text .= qq#  <tr>\n    <th rowspan="# . scalar (@vals1)
	. qq#"># . ucfirst ($key1) . "</th>\n";
	
	my $this_is_the_first_line = 1;
	for (@vals1)
	{
		my $val1 = $_;

		$text .= "  <tr>\n" unless ($this_is_the_first_line);
		$this_is_the_first_line = 0;

		$text .= qq#    <th class="subhdr">$val1</th>\n#;
			
		for (@vals2)
		{
			my $val2 = $_;

			my $query = { $key1 => $val1, $key2 => $val2 };
			if ($key3 and $val3)
			{
				$query->{$key3} = $val3;
			}
				
			for (@aggs)
			{
				my $agg = $_;
			
				my $this_val = receive ($sel, $agg, $query);
				my $print_val = convert ($agg, $this_val);
	
				$text .= '    <td>' . ($print_val ? $print_val : '&nbsp;') . "</td>\n";
			}
		}

		my $query = { $key1 => $val1 };
		if ($key3 and $val3)
		{
			$query->{$key3} = $val3;
		}

		my $tmp = '';
		for (@aggs)
		{
			my $this_val = receive ($sel, $_, $query);
			my $print_val = convert ($_, $this_val);

			$text .= '    <td class="total">' . ($print_val ? $print_val : '&nbsp;') . "</td>\n";
			$tmp .= '    <td class="total">'
			.	($this_val ? sprintf ("%.1f%%", 100 * $this_val / $grand_total{$_}) : '&nbsp;')
			.	"</td>\n";
		}
		$text .= $tmp . "  </tr>\n";
	}
	# TODO 2003-05-10 13:00
	$text .= qq#  <tr>\n    <th colspan="2">Total</th>\n#;
	my @percentages = ();
	for (@vals2)
	{
		my $val2 = $_;

		my $query = { $key2 => $val2 };
		if ($key3 and $val3)
		{
			$query->{$key3} = $val3;
		}

		for (@aggs)
		{
			my $agg = $_;

			my $this_val = receive ($sel, $agg, $query);
			my $print_val = convert ($agg, $this_val);

			$text .= '    <td class="total">' . ($print_val ? $print_val : '&nbsp;') . "</td>\n";

			my $pc = ($this_val ? sprintf ("%.1f%%", 100 * $this_val / $grand_total{$agg}) : '&nbsp;');
			push (@percentages, $pc);
		}
	}

	for (@aggs)
	{
		my $agg = $_;
		
		my $print_val = convert ($agg, $grand_total{$agg});
		$text .= '    <td class="total">' . ($print_val ? $print_val : '&nbsp;') . "</td>\n";
	}
	
	$text .= qq#    <td class="blank"$agg_column_width>&nbsp;</td>\n#
	.	qq#  </tr>\n#
	.	qq#  <tr>\n#
	.	qq#    <th colspan="2">Percent</th>\n#;
	$text .= qq#    <td class="total">$_</td>\n# for (@percentages);
	$text .= qq#    <td class="blank" colspan="# . (2 * $num_aggs) . qq#">&nbsp;</td>\n#
	.	qq#  </tr>\n#
	.	qq#</table>\n#;
	
	return ($text);
}
