The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package Excel::Template::Element::Cell::AutoSize;
$VERSION = '0.04';
use strict;

BEGIN {
    use Excel::Template::Element::Cell;
    use Font::TTFMetrics;
    use vars qw(@ISA);

    @ISA = qw(Excel::Template::Element::Cell);

    Excel::Template::Factory::register(name => 'CELLAUTOSIZE', class => 'Excel::Template::Element::Cell::AutoSize', isa => 'CELL');
}

sub render
{
    my $self = shift;
    my ($context) = @_;

	my $font_path = $ENV{'FONT_PATH'} || die "Environment variable FONT_PATH not set\n";
	my $font_name = lc($context->active_format->{'_font'});
	$font_name .= 'bd' if $context->active_format->{'_bold'} == 700;
	my $font_size = $context->active_format->{'_size'};

	my $font_found = 0;
	foreach my $path (split(':', $font_path)){
		$font_found = 1 if -e "$path/$font_name.ttf";
		$font_path = $path if $font_found;
		last if $font_found;
	}
		
	my $font = Font::TTFMetrics->new("$font_path/$font_name.ttf") || die "Font $font_name not found\n";

	my $dpi          = 96;
	my $units_per_em = $font->get_units_per_em();
	my $text = $self->get_text($context) || ' ';
	my $font_width   = $font->string_width($text);

    	#The following expression is from the TTFMetrics docs.
	my $pixel_width  = $font_width *$font_size *$dpi /(72 *$units_per_em);

    	#The following expression is from the Spreadsheet::WriteExcel internals.
	my $cell_width   = (($pixel_width -5) /7) + 1; # For cell widths > 1

	#Set larger column width if $cell_text_length is greater than current max for column
	my $max_width_key = '_COL_WIDTH_' . $context->get($self, 'COL');
	#Initialize current max column width if this is our first access of this column
	$context->active_worksheet->{$max_width_key} = $context->active_worksheet->{$max_width_key} || 0;
	
	#print $font_name . "," . $context->active_format->{'_bold'} . "\n";
	if ($cell_width > $context->active_worksheet->{$max_width_key}){
		$context->active_worksheet->{$max_width_key} = $cell_width;
		$context->active_worksheet->set_column($context->get($self, 'COL'), $context->get($self, 'COL'), $cell_width);
   	}
	$context->active_worksheet->write(
        (map { $context->get($self, $_) } qw(ROW COL)),
        $self->get_text($context),
        $context->active_format,
    );

    return 1;
}

1;
__END__

=head1 NAME

Excel::Template::Element::Cell::AutoSize

=head1 PURPOSE

To provide a cell that is correctly sized for inserted text

=head1 NODE NAME

CELLAUTOSIZE

=head1 INHERITANCE

Excel::Template::Element::Cell

=head1 CHILDREN

Excel::Template::Element::Formula

=head1 EFFECTS

This will consume one column on the current row. 

=head1 DEPENDENCIES

Font::TTFMetrics

=head1 USAGE

  <cellautosize text="Some Text Here"/>
  <cellautosize>Some other text here</cellautosize>

  <cellautosize text="$Param2"/>
  <cellautosize>Some <var name="Param"> text here</cellautosize>

In the above example, four cells are written out. The first two have text hard-
coded. The second two have variables. The third and fourth items have another
thing that should be noted. If you have text where you want a variable in the
middle, you have to use the latter form. Variables within parameters are the
entire parameter's value.

Please see Spreadsheet::WriteExcel for what constitutes a legal formula.

=head1 AUTHOR

Tim Howell (tim@fefcful.org)
Based on Excel::Template::Element::Cell by Rob Kinyon

=head1 SEE ALSO

CELL, ROW, VAR, FORMULA

=cut