#!/usr/bin/perl

# Copyright (C) 2006 Mandriva
#                    Olivier Blin <oblin@mandriva.com>
#
# This program 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, or (at your option)
# any later version.
#
# 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 /usr/share/drakvirt);

# i18n: IMPORTANT: to get correct namespace (drakvirt instead of libDrakX)
BEGIN { unshift @::textdomains, 'drakvirt' }

use common;
use standalone;
use mygtk2 qw(gtknew);
use ugtk2 qw(:create :helpers :wrappers :dialogs);
use Gtk2::SimpleList;
use Gnome2::Vte;
use interactive;
use virtual::xen;
use drakvirt;

my $in = interactive->vnew('su');

$ugtk2::wm_icon = drakvirt::get_icon();
my $title = N("Virtualization");
my $w = ugtk2->new($title);
$::main_window = $w->{real_window}; #- so that transient_for is defined for wait messages and dialogs
my @popups;

my $virtual = 'virtual::xen';
$virtual->ensure_is_installed($in) or $in->exit;

my @guests;
my $guests_list = Gtk2::SimpleList->new(
    N("Name") => "text",
    N("Running") => "pixbuf",
);

my $running_icon = gtkcreate_pixbuf('play-16');
my $stopped_icon = gtkcreate_pixbuf('stop-16');

sub get_current_guest() {
    my ($selected) = $guests_list->get_selected_indices;
    defined $selected && $guests[$selected];
}

sub guest_run_method {
    my ($method, $message) = @_;
    my $guest = get_current_guest() or return;
    my $_w = $in->wait_message($title, sprintf(translate($message), $guest->{name}));
    $guest->$method;
    update_guests();
}

sub guest_run_console {
    my $guest = get_current_guest() or return;
    my $console_w;
    $console_w = ugtk2->new(N("Console on guest %s", $guest->{name}));
    my $vte = Gnome2::Vte::Terminal->new;
    my @command = $guest->get_console_command;
    $vte->fork_command($command[0], \@command, undef, undef, 0, 0, 0);
    push @popups, $console_w->{real_window};
    $console_w->{real_window}->signal_connect(delete_event => sub { $console_w->destroy });
    gtkadd($console_w->{window}, gtksignal_connect($vte, 'child-exited' => sub { $console_w->destroy }));
    $console_w->{window}->show_all;
}

sub update_guests() {
    @guests = $virtual->list_configured_guests;
    @{$guests_list->{data}} = ();
    @{$guests_list->{data}} = map {
        [
            $_->{name},
            $_->is_running ? $running_icon : $stopped_icon,
        ];
    } @guests;
}

sub gtkset_image {
    my ($w, $file, $o_size) = @_;
    my $image = $o_size
    ?  Gtk2::Image->new_from_pixbuf(gtkcreate_pixbuf($file)->scale_simple($o_size, $o_size, 'hyper'))
    :  gtknew('Image', file => $file);
    $w->set_image($image);
    $w;
}

gtkadd($w->{window},
       gtknew('VBox', spacing => 5, children => [
	   $::isEmbedded ? () : (0, Gtk2::Banner->new(drakvirt::get_icon(), $title)),
	   0, gtknew('Title2', label => N("This tool allows you to configure virtualization.")),
               1, gtknew('VBox', spacing => 5, children => [
                   ($virtual->is_available ? (
                   1, gtknew('ScrolledWindow', width => 500, height => 300, child => $guests_list),
                   0, gtknew('HButtonBox', layout => 'edge', children_loose => [
                       gtkset_image(gtknew('Button', text => N("Start"), clicked => sub { guest_run_method('start', N_("Starting %s")) }),
                                   'play-24'),
                       gtkset_image(gtknew('Button', text => N("Stop"), clicked => sub { guest_run_method('stop', N_("Stopping %s")) }),
                                   'stop-24'),
                       gtkset_image(gtknew('Button', text => N("Kill"), clicked => sub { guest_run_method('kill', N_("Killing %s")) }),
                                   'stop-24'),
                       gtkset_image(gtknew('Button', text => N("Run console"), clicked => \&guest_run_console),
                                   'terminals_section', 24),
                   ])) : (
                   0, $virtual->get_not_available_message,
                   )),
                   0, gtknew('HButtonBox', layout => 'edge', children_loose => [
                       ($virtual->is_available ? (
                       gtkset_image(gtknew('Button', text => N("Refresh"), clicked => \&update_guests),
                                   'refresh'),
                       gtkset_image(gtknew('Button', text => N("Install new guest"),
                                           clicked => sub { drakvirt::install_guest($in, $virtual) }),
                                   'IC-installone-24'),
                       ) : ()),
                       gtksignal_connect(Gtk2::Button->new_from_stock('gtk-quit'), clicked => sub { Gtk2->main_quit }),
                   ]),
               ]),
       ]));

update_guests();

#- remove over-zealous main quit connected to delete_event by mygtk2
Gtk2::Widget->signal_add_emission_hook('delete_event', sub {
                                   my (undef, $args) = @_;
                                   member($args->[0], @popups) and $Gtk2::block_next_main_quit = 1;
                                   1;
                               });
{
    package Gtk2;
    our $block_next_main_quit = 0;
    my $main_quit = \&Gtk2::main_quit;
    *main_quit = sub {
        my $ret = !$Gtk2::block_next_main_quit && Gtk2->$main_quit;
        $Gtk2::block_next_main_quit = 0;
        $ret;
    };
}

$w->main;
