#!/usr/bin/perl -w
# a simple Gtk/Perl app to switch gtk-themes on the fly
# Released under GNU GPL
# muhri <muhri@muhri.net>
$version = "0.4";
use File::Basename qw/basename/;
$me = basename($0);
$fontchanged = 0;

	if (!$ARGV[0]) { 
		usage();
	} else {
		parse_args();
	}	


####### subs ##########

sub parse_args 
{

	if ($ARGV[0] =~ /\-\-dock/) {
		dock();
	
	} else { 

		if ($ARGV[0] =~ /(.*).tar.gz/i) {		
			install();
			exit;
		}	
		if (! -f "$ARGV[0]/gtk/gtkrc") {
			die "The dir you passed me does not seem to contain a gtk theme!\n";
		}
	}	


	if ($ARGV[1] and $ARGV[1] =~ /preview/) {
		preview("1");
	} else {
		switch();
	}	

}

sub usage {
	die "usage: $me gtk-theme-dir --preview (if you want to preview)\nor $me --dock to start in dock-mode\nor $me theme.tar.gz to install a .tar.gz\nor $me theme.tar.gz --preview to preview after installing\nor $me switch theme.tar.gz --switch to switch after installing\n";
}

sub install
{
	if (!-f "$ARGV[0]") {
		die "could not find the tar you passed me\n";
	}
	if (!-e "$ENV{'HOME'}/.themes") {
		print("Making local themes dir at $ENV{'HOME'}/.themes\n");
		mkdir($ENV{'HOME'}."/.themes",0755);
	}
	open(TMP,"tar --directory=$ENV{'HOME'}/.themes -xvzf $ARGV[0] 2>&1 |");
	print("Installing $ARGV[0]\n");
	while (<TMP>) {
		if (/error/i) {
			die "tar said: $_\n";
		}
		print("*");
	}
	print("\n");
	close(TMP);
	if (($ARGV[1] && $ARGV[1] =~/preview/) or ($ARGV[1] && $ARGV[1]=~/switch/)) {
		$ARGV[0] =~ s/\-1.(.*)//g;
		$ARGV[0] = basename($ARGV[0]);
		$ARGV[0] = "$ENV{'HOME'}/.themes/$ARGV[0]";
		if ($ARGV[1] =~/preview/) {
			preview("1");
		} elsif ($ARGV[1]=~/switch/) {
			switch();
		}	
	}
}      
	
sub switch 
{
	
	if ($fontchanged == 0) { 
		open(TMP,"$ENV{'HOME'}/.gtkrc");
		@array = <TMP>;
		close(TMP);
		$array[1] = "include \"$ARGV[0]/gtk/gtkrc\"\n\n";
		open(TMP,">$ENV{'HOME'}/.gtkrc");
		foreach (@array) { 
			print TMP $_; 
		}
	close(TMP);
	
	} elsif ($fontchanged == 1) {
		open(TMP,">$ENV{'HOME'}/.gtkrc");
		print TMP "# -- THEME AUTO-WRITTEN DO NOT EDIT\n";
		print TMP "include \"$ARGV[0]/gtk/gtkrc\"\n\n";	
		print TMP "style \"user-font\"\n";
		print TMP "{\n";
		print TMP "  font=\"$font\"\n";
		print TMP "}\n";
		print TMP "widget_class \"*\" style \"user-font\"\n\n";
		print TMP "include \"$ENV{'HOME'}/.gtkrc.mine\"\n\n";
		print TMP "# -- THEME AUTO-WRITTEN DO NOT EDIT\n";
		close(TMP);
	}	
    	
	if (-f "./gthemeswitch") {
		system("./gthemeswitch 1");
	} else {
		system("gthemeswitch 1");
	}	
}

sub preview 
{
	my ($flag) = @_;
	if ($flag == 1) {
		unless(eval 'use Gtk; init Gtk;') {
			die " couldn't find Gtk::Perl, dont use preview!\n"
		}	
	}
	Gtk::Rc->parse("$ARGV[0]/gtk/gtkrc");	
	$win = new Gtk::Window("toplevel");
	$win->set_default_size(200,250);
	$win->set_title("Theme Preview $ARGV[0]");
	$win->set_policy(1,1,0);
	$win->show;
	if ($flag == 1) {
		$win->signal_connect("destroy", sub { $win->destroy; Gtk->exit(0) });
	} else {
		$win->signal_connect("destroy", sub { $win->destroy });
	}	
	$vbox=new Gtk::VBox(0,0);
	$vbox->show;
	$notelabel = new Gtk::Label("Page 1");
	$notelabel->show();
	$notebook=new Gtk::Notebook;
	$notebook->show();
	$win->add($notebook);
	$notebook->append_page($vbox,$notelabel);
	$label = new Gtk::Label("Label");
	$label->show;
	$vbox->pack_start($label,0,0,0);
	$button = new Gtk::Button("Button");
	$button->show;
	$vbox->pack_start($button,0,0,0);
	$toggle = new Gtk::ToggleButton("Toggle Button");
	$toggle->show;
	$vbox->pack_start($toggle,0,0,0);
	$check = new Gtk::CheckButton("CheckBox");
	$check->show;
	$vbox->pack_start($check,0,0,0);
	$radio = new Gtk::RadioButton("Radio 1");
	$radio->{'2'} = new Gtk::RadioButton("Radio2",$radio);
	$radio->{'3'} = new Gtk::RadioButton("Radio3",$radio->{'2'});
	$radio->show;
	$radio->{'2'}->show;
	$radio->{'3'}->show;
	$radiobox = new Gtk::HBox(0,0);
	$radiobox->show;
	$radiobox->pack_start($radio,0,0,0);
	$radiobox->pack_start($radio->{'2'},0,0,0);
	$radiobox->pack_start($radio->{'3'},0,0,0);
	$vbox->pack_start($radiobox,0,0,0);
	$sw = new Gtk::ScrolledWindow(undef,undef);
	$sw->set_policy('automatic','automatic');
	$sw->show;
	@titles=("Column 1","Column 2");
	$clist = new_with_titles Gtk::CList(@titles);
       	for ($i=0;$i<5;$i++) {
		$clist->append("blah 1","blah2");
	}
	$clist->show;
	$sw->add($clist);
	$vbox->pack_start($sw,1,1,0);
	$buttonbox = new Gtk::HBox(0,0);
	$buttonbox->show;
	$vbox->pack_start($buttonbox,0,0,0);
	$font_but = new Gtk::Button("Change Font");
	$font_but->signal_connect("clicked" => \&change_font);
	$ok = new Gtk::Button("Ok");
	if ($flag ==1) {
		$ok->signal_connect("clicked", sub { switch(); $win->destroy; Gtk->exit(0)});
	} else {
		$ok->signal_connect("clicked", sub { switch(); $win->destroy; });
	}
	$cancel = new Gtk::Button("Cancel");
       	if ($flag==1) {
		$cancel->signal_connect("clicked", sub { $win->destroy; Gtk->exit(0); });
	} else {
		$cancel->signal_connect("clicked", sub {$win->destroy});
	}
	$ok->show;
	$cancel->show;
	$font_but->show;
	$buttonbox->pack_start($font_but,1,1,0);
	$buttonbox->pack_start($ok,1,1,0);
	$buttonbox->pack_start($cancel,1,1,0);
	$vbox=new Gtk::VBox(0,0);
	$vbox->show();
	$notelabel = new Gtk::Label("Page 2");
	$notelabel->show();
	$notebook->append_page($vbox,$notelabel);
	$label2 = new Gtk::Label("Insensitive Label");
	$label2->show();
	$label2->set_sensitive(0);
	$button = new Gtk::Button("Insensitive Button");
	$button->show();
	$button->set_sensitive(0);
	$sw = new Gtk::ScrolledWindow(undef,undef);
	$sw->set_policy('automatic','automatic');
	$sw->show();
	$text=new Gtk::Text(undef,undef);
	$text->set_editable(1);
	$text->show();
	$sw->add($text);
	$body = "Type sometext here\nto check if your\ntheme has a problem\n with the textwidget\nAlso rightclick here\nfor a popup menu sample\n";	
	$text->insert("","","",$body);
	$text->signal_connect("button_press_event" => \&rightclick);
	$text->{'popup'} = new Gtk::Menu();
	$text->{'popup'}->show();
	$text->{'popup'}->{'1'} = new Gtk::MenuItem("Menu Entry 1");
	$text->{'popup'}->{'1'}->show();
	$text->{'popup'}->{'2'} = new Gtk::MenuItem("Menu Entry 2");
	$text->{'popup'}->{'2'}->show();
	$text->{'popup'}->{'3'} = new Gtk::MenuItem("Menu Entry 3");
	$text->{'popup'}->{'3'}->show();
	$text->{'popup'}->append($text->{'popup'}->{'1'});
	$text->{'popup'}->append($text->{'popup'}->{'2'});
	$text->{'popup'}->append($text->{'popup'}->{'3'});
	$vbox->pack_start($label2,0,0,0);
	$vbox->pack_start($button,0,0,0);
	$vbox->pack_start($sw,1,1,0);
	$notelabel = new Gtk::Label("About");
	$notelabel->show();
	$vbox = new Gtk::VBox(0,0);
	$vbox->show();
	$notebook->append_page($vbox,$notelabel);
	$about = new Gtk::Label("Gtk Theme Switch version $version\nby Maher Awamy\n<muhri\@muhri.net>\nhttp://www.muhri.net\n");
	$about->show();
	$vbox->pack_start($about,1,1,0);			 
	if ($flag ==1) {
		main Gtk;
	}
}

sub rightclick
{
	my ($widget,$event,$data) = @_;
	if (($event->{button} == 3) && ($widget->{'popup'})) {
		$text->{'popup'}->popup(undef,undef,$event->{button},1);
	}
	return 1;
}	

sub change_font
{

        my ($font_dlg);
	$font_dlg = new Gtk::FontSelectionDialog("Select Font");
	$font_dlg->position(-mouse);
	$font_dlg->set_preview_text("Gtk Switch Theme");
	open(TMP,"$ENV{'HOME'}/.gtkrc");
       	@file = <TMP>;
	close(TMP);
	foreach(@file) {
		if ($_=~ /font\=/) {
			chomp;
			$current_font = $_;
			$current_font=~ s/font\=//;
			$current_font=~ s/\"//g;
		}
	}
	if ($current_font && $current_font ne "") {
		$font_dlg->set_font_name($current_font);
	}	
	$font_dlg->signal_connect("destroy", sub {$font_dlg->destroy;});
	$font_dlg->ok_button->signal_connect("clicked" => \&set_font, $font_dlg );
	$font_dlg->cancel_button->signal_connect("clicked", sub {$font_dlg->destroy});
        $font_dlg->show;
									
}									
	
sub set_font
{
	my ($widget,$font_dialog) = @_;
	$fontchanged = 1;
	$font = $font_dialog->get_font_name();
	$style = new Gtk::Style;
	$style->font(Gtk::Gdk::Font->load($font));
	$label->set_text("Font changed");
	$label->set_style($style);
	$font_dialog->destroy;
}

sub dock
{
       	unless(eval 'use Gtk; init Gtk;') {
		die " couldn't find Gtk::Perl, dont use preview!\n"
	}	
	
	$dialog = new Gtk::Dialog;
	$dialog->signal_connect("destroy", sub { $dialog->destroy; Gtk->exit(0);});
	$dialog->set_title("Theme Switch Dock");
	$dialog->set_position(-mouse);
	$dialog_label = new Gtk::Label("Theme:  ");
	$dialog_label->show;
	$gtk_dir = Gtk::Rc->get_theme_dir();
	%dirs = ();
	opendir(DIR,$gtk_dir);
	while (defined (my $dir = readdir DIR)) {
		next if $dir =~ /^\.\.?$/;
		next if (! -f "$gtk_dir/$dir/gtk/gtkrc");
		$dirs{$dir} = $gtk_dir;
	}	
	closedir(DIR);
	$gtk_home_dir = "$ENV{'HOME'}/.themes/";
	opendir(DIR,$gtk_home_dir);
	while (defined (my $dir = readdir DIR)) {
		next if $dir =~ /^\.\.?$/;
		next if (! -f "$gtk_home_dir/$dir/gtk/gtkrc");
		$dirs{$dir} = $gtk_home_dir;
	}	
	closedir(DIR);
	$dialog_entry = new Gtk::Combo;
	$dialog_entry->set_popdown_strings(sort keys(%dirs));
      	$dialog_entry->set_usize(200,20);
	$dialog_entry->show;
	$hbox = new Gtk::HBox(0,5);
	$hbox->show;
	$dialog->vbox->pack_start($dialog_label,0,0,0);
	$dialog->vbox->pack_start($dialog_entry,0,0,0);
	$dialog->show;
	$apply = new Gtk::Button("Apply");
	$preview = new Gtk::Button("Preview");
	$apply->signal_connect("clicked" => \&apply_from_dock, $dialog_entry);
	$preview->signal_connect("clicked" => \&preview_from_dock, $dialog_entry);
	$apply->show;
	$preview->show;
	$dialog->action_area->pack_start($apply,1,1,0);
	$dialog->action_area->pack_start($preview,1,1,0);
	main Gtk;
}

sub apply_from_dock 
{
	my ($x,$widget)=@_;
	$ARGV[0] = $dirs{$widget->entry->get_text}."/".$widget->entry->get_text;
	switch();
}

sub preview_from_dock
{
	my ($x,$widget)=@_;
	$ARGV[0] = $dirs{$widget->entry->get_text}."/".$widget->entry->get_text;;
	preview("2");
}
