#!/usr/bin/perl
#
# Copyright (C) 2005 by Mandriva aginies _ateuh_ 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.

my $version = "0.1";

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

use lib qw(/usr/lib/libDrakX);
use standalone;
use strict;
use common;
use network::network;

use ugtk2 qw(:ask :wrappers :create :dialogs);

use constant FALSE => 0;


my $HOSTS = "/etc/hosts";
my @listhosts;

use constant COLUMN_IP => 0;
use constant COLUMN_HOSTNAME => 1;
use constant COLUMN_ALIAS => 2;
use constant NUM_COLUMNS => 3;

require_root_capability();

my %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget);
my $label_and_widgets = sub {
  my ($label, $widget) = @_;
  gtkpack_(Gtk2::HBox->new(0,5),
           0, gtkadd_widget($size_groups{label}, $label),
           1, gtkadd_widget($size_groups{widget}, $widget),
          );
};


sub get_host_data() {
# 127.0.0.1        localhost.localdomain localhost
# 10.0.1.253        guibpiv.guibland.com
  foreach (cat_($HOSTS)) {
    my ($ip, $name, $alias) = /^(\d\S*)\s+(\S*)\s+(.*)$/;
    $ip and push @listhosts, {
			      ip => $ip,
			      hostname => $name,
			      alias => $alias,
			     };
  }
}

sub write_conf_hosts() {
  output($HOSTS, "# generated by drakhosts\n");
  foreach my $a (@listhosts) {
    append_to_file($HOSTS, "$a->{ip} $a->{hostname} $a->{alias}\n");
  }
}

sub add_modify_entry {
  my ($treeview, $wanted) = @_;
  my $model = $treeview->get_model;
  my $selection = $treeview->get_selection;
  my $iter;
  my ($i, $ip, $hostname, $alias, $oldip);
  undef $i;
  undef $iter;

  $_ = Gtk2::Entry->new foreach $ip, $hostname, $alias;

# test if modify or add a host

  my $dialog = _create_dialog();
  $dialog->set_transient_for($::main_window);
  $dialog->set_title("Drakhosts $wanted entry");
  $dialog->set_modal(1);
  $dialog->set_resizable(1);
  $dialog->set_size_request(300, -1);

  if ($wanted =~ /modify/) {
    $iter = $selection->get_selected;
    $iter or info_dialog(N("Error"), N("Please add an host to be able to modify it.")) and return;
    my $path = $model->get_path($iter);
    $i = ($path->get_indices)[0];
    $ip->set_text($listhosts[$i]{ip});
    $hostname->set_text($listhosts[$i]{hostname});
    $alias->set_text($listhosts[$i]{alias});
    $oldip = $listhosts[$i]{ip};
  }

  my $text;
  $text = N("Please modify information") if $wanted =~ /modify/;
  $text = N("Please delete information") if $wanted =~ /delete/;
  $text = N("Please add information") if $wanted =~ /add/;
  
  gtkpack_($dialog->vbox,
	   0, gtkadd(Gtk2::Frame->new($text),
		     gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5),
			      0, $label_and_widgets->(N("IP address:"), $ip),
			      0, $label_and_widgets->(N("Host name:"), $hostname),
			      0, $label_and_widgets->(N("Host Aliases:"), $alias),
			     ),
		    ),
	   0, create_okcancel({
			       cancel_clicked => sub { $dialog->destroy },
			       ok_clicked => sub {
				 is_ip($ip->get_text) or err_dialog(N("Error!"), N("Please enter a valid IP address.")) and return;
				 my $testip = chomp_($ip->get_text);
				 my $toldip = chomp_($oldip);
				 if ($testip !~ /$toldip/ || $wanted =~ /add/) {
				   foreach my $a (@listhosts) {
				     if ($a->{ip} =~ /$testip/) {
				       err_dialog(N("Error!"), N("Same IP is already in %s file.", $HOSTS)) and return;
				     }
				   }
				 }
				 if ($wanted =~ /add/) {
				   $iter = $model->append;
				   $i = "-1";
				   push @listhosts, {
						     ip => $ip->get_text,
						     hostname => $hostname->get_text,
						     alias => $alias->get_text,
						    };
				 }
				 $listhosts[$i]{hostname} = $hostname->get_text;
				 $listhosts[$i]{alias} = $alias->get_text;
				 $listhosts[$i]{ip} = $ip->get_text;
				 $model->set($iter,
					     COLUMN_IP, $listhosts[$i]{ip},
					     COLUMN_HOSTNAME, $listhosts[$i]{hostname},
					     COLUMN_ALIAS, $listhosts[$i]{alias},
					    );
				 $dialog->destroy;
#				 write_conf_hosts();
			       },
			      },
			     ),
	  );
  $dialog->show_all;
}

sub remove_entry {
  my ($treeview) = @_;
  my $model = $treeview->get_model;
  my $selection = $treeview->get_selection;
  my $iter = $selection->get_selected;
    if ($iter) {
      my $path = $model->get_path($iter);
      my $i = ($path->get_indices)[0];
      ask_okcancel("Remove entry ?", "Remove $listhosts[$i]{hostname}") or return;
      $model->remove($iter);
      splice @listhosts, $i, 1;
    }
#  write_conf_hosts();
}

sub create_model() {
  get_host_data();
  my $model = Gtk2::ListStore->new("Glib::String", "Glib::String",  "Glib::String");
  foreach my $a (@listhosts) {
    my $iter = $model->append;
    $model->set($iter,
		 COLUMN_IP, $a->{ip},
		 COLUMN_HOSTNAME, $a->{hostname},
		 COLUMN_ALIAS, $a->{alias},
		);
	     }
  return $model;
}

# add colum to model
sub add_columns {
  my $treeview = shift;
  my $model = $treeview->get_model;
  each_index {
    my $renderer = Gtk2::CellRendererText->new;
    $renderer->set(editable => 0);
    $renderer->set_data(column => $::i);
    $treeview->insert_column_with_attributes(-1, $_, $renderer, 'text' => $::i);
  } N("IP address"), N("Host name"), N("Host Aliases");
}


###############
# Main Program
###############
# create model
my $model = create_model();

my $window = ugtk2->new("Drakhosts");
$::main_window = $window->{real_window};
$window->{rwindow}->set_size_request(500, 400) unless $::isEmbedded;
my $W = $window->{window};
$W->signal_connect(delete_event => sub { ugtk2->exit });

my $treeview = Gtk2::TreeView->new_with_model($model);
$treeview->set_rules_hint(1);
$treeview->get_selection->set_mode('single');
add_columns($treeview);

$treeview->signal_connect(button_press_event => sub {
			    my (undef, $event) = @_;
			    my $selection = $treeview->get_selection;
			    my $iter = $selection->get_selected;
			    if ($iter) {
			      add_modify_entry($treeview, "modify") if $event->type eq '2button-press';
			    }
			  });

my $okcancel = create_okcancel({
				cancel_clicked => sub { ugtk2->exit },
				ok_clicked => sub { write_conf_hosts(); ugtk2->exit },
			       },
			      );



# main interface
$W->add(gtkpack_(Gtk2::VBox->new(0,0),
		 if_(!$::isEmbedded, 0, Gtk2::Banner->new('IC-Dhost-48', N("DrakHOSTS manage hosts definitions"))),
		 #if_($::isEmbedded, 0, Gtk2::Label->new("Here you can add, remove and alter hosts definition.")),
		 1, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0),
			     1, create_scrolled_window($treeview),
			     0, gtkpack_(gtkset_border_width(create_vbox('start', 3)),
					 0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub {
								eval { add_modify_entry($treeview, "add") };
								my $err = $@;
								if ($err) {
								  err_dialog(N("Error"), N("Failed to add host.") . "\n\n" . $err);
								}
							      }),
					 0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub {
								eval { add_modify_entry($treeview, "modify") };
								my $err = $@;
								if ($err) {
								  err_dialog(N("Error"), N("Failed to Modify host.") . "\n\n" . $err);
								}
							      }),
					 0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub {
								eval { remove_entry($treeview) };
								my $err = $@;
								if ($err) {
								  err_dialog(N("Error"), N("Failed to remove host.") . "\n\n" . $err);
								}
							      }),
					 if_($::isEmbedded, 0, gtksignal_connect(Gtk2::Button->new(N("Quit")), clicked => sub { ugtk2->exit })),
					),
			    ),
		 0, $okcancel,
		),
       );
	
$W->show_all;
Gtk2->main;