package GCPlugins::GCfilms::GCImdb;

###################################################
#
#  Copyright 2005-2014 Christian Jodar
#
#  This file is part of GCstar.
#
#  GCstar is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  GCstar is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with GCstar; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
###################################################

###################################################
#
#  Features:
#  + Multiple directors separated by comma
#  + Multiple countries separated by comma
#  + Correct URL in case of redirection
#  + Fetches Original Title
#

use strict;

use GCPlugins::GCfilms::GCfilmsCommon;

{
    package GCPlugins::GCfilms::GCPluginImdb;

    use base qw(GCPlugins::GCfilms::GCfilmsPluginsBase);

    sub start
    {
        my ($self, $tagname, $attr, $attrseq, $origtext) = @_;

        $self->{inside}->{$tagname}++;

        return if ($self->{parsingEnded});

        if ($self->{parsingList} && $self->{pass} eq 1)
        {
            if ($tagname eq "table" && $attr->{class} eq "findList")
            {
                $self->{parsingBegun} = 1;
            }
            elsif ($self->{parsingBegun} && $tagname eq "a")
            {
                my $url = $attr->{href};
                if (($url =~ /^\/title\/.*_tt_\d+$/) && (!$self->{alreadyListed}->{$url}))
                {
                    $self->{isMovie} = 1;
                    $self->{isInfo} = 1;
                    $self->{url} = $url;
                }
            }
        }
        else
        {
            if ($tagname eq "label")
            {
                $self->{insideSeasonsNumber} = 1 if $attr->{for} eq "browse-episodes-season";
            }
            elsif ($tagname eq "link")
            {
                if ($attr->{rel} eq "canonical")
                {
                    $self->{curInfo}->{webPage} = $attr->{href};
                }
            }
            elsif ($attr->{"data-testid"})
            {
                while (my ($key, $value) = each(%{$self->{patternsTestid}}))
                {
                    $self->{"inside$key"} = 0;
                    $self->{"inside$key"} = 1 if ($attr->{"data-testid"} =~ /$value/);
                }
                $self->{isSerie} ||= $self->{insideSerie};
            }
            elsif ($tagname eq "meta")
            {
                if ($attr->{itemprop} eq "contentRating")
                {
                     ($self->{curInfo}->{age} = $attr->{content}) =~ s/.*?([0-9]+)$/$1/;
                }
            }
            elsif ($tagname eq "time")
            {
                ($self->{curInfo}->{time} = $attr->{datetime}) =~ s/[A-Z]*([0-9]+)M/$1\ min/;
            }
            elsif ($tagname eq "span")
            {
                if ($attr->{itemprop} && $attr->{itemprop} eq "ratingValue")
                {
                    $self->{insideRating} = 1;
                }
                elsif ($attr->{class} && $attr->{class} =~ /see\-more/)
                {
                    $self->{insideStoryline} = 0;
                }
            }
            elsif ($tagname eq "img")
            {
                if ($self->{insidePrimaryImage})
                {
                    if ($attr->{src} !~ m/nopicture/ && $attr->{src} =~ /\/images\/M\//)
                    {
                        # trying to find a reasonable size
                        foreach my $size (('UX770', 'UY562', 'UX380'))
                        {
                            $attr->{src} =~ s/V1.*/V1_QL75_$size.jpg/ if $attr->{srcset} =~ /$size/;
                            last;
                        }
                        $self->{curInfo}->{image} = $attr->{src} if ! $self->{curInfo}->{image};
                        $self->{insidePrimaryImage} = 0;
                    }
                }
            }
            elsif ($tagname eq "a")
            {
                while (my ($key, $value) = each(%{$self->{patterns}}))
                {
                    $self->{"inside$key"} = 0;
                    $self->{"inside$key"} = 1 if ($attr->{href} =~ /$value/);
                }
                if ($attr->{href} =~ /ttep_ep(\d+)/)
                {
                    if ($self->{curInfo}->{episode} ne $1)
                    {
                        push @{$self->{curInfo}->{episodes}}, [$1, $attr->{title}];
                        $self->{curInfo}->{episode} = $1;
                        $self->{curInfo}->{synopsis} .= "S".$self->{curInfo}->{season}." E".$1." - ".$attr->{title}." - ".$self->{curInfo}->{airdate};
                    }
                }
                elsif ($attr->{href} =~ /tt_eps_sn_1/)
                {
                    # serie with a single season
                    $self->{insideSeasonsNumber} = 1;
                }
            }
            elsif ($tagname eq 'div' && $attr->{class} =~ /poster__poster/)
            {
                    $self->{insidePrimaryImage} = 1;
            }
            elsif ($tagname eq 'div' && $attr->{class} =~ /airdate/)
            {
                    $self->{insideAirDate} = 1;
            }
            elsif ($tagname eq 'div' && $attr->{class} =~ /item_description/)
            {
                    $self->{insideEpisodeDescription} = 1;
            }
            elsif ($tagname eq 'li' && $self->{insideTime})
            {
                $self->{insideTime} = 2;
            }
            elsif ($tagname eq 'h3' && $attr->{id} eq 'episode_top')
            {
                $self->{insideSeason} = 1;
            }
        }
    }

    sub end
    {
        my ($self, $tagname) = @_;

        $self->{inside}->{$tagname}--;
        if ($self->{parsingList} && $self->{pass} eq 1)
        {
            if ($tagname eq "table" && $self->{parsingBegun})
            {
                $self->{parsingEnded} = 1;
            }
        }
        else
        {
            if ($tagname eq "a")
            {
                while (my ($key, $value) = each(%{$self->{patterns}}))
                {
                    $self->{"inside$key"} = 0;
                }
                $self->{insideGenre} = 0;
                $self->{insideActor} = 0;
                $self->{insideRole} = 0;
            }
            elsif ($tagname eq "div")
            {
                $self->{insideStoryline} = 0;
            }
            elsif ($tagname eq "span")
            {
                $self->{insideRating} = 0;
            }
            elsif ($tagname eq "li" && $self->{insideTime} eq 2)
            {
                if ($self->{curInfo}->{time} =~ /(\d+)h\s*(\d+)m.*/)
                {
                    $self->{curInfo}->{time} = ($1*60) + $2;
                }
                elsif ($self->{curInfo}->{time} =~ /(\d+)m.*/)
                {
                    $self->{curInfo}->{time} = $1;
                }
                $self->{insideTime} = 0;
            }
            elsif ($tagname eq 'body' && $self->{pass} eq 2)
            {
                foreach (@{$self->{serieFields}})
                {
                    $self->{$_} = $self->{curInfo}->{$_};
                }
            }
        }
    }

    sub text
    {
        my ($self, $origtext) = @_;

        return if length($origtext) < 2 && $self->{insideTime} ne 2;

        return if ($self->{parsingEnded});

        $origtext =~ s/^\s+|\s+$//g;
        return if ($origtext eq '');

        if ($self->{parsingList} && $self->{pass} eq 1)
        {
            if ($self->{isMovie})
            {
                $self->{title} = $origtext;
                $self->{isMovie} = 0;
                $self->{isInfo} = 1;
                return;
            }
            if ($self->{isInfo})
            {
                if ($self->{pluginType} eq 'films' || $origtext =~ m/TV.*Series/)
                {
                    $self->{itemIdx}++;
                    $self->{itemsList}[$self->{itemIdx}]->{url} = $self->{url};
                    $self->{itemsList}[$self->{itemIdx}]->{nextUrl} = "http://www.imdb.com".$self->{url};

                    $self->{alreadyListed}->{$self->{url}} = 1;

                    $self->{itemsList}[$self->{itemIdx}]->{date} = $1 if $origtext =~ m|\(([0-9]*)(/I+)?\)|;
                    $origtext =~ s/\(\d+\)\s*//;
                    $self->{itemsList}[$self->{itemIdx}]->{title} = $self->{title}." ".$origtext;
                    $self->{itemsList}[$self->{itemIdx}]->{firstaired} = $self->{itemsList}[$self->{itemIdx}]->{date};
                }
                $self->{isInfo} = 0;
            }
        }
        else
        {
            if ($self->{insideOriginalTitle})
            {
                $origtext =~ s/[^:]*:\s*//;
                $self->{curInfo}->{original} = $origtext;
                $self->{insideOriginalTitle} = 0;
            }
            elsif ($self->{insideTitle})
            {
                if ($self->{pass} eq 2)
                {
                    $self->{itemIdx}++;
                    $self->{itemsList}[$self->{itemIdx}]->{series} = $origtext;
                    $self->{itemsList}[$self->{itemIdx}]->{url} = $self->{loadedUrl};
                }
                if (!$self->{curInfo}->{title})
                {
                    $self->{curInfo}->{title} = $origtext;
                    $self->{curInfo}->{series} = $origtext;
                    $self->{curInfo}->{name} = $origtext;
                    $self->{curInfo}->{original} = $origtext if (!$self->{curInfo}->{original});
                }
                $self->{insideTitle} = 0;
            }
            elsif ($self->{insideGenre})
            {
                return if ($self->{curInfo}->{genre} =~ m/$origtext/);
                $self->{curInfo}->{genre} .= ", " if $self->{curInfo}->{genre};
                $self->{curInfo}->{genre} .= $origtext;
            }
            elsif ($self->{insideAge})
            {
                $origtext = 1 if ($origtext =~ /^(Tous publics|PQ|T|A|Livre)$/);
                ($self->{curInfo}->{age} = $origtext) =~ s/.*?([0-9]+)$/$1/;
                $self->{insideTime} = 1;
            }
            elsif ($self->{insideTime} eq 2)
            {
                $self->{curInfo}->{time} .= $origtext;
            }
            elsif ($self->{insideRating} && $origtext =~ m/[0-9]\.[0-9]/)
            {
                $self->{curInfo}->{ratingpress} = int($origtext + 0.5);
            }
            elsif ($self->{insideSynopsis})
            {
                $self->{curInfo}->{synopsis} = $origtext;
            }
            elsif ($self->{insideNat} && $self->{inside}->{a})
            {
                if ($self->{curInfo}->{country} !~ /$origtext/)
                {
                    $self->{curInfo}->{country} .= ", " if $self->{curInfo}->{country};
                    $self->{curInfo}->{country} .= $origtext;
                }
            }
            elsif ($self->{insideActor})
            {
                $self->{actor} .= $origtext;
            }
            elsif ($self->{insideRole})
            {
                $self->{role} .= $origtext;
                if ($self->{actor} && $self->{role})
                {
                    $self->{actor} =~ s/^\s+|\s+$//g;
                    $self->{actor} =~ s/\s{2,}/ /g;
                    push @{$self->{curInfo}->{actors}}, [$self->{actor}];
                    $self->{role} =~ s/^\s+|\s+$//g;
                    $self->{role} =~ s/\s{2,}/ /g;
                    push @{$self->{curInfo}->{actors}->[$self->{actorsCounter}]}, $self->{role};
                    $self->{actorsCounter}++;
                }
                $self->{actor} = "";
                $self->{role} = "";
            }
            elsif ($self->{insideStoryline} && $self->{inside}{p})
            {
                $self->{curInfo}->{synopsis} .= $origtext.' ';
            }
            elsif ($self->{insideEpisodeTitle})
            {
                $self->{curInfo}->{synopsis} .= $self->{curInfo}->{episode}." : ".$origtext."\n";
                $self->{insideEpisodeTitle} = 0;
            }
            elsif ($self->{insideAirDate})
            {
                $self->{curInfo}->{airdate} = $origtext;
                $self->{curInfo}->{synopsis} .= " ".$origtext;
                $self->{insideAirDate} = 0;
            }
            elsif ($self->{insideEpisodeDescription})
            {
                $self->{curInfo}->{synopsis} .= "\n".$origtext."\n\n";
                $self->{insideEpisodeDescription} = 0;
            }
            elsif ($self->{insideDirector} || $self->{insideWriter})
            {
                    $origtext =~ s/,/, /;
                    $origtext =~ s/\(as\ .*\)$//;
                    if ($self->{curInfo}->{director})
                    {
                        $self->{curInfo}->{director} .= ", ".$origtext
                            if ($self->{curInfo}->{director} !~ /$origtext/);
                    }
                    else
                    {
                        $self->{curInfo}->{director} .= $origtext;
                    }
            }
            elsif ($self->{insideReleaseDate})
            {
                $origtext =~ s/\(.*\)//;
                $origtext = GCUtils::strToTime($origtext,"%e %B %Y",$self->getLang());
                $origtext = GCUtils::strToTime($origtext,"%B %e %Y",$self->getLang());
                $origtext = $1 if ($origtext =~ m/[^\d]*(\d+)/ && ($origtext !~ m|/|));
                $self->{curInfo}->{date} = $origtext;
                $self->{curInfo}->{firstaired} = $origtext;
            }
            elsif ($self->{insideSeasonsNumber})
            {
                $self->{curInfo}->{synopsis} .= "\n\n".$origtext."\n";
                $self->{insideSeasonsNumber} = 0;
                my $serieUrl = $self->{loadedUrl};
                $serieUrl =~ s/\/\?.*//;
                if ($self->{parsingList} && $self->{pass} eq 2)
                {
                    $origtext =~ s/(\d)+ .*/$1/;
                    my $serie = $self->{itemsList}[$self->{itemIdx}]->{series};
                    $self->{itemsList}[$self->{itemIdx}]->{season} = 1;
                    $self->{itemsList}[$self->{itemIdx}]->{url} = $serieUrl."/episodes?season=1&ref_=tt_eps_sn_1";
                    my $i = 2 ;
                    while ($i <= $origtext)
                    {
                        $self->{itemIdx}++;
                        $self->{itemsList}[$self->{itemIdx}]->{series} = $serie;
                        $self->{itemsList}[$self->{itemIdx}]->{url} = $serieUrl."/episodes?season=$i&ref_=tt_eps_sn_$i";
                        $self->{itemsList}[$self->{itemIdx}]->{season} = $i;
                        $i++;
                    }
                }
            }
            elsif ($self->{insideSeason})
            {
                (my $seasonNumber = $origtext) =~ s/.*(\d+)/$1/;
                $self->{curInfo}->{season} = $seasonNumber;
                $self->{curInfo}->{title} = $self->{curInfo}->{title}." - ".$origtext;
                $self->{insideSeason} = 0;
            }
            elsif ($self->{inside}->{h3})
            {
                if ($origtext eq "Storyline")
                {
                    $self->{insideStoryline} = 1;
                    $self->{curInfo}->{synopsis} .= "\n" if ($self->{curInfo}->{synopsis});
                }
            }
        }
    }

    sub new
    {
        my $proto = shift;
        my $class = ref($proto) || $proto;
        my $self  = $class->SUPER::new();
        bless ($self, $class);

        # uncomment this line to search english titles
        $self->{ua}->default_header('Accept-Language' => 'en-US');

        $self->{hasField} = {
            title => 1,
            date => 1,
            director => 0,
            actors => 0,
        };

        $self->{patterns} = {
            "Director" => "_dr",
            "Writer" => "_wr",
            "Genre" => ",genres",
            "ReleaseDate" => "_rdat",
            "Age" => "_pg",
            "Title" => "ep_ep_tt",
        };

        $self->{patternsTestid} = {
            Role => "characters-list",
            StoryLine => "storyline-plot-summary",
            Actor => "item__actor",
            Role => "characters-link",
            Title => "__title",
            Synopsis => "plot-l",
            CastList => "title-cast-header",
            Nat => "title-details-origin",
            OriginalTitle => "__original-title",
            Rating => "rating__score",
            Serie => "series-episode-count",
        };

        my @serieFields = ('image','synopsis','genre','actors','country',
                           'ratingpress','director','age','firstaired','time');
        $self->{serieFields} = \@serieFields;

        $self->{isInfo} = 0;
        $self->{isMovie} = 0;
        $self->{curName} = undef;
        $self->{curUrl} = undef;

        $self->{pluginType} = "films";
        $self->{pass} = 1;

        return $self;
    }

    sub preProcess
    {
        my ($self, $html) = @_;

        $self->{parsingBegun} = 0;
        $self->{parsingEnded} = 0;
        $self->{insideReleaseDate} = 0;
        $self->{insideCastList} = 0;

        if ($self->{parsingList})
        {
            $self->{alreadyListed} = {};
            foreach (@{$self->{serieFields}})
            {
                    $self->{$_} = undef;
            }
        }
        elsif (! $self->{synopsisSerie})
        {
            # save the global synopsis of the serie
            $self->{synopsisSerie} = "".$self->{synopsis};
        }
        else
        {
            # synopsis may contains content from other seasons
            $self->{synopsis} = "".$self->{synopsisSerie};
        }

        foreach (@{$self->{serieFields}})
        {
            $self->{curInfo}->{$_} = $self->{$_};
        }

        return $html;
    }

    sub getSearchUrl
    {
        my ($self, $word) = @_;

        return "http://www.imdb.com/find?s=tt&q=$word";
    }

    sub getItemUrl
    {
        my ($self, $url) = @_;

        return "http://www.imdb.com" if $url eq "";
        return $url if $url =~ /^http:/;
        return "http://www.imdb.com".$url;
    }

    sub getName
    {
        return "IMDb";
    }

    sub getAuthor
    {
        return 'groms - snaporaz - Kerenoc';
    }

    sub getLang
    {
        return 'EN';
    }

    sub getSearchCharset
    {
        return 'UTF-8';
    }
}

1;
