#!/usr/bin/perl
# Date: 14-02-2001      Alex DU <dxiaoming@mandrakesoft.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.
#
# Changelog:
# 14-01-2001    	Alex DU
# 31-01-2001		Alex DU
#					- change the format of configuration file.
#					- make use of libDrakeX instead including it.
#					- add the history feature.
#					- add default action. (enter key to run the program)
# 01-02-2001		Alex DU
#					- can start xim input server.
use Gtk;
use Gtk::Atoms;
use Locale::GetText;
use POSIX;

use strict 'vars';
# the $usrlang and @history will be initialized by the config file.
use vars qw($mylang @history);
use lib qw(/usr/lib/libDrakX);
use lang;
use common qw(:common);

my $HISTORY_LENGTH = 10;
my $aprc = $ENV{'HOME'}."/.aprc";
my $file = "";

# initializations
setlocale(LC_ALL, "");
Locale::GetText::textdomain("appl");
import Locale::GetText I_;
init Gtk;

# dirty sub find installed languages
sub get_langs {
    my ($prefix) = @_;
    (-e "$prefix/etc/rpm/macros") || die "$prefix/etc/rpm/macros NO SUCH FILE ";
    open L ,"<$prefix/etc/rpm/macros";
    while (<L>) {
	s/%_install_langs (.*)/$1/ && return [split(":")];
    }
}

#####
#  Subroutine
#	read user configuration from file.
#####
sub read_config {
    if (-e $aprc) {
	require "$aprc";
    }
}

#####
#  Subroutine
#	save user configuration to file.
#####
sub save_config {
    # print "DEBUG: $mylang, @history\n";
    open RC, ">$aprc";
    print RC "# AL resource file\n";
    print RC "\$mylang=\"$mylang\";\n";
    print RC "\@history=(\n\t\'". join ("',\n\t\'", @history) ."\',\n\t);\n";
    print RC "1;\n";
    close RC;
}

#####
#  Subroutine
#	Add an element to the history list. 
#	@history is seen as a global var.
#
#	Don't forget to update the combo box!!!
#####
sub history_add {
    my($prog) = @_;
    
    @history = grep (!/^$prog/, @history);
    if (unshift(@history, "$prog") > $HISTORY_LENGTH) { 
	pop(@history);
    } 
}

#####
#  Subroutine
#	find current available locales and return their names as a list.
#####
#sub get_lang_list {
#	my(@list);
#	foreach (get_langs()) {
#	  foreach (lang::list()) {
#	    @list = (lang::lang2text($_), @list);
#	  }
#	}
#	@list = sort(@list);
#	return @list;
#}
sub get_lang_list {
    my(@list);
    foreach my $l (@{get_langs("")}) {
	foreach (lang::list()) {
	    substr($l,0,2) eq substr($_,0,2) or next;
	    ($l eq $_) or next;
	    @list = (lang::lang2text($_), @list);
	}
    }
    @list = sort(@list);
    return @list;
}

#####
#  Subroutine
#	do the verso-vice as the lang2text()
#####
sub text2lang {
    my($text) = @_;
    foreach (lang::list()) {
	if (lang::lang2text($_) eq $text) { 
	    return $_;
	}
    }
    return undef;
}

#####
#  Subroutine
#	take the program name and locale as parameters, and run the program.
#####
sub runit {
    my ($p, $l) = @_;
    my($lc_all)   = $l;
    my($lang)     = lang::lang2LANG($l);
    my($language) = lang::lang2LANGUAGE($l);
    
    # get the XIM variables.
    my($ximinfo) = lang::getxim($lang);
    my($xim) = $$ximinfo{XIM};
    my($xim_prog) = $$ximinfo{XIM_PROGRAM};
    my($xmod) = $$ximinfo{XMODIFIERS};

    # if the $xim_prog is not running or XMODIFIERS is different from the current one.
    # we run it.
    my($running) = `/sbin/pidof $xim_prog`;
    chop($running);
    
    if(($running eq "") || ("\"".$ENV{XMODIFIERS}."\"" ne $xmod)) {
	system "LC_ALL=$lc_all LANG=$lang LANGUAGE=$language $xim_prog&\n";
	system "LC_ALL=$lc_all LANG=$lang LANGUAGE=$language XIM=$xim XMODIFIERS=$xmod $p&\n";
#		$ENV{XIM}         = $xim;
#		$ENV{XIM_PROGRAM} = $xim_prog;
#		$ENV{XMODIFIERS}  = $xmod;
    }
    else {
#	print("ENV: $ENV{XIM}, $ENV{XIM_PROGRAM}, $ENV{XMODIFIERS}\n");
#	print "DEBUG: $xim, $xim_prog, $xmod\n";
	system "LC_ALL=$lc_all LANG=$lang LANGUAGE=$language XIM=$xim XMODIFIERS=$xmod $p&\n";
    }
}

#####
#  Subroutine
#	run program in command line.
#####
sub console_run {
    my($progname) = @_;
    my(@fields) = split(' ', $progname);
    my($file) = $fields[0];
    my($exist) = `which $file`;
    
    chop($exist);
    unless(-e $exist && -x $exist) {
	print("\n  Error: \'$file\' not found or is not executable.\n"); 
	return 0;
    }
    my($key) = text2lang($mylang);
    runit($progname, $key);
    return 1;
}

#####
#  Subroutine
#	run xwindow apps. If the program does ont exist, so warn the user.
#####
sub window_run {
    my($progname, $locale) = @_;
    
    my(@fields) = split(' ', $progname);
    my($file) = $fields[0];
    my($exist) = `which $file`;
    
    chop($exist);
    unless(-e $exist && -x $exist) {
	my($dialog) = new Gtk::Dialog();
	$dialog->set_policy( 0, 0, 1);
	$dialog->set_modal(true);
	$dialog->set_position('center');
	$dialog->show();
	my($button) = new Gtk::Button("Close");
	$button->signal_connect("clicked", sub {destroy $dialog});
	$dialog->action_area->pack_start( $button, 0, 0, 0 );
	$button->show();
	my($label) = new Gtk::Label(I_("\n\nError: \'$file\' not found or is not executable.\n\n"));
	$dialog->vbox->pack_start( $label, 1, 1, 0 );
	$label->show();
	return 0;
    }
    
    runit($progname, $locale);
    return 1;
}

########################################################
#sub file_selection_ok {
#	my($widget, $fs) = @_;
#	Gtk->print($fs->get_filename . "\n");
#	$fs->destroy($fs);
#}
#
#sub file_select {
#	my($fs_window);
#	if (not defined $fs_window) {
#		$fs_window = new Gtk::FileSelection "File selection dialog";
#		$fs_window->position(-mouse);
#		$fs_window->signal_connect("destroy", \&destroy_window, \$fs_window);
#		$fs_window->signal_connect("delete_event", \&destroy_window, \$fs_window);
#		$fs_window->ok_button->signal_connect("clicked", \&file_selection_ok, $fs_window);
#		$fs_window->cancel_button->signal_connect("clicked", \&destroy_window, $fs_window;});
#	}
#	if (!visible $fs_window) {
#		show $fs_window;
#	} else {
#		destroy $fs_window;
#	}
#}
########################################################

######
#  MAIN PROCEDURE
######
sub main {
    my(@langlist) = get_lang_list;
    my($argc);
    my($run_button);
    
    read_config();
#  `echo $ARGV[0] > /tmp/debug`;
    if (($argc = @ARGV) > 0) {
	console_run ($ARGV[0]);
	exit (0);
    }
    
    ######
    #   Main Widget is created here.
    ######
    my($main_win) = new Gtk::Window('toplevel');
    $main_win->signal_connect("destroy" => \&Gtk::main_quit);
    $main_win->signal_connect("delete_event" => \&Gtk::false);
    $main_win->set_title(I_("Application Launcher in Locale"));
    $main_win->border_width(0);
    $main_win->set_policy( 0, 0, 1);
    $main_win->set_uposition(20, 20);
    $main_win->set_usize(320, 125);
    
    my($box) = new Gtk::VBox 0, 0;
    $main_win->add($box);
    $box->show;
    
    #####
    #   vbox -> hbox -> label1, entry
    #        -> hbox -> label2, combo
    #####
    my($vbox) = new Gtk::VBox 0, 10;
    $vbox->border_width(10);
    $box->pack_start($vbox, 1, 1, 0);
    $vbox->show;
    
    my($hbox) = new Gtk::HBox 0, 0;
    $vbox->pack_start($hbox, 1, 1, 0);
    $hbox->show;
    
    my($label1) = new Gtk::Label I_("   Run:");
    $label1->set_alignment(0, 0.5);
    $hbox->pack_start($label1, 1, 1, 0);
    $label1->show;
    
    my($history) = new Gtk::Combo;
    $history->set_use_arrows_always(1);
    $history->disable_activate();
    $history->set_popdown_strings(@history);
    $history->entry->set_text(@history[0]);
    $history->entry->signal_connect("key_press_event", sub {
	my (undef, $e) = @_;
	local $_ = chr ($e->{keyval} & 0xff);
	if ( /\r/ ) {
	    $run_button->signal_emit_by_name("clicked");
	}
    });
    $hbox->pack_start($history, 1, 1, 0);
    $history->show;
    
#  my($fs_button) = new Gtk::Button "...";
#  $fs_button->signal_connect("clicked", \&file_select);
#  $hbox->pack_start($fs_button, 1, 1, 0);
#  $fs_button->show;
    
    $hbox = new Gtk::HBox 0, 0;
    $vbox->pack_start($hbox, 1, 1, 0);
    $hbox->show;
    
    my($label2) = new Gtk::Label I_("Locale:");
    $label2->set_alignment(0, 0.5);
    $hbox->pack_start($label2, 1, 1, 0);
    $label2->show;
    
    my($cb) = new Gtk::Combo;
    $cb = new Gtk::Combo;
    $cb->set_popdown_strings(@langlist);
    $cb->entry->set_text($mylang);
    $hbox->pack_start($cb, 1, 1, 0);
    $cb->show;
    
    my($separator) = new Gtk::HSeparator;
    $separator->show;		
    $box->pack_start($separator, 0, 1, 0);
    
    $hbox  = new Gtk::HButtonBox;
    $hbox->border_width(20);
    $box->pack_start($hbox, 1, 1, 0);
    $hbox->show;
    
    $run_button = new Gtk::Button(I_("Run"));
    $main_win->set_focus($run_button);
#  $main_win->set_default($run_button);
    $run_button->signal_connect("clicked", sub {
	my($text) = $cb->entry->get_text();
	my($key) = text2lang($text);
	my($prog) = $history->entry->get_text();
	$mylang = $text;
	history_add($prog);
	# update the history combo box.
	$history->set_popdown_strings(@history);
	window_run($prog, $key);
    });
    $hbox->add($run_button);
    $run_button->show;
    
    my($cancel_button) = new Gtk::Button I_("Quit");
    $cancel_button->signal_connect("clicked", sub {
	my($text) = $cb->entry->get_text();
	my($key) = text2lang($text);
	$mylang = $text;
	destroy $main_win
	});
    $hbox->add($cancel_button);
    $cancel_button->show;
    
    if (!visible $main_win) {
	show $main_win;
    } else {
	destroy $main_win;
    }
    
    main Gtk;
    save_config();
}

main ();
