use utf8;
use Encode;
use Text::Wrap;
use URI::Escape;
use Date::Parse;
use Date::Format;
#use Date::Language;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
#TOOLS
#geef output terug aan gebruiker
sub output
{
    my ($msg, $server, $target) = @_, my @lines, my ($toprint, $i);

    $msg = bigwrap(split(/[\r\n]+/, $msg));
    $msg =~ s/[\r\n\s]+$//;
    @lines = split(/[\r\n]+/, $msg);
    for ($i = 0; $i <= $#lines; $i++)
    {
        if ($lines[$i] !~ m/^\s*$/)
        {
            $server->command("/msg $target ".$lines[$i]);
        }
    }

    $server->print($target, join("", $msg));
}

#download een pagina
sub download
{
    my ($url, $sendheaders, $post, $timeout) = @_, my %post, my $key, my $value, my $ua, my $headers, my $req, my $res;
    if (!defined($sendheaders))
    { $sendheaders = 0; }
    if (defined($post))
    { %post = %$post; $post = ''; }
    else
    { %post = (); $post = ''; }
    if (!defined($timeout))
    { $timeout = 3; }
    while (1)
    {
        ($key, $value) = each %post;
        if (!defined($key)) { last; }
        $post .= sprintf('%s=%s&', uri_escape($key), uri_escape($value)) unless !defined($key) || !defined($value);
    }
    chop($post);

    #maak UserAgent aan
    $ua = new LWP::UserAgent('keep_alive' => 1
                            ,'requests_redirectable' => [ 'GET', 'HEAD', 'POST' ]
                            );
    $ua->timeout($timeout); #timeout van 3 seconden, of via @_
    $ua->agent("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"); #nodig voor Google
    $headers = new HTTP::Headers("User-Agent" => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
                                ,"Accept" => "text/html, application/xhtml+xml, */*;q=0.1"
                                ,"Accept-Language" => "en"
                                ,"Connection" => "Keep-Alive"
                                ,"Accept-Charset" => "windows-1252, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1"
                                ,"Accept-Encoding" => "deflate, gzip, x-gzip, identity, *;q=0"
                                ,"Content-Type" => "application/x-www-form-urlencoded"
                                );

    #alleen GET
    if ($post eq '')
    {
        if ($sendheaders)
        { $req = HTTP::Request->new('GET', $url, $headers); }
        else
        { $req = HTTP::Request->new('GET', $url); }
    }
    #ook POST
    else
    {
        if ($sendheaders)
        { $req = HTTP::Request->new('POST', $url, $headers); }
        else
        { $req = HTTP::Request->new('POST', $url); }
        $req->content($post);
    }
    $res = $ua->request($req);

    #controleer of 't goed ging
    if ($res->is_success && $res->status_line eq '200 OK')
    {
        #encoding goedzetten
        my $charset = "iso-8859-1";
        if (join(',', $res->header('Content-Type')) =~ m/charset=([a-z0-9\._-]+)$/i)
        { $charset = $1; }
        #probeer encoding uit html te halen
        elsif ($res->content =~ m/<meta [^>]*charset=([\w-]+)/i)
        { $charset = $1; }

        #encoding niet gevonden
        if (!ref find_encoding($charset))
        { $charset = "iso-8859-1"; }

        #probeer om te zetten
        eval
        { $content = decode($charset, $res->content); };
        if ($content)
        { return $content; }
        else
        { return $res->content; }
    }
    else
    { print "$url -> ".$res->status_line; return ''; }

    return $res->content;
}

#cache bericht
sub cache
{
    #oude weggooien, nieuwe inserten
    my ($commando, $bericht, $verloopt) = @_; my ($dbh);

    #verloopt:
    #twee maanden -> define, imdb, omschrijf, spel, vertaal
    #uur          -> teletekst
    #kwartier     -> temp, weer
    $dbh = mysqlconnect();
    mysqldo($dbh, sprintf('DELETE FROM cache WHERE commando=%s', $dbh->quote($commando)));
    mysqldo($dbh, sprintf('INSERT INTO cache VALUES(0, %s, %s, %s)'
                         ,$dbh->quote($commando)
                         ,$dbh->quote($bericht)
                         ,$dbh->quote($verloopt)
                         )
           );
    $dbh->disconnect();
}

#schoon cache op
sub cachecron
{
    my $dbh = mysqlconnect();
    mysqldo($dbh, "DELETE FROM cache WHERE verloopt<NOW()");
    $dbh->disconnect();
}

#strip tags uit HTML
sub striptags
{
    my ($html) = @_;
    $html =~ s/<[^>]+>//ig;
    return $html;
}

#strip HTML uit ehm, HTML :)
sub striphtml
{
    my ($html) = @_;
    $html =~ s/&lt;/</g;
    $html =~ s/&gt;/>/g;
    $html =~ s/&euro;/EUR/g;
    $html =~ s/&amp;/&/g;
    $html =~ s/&quot;/"/g;
    $html =~ s/&nbsp;/ /g;
    $html =~ s/&deg;/°/g;
    $html =~ s/&#(\d+);/chr($1)/ge;
    $html =~ s/&(.)[a-z]{2,6};/$1/ig;
    return $html;
}

#parse text naar datum-tijd (yyyy-mm-dd hh:mm)
sub parsedatum
{
    my ($input, $correct) = @_, my $stamp, my $inputweekday;
    my ($second, $minute, $hour, $day, $month, $year, $weekday) = localtime(time);
    $month++; $year+=1900; #rare Perl
    if (!defined($correct))
    { $correct = 1; }

    #tijdsduur vanaf nu
    if ($input =~ m/^\+(\d{1,2})[\.:](\d\d)$/)
    {
        $stamp = time + 3600*$1 + 60*$2;
    }
    #alleen tijdstip
    elsif ($input =~ m/^(\d{1,2})[\.:](\d\d)$/)
    {
        $stamp = str2time("$1:$2");
        if (!defined($stamp)) #niet te parsen
        { $stamp = str2time("$hour:$minute"); }
        $stamp += ((60*$1+$2<=60*$hour+$minute) ? 86400 : 0) if ($correct); #indien al geweest -> morgen
    }
    #dag gebruikt
    elsif ($input =~ m/^([a-z]{3,6}dag)@(\d{1,2})[\.:](\d\d)$/)
    {
        if ($1 eq 'zondag')
        { $inputweekday = 0; }
        elsif ($1 eq 'maandag')
        { $inputweekday = 1; }
        elsif ($1 eq 'dinsdag')
        { $inputweekday = 2; }
        elsif ($1 eq 'woensdag')
        { $inputweekday = 3; }
        elsif ($1 eq 'donderdag')
        { $inputweekday = 4; }
        elsif ($1 eq 'vrijdag')
        { $inputweekday = 5; }
        elsif ($1 eq 'zaterdag')
        { $inputweekday = 6; }
        else
        { $inputweekday = $weekday; }
        $stamp = str2time("$2:$3");
        if (!defined($stamp)) #niet te parsen
        { $stamp = str2time("$hour:$minute"); }
        $stamp += ((($inputweekday - $weekday)%7)*86400); #dagen erbij tellen
        $stamp += ((60*$2+$3<=60*$hour+$minute && $weekday == $inputweekday) ? 7*86400 : 0) if ($correct); #indien al geweest -> volgende week
    }
    #datum + tijd gebruikt
    elsif ($input =~ m/^(\d{1,2})-(\d{1,2})@(\d{1,2})[\.:](\d\d)$/)
    {
        if ($month == $2 && $day == $1 && $hour == $3 && $minute >= $4 #minuut is al geweest
            ||
            $month == $2 && $day == $1 && $hour > $3                   #uur is al geweest
            ||
            $month == $2 && $day > $1                                  #dag is al geweest
            ||
            $month > $2                                                #maand is al geweest
           )
        { $year++ if ($correct); }

        $stamp = str2time("$year-$2-$1 $3:$4");
        if (!defined($stamp)) #niet te parsen
        { $stamp = str2time("$year-$month-$day $hour:$minute"); }
    }
    else #geef 'nu' terug
    { $stamp = str2time("$hour:$minute"); }
    return (time2str('%Y-%m-%d', $stamp), time2str('%H:%M:00', $stamp));
}

#geef dag als woord terug
sub dag_van_de_week
{
    my ($weekday) = @_;
    if ($weekday eq 0) { return 'zondag'; }
    elsif ($weekday eq 1) { return 'maandag'; }
    elsif ($weekday eq 2) { return 'dinsdag'; }
    elsif ($weekday eq 3) { return 'woensdag'; }
    elsif ($weekday eq 4) { return 'donderdag'; }
    elsif ($weekday eq 5) { return 'vrijdag'; }
    elsif ($weekday eq 6) { return 'zaterdag'; }
}

#geef dag als getal terug
sub week_van_de_dag
{
    my ($weekday) = @_;
    if ($weekday eq 'zondag') { return 0; }
    elsif ($weekday eq 'maandag') { return 1; }
    elsif ($weekday eq 'dinsdag') { return 2; }
    elsif ($weekday eq 'woensdag') { return 3; }
    elsif ($weekday eq 'donderdag') { return 4; }
    elsif ($weekday eq 'vrijdag') { return 5; }
    elsif ($weekday eq 'zaterdag') { return 6; }
}

#return day as a word
sub day_of_the_week
{
    my ($weekday) = @_;
    if ($weekday eq 0) { return 'sunday'; }
    elsif ($weekday eq 1) { return 'monday'; }
    elsif ($weekday eq 2) { return 'tuesday'; }
    elsif ($weekday eq 3) { return 'wednesday'; }
    elsif ($weekday eq 4) { return 'thursday'; }
    elsif ($weekday eq 5) { return 'friday'; }
    elsif ($weekday eq 6) { return 'saturday'; }
}

#wrap alleen te lange lijnen
sub bigwrap
{
    my @lines = @_, my $return = '', my $line;

    $Text::Wrap::columns = 400;
    $Text::Wrap::unexpand = 0;
    foreach$line(@lines)
    { $return .= wrap("", "", ($line))."\n"; }
    return $return;
}

#reken afstand tussen strings uit
sub distance
{
    my ($s1, $s2) = @_;
    my ($len1, $len2) = (length $s1, length $s2);

    return $len2 if ($len1 == 0);
    return $len1 if ($len2 == 0);

    my %mat;

    for (my $i = 0; $i <= $len1; ++$i)
    {
        for (my $j = 0; $j <= $len2; ++$j)
        {
            $mat{$i}{$j} = 0;
            $mat{0}{$j} = $j;
        }
        $mat{$i}{0} = $i;
    }

    my @ar1 = split(//, $s1);
    my @ar2 = split(//, $s2);

    for (my $i = 1; $i <= $len1; ++$i)
    {
        for (my $j = 1; $j <= $len2; ++$j)
        {
            my $cost = ($ar1[$i-1] eq $ar2[$j-1]) ? 0 : 1;
            $mat{$i}{$j} = min([$mat{$i-1}{$j} + 1,
                                $mat{$i}{$j-1} + 1,
                                $mat{$i-1}{$j-1} + $cost]);
        }
    }
    return $mat{$len1}{$len2};
}

#geef kleinste element in lijst terug
sub min
{
    my @list = @{$_[0]};
    my $min = $list[0];

    foreach my $i (@list)
    { $min = $i if ($i < $min); }
    return $min;
}

1;
