package WWW::Vimeo::Download;
use Moose;
use XML::XPath;
use LWP::UserAgent;
use HTTP::Request;
use Perl6::Form;
use utf8;

our $VERSION = '0.03';
my $VER = $VERSION;

has video_id => (
    is      => 'rw',
    isa     => 'Str',
    default => '',
);

has download_url => (
    is  => 'rw',
    isa => 'Str',
);

has [
    qw/caption width height duration thumbnail totalComments totalLikes totalPlays url_clean url uploader_url uploader_portrait uploader_display_name nodeId isHD privacy isPrivate isPassword isNobody embed_code filename nfo filename_nfo/
  ] => (
    is  => 'rw',
    isa => 'Any',
  );

has browser => (
    is      => 'ro',
    isa     => 'LWP::UserAgent',
    default => sub {
        my $ua = LWP::UserAgent->new();
        $ua->agent('Windows IE 6');
        return $ua;
    },
);

has res => (    #browser response
    is  => 'rw',
    isa => 'Any',
);

has xml => (
    is  => 'rw',
    isa => 'Any',
);

has target_dir => (
    is      => 'rw',
    isa     => 'Str',
    default => './',
);

sub load_video {
    my ( $self, $video_id_or_url ) = @_;
    if ( defined $video_id_or_url ) {
        if ( $video_id_or_url =~ m{http://www\.vimeo\.com/([^/]+)}i ) {
            $self->video_id($1);
        }
        elsif ( $video_id_or_url =~
            m{http://vimeo.com/groups/([^/]+)/videos/([^/]+)}i )
        {
            $self->video_id($2);
        }
        else {
            $self->video_id($video_id_or_url);
        }
        $self->set_download_url();
    }
    else {
        warn "Example usage: \$self->load_video( 'VIMEO_VIDEO_ID' ) "
          and return 0;
    }
}

sub download {
    my ( $self, $args ) = @_;
    warn
"Please set a video url first. ex: \$vimeo->load_video( 'http://www.vimeo.com/27855315' ) "
      and return
      if !$self->download_url;
    $self->res( $self->browser->get( $self->download_url ) );
    if ( defined $self->res and $self->res->is_success ) {
        if ( !exists $args->{filename} ) {
            $self->prepare_nfo;
            $self->save_nfo;
            $self->save_video( $self->res->content );
        }
        else {
            $self->save_video( $self->res->content, $args );
        }
    }
}

sub save_video {
    my ( $self, $video_data, $args ) = @_;
    my $filename;
    if ( !exists $args->{filename} ) {
        $filename =
          $self->filename( $self->target_dir . '/' . $self->filename . '.mp4' );
    }
    else {
        $filename =
          $self->filename( $self->target_dir . '/' . $args->{filename} );
    }
    open FH, ">$filename";
    print FH $video_data;
    close FH;
}

sub save_nfo {
    my ($self) = @_;
    $self->filename_nfo( $self->target_dir . '/' . $self->filename . '.nfo' );
    my $filename = $self->filename_nfo;
    open FH, ">$filename";
    print FH $self->nfo;
    close FH;
}

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

    my $info = form
"===============================================================================",
"--[ WWW::Vimeo::Download ]-----------------------------------------------------",
"                                                                               ",
"  {||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||} ",
      "[" . $self->caption . "]",
"                                                                               ",
"  .............Title: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} ",
      $self->caption,
"  .........Video Url: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} ",
      $self->url,
"  ............Author: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} ",
      $self->uploader_display_name,
"  ........Author Url: {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<} ",
      $self->uploader_url,
"                                                                               ",
"                                [ REVIEW ]                                     ",
"                                                                               ",
"  {[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} ",
      $self->thumbnail,
"                                                                               ",
"---------------------------------------------------[ version $VER by HERNAN ]--",
"==============================================================================="
      ,;
    $self->nfo($info);
}

sub title_to_filename {
    my ( $self, $title ) = @_;
    $title =~ s/\W/-/ig;
    $title =~ s/--{1,}/-/ig;
    $title =~ s/^-|-$//ig;
    $title =~
tr/àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ/aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY/;
    return $title;
}

sub set_filename {
    my ($self) = @_;
    $self->filename( $self->title_to_filename( $self->caption ) );
}

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

    #sets the download_url for specified video
    warn "getting download_url for video id: "
      . "http://www.vimeo.com/moogaloop/load/clip:"
      . $self->video_id;
    $self->res(
        $self->browser->get(
            "http://www.vimeo.com/moogaloop/load/clip:" . $self->video_id
        )
    );
    if ( $self->res->is_success ) {
        $self->xml( XML::XPath->new( xml => $self->res->content ) );

        $self->caption( $self->xml->findvalue('/xml/video/caption') )
          and $self->set_filename;
        $self->width( $self->xml->findvalue('/xml/video/width') );
        $self->height( $self->xml->findvalue('/xml/video/height') );
        $self->duration( $self->xml->findvalue('/xml/video/duration') );
        $self->thumbnail( $self->xml->findvalue('/xml/video/thumbnail') );
        $self->totalComments(
            $self->xml->findvalue('/xml/video/totalComments') );
        $self->totalLikes( $self->xml->findvalue('/xml/video/totalLikes') );
        $self->totalPlays( $self->xml->findvalue('/xml/video/totalPlays') );
        $self->url_clean( $self->xml->findvalue('/xml/video/url_clean') );
        $self->url( $self->xml->findvalue('/xml/video/url') );
        $self->uploader_url( $self->xml->findvalue('/xml/video/uploader_url') );
        $self->uploader_portrait(
            $self->xml->findvalue('/xml/video/uploader_portrait') );
        $self->uploader_display_name(
            $self->xml->findvalue('/xml/video/uploader_display_name') );
        $self->nodeId( $self->xml->findvalue('/xml/video/nodeId') );
        $self->isHD( $self->xml->findvalue('/xml/video/isHD') );
        $self->privacy( $self->xml->findvalue('/xml/video/privacy') );
        $self->isPrivate( $self->xml->findvalue('/xml/video/isPrivate') );
        $self->isPassword( $self->xml->findvalue('/xml/video/isPassword') );
        $self->isNobody( $self->xml->findvalue('/xml/video/isNobody') );
        $self->embed_code( $self->xml->findvalue('/xml/video/embed_code') );

        my $request_signature = $self->xml->findvalue('/xml/request_signature');
        my $request_signature_expires =
          $self->xml->findvalue('/xml/request_signature_expires');
        my $caption = $self->xml->findvalue('/xml/video/caption');
        my $is_hd   = $self->xml->findvalue('/xml/video/isHD');
        my $quality = 'sd';
        $quality = 'hd' if ( $is_hd eq '1' );
        my $download_url_with_req_id =
            "http://www.vimeo.com/moogaloop/play/clip:"
          . $self->video_id . "/"
          . $request_signature . "/"
          . $request_signature_expires . "/?q="
          . $quality;

        $self->res(
            $self->browser->request(
                HTTP::Request->new( HEAD => $download_url_with_req_id )
            )
        );
        my $video_download_url = $self->res->request->uri;
        if ( defined $video_download_url ) {
            $self->download_url( $video_download_url->as_string );
        }
        $self->xml(undef);
    }
    else {
        warn "Could not get success response for req. error: "
          . $self->res->status_line;
    }

}

=head1 NAME

    WWW::Vimeo::Download - interface to download vimeo videos

=head1 SYNOPSIS

    use WWW::Vimeo::Download;
    my $vimeo = WWW::Vimeo::Download->new();
    $vimeo->load_video( 'XYZ__ID_VIDEO' );        #REQ videoid or video url
    $vimeo->target_dir( '/home/catalyst/tmp/' );  #OPTIONAL target dir
    $vimeo->download();                           #start download
    $vimeo->download( { filename =>'file.mp4'} ); #start download custom filename
    print $vimeo->download_url;                   #print the url for download

=head1 DESCRIPTION


=head1 AUTHOR

    Hernan Lopes
    CPAN ID: HERNAN
    hernanlopes < @t > gmail
    https://github.com/hernan604

=head1 COPYRIGHT

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

    The full text of the license can be found in the
    LICENSE file included with this module.


=head1 SEE ALSO

perl(1).

=cut

1;

