#!/usr/bin/perl -w

#
# Gtk2::Leo
# gtkleo.pl Version 0.12: GTK2 Frontend for leo.pl
# Author/Copyright (c) 2007: Stefan Deser <stefan@philonous.org>
# Thanks to: Christian Winter. 
#
# You will need libgtk2-perl (GTK2 Perl bindings) and libwww-perl to run this script. 
#
# Originally based on (but now completely rewritten): 
# leo.pl Version 1.15b: English<->German Dictionary
#
# Author/Copyright (c) 2005: Christian Birchinger <cbirchinger@netswarm.net>
# All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#


use strict;
use LWP::UserAgent;
use HTTP::Request;
use HTML::TreeBuilder;
use Glib qw/TRUE FALSE/;
use Gtk2::SimpleList;
use Gtk2 '-init';


# build GUI
my $default_width = 400; 
my $default_height = 300;
my $window = Gtk2::Window->new('toplevel');
$window->set_title("LEO");
$window->set_border_width(10);
$window->set_default_size($default_width, $default_height);
$window->set_position('mouse');
# shift window (top left corner on current mouse position)
my @size = $window->get_default_size;
my @pos  = $window->get_position;
$window->move( map { $size[$_] / 2 + $pos[$_] } 0 .. 1 );

$window->signal_connect(delete_event => sub { return FALSE; } );
$window->signal_connect(destroy => sub { Gtk2->main_quit; });
# TODO? alter GUI on window-maximizing?
# $window->signal_connect(expose_event => sub { do_something; });

my $entry = Gtk2::Entry->new;
my $button = Gtk2::Button->new("Go!");
$button->signal_connect(clicked => \&search_leo, $window);

my $hbox = Gtk2::HBox->new(0,5); 
my $vbox = Gtk2::VBox->new(0,5);

$hbox->add($entry);
$hbox->add($button);

my $slist = Gtk2::SimpleList->new (
               'English' => 'text',
               'German' => 'text',
            );

$slist->set_rules_hint (TRUE);
($slist->get_column(0))->set_max_width(200);
map { $_->set_resizable (TRUE) } $slist->get_columns;

my $scrolled = Gtk2::ScrolledWindow->new;
$scrolled->set_policy ('automatic', 'automatic');
$scrolled->add($slist);

$vbox->pack_start($hbox, FALSE, FALSE, FALSE);
$vbox->add($scrolled);

$window->add($vbox);
$window->show_all;

# get stuff from clipboard
my $clipboard = Gtk2::Clipboard->get(Gtk2::Gdk->SELECTION_PRIMARY);

$clipboard->request_text( sub { $entry->set_text(defined $clipboard->wait_for_text ? $clipboard->wait_for_text : ""); &search_leo; } );

Gtk2->main;


# sub for searching dict.leo.org 
sub search_leo()
{
    # clear list
    @{$slist->{data}} = (); 

    my $words = $entry->get_text;

    if ($words =~ /[a-zA-Z0..9]/) 
    {

        # only allow alphanums, and quote all other chars as hex string
        $words =~ s/([^[a-zA-Z0..9])/uc(sprintf("%%%02lx", ord $1))/eg;

        my $response = LWP::UserAgent->new->request(
        HTTP::Request->new( GET => "http://dict.leo.org/ende?lang=en\&sectHdr=off\&search=" . $words ) 
        );

        # simple GUI warning...
        unless($response->is_success) 
        {
            push @{$slist->{data}}, [ "Could not get it: ", $response->status_line ];
            return; 
        }

        my $tree = HTML::TreeBuilder->new();
        $tree->parse($response->content); 
        $tree->eof; 

        my $resulttable = ( $tree->look_down('_tag', 'table', sub{ defined $_[0]->attr('id') && $_[0]->attr('id') =~ m{results}; }) )[0]; 

        if ( $resulttable ) 
        {
            my @rows = ( $resulttable->look_down('_tag', 'tr', sub { not defined $_[0]->attr('colspan') }) );

            # cut off the first two rows
            for(2..$#rows) 
            {
                my @results = ($rows[$_]->look_down('_tag', 'td'));
                my $english = $results[1]->as_text; # 2nd column
                my $german = $results[3]->as_text; # 4th column
                push @{$slist->{data}}, [ $english, $german ];
            }
        }
        else
        {
            push @{$slist->{data}}, [ "Not found.", "Nicht gefunden." ];
        }

        $tree->delete;
    }
}


