#!/usr/bin/env perl
#
# SlimRat
# v0.9.4 (2009-03-23) Nhung
# GTK GUI
# Přemek Vyhnal <premysl.vyhnal gmail com> 2009 
# public domain
#

use FindBin qw($RealBin);
use lib $RealBin;
use warnings;
use strict;
use locale;
use Gtk2 -init;
use Gtk2::GladeXML;
use Glib qw(TRUE FALSE);
use Gtk2::SimpleList;
use File::Basename;
use Plugin;
use Toolbox;
use Clipboard;

use Data::Dumper;


my $quefile = $ENV{HOME}.'/.slimrat';
my $gladefile = $RealBin.'/slimrat.glade';

$SIG{'INT'} = 'quit';

# GUI
my $gui = Gtk2::GladeXML->new($gladefile, 'mainWindow');
$gui->signal_autoconnect_from_package('main');

#CAPTCHA
#my $ui = Gtk2::GladeXML->new($gladefile, 'captchaDialog');
#$ui->signal_autoconnect_from_package('main');
#$ui->get_widget('captchaDialog')->show_all;

# treeview

use constant { # pořadí sloupečků;
	COL_STATUS	=> 0,
				COL_PASS	=> 3,
				COL_TYPE	=> 1,
				COL_LINK	=> 2,
};
my $slist = Gtk2::SimpleList->new (
		''			=> 'pixbuf',
		'Type'		=> 'text',
		'Link'		=> 'text',
		'Pass'		=> 'text',
		);
$slist->get_column(COL_PASS)->set_visible(0); ## pak dat pryc;


$slist->get_selection->set_mode ('multiple');
$slist->get_column($_)->set_resizable(1) foreach (COL_STATUS, COL_TYPE, COL_LINK, COL_PASS);
$slist->get_column($_)->set_reorderable(1) foreach (COL_STATUS, COL_TYPE, COL_LINK, COL_PASS);
$slist->set_column_editable ($_, TRUE) foreach (COL_LINK, COL_PASS);

$slist->set_search_column(COL_LINK);
$slist->set_search_equal_func(sub # vyhledávání i podle shody uprostřed řetězce (ne jen na začátku)
		{   my($store,$col,$pat,$iter)=@_;
		return 1 if($pat =~ m/[^-a-z0-9:_&?=.\/]+/im); # ošetřit!
		return $store->get($iter,$col)!~m/$pat/i;
		});
$gui->get_widget('mainwin')->add_with_viewport($slist);
$gui->get_widget('mainwin')->show_all;
#$gui->get_widget('statusbar')->push(0,"AAAA");




# load from file
open (QUE, "+<$quefile");
while (<QUE>){
	chomp;
	my @newRow;
	$newRow[COL_STATUS] = $slist->render_icon ("gtk-dialog-question", 'menu');
	$newRow[COL_TYPE] = Plugin::get_name($_);
	$newRow[COL_LINK] = $_;
	push @{$slist->{data}},[@newRow];
}
close (QUE);

# config
our ($gui_xterm);
do "config";


Gtk2->main;




#######################


# key 
use constant KEY_CTRL	=> 65507;
use constant KEY_v		=> 118;
use constant KEY_V		=> 86;
use constant KEY_DELETE	=> 65535;
use constant KEY_INSERT	=> 65379;
use constant KEY_ENTER	=> 65293;

my $ctrl;
sub key_press {
	my ($cmdbox, $event)=@_;
	if($event->keyval==KEY_CTRL){$ctrl = 1;}
	elsif($ctrl && ($event->keyval==KEY_v || $event->keyval==KEY_V)){&on_btnAddClip_clicked;}
	elsif($event->keyval==KEY_DELETE){&on_btnRemove1_clicked;}
	elsif($event->keyval==KEY_INSERT){&on_btnAdd1_clicked;}
#	print	$event->keyval."\n";
}
sub key_release {
	my ($cmdbox, $event)=@_;
	if($event->keyval==KEY_CTRL) {$ctrl = 0;}
}
sub on_addDialog_key_press_event {
	my ($cmdbox, $event)=@_;
	if($event->keyval==KEY_CTRL){$ctrl = 1;}
	&on_addOkBtn_clicked if($ctrl && $event->keyval==KEY_ENTER);
}
sub on_addDialog_key_release_event {goto &key_release;}



# quit
$SIG{'INT'} = 'quit';

sub on_mainWindow_destroy { &quit; }
sub gtk_main_quit { &quit; }
sub quit {
	&saveque;
	Gtk2->main_quit;
}
sub saveque {
	open (QUE, "> $quefile");
	print QUE @{$_}[COL_LINK]."\n" foreach @{$slist->{data}};
	close (QUE);
}




### toolbar buttons ###

# add
my ($addDialog, $addDialogBuff);
sub on_btnAdd1_clicked {
	my $gui = Gtk2::GladeXML->new($gladefile, 'addDialog');
	$gui->signal_autoconnect_from_package('main');
	$addDialog = $gui->get_widget('addDialog');
	$addDialogBuff = $gui->get_widget('addLinks')->get_buffer();
}
# add cancel
sub on_addCancelBtn_clicked {
	$addDialog->destroy();	
}
# add ok
sub on_addOkBtn_clicked {
	links_parse_add($addDialogBuff->get_text($addDialogBuff->get_start_iter, $addDialogBuff->get_end_iter, FALSE));
	$addDialog->destroy();	
}

# add from clipboard
sub on_btnAddClip_clicked {
	links_parse_add(Clipboard->paste);
}

# parse links from text input or clipboard and add them
sub links_parse_add {
	my $links = shift;
	push @{$slist->{data}}, [ $slist->render_icon ("gtk-dialog-question", 'menu'), Plugin::get_name($_), $_] foreach split /\s+/, $links; # TODO mezery na začátku;

}

#remove
my $confirmDialog;
sub on_btnRemove1_clicked{
	if(scalar $slist->get_selected_indices > 0){
#confirm
		my $gui = Gtk2::GladeXML->new($gladefile, 'confirmDelete');
		$gui->signal_autoconnect_from_package('main');
		$confirmDialog = $gui->get_widget('confirmDelete');
	}
}
sub on_confirmDelete_response{
#if($_[1] eq 'no' || $_[1]=='delete-event'){
	if($_[1] eq 'yes'){
		my $i=0;
		splice (@{$slist->{data}}, $_- $i++, 1) foreach ($slist->get_selected_indices);
	}
	$confirmDialog->destroy();
}
# remove all
sub on_btnRemoveAll_clicked{
	$slist->select($_) foreach (0 .. (scalar @{$slist->{data}})-1);
	&on_btnRemove1_clicked;
}



# MOVING TREEVIEW ITEMS
sub move_item{
	my($from,$to) = @_;
	return if($to<0 || $to >= scalar @{$slist->{data}});
	splice @{$slist->{data}}, $to, 0, splice @{$slist->{data}}, $from, 1; 
	$slist->unselect($from);
	$slist->select($to);
}

# up
sub on_btnUp1_clicked{
	return if (grep($_-1<0,$slist->get_selected_indices));
	move_item($_, $_-1) foreach ($slist->get_selected_indices);
#$gui->get_widget('statusbar')->push(1,"BBB");
}
# down
sub on_btnDown1_clicked{
	return if (grep($_+1>=scalar @{$slist->{data}},$slist->get_selected_indices));
	move_item($_,$_+1) foreach (reverse $slist->get_selected_indices);
#$gui->get_widget('statusbar')->pop(1);
}
# first
sub on_btnBeg1_clicked{
	my $i=0;
	move_item($_,$i++) foreach ($slist->get_selected_indices);
}
#last
sub on_btnEnd1_clicked{
	my $i=scalar @{$slist->{data}}-1;
	move_item($_,$i--) foreach (reverse $slist->get_selected_indices);
}


# unpack - show/hide pass col
sub on_unpack_toggled{
	$slist->get_column(COL_PASS)->set_visible($gui->get_widget('unpack')->get_active());
}



# DOWNLOAD
sub on_btnStart1_clicked {
	&saveque; 
	my $download_to = $gui->get_widget('downto')->get_filename();
	my $unpack = "";
	if($gui->get_widget('unpack')->get_active()) { # unpack
		$unpack = "-u";
		@{$_}[COL_PASS] and $unpack.=" -p ".@{$_}[COL_PASS] foreach @{$slist->{data}};
	}
	my $command = sprintf $gui_xterm, "$RealBin/slimrat -l '$quefile' -t '$download_to' $unpack";
#print $command;
	system($command); 
# spustí cli verzi v xtermu a předá soubor do kterého si gui ukládá seznam;
# slimrat si hned po spuštění přečte celej soubor a zapamatuje si všechny odkazy takže se ten soubor pak může hned zase měnit.;
	&quit;
}




sub on_btnCheck_clicked {

# kontrola vybranych radku - oznaceny zustanou jen mrtve (chceme to? nechceme radsi zachovat vyber?)
	if(scalar $slist->get_selected_indices > 0){
		foreach my $rownum ($slist->get_selected_indices){
			my $row = @{$slist->{data}}[$rownum];
			my $link = @{$row}[COL_LINK];
			my $pluginname = Plugin::get_name($link);
			my $check = eval $pluginname."::check('$link')";
			my $ico;
			if($check>0) { #live
				$ico="gtk-yes";
				$slist->unselect($rownum);
			} elsif($check<0) { # dead
				$ico="gtk-no";
				$slist->select($rownum);
			} else { #?
				$ico="gtk-dialog-question";
				$slist->unselect($rownum);
			}
			$row->[COL_STATUS] = $slist->render_icon ($ico, 'menu');
			$rownum++;
		}
	}



# varianta kde se kontroluje vsechno bez ohledu na vyber a dead linky se potom vyberou
# doplnit odvybrani vsecho
#    my $row;
#    my $rownum=0;
#    foreach $row (@{$slist->{data}}) {
#        my $link = @{$row}[2];
#        my $pluginname = Plugin::get_name($link);
#        my $check = eval $pluginname."::check('$link')";
#        my $ico;
#        if($check>0) { #live
#            $ico="gtk-yes";
#        } elsif($check<0) { # dead
#            $ico="gtk-no";
#            $slist->select($rownum);
#        } else { #?
#            $ico="gtk-dialog-question";
#        }
#        $row->[0] = $slist->render_icon ($ico, 'menu');
#        $rownum++;
#    }
}
