#!/usr/bin/perl
# Mandriva Fax
#
# Copyright (C) 2003, 2004 Mandriva Daouda Lo (daouda at mandriva dot 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/);
use standalone;
use common;
BEGIN { unshift @::textdomains, 'drakfax' }
use ugtk2 qw(:all);

#my $faxprog = 'hylafax';
#my $spooldir = '/var/spool/fax/';
my $pixdir = '/usr/share/drakfax/pixmaps/';
my $exec_server = '/usr/sbin/drakfax_server';
my $exec_sendfax = '/usr/bin/sendfax';

my ($popit, $error) = (0, 0);
my $fax = {};
my $confDir = "$ENV{HOME}/.drakfax";

my $window_splash = Gtk2::Window->new('popup');
$window_splash->signal_connect(delete_event => \&quitGlobal);
$window_splash->set_title(N("Drakfax"));
$window_splash->set_position('center_always');
$window_splash->add(gtkadd(gtkset_shadow_type(Gtk2::Frame->new, 'etched_out'),
                           gtkpack(Gtk2::VBox->new(0, 0),
                                   gtkcreate_img("$pixdir/splash.png"),
                                   Gtk2::Label->new(N("Loading Settings... Please wait"))
				  )
			  )
		   );
$window_splash->show_all;
gtkflush();

mkdir_p($confDir);
foreach (qw(histfaxfiles histfaxnum addressbook settings)) {
    $fax->{$_} = $confDir . "/" . $_;
}
my %h = -e $fax->{settings} && getVarsFromSh($fax->{settings});

sub HelpSystem() { exec("drakhelp --id drakfax") unless fork() }

my $coverstate = text2bool($h{COVER});

$fax->{wnd} = ugtk2->new(N("Fax Client/Server Configuration") . " " . $fax->{VERSION});
gtkset_size_request($fax->{wnd}{real_window}, 600, 480);
$fax->{wnd}{real_window}->set_position('center') if !$::isEmbedded;
$fax->{wnd}{window}->signal_connect(delete_event => \&quitGlobal);
my $faxtree_model = Gtk2::ListStore->new("Glib::Int", "Glib::Int", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String");
my $addphonetree_model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String");
my $faxtree;
my $addphonetree;
$faxtree = createTree($faxtree_model); 
$addphonetree = createTree($addphonetree_model);
# slightly verbatimed from control-center
my ($menu, $_factory) = create_factory_menu($::isEmbedded ? $::Plug : $fax->{wnd}{window},
                                           ([ N("/_File"), undef, undef, undef, '<Branch>' ],
                                            [ N("/_File") . N("/_Quit"), N("<control>Q"), \&quitGlobal, undef, ],
                                            [ N("/_Actions"), undef, undef, undef, '<Branch>' ],
                                            [ N("/_Actions") . N("/_Send Fax"), undef, sub { setPage('nb', 0) }, undef ],
                                            [ N("/_Actions") . N("/_Fax status"), undef, sub { setPage('nb', 1) }, undef ],
                                            [ N("/_Settings"), undef, undef, undef, '<Branch>' ],
					    [ N("/_Settings") . N("/_Preferences"), undef, \&faxPref, undef ],
					    [ N("/_Settings") . N("/_Server Configuration"), undef, \&faxServer, undef ],
					    [ N("/_Help"), undef, undef, undef, '<Branch>' ],
                                            [ N("/_Help") . N("/_Help"), undef, sub { HelpSystem() }, undef ],
                                            [ N("/_Help") . N("/_Report Bug"), undef, sub { system("$ENV{BROWSER} https://qa.mandriva.com &") }, undef ],
                                            [ N("/_Help") . N("/_About..."), undef, \&About, undef ]
					   )
					  );
$fax->{nb} = Gtk2::Notebook->new; #$fax->{nb}->set_show_tabs(0); $fax->{nb}->set_show_border(0);
my %toolbars = (
		sendfax => [
			    [ N("Send"), N("Send Fax to the spool"), 'send', \&faxSend ],
			    [ N("Clear"), N("Reset fax sending"), 'clear', \&faxClear ]
			   ],
		status => [
			   [ N("Send"), N("Queue for sending jobs"), 'gtk-go-forward', \&Sendq ],
			   [ N("Done"), N("Check jobs that are done"), 'gtk-yes', \&Doneq ],
			   [ N("Recv"), N("Check Received fax Queue"), 'gtk-go-back', \&Recvq ],
			   [ N("Refresh"), N("Refresh queues"), 'gtk-refresh', \&Refreshq ]
			  ],
	       );
foreach my $l (keys %toolbars) { 
    $fax->{$l} = Gtk2::Toolbar->new; 
    $fax->{$l}->set_orientation('vertical'); 
    createToolbar($l);
}
#PO: list of users belonging to that group
my @faxcolsize = (30, 45, 60, 60, 80, 40, 120, -1); my @phonecolsize = (120, 160, 120, -1);
each_index {
    my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i);
    $col->set_sort_column_id($::i);
    $col->set_min_width($faxcolsize[$::i]);
    $faxtree->append_column($col);
} ('Job Id', N("Number"), N("Status"), N("Owner"), N("Pages"), N("Dials"), N("Error"));
each_index {
    my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i);
    $col->set_sort_column_id($::i);
    $col->set_min_width($phonecolsize[$::i]);
    $addphonetree->append_column($col);
} (N("Fax Number"), N("Organization"), N("Contact"));

my $sg = Gtk2::SizeGroup->new('vertical');
my $sg = Gtk2::SizeGroup->new('horizontal');

gtkappend_page($fax->{nb},
	       gtkpack_(Gtk2::HBox->new(0, 10),
			1, gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("New Fax")), 'etched_in'),
				  gtkpack_(Gtk2::VBox->new(0, 30),
					   0, gtkpack_(Gtk2::VBox->new(0, 10),
						       0, create_packtable({ homogeneous => 0, col_spacings => 0, row_spacings =>0 },
									   [ N("File to fax"), 
									     gtkpack_(Gtk2::HBox->new(0, 5),
										      1, $fax->{file2fax} = Gtk2::Combo->new, 
										      0, gtksignal_connect(gtkadd_widget($sg, Gtk2::Button->new(N("Browse"))),
                                                                             clicked => sub { browseFile("file2fax") })) ],
									   [ N("Fax Number"), 
									     gtkpack_(Gtk2::HBox->new(0, 5),
										      1, $fax->{num2fax} = Gtk2::Combo->new, 
										      0, gtksignal_connect(gtkadd_widget($sg, Gtk2::Button->new(N("Add"))),
                                                                             clicked => sub { getNum('', '', $fax->{num2fax}->entry->get_text) })) ],
									  )),
					   1, gtkpack_(Gtk2::VBox->new(0, 10),
						       1,  create_scrolled_window($addphonetree)
						      ),
					   1, gtkpack_(Gtk2::VBox->new(0, 10),
						       0, gtkpack_(Gtk2::HBox->new(0, 3),
								   0, gtksignal_connect(gtkset_active($fax->{usecover_cb} = Gtk2::CheckButton->new(N("Cover Page")), $coverstate),
                                                                clicked => sub {
                                                                    $coverstate = !$coverstate;
                                                                    $fax->{hboxcover}->set_sensitive($coverstate);
                                                                }),
								   1, gtkpack_($fax->{hboxcover} = Gtk2::HBox->new(0, 3),
									       1, $fax->{cover_c} = Gtk2::Combo->new,
									       0, gtksignal_connect(Gtk2::Button->new(N("Browse")), clicked => sub { browseFile("cover_c") })
									      )),
 						       0, gtkpack_(Gtk2::VBox->new(0, 5),
								   0, $fax->{sendnow_rb} = Gtk2::RadioButton->new_with_label(undef, N("Send now")),
								   0, $fax->{sendat_rb} = Gtk2::RadioButton->new_with_label($fax->{sendnow_rb}, N("Send At")),
								   0, gtkset_sensitive(gtkpack_($fax->{send_hbox} = Gtk2::HBox->new(0, 3),
												0, $fax->{date_e} = gtkentry('xxxx/xx/xx'),
												0, $fax->{cal_b} = dateEdit(),
												0, $fax->{hour_e} = gtkentry('xx:xx'),
												0, $fax->{hour_o} = hourEdit(7, 20),
											       ), 0)
								  )))),
			0, gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Actions")), 'etched_in'),
				  gtkpack_(Gtk2::VBox->new(0, 0),
					   0, $fax->{sendfax},
					  ))),
			   N("New Fax"),
           );

gtkappend_page($fax->{nb},
	       gtkpack_(Gtk2::HBox->new(0, 10),
			1, gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Status")), 'etched_in'),
				  gtkpack_(Gtk2::VBox->new(0, 5),
					   0, Gtk2::Label->new(N("Send Queue")),
					   1, $faxtree,
					   0, create_scrolled_window($fax->{status_t} = Gtk2::TextView->new
								    ))),
			0, gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Queues")), 'etched_in'),
				  gtkpack_(Gtk2::VBox->new(0, 0),
					   0, $fax->{status},
					  ))),
               N("Fax Status"),
           );
getSettings();
$fax->{wnd}{window}->add(gtkpack_(Gtk2::VBox->new(0, 0),
				  0, $menu,
				  1, $fax->{nb}));
$fax->{cal_b}->signal_connect(clicked => sub { 
				   my ($x_win, $y_win) =  $fax->{cal_b}->get_parent_window->get_position;
				   my ($x, $y) = ($fax->{cal_b}->allocation->x, $fax->{cal_b}->allocation->y);
				   my $bwidth = $fax->{cal_b}->allocation->width; my $bheight = $fax->{cal_b}->allocation->height;  
				   $fax->{popup_c}->move($x_win + $x + $bwidth - 250, $y_win + $y + $bheight);
				   if (!$popit) { 
				       $fax->{popup_c}->show; 
				       my ($year, $month, $day) = split('/', $fax->{date_e}->get_text);
				       $fax->{calendar}->select_month($month - 1, $year);
				       $fax->{calendar}->select_day($day);
				   } else { $fax->{popup_c}->hide }
				   $popit = !$popit;
			       });
$coverstate and $fax->{cover_c}->entry->set_text($h{COVERFILE});
foreach my $t (['sendnow_rb', 0], ['sendat_rb', 1]) {
    $fax->{$t->[0]}->signal_connect(clicked => sub { 
					$fax->{send_hbox}->set_sensitive($t->[1]);
					$t->[1] and entryDate();
				    });
} 

$fax->{wnd}{window}->show_all;

$window_splash->destroy;
undef $window_splash;

$fax->{wnd}->main;
ugtk2->exit(0);

sub faxClear() {
    $fax->{$_}->entry->set_text('') foreach qw(num2fax file2fax);
}

sub faxPref() {
    my $w = newWindow(N("User Preferences"), 1);
    my ($hbox, $state, $filecov, $coverfile);
    my %e = ( 
	     res => { high => N("High (204x196 dpi)"), low => N("Low (204x98 dpi)") },
	     paper => { 'a4' => N("A4"), 'na-let' => N("Letter"), legal => N("Legal") }
	    );
    my %h = -e $fax->{settings} && getVarsFromSh($fax->{settings});
    $state = text2bool($h{COVER});
    $filecov = $h{COVERFILE};
    my $toolbar = Gtk2::Toolbar->new; $toolbar->set_orientation('vertical');
    my $nbset = Gtk2::Notebook->new; $nbset->set_show_tabs(0); $nbset->set_show_border(0);
    foreach ([ N("Personal"), N("Personal settings"), 'home', sub { setPage($nbset, 0) } ],
	     [ N("Server"), N("Hylafax server address"), 'server', sub { setPage($nbset, 1) } ],
	     [ N("Page"), N("Page Style"), 'page', sub { setPage($nbset, 2) } ]) {
	my $pix = $pixdir . $_->[2] . '.png';
	$toolbar->append_item($_->[0], $_->[1], $_->[2], -e $pix ? Gtk2::Image->new_from_file($pix) : Gtk2::Image->new_from_stock($_->[2], 'button'), $_->[3], $toolbar); 
    }    
    gtkappend_page($nbset,
		   gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Personal Data")), 'etched_in'),
			  gtkpack_(Gtk2::VBox->new(0, 4),
				   1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings => 5 },
						       [ N("Name") . " :", my $pname = Gtk2::Entry->new ],
						       [ N("Company") . " :", my $pcp = Gtk2::Entry->new ],
						       [ N("Number") . " :", my $pn = Gtk2::Entry->new ]
						      ))));
    gtkappend_page($nbset,
		   gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Fax Server")), 'etched_in'),
			  gtkpack_(Gtk2::VBox->new(0, 3),
				   1, create_packtable({ homogeneous => 0, col_spacings => 3, row_spacings => 3 },
						       [ N("Fax Server Host"), my $serv = Gtk2::Entry->new ],
						       [ N("Mail notification"), my $mailnot = Gtk2::Entry->new ],
						      ))));
    gtkappend_page($nbset,
		   gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Setup Page")), 'etched_in'),
			  gtkpack_(Gtk2::VBox->new(0, 2),
				   1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings => 5 },
						       [ N("Resolution") . " :", my $resopt = Gtk2::OptionMenu->new ],
						       [ N("Paper Size") . " :", my $psopt = Gtk2::OptionMenu->new ],
						      ),
				   0, gtksignal_connect(gtkset_active(my $usecover = Gtk2::CheckButton->new(N("Use default cover")), $state), clicked => sub { $state = !$state; $hbox->set_sensitive($state) }),
				   0, gtkpack_($hbox = Gtk2::HBox->new(0, 5),
					       1, $coverfile = Gtk2::Combo->new,
					       0, gtksignal_connect(Gtk2::Button->new(N("Browse")), clicked => sub {
									my $dlg = new Gtk2::FileSelection(N("File selection"));
									$dlg->set_modal(1);
									$dlg->set_transient_for($w);
									$dlg->show;
									$dlg->set_filename($coverfile->entry->get_text);
									$dlg->cancel_button->signal_connect(clicked => sub { $dlg->destroy });
									$dlg->ok_button->signal_connect(clicked => sub {
													    $coverfile->entry->set_text($dlg->get_filename);
													    $dlg->destroy;
													});
								    })
					      )
				  )));
    gtkadd($w,
	   gtkpack_(Gtk2::VBox->new(0, 2),
		    1, gtkpack_(Gtk2::HBox->new(0, 3),
				1, $nbset,
				0, gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Sections")), 'etched_in'),
					  $toolbar
					 )),
		    0, gtkpack(create_hbox('edge'),
			       map {
				   my $r = $_->[1];
				   gtksignal_connect(Gtk2::Button->new_from_stock($_->[0]), clicked => sub {
							 if (!$r) {
							     $error = 0;
							     my $u = $pname->get_text; my $v = $pcp->get_text; 
							     my $t = $usecover->get_active; my $x = $coverfile->entry->get_text;
							     my $z = $mailnot->get_text;
							     $t && !$x and raiseError(N("Provide a Cover File Please"));
							     if (!$error) {
								 setVarsInSh($fax->{settings},
									     {
									      NAME => $u,
									      COMPANY => $v,
									      FAXNUMBER => $pn->get_text,
									      SERVER => $serv->get_text,
									      MAIL => $z,
									      RES => getKeysFromValues($e{res}, $resopt),
									      PAPER => getKeysFromValues($e{paper}, $psopt),
									      COVER => $t ? 'TRUE' : 'FALSE',
									      COVERFILE => $x
									     } 
									    );
								 $fax->{usecover_cb}->set_active($t); $fax->{hboxcover}->set_sensitive($t);
								 $fax->{cover_c}->entry->set_text($x);
							     }
							 }
							 !$error and $w->destroy; $error = 0 });
			       } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ]))
		   )
	  );
    foreach my $r ([$resopt, 'res'], [$psopt, 'paper'], [$pname, 'name'], [$pcp, 'company'], [$pn, 'faxnumber'], [$serv, 'server'], [$mailnot, 'mail']) { 
	if (member($r->[1], qw(res paper))) {
	    $r->[0]->set_popdown_strings(values %{$e{$r->[1]}});
	    $h{uc($r->[1])} and $r->[0]->entry->set_text($e{$r->[1]}{$h{uc($r->[1])}});
	} else { 
	    $h{uc($r->[1])} and $r->[0]->set_text($h{uc($r->[1])});
	}
    }
    $hbox->set_sensitive($state); $usecover->set_active($state); $coverfile->entry->set_text($filecov);
    # This is just shit
    $pname->get_text or $pname->set_text($ENV{USER});
    $serv->get_text or $serv->set_text('localhost');
    $w->show_all;
}

sub faxServer() {
    my $w = newWindow(N("Configure a Fax Server"), 1);
    $w->set_size_request(270, 150);
    gtkadd($w,
	    gtkpack_(Gtk2::VBox->new(0, 5),
		     1, insertText(N("You are about to configure a Fax server. This action requires root capabilities") .
 "\n\n" . N("Click on Ok and supply root password or cancel if you don't know the root password")
				  ),
		     0, gtkpack(Gtk2::HBox->new(1, 50),
			       map {
				   my $r = $_->[1];
				   gtksignal_connect(Gtk2::Button->new_from_stock($_->[0]), clicked => sub {
							 if (!$r) {
							     system("$exec_server &");
							 }
							 $w->destroy;
                                });
			       } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ])) 
		    )
	  );
    $w->show;
}

sub faxSend() {
    # Sanity checks before sending faxes
    my %h = getVarsFromSh($fax->{settings});
    my ($cmd, $date);
    $cmd = $exec_sendfax . " -n";
    $error = 0;
    my $num =  $fax->{num2fax}->entry->get_text;
    my ($rnum, $company, $name) = getNameFromFile($fax->{addressbook}, $num);
    my $file = $fax->{file2fax}->entry->get_text;
    my $mail = $h{MAIL};
    $fax->{sendat_rb}->get_active and $date = getGMTDate();
    $num && $file or raiseError(N("Please supply a Fax Number or a File to fax"));
    if (!$error) {
	$h{SERVER} and $cmd .= " -h $h{SERVER}";
	$cmd .= $h{RES} eq 'low' ? " -l" : " -m";
	$cmd .= $date ? " -a '$date'" : '';
	$cmd .= $company ? " -x $company" : '';
	$mail and $cmd .= " -f $mail";
	$cmd .= " -d";
	$cmd .= $rnum ? " $name" . '@' . $rnum : " $num";
	$cmd .= " $file";
    }
    -e $exec_sendfax or raiseError(N("Sendfax client not found.\nCheck your hylafax-client package installation\n"));
    !$error and system($cmd);
    $error = 0;
}

sub getGMTDate() {
    my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    my @d = split('/', $fax->{date_e}->get_text); my $h = $fax->{hour_e}->get_text;
    my $date = $h . " " . $months[$d[1] - 1] . " " . $d[2];
    $date;
}

sub getNameFromFile {
    my ($file, $num) = @_;
    my ($str, @f);
    foreach (cat_($file)) {
	$str = $_ if /\Q$num/;
    }
    chomp($str);
    @f = split(':', $str);
    @f;
}

sub installPkg {
    my $pkg = shift;
    my $w = newWindow(N("Install client package"), 1);
    gtkadd($w, 
	   gtkpack_(Gtk2::VBox->new(0, 2),
		    1, Gtk2::Label->new(N("Drakfax needs sendfax to send faxes\nDo you want to install hylafax-client package?\n")),
		    0, Gtk2::HSeparator->new,
		    0, gtkpack(Gtk2::HBox->new(1, 20),
			       map {
				   my $r = $_->[1];
				   gtksignal_connect(Gtk2::Button->new_from_stock($_->[0]), clicked => sub {
							 system("drakhelp_inst $pkg") if !$r;
							 $w->destroy;
                                });
			       } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ]))
		   )
	  );
    $w->show_all;
}

sub Sendq {}

sub Doneq {}

sub Recvq {}

sub Refreshq {}

sub insertText {
    my $text = shift;
    my $t;
    $t = create_scrolled_window(gtktext_insert(Gtk2::TextView->new, $text));
    $t;
}

sub getKeysFromValues {
    my ($hash, $widget) = @_;
    find { $hash->{$_} eq $widget->entry->get_text } keys %$hash;
}

sub getSettings() {
    setState([$_, $coverstate]) foreach qw(usecover_cb hboxcover);
    buildRefreshList();
}

sub setState {
    foreach my $l (@_) { if ($l->[0] =~ /cb/) { $fax->{$l->[0]}->set_active($l->[1]) } else { $fax->{$l->[0]}->set_sensitive($l->[1]) } }
}

sub setPage { 
    my ($notebook, $page) = @_;
    $fax->{$notebook} ? $fax->{$notebook}->set_current_page($page) : $notebook->set_current_page($page);
}

sub browseFile {
    my $ent = shift;
    my $dlg = new Gtk2::FileSelection(N("Path selection"));
    $dlg->set_modal(1);
    $dlg->set_transient_for($fax->{wnd}{real_window});
    $dlg->show;
    $dlg->set_filename($fax->{$ent}->entry->get_text);
    $dlg->cancel_button->signal_connect(clicked => sub { $dlg->destroy });
    $dlg->ok_button->signal_connect(clicked => sub {
					$fax->{$ent}->entry->set_text($dlg->get_filename);
					$dlg->destroy;
				    });
}

sub getNum {
    my ($name, $company, $faxnum) = @_;
    my $w = newWindow(N("Add to Address Book"), 1);
    my ($fn, $cp, $fnum);
    gtkadd($w, 
	   gtkpack_(Gtk2::VBox->new(0, 2),
		    1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings =>5 },
					[ N("Full Name") . " :", $fn = Gtk2::Entry->new ],
					[ N("Company") . " :", $cp = Gtk2::Entry->new ],
					[ N("Fax Number") . " :", $fnum = Gtk2::Entry->new ]
				       ),
		    0, gtkpack(Gtk2::HBox->new(1, 20),
			       map {
				   my $r = $_->[1];
				   gtksignal_connect(Gtk2::Button->new_from_stock($_->[0]), clicked => sub {
							 if (!$r) {
							     $error = 0; my $valnum = $fnum->get_text;
							     $valnum or raiseError(N("Please Provide A Fax Number at least"));
							     !$error and add2File($fax->{addressbook}, $valnum, $cp->get_text, $fn->get_text);
							 }
							 !$error and $w->destroy; $error = 0 });
			       } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ]))
		   )
	  );
    $fn->set_text($name) if $name; $cp->set_text($company) if $company; $fnum->set_text($faxnum) if $faxnum;
    $w->show_all;
}

sub dateEdit() {
    my $Calbut = Gtk2::Button->new;
    gtkpack_(my $hbox = Gtk2::HBox->new(0, 3),
	      0, Gtk2::Label->new(N("Calendar")),
	      0, Gtk2::Arrow->new('down', 'in')
	    );
    gtkadd($fax->{popup_c} = Gtk2::Window->new('popup'),
	    gtkadd(gtkset_shadow_type(Gtk2::Frame->new(""), 'out'),
		   gtkpack($fax->{calendar} = Gtk2::Calendar->new)
		  )
	  );
    $fax->{popup_c}->set_size_request(250, 210);
    $fax->{popup_c}->set_resizable('false');
    $fax->{calendar}->display_options([qw(show_heading
                                   show_day_names
                                   week_start_monday)]);
    $fax->{calendar}->signal_connect(day_selected_double_click => sub {
					 my ($calendar) = @_;
					 my ($y, $m, $d) = $calendar->get_date;
					 $fax->{date_e}->set_text(join('/', $y, sprintf("%02d", ($m+1)), sprintf("%02d", $d)));
					 $fax->{popup_c}->hide; $popit = !$popit;
				     });
    $fax->{calendar}->signal_connect('day_selected' || 'month-changed' => sub {
					 my ($calendar) = @_;
					 my ($y, $m, $d) = $calendar->get_date;
					 $fax->{date_e}->set_text(join('/', $y, sprintf("%02d", ($m+1)), sprintf("%02d", $d)));
				     });
    $Calbut->add($hbox);
    $Calbut;
}

sub hourEdit {
    my ($min, $max) = @_;
    my ($buf, $bufh);
    my $Houroptm = Gtk2::OptionMenu->new;
    my $menu = Gtk2::Menu->new;
    foreach my $i (($min .. $max)) {
	$buf = sprintf("%02d:00", $i);
	my $menuitem = Gtk2::MenuItem->new_with_label($buf);
	$menu->append($menuitem);
	$menuitem->show;
	my $submenu = Gtk2::Menu->new;
	foreach my $j (0, 15, 30, 45) {
	    $bufh = sprintf("%02d:%02d", $i, $j);
	    my $mi = Gtk2::MenuItem->new_with_label($bufh);
	    $submenu->append($mi);
	    $mi->signal_connect('activate' => sub { $fax->{hour_e}->set_text($mi->child->get_label) });
	    $mi->show;
	    }
	$menuitem->set_submenu($submenu);
	}
    $Houroptm->set_menu($menu);
    $Houroptm;
}

sub entryDate() {
    my ($_Second, $Minute, $Hour, $Day, $Month, $Year, $_WeekDay, $_DayOfYear, $_IsDST) = localtime();
    my %t;
    # Let's do some Text formatting
    foreach my $l (['m', $Month], ['d', $Day], ['h', $Hour], ['mn', $Minute]) {
	$t{$l->[0]} = sprintf("%02d", $l->[1]); 
	$l->[0] eq 'm' and $t{$l->[0]}++;
    }
    $fax->{date_e}->set_text(join('/', ($Year + 1900), $t{m}, $t{d}));
    $fax->{hour_e}->set_text(join(':', $t{h}, $t{mn}));
}

sub createToolbar {
    my ($t) = @_;
    foreach (@{ $toolbars{$t} }) {
	my $pix = $pixdir . $_->[2] . '.png';
	defined $fax->{$t} and $fax->{$t}->append_item($_->[0], $_->[1], $_->[2], -e $pix ? Gtk2::Image->new_from_file($pix) : Gtk2::Image->new_from_stock($_->[2], 'button'), $_->[3], $fax->{$t}); 
    }
}

sub buildRefreshList {
    my $file = shift || $fax->{addressbook};
    -e $file or return;
    my @pb = qw(phone org contact);
    $addphonetree_model->clear;
    foreach (cat_($file)) {
	my %pl;
	s/#.*//; # remove comments
        @pl{@pb} = split ':'; 
        chomp $pl{contact};
	$addphonetree_model->append_set([ if_($pl{phone}, 0 => $pl{phone}), if_($pl{org}, 1 => $pl{org}), if_($pl{contact}, 2 => $pl{contact}) ]);
    }
}

sub add2File {
    my ($file, $nm, $comp, $faxn) = @_;
    my $str = join(':', $nm, $comp, $faxn);
    member($str, cat_($file)) and raiseError("Entry already in Phonebook");
    !$error and append_to_file($file, $str, "\n");
    buildRefreshList();
    $error = 0;
}

sub delFromFile {
    my ($file, $str) = @_;
    substInFile {
	my $l = chomp_($_);
	if ($l eq $str) { $_ = '' }
    } $file;
    buildRefreshList();
}

sub createTree {
    my ($tree_model) = @_;
    my $tree = Gtk2::TreeView->new_with_model($tree_model);
    $tree->get_selection->set_mode('browse');
    $tree->set_headers_visible(1);
    $tree->set_rules_hint(1);
    my $menu_treeview = Gtk2::Menu->new;
    my @menu_treeview_actions = ([ 'select', N("Select") ], [ 'delete', N("Delete entry") ]);
    foreach (@menu_treeview_actions) {
	my ($action, $text) = @$_;
	my %actions; %actions = (
				 select => sub {
				     my (undef, $iter) = $tree->get_selection->get_selected;
				     $iter and $fax->{num2fax}->entry->set_text($tree_model->get($iter, 0));
				 },
				 delete => sub {
				     my $w = newWindow(N("Deleting phonebook entry"), 1);
				     gtkadd($w,
					    gtkpack_(Gtk2::VBox->new(0, 3),
						     1, Gtk2::Label->new(N("Do you want to delete this entry from phonebook?")),
						     0, Gtk2::HSeparator->new,
						     0,  gtkpack(Gtk2::HBox->new(1, 20),
								 map {
								     my $r = $_->[1];
								     gtksignal_connect(Gtk2::Button->new_from_stock($_->[0]), clicked => sub {
											   if (!$r) {
											       my (undef, $iter) = $tree->get_selection->get_selected;
											       my $str = join(':', ($tree_model->get($iter, 0), $tree_model->get($iter, 1), $tree_model->get($iter, 2)));
											       delFromFile($fax->{addressbook}, $str);
											   }
											   $w->destroy });
								 } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ]))
						    )
					   );
				     $w->show_all;
				 }
				);
	$menu_treeview->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($text)), activate => sub { $actions{$action}->() }));
    }
    $tree->signal_connect(button_press_event => sub {
			       my (undef, $event) = @_;
			       my (undef, $iter) = $tree->get_selection->get_selected;
			       return unless $iter;
			       getNum(getIters($tree_model, $iter, 2)) if $event->type eq '2button-press';
			       $_[1]->button == 3 and  $menu_treeview->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time);
			   });
    $tree->signal_connect(key_press_event => sub {
			       my (undef, $event) = @_;
			       my (undef, $iter) = $tree->get_selection->get_selected;
			       return unless $iter;
			       getNum(getIters($tree_model, $iter, 2)) if $event->keyval == $Gtk2::Gdk::Keysyms{Return};
			   });
    $tree;
}

sub getIters {
    my ($model, $iter, $_maxcol) = @_;
    my @items;
    unshift @items, $model->get($iter, $_) foreach 0, 1, 2;
    @items;
}

sub getlargestSize {
  my $id = shift;
  my $best_size = 'invalid';
  my $best_pixels = 0;

  my $set = Gtk2::IconFactory->lookup_default($id);

  foreach my $size ($set->get_sizes) {
     my ($width, $height) = Gtk2::IconSize->lookup($size);
     next unless defined $height;
     if ($width * $height > $best_pixels) {
	 $best_size = $size;
	 $best_pixels = $width * $height;
     }
  }
  return $best_size;
}

sub newWindow {
    my ($label, $mode) = @_;
    my $win = ugtk2->new($label);
    my $w = $win->{window};
    $w->signal_connect(delete_event => sub { $w->destroy });
    $w->set_position('center');
    $w->set_modal($mode);
    $w->{parent} = $win; # fix refcounting (#21946)
    $w;
}

sub raiseError {
    my $w = newWindow(N("Error"), 1);
    $error = 1;
    gtkadd($w,
           gtkpack_(Gtk2::VBox->new,
                    1, Gtk2::Label->new($_[0]),
                    0, Gtk2::HSeparator->new,
                    0, gtksignal_connect(Gtk2::Button->new_from_stock(N("Ok")), clicked => sub { $w->destroy })
                   ),
          );
    $w->show_all;
}

sub About() {
    my $d =  gtkset_border_width(Gtk2::Dialog->new, 5);
    $d->set_size_request(350,200);
    $d->set_transient_for($fax->{mw}{real_window});
    $d->set_position('center-always');
    $d->set_title(N("About Drakfax"));
    $d->action_area->pack_start(gtkadd(Gtk2::HButtonBox->new,
				       gtksignal_connect(Gtk2::Button->new(N("Close")), clicked => sub { $d->destroy })
				      ),
				0,0,0);
    gtkpack_($d->vbox,
             (0, gtkset_size_request(Gtk2::Banner->new("$pixdir/about.png", N("Fax configuration"), { txt_ypos => 50 }), -1, 100)),
             0, Gtk2::Label->new(""),
             0, Gtk2::Label->new(N("Copyright (C) 2004 Mandriva SA") . "\n"),
             0, Gtk2::Label->new(""),
             1, 
	    );
    gtkset_modal($d, 1);
    $d->show_all;
}

sub quitGlobal() {
    Gtk2->main_quit;
}
