
# SUMMARY NOTES
# -------------
# => calls exit() if data is to wide/tall
# => default histogram height is max data
# => default histogram width is data count
# => histogram built by "rastering" over x, y coordinates
# => vertical scaling done with map() in separate, final step

use strict;

sub histogram() {

	# $HISTOGRAM_CHAR parameter validation
	exit unless not defined($HISTOGRAM_CHAR) or 
	            $HISTOGRAM_CHAR =~ /^[[:print:]]$/; 
	
	my @data = @_;
	# data validation
	map {exit unless $_ =~ /^\d+$/ } @data ; 

	my $sample_size = @data;
	my $max_element = (sort @data)[ $sample_size - 1 ];

	# $HISTOGRAM_HEIGHT and $HISTOGRAM_WIDTH validation
	if (defined $HISTOGRAM_HEIGHT and 
		not ($HISTOGRAM_HEIGHT >= $max_element)) {exit;};
	if (defined $HISTOGRAM_WIDTH and 
		not ($HISTOGRAM_WIDTH   >= $sample_size)) {exit;};
	
	# parameter default values
	$HISTOGRAM_CHAR = "*" unless defined($HISTOGRAM_CHAR);
	$HISTOGRAM_HEIGHT = $max_element unless defined($HISTOGRAM_HEIGHT);
	$HISTOGRAM_WIDTH = $sample_size unless defined($HISTOGRAM_WIDTH);

	# Scaling multipliers
	my $w_multiplier = int( $HISTOGRAM_WIDTH  / $sample_size );
	my $h_multiplier = int( $HISTOGRAM_HEIGHT / $max_element );
	
	# Creation of the rows and scaling them horizontally
	my @rows;
	for (my $i = 1; $i <= $max_element ; $i++) {

		for (my $j = 0; $j <= $sample_size - 1 ; $j++) {

			if ( $data[$j] >= $i ) {

				$rows[$i- 1] .= $HISTOGRAM_CHAR x $w_multiplier;
			} else {
				$rows[$i- 1] .= " " x $w_multiplier;
			}
		}
	}

	# adding "\n" after the final $HISTOGRAM_CHAR 
	map $_ =~ s/ *$/\n/, @rows;

	# scaling vertically
	my @final_rows;
	map { push @final_rows, $_ x $h_multiplier } @rows;
	
	return reverse(@final_rows);
}

1;

