package HTML::AutoConvert;

use warnings;
use strict;

=head1 NAME

HTML::AutoConvert - Best-effort HTML conversion of arbitrary files to HTML.

=head1 VERSION

Version 0.01

=cut

our $VERSION = '0.01';

=head1 SYNOPSIS

    use HTML::AutoConvert;

    my $converter = HTML::AutoConvert->new();
    #or to turn on debugging
    my $converter = HTML::AutoConvert->new('debug'=>1);

    my $html = $converter->html_convert( $file );
    # OR 
    my( $html, @images ) = $converter->html_convert( $file );

    #turn on or off debugging later
    $converter->debug(1);

=head1 DESCRIPTION

Convert arbitrary file types to HTML.

#=head1 EXPORT
#
#doc on also using html_convert functional interface

=head1 FUNCTIONS

=head2 new

=cut

sub new {
  my $proto = shift;
  my $class = ref($proto) || $proto;

  my $opts = ref($_[0]) ? shift : { @_ };
  my $self = $opts; #{};
  bless ($self, $class);

  $self->find_handlers;

  $self;

}

=head2 html_convert FILENAME

Convert the given filename to HTML.

In a scalar context, simply returns the HTML output as a scalar.

    my $html = $converter->html_convert( $file );

In a list context, returns a list consisting of the HTML output as a scalar,
followed by references for each image extracted, if any.  Each image reference
is a list reference consisting of two elements: the first is the filename and
the second is the image itself.

    my( $html, @images ) = $converter->html_convert( $file );
    foreach my $image ( @images ) {
      my( $filename, $data ) = @$image;
      #...
    }

=cut

sub html_convert {
  my( $self, $file ) = ( shift, shift );
  my $opt = ref($_[0]) ? shift : { @_ };

  $self->{'file'} = $file;

  my @handlers = $self->handlers
    or die "no registered handlers for filetype ". $self->filetype( $file );

  my( $converted, $html, $errors ) = ( 0, '', '' );
  my @imgs = ();
  foreach my $handler ( @handlers ) {

    my $module = 'HTML::AutoConvert::'. $handler->{'module'};

    my $tmp_html = '';
    my @tmp_imgs = ();
    if ( $handler->{'returns_images'} && wantarray ) {
      ( $tmp_html, @tmp_imgs ) =
        eval { $module->html_convert( $self->{'file'} ) };
    } else {
      $tmp_html =
        eval { $module->html_convert( $self->{'file'} ) };
    }

    if ( $@ ) {
       my $tmp_err = "conversion with $module failed: $@\n";
       warn $tmp_err if $self->{'debug'};
       $errors .= $tmp_err;
       next;
    }

    $converted = 1;
    $html = $tmp_html;
    @imgs = @tmp_imgs;
    last;
  }

  die "couldn't convert $file:\n$errors" unless $converted;

  if ( wantarray ) {
    ( $html, @imgs );
  } else {
    $html;
  }

}

=head2 debug

Get or set the debugging level

=cut

sub debug {
  my $self = shift;
  $self->{'debug'} = shift if @_;
  $self->{'debug'};
}

=head1 INTERNAL FUNCTIONS

=head2 find_handlers

Search for installed HTML::AutoConvert::* plugins.

=cut

sub find_handlers {
  my $self = shift;

  my %types;
  foreach my $INC ( @INC ) {
    warn "globbing $INC/HTML/AutoConvert/*.pm\n" if $self->{'debug'};
    foreach my $file ( glob("$INC/HTML/AutoConvert/*.pm") ) {
      warn "attempting to load handler info from $file\n" if $self->{'debug'};
      $file =~ /\/(\w+)\.pm$/ or do {
        warn "unrecognized file in $INC/HTML/AutoConvert/: $file\n";
        next;
      };
      my $mod = $1;
      my $info = eval "use HTML::AutoConvert::$mod; ".
                      "\\%HTML::AutoConvert::$mod\::info;";
      if ( $@ ) {
        die "error using HTML::AutoConvert::$mod (skipping): $@\n" if $@;
        next;
      }
      unless ( keys %$info ) {
        warn "no %info hash in HTML::AutoConvert::$mod, skipping\n" if $self->{'debug'};
        next;
      }
      warn "got handler info from HTML::AutoConvert::$mod: $info\n" if $self->{'debug'};
      if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
        warn "skipping disabled handler HTML::AutoConvert::$mod" if $self->{'debug'};
        next;
      }

      my $types = $info->{'types'};
      $types = [ $types ] unless ref($types);

      foreach my $type ( @$types ) {
        $types{lc($type)}->{$mod} = { 'module' => $mod, %$info };
      }

    }
  }

  $self->{'handlers'} = \%types;

}

=head2 handlers

Return the available handlers for the current file.

=cut

sub handlers {
  my( $self ) = @_;

  my $types = $self->{'handlers'};

  my $type = $self->filetype;

  sort { $a->{'weight'} <=> $b->{'weight'} }
       values %{ $types->{lc($type)} };
}

=head2


=head2 filetype

Determine the type of the current file.

=cut

#just use the file extension...  could also use File::MMagic or something
sub filetype {
  my $self = shift;

  my $file = $self->{'file'};
  $file =~ /\.(\w{3,4})$/ or die "can't parse $file for extension";
  lc($1);
}

=head1 AUTHOR

Ivan Kohler, C<< <ivan-html-autoconvert at 420.am> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-html-autoconvert at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HTML-AutoConvert>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc HTML::AutoConvert

You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=HTML-AutoConvert>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/HTML-AutoConvert>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/HTML-AutoConvert>

=item * Search CPAN

L<http://search.cpan.org/dist/HTML-AutoConvert>

=back


=head1 ACKNOWLEDGEMENTS



=head1 COPYRIGHT & LICENSE

Copyright 2008 Freeside Internet Services, Inc.
All rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1; # End of HTML::AutoConvert

