#!/usr/bin/perl
################################################################################
# MandrakeOnline                                                               # 
#                                                                              #
# Copyright (C) 2003-2004 MandrakeSoft                                         #
#                                                                              #
# Daouda Lo <daouda@mandrakesoft.com>                                          #
#                                                                              #
# This program is free software; you can redistribute it and/or modify         #
# it under the terms of the GNU General Public License Version 2 as            #
# published by the Free Software Foundation.                                   #
#                                                                              #
# This program 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 this program; if not, write to the Free Software                  #
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   #
################################################################################

use strict;
use lib qw(/usr/lib/libDrakX);
use common;
BEGIN { unshift @::textdomains, 'mdkonline' }

use Gtk2::TrayIcon;

eval { require ugtk2; ugtk2->import(qw(:all)); require Gtk2::Pango; };
if ($@) {
    print "This program cannot be run in console mode.\n";
    c::_exit(0);  #- skip ugtk2::END
}
my ($eventbox, $img);
add_icon_path("/usr/share/mdkonline/pixmaps/");
my ($menu, $url, $timeout, $refreshtm);
my $nowindow = 1;
my $arch = arch();
my $av_pkgs;
my $need_update = 0;
my $conffile = '/etc/sysconfig/mdkonline';

my %state = (
	     okay => {
		      colour => [ 'green' ],
		      changes => [ 'busy', 'critical', 'disconnected' ],
		      menu => [ 'update', 'configureApplet', 'check', 'weblink' ],
		      tt => [ N("No updates available for your system") ]
		     },
 	     critical => {
			  colour => [ 'orange' ],
			  changes => [ 'okay', 'busy', 'critical', 'disconnected' ],
			  menu => [ 'update', 'configureApplet', 'check', 'weblink' ],
			  tt => [ N("Config problems. Launch \"configure\" again") ]
			 },
	     busy => {
		      colour => [ 'orange' ], 
		      changes => [ 'okay', 'critical', 'error', 'disconnected' ],
		      menu => [ ],
		      tt => [ N("System is busy. Wait ...") ]
		     },
	     error => {
		       colour => [ 'red' ],
		       changes => [ 'okay' ],
		       menu => [ 'update', 'check' ],
		       tt => [ N("%s packages available for update", $av_pkgs) ]
		      },
	     noconfig => {
			  colour => [ 'orange' ],
			  changes => [ 'okay' ],
			  menu => [ 'weblink', 'register' ],
			  tt => [ N("Service not available. Click on \"configuration\"") ]
			 },
	     disconnected => {
			      colour => [ 'orange' ],
			      changes => [ 'okay', 'busy', 'critical', 'error' ],
			      menu => [ 'confNetwork' ],
			      tt => [ N("Network is down. Click on \"configure Network\"") ]
			     },
	     disabled => {
			  colour => [ 'red' ],
			  changes => [ 'okay', 'busy', 'critical', 'error' ],
			  menu => [ 'weblink' ],
			  tt => [ N("Service deactivated. Waiting for payment...") ]
			 }
	    );
my %actions = (
	       'update' => { name => N("Launch Mandrake Update"), launch => sub { launchUpdate() } },
	       'configureApplet' => { name => N("Configuration"), launch => sub { configure() } },
	       'check' => { name => N("Check Updates"), launch => sub { checkUpdates() } }, 
	       'weblink' => { name => N("Online WebSite"), launch => sub { getSite() } },
	       'confNetwork' => { name => N("Configure Network"), launch => sub { configNetwork() } },
	       'register' => { name => N("Configure Now!"), launch => sub { configure() } }
	      );

gtkadd(my $icon = Gtk2::TrayIcon->new("MdkApplet"), 
       gtkpack_( Gtk2::VBox->new(0, 3), 
		 0, gtkadd($eventbox = Gtk2::EventBox->new, 
			   gtkpack($img = Gtk2::Image->new)
			  )
	       )
      );
$eventbox->signal_connect(button_press_event => sub {
			      if ($_[1]->button == 1) {
				  if (-e $conffile) { showMainWindow() } else { configure() }
			      }
			      $_[1]->button == 3 && $menu and $menu->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time);
			  });

shouldStart() or die "$ENV{HOME}/.mdkonline should be set to TRUE";

checkUpdates();
cronUpdate();

$icon->show_all;
Gtk2->main;

ugtk2::exit(0);

sub showMainWindow() {
    my $w = Gtk2::Window->new('toplevel');
    $w->set_title(N("Mandrake Updates Applet"));
    $w->signal_connect(delete_event => sub { $w->destroy });
    $w->set_position('center');
    my ($choice, $isAvailable, $time);
    my $autocheck;
    gtkadd($w,
           gtkpack__(Gtk2::VBox->new(0,5),
		     gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Actions")), 'etched_in'),
			    gtkpack_(Gtk2::VBox->new(0, 3),
				     1, gtksignal_connect(Gtk2::Button->new(N("Install updates")), clicked => sub { installUpdates() }),
				     1, gtksignal_connect(Gtk2::Button->new(N("Configure")), clicked => sub { configure() }),
				     1, gtksignal_connect(Gtk2::Button->new(N("Check updates")), clicked => sub { checkUpdates() }),
				     1, gtksignal_connect(Gtk2::Button->new(N("See logs")), clicked => sub { displayLogs() }),
				    )
			   ),
		     gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Status")), 'etched_in'),
			    gtkpack_(Gtk2::VBox->new(0, 3),
				     0, gtkpack_(Gtk2::HBox->new(0, 3),
						 0, Gtk2::Label->new(N("Network Connection: ")),
						 0, Gtk2::Label->new(isNetwork() ? N("Up") : N("Down"))
						),
				     0, gtkpack_(Gtk2::HBox->new(0, 3),
						 0, Gtk2::Label->new(N("New Updates: ")),
						 0, Gtk2::Label->new($isAvailable ? N("Available") : N("Not Available"))
						),
				     0, gtkpack_(Gtk2::HBox->new(0, 3),
						 0, Gtk2::Label->new(N("Last check: ")),
						 0, Gtk2::Label->new(lastCheck())
						),
				    )
			   ),
		     gtkpack(Gtk2::HSeparator->new),
                     gtkpack(gtksignal_connect(Gtk2::Button->new(N("Close")), clicked => sub {
						   $w->destroy;
					       })
			    )
		    ));
    $w->show_all
}
sub confNetwork {
    system "/usr/sbin/drakconnect &";
}
sub launchUpdate {
    system "/usr/sbin/MandrakeUpdate &";
}
sub installUpdates {
    system "/usr/sbin/mdkupdate", "--applet";
}
sub silentCheck {
    my $link = "https://www.mandrakeonline.net/online3_RemoteAction.php" . '?action=UpdateList';
    my %h = getVarsFromSh($conffile); 
    my $u;
    require LWP::UserAgent;
    require HTTP::Request::Common;
    require HTTP::Request;
    my $ua = LWP::UserAgent->new;
    $ua->agent("MdkAppletAgent/0.1" . $ua->agent);
    $ua->env_proxy;
    #    my $request = HTTP::Request->new(GET => $link . '&log=' . "ayomigration" . '&host=' . "online");
    my $request = HTTP::Request->new(GET => $link . '&log=' . $h{LOGIN} . '&host=' . $h{MACHINE});
    my $lnk = $link . '&log=' . $h{LOGIN} . '&host=' . $h{MACHINE};
    my $response = $ua->request($request);
    my $ct = $response->content;
    print "\nCONTENTS = $ct; link = $lnk \n";
    if ($ct =~ /rpm/) { $u = 11 } elsif ($ct =~ m/(\d+)/) { $u = sprintf("%d",$1); } else { $u = 10 };
    #   99 - log or host or action or pass empty, wrong action
    #   98 - wrong pass
    #   97 - host not active
    my $retcode = {
		   10 => sub { go2State('okay') },
		   11 => sub {
		       my @contents = sort ( split /\n/, $ct);
		       my @r = sort( split /\n/, `rpm -qa` );
		       foreach my $cand (@contents) {
			   $cand =~ s/\.(i586|ppc|ia64).rpm//;
			   $cand =~ /(.*)-(.*)$/; my ($namever, $release) = ($1, $2);
			   if (member($namever, @r) && $cand ne chomp_(`rpm -q $namever`)) {
			       go2State('error') and last
			   }
		       }
		   },
		   97 => sub { go2State('disabled'); },
		   98 => sub { go2State('critical'); },
		   99 => sub { go2State('critical'); }
		  };
    $retcode->{$u}->();
}
sub cronUpdate {
    my ($to) = shift;
    $timeout = Glib::Timeout->add(60*60*1000, sub {
				      checkUpdates();
				      1;
				  });
}
sub lastCheck {
    my %h = getVarsFromSh($conffile);
    my ($t, $l);
    $t = $h{LASTCHECK} ;
    $t =~ s/\_/  /g;
    $t ? $t : N("No check")
}
sub checkUpdates {
    if (!isNetwork()) {
	go2State('disconnected')
    } elsif (!-e $conffile) {
	go2State('noconfig')
    } else {				   
	silentCheck();
    }
}
sub go2State {
    my $state = shift;
    $menu && $menu->destroy;
    $menu = setState($state);
}
sub isNetwork {
    my $network;
    $network = gethostbyname("mandrakeonline.net") ? 1 : 0;
    $network;
}
sub configure {
    system "/usr/sbin/mdkonline &";
    $refreshtm = Glib::Timeout->add(1*60*1000, sub {
					-e $conffile and Glib::Source->remove($refreshtm);
					silentCheck();
					1;
				    });
}
sub getSite {
    my $b = browser();
    system("$b " . "https://www.mandrakeonline.net" . "&")
}
sub browser {
    require any;
    my $wm = any::running_window_manager();
    member ($wm, 'kwin', 'gnome-session') or $wm = 'other';
    my %Br = (
	      'kwin' => 'konqueror',
	      'gnome-session' => 'mozilla',
	      'other' => $ENV{BROWSER} || find { -x "/usr/bin/$_"} qw(mozilla konqueror galeon)
	     );
    $Br{$wm}
}
sub displayLogs {
    system "/usr/sbin/logdrake --explain=drakxtools &"
}
sub shouldStart() {
    my %p = getVarsFromSh("$ENV{HOME}/.mdkonline");
    my $ret = $p{AUTOSTART} eq 'FALSE' ? 0 : 1;
    $ret
}
sub setState {
    my $state_type = shift;
    my $arr = $state{$state_type}{menu};
    my $tmp = gtkcreate_pixbuf($state{$state_type}{colour}->[0]);
    $img->set_from_pixbuf($tmp);
    #my $tooltip = Gtk2::Tooltips->new;
    gtkset_tip(new Gtk2::Tooltips, $eventbox, formatAlaTeX($state{$state_type}{tt}->[0]));
    my $menu = Gtk2::Menu->new;
    foreach (@$arr) { 
	my $l = $actions{$_}{name};
	$menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($actions{$_}{name})), activate => $actions{$_}{launch}));
    }
    $menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));
    $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("About.."))), activate => sub { about() }));
    $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("Quit"))), activate => sub { mainQuit() }));
    $menu
}
sub about {
    my $b = browser();
    system("$b " . "https://mandrakeonline.net/info.php" . "&")
}
sub mainQuit() {
    output_p "$ENV{HOME}/.mdkonline",
    qq(AUTOSTART=FALSE
);
    chmod 0644, "$ENV{HOME}/.mdkonline";
    Gtk2->main_quit
}