#!/usr/bin/perl -w
#
#    Poldex
#    v 0.17.3
#    Simple frontend to great POLDEK.
#    
#==============================================================================
#    Copyright (C) 2003 Zbigniew Banasik (zban@intermedia.net.pl)
#
#    www.yogib.risp.pl
#
#    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 of the License, 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 Curses;
use POSIX;
use Locale::gettext;
use RPM::Database;
use RPM::Header;
use Getopt::Long 2.24 qw(GetOptions :config bundling);

# alias gettext() to _() (shorter)
*_=\&Locale::gettext::gettext;

# Set locale
setlocale(LC_MESSAGES, "");
bindtextdomain("poldex", "/usr/share/locale");
textdomain("poldex");
   
my %options = (sn => [], source => [], color => 0, dont_su => 0, sudo => 0);
GetOptions(
	\%options,
	'sn|n=s@'      => $options{sn},
	'source|s=s@'  => $options{source},
	'dont_su|D', 'sudo|S', 'color|c'
  )
  or die <<"EOF";
	usage:
		$0 [ options ]
	Options:
		--color|-c			 - color packages from different sources	
		--dont_su|D          - do not "su -" to call poldek
		--sudo|S             - call poldek with sudo
		--sn|-n --source|s   - passed to poldek (untested)
							   /comma-separaded list of sources/	
EOF

# for comma-separated list of sources names
@{$options{sn}}=split(/,/,join(',',@{$options{sn}}));
@{$options{source}}=split(/,/,join(',',@{$options{source}}));
$options{dont_su} = 1 if $options{sudo};

my %packets = ();
my %all_packets = ();
my %sources = ();
my @packets_list = ();
my @installed = ();
my @desc = ();
my @to_install = ();
my @to_uninstall = ();
my @to_reinstall = ();
my $index = 0;
my $input = '';
my $i = 0;
my $sort = 0;
my $num_p = 0;
my $num_pinst = 0;
my $size_p = 0;
my $size_pinst = 0;
my %op = ();
my $op = 0;
my @inst_op = ();
my @uninst_op = ();
my $z = 0;
my %RPM = ();
my $START = 0;
my $init_curses_performed; # flag, avoids clearing screen if died before curses_init
my @sn = '';
@sn = ("-n", @{$options{sn}}, @{$options{source}}) if (@{$options{sn}} || @{$options{source}});

# Start curses
&init_curses;
getmaxyx(stdscr ,my $y, my $x);
&logo;
#&end_curses;

&init;
#&init_curses;
erase();

# table height
my $th = $y - 12;
if($th < 2){$th = 2}

# windows x, y
my ($nx, $ny, $sx, $sy);
if($x > 80){$nx = 80; $sx = ($x / 2) - 40}else{$nx = $x; $sx = 0}
if($y > 30){$ny = 30; $sy = ($y / 2) - 15}else{$ny = $y; $sy = 0}
my $gl = ' ' x $nx;

# Colors
my $kzie = "\033[32m";
my $kbia = "\033[0m";
my $kcze = "\033[31m";
my $kzol = "\033[33m";
my $knie = "\033[34m";
my $ktur = "\033[36m";

&op;
&table;
&men_key;

# Main
while($input ne 'q'){
	$input = &key();
	&on_key();
}

# End curses 
&end_curses;

sub init{
	# Initialisation
	# Read the packets descriptions from poldek
	%all_packets = ();
	%packets = ();
	&read_poldek;
	@packets_list = ();
	%all_packets = %packets;
	&chkinstalled;
	@packets_list = sort keys %packets;
	$num_p = @packets_list;
	if ($options{color}){
		&chk_sources;
		my $num = 1;
		foreach (keys %sources){
			$sources{$_}[2] = $num++;
			$num = 1 if $num == 6;
		}
	}
}
		
sub key{
	my $key = getch();
	return $key;
}

sub help{
}

sub table{
	my $ilosc = 0;
	my $yy = 3;
	my $gl = ' ' x $x;
	my $wsk = '';
	erase;
        $ilosc = @packets_list;
        while($index > $ilosc - 1){$index--};
        if($index < 0){$index = 0};
        while($index > $i + $th){$i++};
        while($index < $i){$i--};
	hline(2, 0, ACS_HLINE, $x);
	attron(COLOR_PAIR(8) | A_REVERSE);
        addstr(1, 0, $gl);
	if($sort == 0){attron(COLOR_PAIR(6)); addch(1, 2, ACS_UARROW)}
	if($sort == 1){attron(COLOR_PAIR(6)); addch(1, 2, ACS_DARROW)}
	if($x > 80){addstr(1, ($x / 4) - 23, _(" Packages ("));
		printw "$num_p/$num_pinst";
		printw _("inst.)");
		printw " ($size_p/$size_pinst MB) ";
	}else{addstr(1, ($x / 4) - 15, _(" Packages ("));
		printw "$num_p/$num_pinst ";
		printw _("inst.)");
	}
	attron(COLOR_PAIR(8));
	if($sort == 2){attron(COLOR_PAIR(6)); addch(1, ($x / 2) - 6, ACS_UARROW)}
	if($sort == 3){attron(COLOR_PAIR(6)); addch(1, ($x / 2) - 6, ACS_DARROW)}
        addstr(1, ($x / 2) - 3, _("Status"));
	attron(COLOR_PAIR(8));
	if($sort == 4){attron(COLOR_PAIR(6)); addch(1, ($x / 2) + 7 ,ACS_UARROW)}
	if($sort == 5){attron(COLOR_PAIR(6)); addch(1, ($x / 2) + 7, ACS_DARROW)}
	addstr(1, ($x / 4 + $x / 2) - 2, _("Groups"));
	attroff(COLOR_PAIR(6) | A_REVERSE);
        for (my $j = $i; $j < $i + $th + 1; $j++){
       	     my ($a, $b, $c);
	     if ($j == $index){attron(COLOR_PAIR(2) | A_REVERSE)};
             if (defined $packets_list[$j] && exists $packets{$packets_list[$j]}){
		   $a = $packets_list[$j];
		   my $short_a = $a;
		   if(defined $packets{$packets_list[$j]}[0] && $packets{$packets_list[$j]}[0] eq 'I'){$b = '[_INSTALLED]';
		   }else{$b = $packets{$packets_list[$j]}[0]};
		   $c = $packets{$packets_list[$j]}[2];
		   my $path = $packets{$a}[10];
		   addstr($yy, 0, $gl);
		   if(length($a) > int($x / 2) - 8){$short_a = substr($a, 0, (int($x / 2) - 8))}
		   if(exists $packets{$a}[10] && exists $sources{$path} && defined $sources{$path}[2]){
		   	attron(COLOR_PAIR($sources{$packets{$a}[10]}[2]));
		   	if(defined $packets{$packets_list[$j]}[12] && $packets{$packets_list[$j]}[12] eq 'b'){
		   	        attron(COLOR_PAIR(1));
			}
		   	addstr($yy, 2, "$short_a");
			attroff(COLOR_PAIR(1));
			attroff(COLOR_PAIR($sources{$packets{$a}[10]}[2]));
		   }else{if(defined $packets{$packets_list[$j]}[12] && $packets{$packets_list[$j]}[12] eq 'b'){
		   	        attron(COLOR_PAIR(1));
			}
		   		addstr($yy, 2, "$short_a");
				attroff(COLOR_PAIR(1));
		   }
		   if($b eq '[_INSTALLED]'){attron(COLOR_PAIR(10))}
		   if($b eq '[__INSTALL_]'){attron(COLOR_PAIR(11))}
		   if($b eq '[_UNINSTALL]'){attron(COLOR_PAIR(12))}
		   if($b eq '[_REINSTALL]'){attron(COLOR_PAIR(13))}
		   if(defined $packets{$packets_list[$j]}[12] && $packets{$packets_list[$j]}[12] eq 'b'){
		   	   attron(COLOR_PAIR(12));
		   	   $b = '[BROKEN_DEP]';
		   }
		   if(defined $b){
		   	addstr($yy, int($x / 2) - 6, _("$b"));
		   }
		   if($j == $index){attron(COLOR_PAIR(2))}
		   else{attroff(COLOR_PAIR(1) | COLOR_PAIR(4))}
		   if (defined $c){
		   	if(length($c) > int($x / 2) + 8){$c = substr($c, 0, (($x - 2) - (int($x / 2) + 8)))}
		   	addstr($yy, int($x / 2) + 8, "$c");
	   	   }
	           $yy++;	
	     }
	     attroff(COLOR_PAIR(2) | A_REVERSE);
        }
	attron(COLOR_PAIR(3));
	addstr($y - 7, 0, $gl);
	addstr($y - 7, 0, _("   Package: "));
	attroff(COLOR_PAIR(3));
	attron(COLOR_PAIR(2));
	printw $packets_list[$index];
	attroff(COLOR_PAIR(2));
	if(defined $packets{$packets_list[$index]}[1]){
		attron(COLOR_PAIR(3));
		addstr($y - 6, 0, $gl);
		addstr($y - 6, 0, _("   Sumary : "));
		attroff(COLOR_PAIR(3));
		printw $packets{$packets_list[$index]}[1];
	}
	if(defined $packets{$packets_list[$index]}[9]){
		attron(COLOR_PAIR(3));
		addstr($y - 5, 0, $gl);
		addstr($y - 5, 0, _("   Package size: "));
		attroff(COLOR_PAIR(3));
		printw $packets{$packets_list[$index]}[9];
	}
	hline($y - 8, 0, ACS_HLINE, $x);
	vline(0, ($x / 2) - 7, ACS_VLINE, $th + 4);
	vline(0, ($x / 2) + 6, ACS_VLINE, $th + 4);
	&scr($x, 3, $y-8, $ilosc, $index); 
}

sub read_poldek{
	my $ind = -1;
	my $pack = '';	
	my $desc = '';
	my $sign = '';
	my $prg = '';
	$x > 120 ? ($prg = '..') : ($prg = '.');
	&if_poldek;
	my $TMP;
	my %fields = map { ; $_ => ++$TMP }
	  qw(Summary Group Vendor License Arch/OS URL Built Size),
	  'Package size', 'Path';
	my $hdr_regex = join '|', map "\Q$_\E", keys %fields;
	open(TMP, "/usr/bin/poldek @sn -q -f --shcmd \'desc *\' 2>&1 |");
	PARSE: while ($desc = <TMP>){
		if ($desc =~ /^Package:\s*(\S+)/){
			$pack = $1; 
			$ind++; 
			if($sign ne substr($1, 0, 1) && $START == 0){
				printw $prg;
				$sign = substr($1, 0, 1);
				refresh();
			}
		}
		elsif ($desc =~ /^($hdr_regex):\s*(\S.*\S)/o) {
			$packets{$pack}[$fields{$1}] = $2;
	   	}
		elsif ($desc =~ /^Description:/) {
			while($desc = <TMP>){
				redo PARSE if $desc =~ /^Package:\s/;
				$packets{$pack}[11] .= $desc;
			}
		}
	}
	close TMP;
	$size_p = int $size_p/1000000;
	$START = 1;
}

sub on_key{
	SWITCH:{
		$input eq KEY_DOWN && do {$index++; last SWITCH;};
		$input eq KEY_UP && do{$index--; last SWITCH;};
		$input eq KEY_NPAGE && do{$index += $th + 1; $i += $th + 1; erase; last SWITCH;};
		$input eq KEY_PPAGE && do{$index -= $th + 1; $i += $th + 1; erase; last SWITCH;};
		$input eq 'i' && do {&install; last SWITCH;};
		$input eq 'u' && do {&uninstall; last SWITCH;};
		$input eq 'r' && do {&reinstall; last SWITCH;};
		$input eq 'p' && do {&proceed; last SWITCH;};
		$input eq 's' && do {&_sort; last SWITCH;};
		$input eq chr(10) && do {&desc; last SWITCH;};
		$input eq 'g' && do {&groups; last SWITCH;};
		$input eq 'o' && do {&options; last SWITCH;};
		$input eq 'z' && do {&sources; last SWITCH;};
		$input eq 'f' && do {&_find; last SWITCH;};
		$input eq 'd' && do {&desc_packets; $input = ''; last SWITCH;};
		$input eq 'e' && do {&edit_conf; last SWITCH;};
		$input eq 'v' && do {&verify; last SWITCH;};
		$input eq 'l' && do {&poldek; last SWITCH;};
		last SWITCH;
	}
	&table;
	&men_key;
}

sub install{
	if($packets{$packets_list[$index]}[0] eq ''  && !grep /^\Q$packets_list[$index]\E$/, @to_install){
		$packets{$packets_list[$index]}[0] = '[__INSTALL_]';
		push @to_install, $packets_list[$index];
		&table();
		&men_key;
	}
	elsif($packets{$packets_list[$index]}[0] eq '[__INSTALL_]'){
		grep s/^\Q$packets_list[$index]\E$/ /, @to_install;
		$packets{$packets_list[$index]}[0] = '';
		&table();
		&men_key;
	}
	elsif($packets{$packets_list[$index]}[0] eq '[_UNINSTALL]'){
		grep s/^\Q$packets_list[$index]\E$/ /, @to_uninstall;
		$packets{$packets_list[$index]}[0] = 'I';
		&table;
		&men_key;
	}
}

sub uninstall{
	if($packets{$packets_list[$index]}[0] eq 'I' && !grep /^\Q$packets_list[$index]\E$/, @to_uninstall){
		$packets{$packets_list[$index]}[0] = '[_UNINSTALL]';
		push @to_uninstall, $packets_list[$index];
		&table();
		&men_key;
	}
	elsif($packets{$packets_list[$index]}[0] eq '[_UNINSTALL]'){
		grep s/^\Q$packets_list[$index]\E$/ /, @to_uninstall;
		$packets{$packets_list[$index]}[0] = 'I';
		&table();
		&men_key;
	}
	elsif($packets{$packets_list[$index]}[0] eq '[__INSTALL_]'){
		grep s/^\Q$packets_list[$index]\E$/ /, @to_install;
		$packets{$packets_list[$index]}[0] = '';
		&table;
		&men_key;
	}
}

sub _sort{
	$index = 0;
	if($sort < 5){$sort++;
	}else{$sort = 0}
	&my_sort;
	&table();
	&men_key;
}

sub reinstall{
	if($packets{$packets_list[$index]}[0] eq 'I' && !grep /^\Q$packets_list[$index]\E$/, @to_reinstall){
		$packets{$packets_list[$index]}[0] = '[_REINSTALL]';
		push @to_reinstall, $packets_list[$index];
		&table();
		&men_key;
	}
	elsif($packets{$packets_list[$index]}[0] eq '[_REINSTALL]'){
		grep s/^\Q$packets_list[$index]\E$/ /, @to_reinstall;
		$packets{$packets_list[$index]}[0] = 'I';
		&table;
		&men_key;
	}
}	

sub proceed{
	def_prog_mode();
	endwin();
	system('clear');
	@$_ = grep /\S/, @$_
	  foreach \@to_install, \@to_uninstall, \@uninst_op, \@to_reinstall;
	if(@to_install || @to_uninstall || @to_reinstall){
		if(@to_reinstall){
			print $kzie;
			print "\n\n   ", _("Packages to reinstall"), ":\n\n";
			foreach (@to_reinstall){print " $_\n"};
			print $kbia;
			print "\n ", _("Do it Poldek!"), "...\n\n";
			system(
				($options{dont_su}
					? ($options{sudo} 
						? ('sudo', 'poldek', @sn, '--shcmd', join ' ', 'install --reinstall -F',@to_reinstall)
						: ())
					: "su -c \"poldek @sn --shcmd 'install --reinstall -F @to_reinstall'\"")
			);
			@to_reinstall = ();
		}
		if(grep /\S/, @to_uninstall){
			print $kcze;
			print "\n\n   ", _("Packages to uninstall"), ":\n\n";
			foreach (@to_uninstall){print " $_\n"};
			if(@uninst_op){
				print $kzol;
				print "\n   ", _("Uninstall options"), ":\n\n";
				print " $_\n" foreach @uninst_op;
			}
			print $kbia;
			print "\n ", _("Do it Poldek!"), "...\n\n";
			system(
				($options{dont_su}
					? ($options{sudo} 
						? ('sudo','poldek', @sn, '--shcmd', join ' ', 'uninstall',@uninst_op, @to_uninstall)
						: ())
					: "su -c \"poldek @sn --shcmd 'uninstall @uninst_op @to_uninstall'\"")
			);
			foreach my $el (@to_uninstall){
				if(exists $packets{$el} && $packets{$el}[10] eq 'Installed from other sources'){
					delete $packets{$el};
					my $ind = 0;
					foreach (@packets_list){
						if($_ eq $el){
							splice(@packets_list,$ind,1);
							last;
						}
						$ind++;
					}
				}
			}
			@to_uninstall = ();
		}
		if(@to_install){
			print $kzie;
			print "\n\n   ", _("Packages to install"), ":\n\n";
			foreach (@to_install){print " $_\n"};
			if(@inst_op){
				print $kzol;
				print "\n   ", _("Install options"), ":\n\n";
				print " $_\n" foreach @inst_op;
			}
			print $kbia;
			print "\n ", _("Do it Poldek!"), "...\n\n";
			system(
				($options{dont_su}
					? ($options{sudo} 
						? ('sudo', 'poldek', @sn, '--shcmd', join ' ', 'install',@inst_op, @to_install)
						: ())
					: "su -c \"poldek @sn --shcmd 'install @inst_op @to_install'\"")
			);
			@to_install = ();
		}
		&chkinstalled;
		print $kcze;
		print "\n\n [KEY]\n";
		print $kbia;
	}else{return;}
  	reset_prog_mode();
	&key();
	refresh();
	&table;
	&men_key;
}

sub desc{
	$input= '';
	my $win_desc = newwin($ny, $nx, $sy, $sx);
	while($input ne chr(10) && $input ne 'q'){
		erase($win_desc);		
		my $l = 2;
		attron($win_desc, COLOR_PAIR(3));
		addstr($win_desc, $l, 1, _(" Package     "));
		attron($win_desc, COLOR_PAIR(2));
		addstr($win_desc,,,":  $packets_list[$index]");
		$l++;
		if(defined $packets{$packets_list[$index]}[3]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Vendor      "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[3]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[1]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Sumary      "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[1]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[4]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" License     "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[4]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[5]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Arch/OS     "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[5]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[6]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, " URL         ");
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[6]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[7]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Built       "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[7]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[8]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Size        "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[8]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[9]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Package size"));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[9]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[10]){
			attron($win_desc, COLOR_PAIR(3));
			addstr($win_desc, $l, 1, _(" Path        "));
			attroff($win_desc, COLOR_PAIR(3));
			addstr($win_desc,,,":  $packets{$packets_list[$index]}[10]");
			$l++;
		}
		if(defined $packets{$packets_list[$index]}[11]){
			vline($win_desc, 0, 14, ACS_VLINE, $l + 1);
			hline($win_desc, $l, 0, ACS_HLINE, $nx);
			$l++;
			attron($win_desc,COLOR_PAIR(6) | A_REVERSE);
			addstr($win_desc, $l, 0, $gl);
			addstr($win_desc, $l, $nx / 2 - 7, _("Description :"));
			attroff($win_desc, COLOR_PAIR(6) | A_REVERSE);
			addstr($win_desc, $l + 1, 0, ' ');
			my @temp_desc = split("\n", $packets{$packets_list[$index]}[11]);
			foreach my $temp (@temp_desc){
				addstr($win_desc,,, "\n   ");
				addstr($win_desc,,, "$temp");
			}
		}
		hline($win_desc, $ny-3, 0, ACS_HLINE, $nx);
		hline($win_desc, $l + 1, 0, ACS_HLINE, $nx);
		addstr($win_desc, $ny - 2, 1, $gl);
		attron($win_desc, COLOR_PAIR(1));
		addstr($win_desc, $ny - 2, $nx / 2 - 34, _("[ENTER/Q]-Exit [UP/DOWN] [F]-Find [I]-Inst. [U]-Uninst. [P]-Proc."));
		attroff($win_desc, COLOR_PAIR(1));
		box($win_desc, 0, 0);
		refresh($win_desc);
		$input = &key;
		if($input eq 'i' or $input eq 'u' or $input eq 'p' or $input eq 'd' or $input eq 'f'){&on_key; $input = ''}
		if($input eq KEY_DOWN){$index++}
		if($input eq KEY_UP){$index--}
		&table;
		for(my $i = 0; $i < $ny; $i++){
			addstr($i + $sy, $sx, $gl);
		}
		box(stdscr, 0, 0);
		refresh();
	}
	delwin($win_desc);
	$input = '';
	&table;
	&men_key;
}

sub groups{
	my $ii = 0;
	my $gi = 0;
	my $choice = $packets_list[$index];
	my $indexg = 0;
	my %groups = ();
	my $win_gr = newwin($ny, $nx, $sy, $sx);
	erase($win_gr);		
	@packets_list = sort {$packets{$a}[2] cmp $packets{$b}[2] || $a cmp $b}  keys %packets;
	my $il = @packets_list;
	for(my $ind = 0; $ind < $il; $ind++){
		$gi++;
		if(defined $packets_list[$ind+1]){
			if($packets{$packets_list[$ind]}[2] ne $packets{$packets_list[$ind+1]}[2]){
				$groups{$packets{$packets_list[$ind]}[2]}[1] = $ind - $gi + 1;
				$groups{$packets{$packets_list[$ind]}[2]}[2] = $gi;
				$gi = 0;
			}
		}elsif($ind == $il - 1){
			$groups{$packets{$packets_list[$ind]}[2]}[1] = $ind - $gi + 1;
				$groups{$packets{$packets_list[$ind]}[2]}[2] = $gi;
		}	
	}
	my @sort_groups = sort keys %groups;
	my $ilosc = @sort_groups;
	while($input ne chr(10) && $input ne 'q'){
	        while($indexg > $ilosc - 1){$indexg--};
	        if($indexg < 0){$indexg = 0};
	        while($indexg > $ii + $ny - 7){$ii++};
	        while($indexg < $ii){$ii--};
		my $y = 3;
		attron($win_gr, COLOR_PAIR(6) | A_REVERSE);
	     	addstr($win_gr, 1, 0, $gl);
	     	addstr($win_gr, 1, $nx / 2 - 6, _("Groups"));
	     	addstr($win_gr, 1, $nx / 2 + 2, "($ilosc)");
		attroff($win_gr, COLOR_PAIR(6) | A_REVERSE);
	        for (my $j = $ii; $j < $ii + $ny - 6; $j++){
		     if ($j == $indexg){attron($win_gr, COLOR_PAIR(8) | A_REVERSE)};
		     if(defined $sort_groups[$j]){
		     	addstr($win_gr, $y, 0, $gl);
		     	addstr($win_gr, $y, 2, $j + 1);
			addstr($win_gr, $y, 8, $sort_groups[$j]);
			addstr($win_gr, $y, $nx - 5, $groups{$sort_groups[$j]}[2]);
			$y++;
		     }
			attroff($win_gr, COLOR_PAIR(8) | A_REVERSE);
		}
		&scr($nx, 3, $ny-3, $ilosc, $indexg, \$win_gr); 
		hline($win_gr, 2, 0, ACS_HLINE, $nx);
		vline($win_gr, 3, 5, ACS_VLINE, $ny - 6);
		vline($win_gr, 3, $nx - 7, ACS_VLINE, $ny - 6);
		hline($win_gr, $ny - 3, 0, ACS_HLINE, $nx);
		attron($win_gr, COLOR_PAIR(1));
		addstr($win_gr, $ny - 2, $nx / 2 -21, _("[Q]-Exit [ENTER]-Group"));
		attroff($win_gr, COLOR_PAIR(1));
		box($win_gr, 0, 0);
		refresh($win_gr);
		$input = &key;
		if ($input eq 'q'){&my_sort; $index = &choice($choice);
		}else{$index = $groups{$sort_groups[$indexg]}[1]}
		if ($input eq KEY_DOWN){$indexg++}
		if ($input eq KEY_UP){$indexg--}
		if ($input eq KEY_NPAGE){$indexg += $ny - 6; $i += $ny - 6}
		if ($input eq KEY_PPAGE){$indexg -= $ny - 6; $i += $ny - 6}
	}
	delwin($win_gr);
	$i = $index;
	$input = '';
	erase;
	&table;
	&men_key;
}

sub sources{
	my $ii = 0;
	my $gi = 0;
	$z = 0;
	my $indexg = 0;
	my $xactive = 1;
	my @sources_list = ();
	my $win_sour = newwin($ny, $nx, $sy, $sx);
	erase($win_sour);		
	@packets_list = sort (keys %all_packets);
	&chk_sources;
	@sources_list = sort (keys %sources);
	my $ilosc = @sources_list;
	while($input ne 'q' || $xactive != 1){
	        while($indexg > $ilosc - 1){$indexg--};
	        if($indexg < 0){$indexg = 0};
	        while($indexg > $ii + $ny - 7){$ii++};
	        while($indexg < $ii){$ii--};
		my $y = 3;
		attron($win_sour, COLOR_PAIR(6) | A_REVERSE);
	     	addstr($win_sour, 1, 0, $gl);
	     	addstr($win_sour, 1, $nx / 2 - 3, _("Sources"));
		attroff($win_sour, COLOR_PAIR(6) | A_REVERSE);
	        for (my $j = $ii; $j < $ii + $ny - 6; $j++){
		     if ($j == $indexg){attron($win_sour, COLOR_PAIR(8) | A_REVERSE)};
		     if(defined $sources_list[$j]){
		     	addstr($win_sour, $y, 0, $gl);
		     	addstr($win_sour, $y, 2, $j + 1);
			if(defined $sources{$sources_list[$j]}[2]){attron($win_sour, COLOR_PAIR($sources{$sources_list[$j]}[2]))}
			addstr($win_sour, $y, 5, $sources_list[$j]);
			if(defined $sources{$sources_list[$j]}[2]){attroff($win_sour, COLOR_PAIR($sources{$sources_list[$j]}[2]))}
			addstr($win_sour, $y, $nx - 12, $sources{$sources_list[$j]}[0]);
			attron($win_sour, COLOR_PAIR(12));
			addstr($win_sour, $y, $nx - 7, $sources{$sources_list[$j]}[1]);
			attroff($win_sour, COLOR_PAIR(1));
			$y++;
		     }
			attroff($win_sour, COLOR_PAIR(8) | A_REVERSE);
		}
		hline($win_sour, 2, 0, ACS_HLINE, $nx);
		vline($win_sour, 3, 4, ACS_VLINE, $ny - 7);
		vline($win_sour, 3, $nx - 8, ACS_VLINE, $ny - 7);
		vline($win_sour, 3, $nx - 13, ACS_VLINE, $ny - 7);
		hline($win_sour, $ny - 4, 0, ACS_HLINE, $nx);
		attron($win_sour, COLOR_PAIR(1));
		addstr($win_sour, $ny - 3, $nx / 2 - 14, _("[1-5]-Color [C]-ClearColors"));
		addstr($win_sour, $ny - 2, $nx / 2 - 24, _("[Q]-Exit [U]-Up [P]-Upa [ENTER][X]-Dis/Activate"));
		attroff($win_sour, COLOR_PAIR(1));
		box($win_sour, 0, 0);
		refresh($win_sour);
		$input = &key;
		if ($input eq KEY_DOWN){$indexg++}
		if ($input eq KEY_UP){$indexg--}
		if ($input eq KEY_NPAGE){$indexg += $ny - 6; $i += $ny - 6}
		if ($input eq KEY_PPAGE){$indexg -= $ny - 6; $i += $ny - 6}
		if ($input eq 'u'){&poldek_upa($sources_list[$indexg], 'up')}
		if ($input eq 'p'){&poldek_upa($sources_list[$indexg], 'upa')}
		if ($input eq chr(10)){
			if($sources{$sources_list[$indexg]}[1] eq 'ACTIVE'){
				$sources{$sources_list[$indexg]}[1] = '';
			}else{$sources{$sources_list[$indexg]}[1] = 'ACTIVE'}
		}
		if ($input eq 'x'){
			if($xactive == 1){
				foreach my $key (keys %sources){
					$sources{$key}[1] = '';
				}
			}else{foreach my $key (keys %sources){
					$sources{$key}[1] = 'ACTIVE';
				}
			}
		}
		$xactive = 0;
		foreach my $key (keys %sources){
			if($sources{$key}[1] eq 'ACTIVE'){
				$xactive = 1;
			}
		}
		if ($input =~ /^[1-5]$/){
			if($input == 1){$input = 6}
			$sources{$sources_list[$indexg]}[2] = $input;
		}
		if ($input eq 'c'){
			undef $sources{$sources_list[$indexg]}[2] ;
		}
	}
	delwin($win_sour);
 		%packets = ();		
	foreach my $key (sort keys %all_packets){
		if(exists $all_packets{$key}[10] && $sources{$all_packets{$key}[10]}[1] eq 'ACTIVE'){
				$packets{$key} = $all_packets{$key};
		}else{$z = 1}
	}
	@packets_list = sort keys %packets;
	$i = 0;
	$index = 0;
	$input = '';
	erase;
	&table;
	&men_key;
}

sub _find{
	@packets_list = sort keys %packets;
	&table;
	my $buf = '';
	my $print_buf = '';
	my $del = 0;
	&clr;
	addstr($y-3, 6, _("Find"));
	printw ">$print_buf";
	&find_inf;			
	$input = &key;
	SO: while($input ne chr(10)){
		my $ind = 0;
		my $indexg = 0;
		if($input ne KEY_BACKSPACE && $input ne KEY_DOWN && $input ne KEY_UP &&  $input =~ /\d\d\d/){
			$input = &key;
			next;
		}
		if($input eq KEY_DOWN){$index++; last}
		if($input eq KEY_UP){$index--; last}
		if($input eq KEY_BACKSPACE){
			if(substr($buf, -2, 2) =~ /\./){
				$buf = substr($buf, 0, (length($buf) - 2));
			}else{$buf = substr($buf, 0, (length($buf) - 1))}
		}else{if($input =~ s/(\^|\$|\.|\+|\?|\{|\(|\)|\\|\/|\||\[)/\\$1/){$del = 2;
			}else{$del = 1}
			if($input =~ s/\*/\.\*/){$del = 2}
			$buf .= $input;
		}
		$print_buf = $buf;
		$print_buf =~ s/\.//g;
		if($buf =~ /\*/ || $buf =~ /^\\\//){
			my $ii = 0;
			my $gi = 0;
			$indexg = 0;
			my %temp_packets_list = ();
			my $win_fi = newwin($ny, $nx, $sy, $sx);
			erase($win_fi);		
			my $tin = 0;
			if($buf =~ s/^\\\//\//){
				$print_buf =~ s/^\\\//\//;
				&clr;
				addstr($y-3, 6, _("Find"));
				printw ">$print_buf";
				&find_inf;			
				$buf = '';
                                       while($input ne chr(10)){
					$input = &key;
					if($input ne chr(10) && $input ne KEY_BACKSPACE){
							$buf .= $input;
					}elsif($input eq KEY_BACKSPACE && length($buf) > 0){
							$buf = substr($buf, 0, (length($buf) - 1));
					}elsif($input eq KEY_BACKSPACE && length($buf) == 0){last SO}
					$print_buf = $buf;
					&clr;
					addstr($y-3, 6, _("Find"));
					printw ":/$print_buf";
					&find_inf;			
				}
				&info(_("Asking Poldek..."));
				my @temp = `/usr/bin/poldek @sn --shcmd 'search -f *$buf'`;
				foreach my $a (@packets_list){
					if(grep /^\Q$a\E$/, @temp){
						$temp_packets_list{$a} = $tin;
						$tin++;
					}else{$tin++}
				}
				$buf = '';
			}else{	
				foreach my $a (@packets_list){
					if($packets_list[$tin] =~ /^$buf/){
						$temp_packets_list{$a} = $tin;
						$tin++;
					}else{$tin++}
				}
			}
			my @find_list = sort keys %temp_packets_list;
			my $ilosc = 0;
			$ilosc = @find_list;
			if($ilosc == 0 && $buf eq ''){
				&info(_("No matches!"));
				sleep 1;
				next SO;
			}
			if($ilosc == 0){
				$buf = substr($buf, 0, (length($buf) - $del));
				$input = &key;
				next SO;
			}
			do{
			        while($indexg > $ilosc - 1){$indexg--};
			        if($indexg < 0){$indexg = 0};
			        while($indexg > $ii + $ny - 7){$ii++};
			        while($indexg < $ii){$ii--};
				my $yy = 3;
				attron($win_fi, COLOR_PAIR(6) | A_REVERSE);
			     	addstr($win_fi, 1, 0, $gl);
				if($buf eq ''){
					addstr($win_fi, 1, 5, _("Founded packages with file"));
					addstr($win_fi, 1, 26, "> $print_buf");
				}else{addstr($win_fi, 1, 5, _("Find package"));
					addstr($win_fi, 1, 18, "> $print_buf");
				}
			     	addstr($win_fi, 1, $nx - 20, _("Matched"));
			     	addstr($win_fi, 1, $nx - 13, ": $ilosc");
				attroff($win_fi, COLOR_PAIR(6) | A_REVERSE);
			        for (my $j = $ii; $j < $ii + $ny - 6; $j++){
				        if ($j == $indexg){attron($win_fi, COLOR_PAIR(8) | A_REVERSE)};
				     	addstr($win_fi, $yy, 0, $gl);
					if(defined $find_list[$j]){
						addstr($win_fi, $yy, 8, $find_list[$j]);
						if($packets{$find_list[$j]}[0] eq 'I'){
							attron($win_fi, COLOR_PAIR(10));	
							addstr($win_fi, $yy, $nx - 14, _("[_INSTALLED]"));
							attroff($win_fi, COLOR_PAIR(10));
						}else{addstr($win_fi, $yy, $nx - 12, $packets{$find_list[$j]}[0]);}
					}
					$yy++;
					attroff($win_fi,COLOR_PAIR(8) | A_REVERSE);
				}
				&scr($nx, 3, $ny-3, $ilosc, $indexg, \$win_fi); 
				attron($win_fi, COLOR_PAIR(1));
				addstr($win_fi, $ny - 2, $nx / 2 - 16, _("[D]-Files  [UP/DOWN]  [ENTER]"));
				attroff($win_fi, COLOR_PAIR(1));
				hline($win_fi, 2, 0, ACS_HLINE, $nx);
				hline($win_fi, $ny - 3, 0, ACS_HLINE, $nx);
				vline($win_fi, 3, $nx - 15, ACS_VLINE, $ny - 6);
				box($win_fi, 0, 0);
				refresh($win_fi);
				$input = &key;
				if ($input eq 'q' && $buf eq ''){$input = ''; last SO}
				if ($input eq KEY_DOWN){$indexg++}
				if ($input eq KEY_UP){$indexg--}
				if ($input eq 'd' && $buf eq ''){&desc_packets($print_buf, $find_list[$indexg]); $input = ''}
				if ($input eq chr(10)){
					if($ilosc > 0){$index = $temp_packets_list{$find_list[$indexg]};
					}else{next SO}	
					delwin($win_fi);
					next SO;
				}
			}while($input eq KEY_DOWN or $input eq KEY_UP);
			delwin($win_fi);
			if($ilosc > 0){next SO};
		}else{foreach my $a (@packets_list){
			if($packets_list[$ind] =~ /^$buf/){
				$index = $ind;
				&table;
				&clr;
				addstr($y-3, 6, _("Find"));
				printw ">$print_buf";
				&find_inf;
				$input = &key;
				next SO;
			}
			$ind++;
			}
		}
		$buf = substr($buf, 0, (length($buf) - $del));
		&table;
		&clr;
		$print_buf = $buf;
		$print_buf =~ s/\.//g;
		addstr($y-3, 6, _("Find"));
		printw ">$print_buf";
		&find_inf;
		$input = &key;
	}
	&table;
	&clr;
	&men_key;
	sub clr{
		my $gl = ' ' x $x;
		addstr($y - 3, 0, $gl);
		addstr($y - 2, 0, $gl);
		addstr($y - 1, 0, $gl);
	}
	sub find_inf{
		hline($y - 4, 0, ACS_HLINE, $x);
		attron(COLOR_PAIR(1));
		addstr($y - 2, $x / 2 - 35, _("[UP]-Up [DOWN]-Next [ENTER]-Ends  Ex: Find package: >foo*, file: >/foo"));
		attroff(COLOR_PAIR(1));
		box(stdscr, 0, 0);
		refresh();
	}
}

sub chkinstalled{
	$num_pinst = 0;
	my $p_name = '';
	foreach my $b (keys %packets){$packets{$b}[0] = ''}
	tie %RPM, "RPM::Database" or die "$RPM::err";
	for (sort keys %RPM){
		my $href = $RPM{$_};
		my $version = $href->{"VERSION"};
		my $release = $href->{"RELEASE"};
		$p_name = $_ . '-' . $version . '-' . $release;
		push @installed, $p_name;
		if(!exists $packets{$p_name}){
			$packets{$p_name}[1] = $href->{"SUMMARY"};
			$packets{$p_name}[2] = $href->{"GROUP"};
			$packets{$p_name}[3] = $href->{"VENDOR"};
			$packets{$p_name}[4] = $href->{"LICENSE"};
			$packets{$p_name}[5] = $href->{"ARCH"};
			$packets{$p_name}[6] = $href->{"URL"};
			$packets{$p_name}[7] = $href->{"BUILDHOST"};
			$packets{$p_name}[8] = $href->{"SIZE"};
#			$packets{$p_name}[9] = $href->{"FILESIZES"};
			$packets{$p_name}[10] = _('Installed from other sources');
			$packets{$p_name}[11] = $href->{"DESCRIPTION"};
		}
		$packets{$p_name}[0] = 'I';
		$num_pinst++;
		if(defined $packets{$p_name}[8] && $packets{$p_name}[8] =~ /\((\d*) B\)/){
			$size_pinst += $1;
		}
			
	}
	untie %RPM;
	$size_pinst = int $size_pinst / 1000000;
	%all_packets = %packets;
	@packets_list = sort keys %packets;
}

sub chk_sources{
	foreach my $key (keys %sources){
		$sources{$key}[0] = 0;
	}
	foreach my $key (@packets_list){
		if(exists $sources{$all_packets{$key}[10]}){
			$sources{$all_packets{$key}[10]}[0]++;
		}else{$sources{$all_packets{$key}[10]}[0] = 1;
			$sources{$all_packets{$key}[10]}[1] = 'ACTIVE';
		}
	}
}

sub poldek_upa{
	my ($sr, $up) = @_;
	def_prog_mode();
	endwin();
	system('clear');
	system(
		($options{dont_su}
			? ($options{sudo} 
				? ('sudo',qw(poldek -s), "$sr/", "--$up")
				: ())
			: "su -c \"poldek -s $sr/ --$up\"")
	);
	print "\n\n", _("Verifying...");
	&read_poldek;
	%all_packets = %packets;
	&chkinstalled;
  	reset_prog_mode();
	refresh();
}			

sub men_key{
	hline($y - 4, 0, ACS_HLINE, $x);
	attron(COLOR_PAIR(1));
	addstr($y - 3, $x / 2 - 37, _("[ENTER]-Prop. [S]-Sort [G]-Grp [V]-Verify [L]-Poldek [I][U][R] "));
	if(grep /\S/, @to_install or grep /\S/, @to_uninstall or grep /\S/, @to_reinstall){
		attron(COLOR_PAIR(3) | A_REVERSE);
		printw _("[P]-Proceed");
		attroff(A_REVERSE);
		attron(COLOR_PAIR(1));
	}else{printw _("[P]-Proceed")}
	addstr($y - 2, $x / 2 - 39, _("[F]-Find [D]-Files "));
	if($z == 1){
		attron(COLOR_PAIR(3) | A_REVERSE);
		printw _("[Z]-Sources");
		attroff(A_REVERSE);
		attron(COLOR_PAIR(1));
	}else{printw _("[Z]-Sources")}
	if($op == 1){
		attron(COLOR_PAIR(3) | A_REVERSE);
		printw _(" [O]-Options");
		attroff(A_REVERSE);
		attron(COLOR_PAIR(1));
	}else{printw _(" [O]-Options")}
	printw _(" [E]-EditConf [Up/Down/PgU/PgD] [Q]");
	attroff(COLOR_PAIR(1));
	box(stdscr, 0, 0);
	refresh();
}

sub my_colors{
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_GREEN, COLOR_BLACK);
	init_pair(3, COLOR_YELLOW, COLOR_BLACK);
	init_pair(4, COLOR_BLUE, COLOR_BLACK);
	init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
	init_pair(6, COLOR_CYAN, COLOR_BLACK);
	init_pair(7, COLOR_WHITE, COLOR_BLACK);
	init_pair(8, COLOR_BLUE, COLOR_WHITE);
	init_pair(9, COLOR_MAGENTA, COLOR_CYAN);
	init_pair(10, COLOR_BLACK, COLOR_YELLOW);
	init_pair(11, COLOR_BLACK, COLOR_GREEN);
	init_pair(12, COLOR_BLACK, COLOR_RED);
	init_pair(13, COLOR_BLACK, COLOR_BLUE);
}	

sub choice{
	my ($a) = @_;
	my $b = @packets_list;
	for(my $i = 0; $i < $b; $i++){
		if($a eq $packets_list[$i]){return $i; last;}
	}
	return 0;
}

sub my_sort {
	if    ($sort == 0) { @packets_list = sort keys %packets }
	elsif ($sort == 1) { @packets_list = reverse sort keys %packets }
	elsif ($sort == 2) {
		@packets_list =
		  sort { $packets{$b}[0] cmp $packets{$a}[0] || $a cmp $b }
		  keys %packets;
	}
	elsif ($sort == 3) {
		@packets_list =
		  sort { $packets{$a}[0] cmp $packets{$b}[0] || $a cmp $b }
		  keys %packets;
	}
	elsif ($sort == 4) {
		@packets_list =
		  sort { $packets{$a}[2] cmp $packets{$b}[2] || $a cmp $b }
		  keys %packets;
	}
	elsif ($sort == 5) {
		@packets_list =
		  sort { $packets{$b}[2] cmp $packets{$a}[2] || $a cmp $b }
		  keys %packets;
	}
}

sub info{
	my ($a) = @_;
	my $info_win = newwin(5, 40, ($y / 2) - 2, ($x / 2) - 20);
	erase($info_win);
	attron($info_win, COLOR_PAIR(1));
	addstr($info_win, 2, 20 - length($a) / 2, $a);
	attroff($info_win, COLOR_PAIR(1));
	box($info_win, 0, 0);
	refresh($info_win);
}

sub desc_packets{
	my ($a, $mfile) = @_;
	my $ind = 0;
	my @desc_f = ();
	my $win_op = newwin($ny, $nx, $sy, $sx);
	erase($win_op);		
	if(!defined $mfile){
		$mfile = $packets_list[$index];
	}
	if($packets{$mfile}[0] eq 'I'){
		@desc_f = `/bin/rpm -ql $mfile`;
	}else{
		&info(_("Asking Poldek..."));
		@desc_f = `/usr/bin/poldek @sn --shcmd 'desc -f $mfile'`
	}
	my %tekst = ();
	my $il = 0;
	foreach my $a (@desc_f){
		if($a =~ /^(\/|\s\s\s)/){
			$tekst{$il} = $a;
			$il++;
		}
	}
	do{
		for(my $i = $ind, my $j = 3; $j < $ny - 3; $i++, $j++){
			if(exists $tekst{$i}){
				if(defined $a && $tekst{$i} =~ /\Q$a\E/){
					attron($win_op, A_REVERSE);
				}
				if($tekst{$i} =~ /(^\S*:)(.*)$/){
					attron($win_op, COLOR_PAIR(2));
					addstr($win_op, $j, 1, $1);
					attroff($win_op, COLOR_PAIR(2));
					addstr($win_op, $j, length($1) + 1, $2);
				}elsif($tekst{$i} =~ /^(.*\/)([^\/]*)$/){
					addstr($win_op, $j, 1, $1);
					attron($win_op, COLOR_PAIR(2));
					addstr($win_op, $j, length($1) + 1, $2);
					attroff($win_op, COLOR_PAIR(2));
				}
				else{addstr($win_op, $j, 1, $tekst{$i})}
				attroff($win_op, A_REVERSE);
			}
		}
		attron($win_op, COLOR_PAIR(6) | A_REVERSE);
	     	addstr($win_op, 1, 0, $gl);
	     	addstr($win_op, 1, $nx / 2 - 5 - (int(length($packets_list[$index]) / 2)), _("Files of"));
	     	addstr($win_op, 1, $nx / 2 + 3 - (int(length($packets_list[$index]) / 2)), " $mfile");
		attroff($win_op, COLOR_PAIR(6) | A_REVERSE);
		hline($win_op, 2, 0, ACS_HLINE, $nx);
		hline($win_op, $ny - 3, 0, ACS_HLINE, $nx);
		&scr($nx, 3, $ny-3, $il, $ind + $ny - 7, \$win_op); 
		attron($win_op, COLOR_PAIR(1));
		addstr($win_op, $ny - 2, $nx / 2 - 9, _("[UP/DOWN]  [ENTER]"));
		attroff($win_op, COLOR_PAIR(1));
		box($win_op, 0, 0);
		refresh($win_op);
		$input = &key;
		if($input eq KEY_DOWN){
			if($ind < $il - $ny + 6){$ind++}
		}elsif($input eq KEY_PPAGE){
			$ind -= $ny + 6;
			if($ind < 0){
				$ind = 0;
			}	
		}elsif($input eq KEY_UP){
			if($ind > 0){$ind--}
		}elsif($input eq KEY_NPAGE){
			$ind += $ny + 6;
			if($ind > $il - $ny + 6){
				$ind = $il - $ny + 6
			}
			if($ind < 0){
				$ind = 0;
			}
		}
		erase($win_op);		
	}while($input eq KEY_UP or $input eq KEY_DOWN or $input eq KEY_PPAGE or $input eq KEY_NPAGE);
		
}

sub if_poldek{
	my @ps = `ps ax`;
	if(grep /\d\d poldek/, @ps){
		endwin();
		&end_curses;
		system('clear');
		print _("\n\n  Some other Poldek is runing!\n\n");
		sleep 2;
		die;
	}
}

sub options{
	my $win_op = newwin($ny, $nx, $sy, $sx);
	erase($win_op);		
						     
	my $line = 1;
	my $ii = 1;
	$op = 0;
	while($input ne 'q'){
		erase($win_op);
		attron($win_op, COLOR_PAIR(6) | A_REVERSE);
     		addstr($win_op, 1, 0, $gl);
     		addstr($win_op, 1, $nx / 2 - 3, _("Options"));
		attroff($win_op, COLOR_PAIR(6) | A_REVERSE);
		hline($win_op, 2, 0, ACS_HLINE, $nx);
		#  for (my $j = 1; $j < 13; $j++){
		for(my $i = $ii, my $j = 3; ($j * 2 - 2) < $ny - 3 && $i < 13; $i++, $j++){
			if($i == $line){
				attron($win_op, COLOR_PAIR(2) | A_REVERSE);
			}
			if($op{$i}[1] eq 'ACTIVE'){
				attron($win_op, COLOR_PAIR(1) | A_REVERSE);
			}
			addstr($win_op, $j*2 - 2, 1, $op{$i}[0]);
			attroff($win_op, COLOR_PAIR(1));
			attroff($win_op, COLOR_PAIR(2) | A_REVERSE);
			addstr($win_op, $j*2 - 2, 14, $op{$i}[2]);
			if($i == 9){
				hline($win_op, $j*2 -3, 0, ACS_HLINE, $nx);
			}
				
		}
		vline($win_op, 3, 12, ACS_VLINE, $ny-6);
		hline($win_op, $ny-3, 0, ACS_HLINE, $nx);
		attron($win_op, COLOR_PAIR(1));
		addstr($win_op, $ny - 2, $nx / 2 - 22, _("[C]-ClearAll  [UP/DOWN]  [ENTER]-Activate [Q]"));
		attroff($win_op, COLOR_PAIR(1));
		&scr($nx, 3, $ny-3, 12, $line - 1, \$win_op); 
		box($win_op, 0, 0);
		refresh($win_op);
		$input = &key();
		if($input eq chr(10)){
			if($op{$line}[1] eq ''){
				$op{$line}[1] = 'ACTIVE';
			}elsif($op{$line}[1] eq 'ACTIVE'){$op{$line}[1] = '';}
		}
		if($input eq KEY_DOWN && $line < 12){
			$line++;
			if($line > (int(($ny - 6) / 2)) + $ii - 1){$ii++}
		}
		if($input eq KEY_UP && $line > 1){
			$line--;
			if($line < $ii && $ii > 1){$ii--}
		}
		if($input eq 'c'){
			foreach (keys %op){
				$op{$_}[1] = '';
			}
		}
	}
	@inst_op = ();
	@uninst_op = ();
	for (my $j = 1; $j < 9; $j++){
		if($op{$j}[1] eq 'ACTIVE'){
			push @inst_op, $op{$j}[0];
			$op = 1;
		}
	}
	for (my $j = 9; $j < 13; $j++){
		if($op{$j}[1] eq 'ACTIVE'){
			push @uninst_op, $op{$j}[0];
			$op = 1;
		}
	}
	delwin($win_op);
	$input = '';
	erase;
	&table;
	&men_key;
}

sub op{
	@op{1..12} = (
		['--downgrade','',_("Downgrade")],
		['--force    ','',_("Be unconcerned")],
		['--fresh    ','',_("Upgrade packages, but only if an earlier version currently exists")],
		['--greedy   ','',_("Upgrade packages which dependencies are broken by unistalled ones")],
		['--mercy    ','',_("Be tolerant for bugs which RPM tolerates")],
		['--nodeps   ','',_("Install packages with broken dependencies")],
		['--nofollow ','',_("Don\'t automatically install packages required by selected ones")],
		['--test     ','',_("Don\'t install, but tell if it would work or not")],
		['--force    ','',_("Be unconcerned")],
		['--nodeps   ','',_("Ignore broken dependencies")],
		['--nofollow ','',_("Don\'t automatically remove packages orphaned by selected ones")],
		['--test     ','',_("Don\'t uninstall, but tell if it would work or not")],
	);
}

sub edit_conf{
	my $win_ed = newwin($ny, $nx, $sy, $sx);
	erase($win_ed);		
	my @edit_conf = ();
	my $ind = 0;
	my $il = @edit_conf;
	my $editor ='';
	my %edit_conf = ();
	if(exists $ENV{EDITOR}){
		$editor = $ENV{EDITOR};
	}else{$editor = 'vi'}
	@edit_conf = `cat /etc/poldek.conf`;
	$il = @edit_conf;
	@edit_conf{0..$#edit_conf} = @edit_conf;
	do{
		attron($win_ed, COLOR_PAIR(6) | A_REVERSE);
     		addstr($win_ed, 1, 0, $gl);
     		addstr($win_ed, 1, $nx / 2 - 5, _("Poldek Conf"));
		attroff($win_ed, COLOR_PAIR(6) | A_REVERSE);
		hline($win_ed, 2, 0, ACS_HLINE, $nx);
		hline($win_ed, $ny-3, 0, ACS_HLINE, $nx);
		for(my $i = $ind, my $j = 3; $j < $ny - 3; $i++, $j++){
			if(exists $edit_conf{$i}){
				if(substr($edit_conf{$i}, 0, 1) eq '#'){
					attron($win_ed, COLOR_PAIR(4));
				}
				addstr($win_ed, $j, 1, $edit_conf{$i});
				attroff($win_ed, COLOR_PAIR(4));
			}
		}
		&scr($nx, 3, $ny-3, $il, $ind + $ny - 7, \$win_ed); 
		attron($win_ed, COLOR_PAIR(1));
		addstr($win_ed, $ny - 2, $nx / 2 - 8, _("[E]-Edit     [Q]"));
		attroff($win_ed, COLOR_PAIR(1));
		box($win_ed, 0, 0);
		refresh($win_ed);
		$input = &key;
		if($input eq KEY_DOWN){
			if($ind < $il - $ny + 6){$ind++}
		}elsif($input eq KEY_PPAGE){
			$ind -= $ny + 6;
			if($ind < 0){
				$ind = 0;
			}	
		}elsif($input eq KEY_UP){
			if($ind > 0){$ind--}
		}elsif($input eq KEY_NPAGE){
			$ind += $ny + 6;
			if($ind > $il - $ny + 6){
				$ind = $il - $ny + 6
			}
			if($ind < 0){
				$ind = 0;
			}
		}elsif($input eq 'e'){
			def_prog_mode();
			endwin();
			system('clear');
			my $time = (stat '/etc/poldek.conf')[9]
			  or die "stat /etc/poldek.conf failed: $!";
#			system((-r _ && -w _ ? () : $options{sudo} ? 'sudo' : qw(su -c)),
#				$editor, '/etc/poldek.conf');
			system(
				($options{dont_su}
					? ($options{sudo} 
						? ('sudo',$editor, '/etc/poldek.conf')
						: ())
					: "su -c \"$editor \/etc\/poldek\.conf\"")
			);
			reset_prog_mode();
			refresh();
			refresh($win_ed);
			if($time != (stat '/etc/poldek.conf')[9]){
				&info(_('Verifying...'));
				&init;
				@edit_conf = `cat /etc/poldek.conf`;
				@edit_conf{0..$#edit_conf} = @edit_conf;
				$il = @edit_conf;
				$ind = 0;
			}
		}
		erase($win_ed);		
	}while($input eq KEY_UP or $input eq KEY_DOWN or $input eq KEY_PPAGE or $input eq KEY_NPAGE or $input eq 'e');
	delwin($win_ed);
	$input = '';
	erase;
	&table;
	&men_key;
}

sub init_curses{
	$init_curses_performed = 1;
	initscr(); 
	if(has_colors()){
		start_color();
		&my_colors;
	}
	noecho();
	cbreak();
	keypad(stdscr, 1);
	curs_set(0);
}

sub end_curses{
	endwin(); 
	system('clear');
}

sub scr{
	my($x_long, $y_up, $y_down, $il, $index, $window) = (@_);
	my  $position = 0;
	$position = int(($index * ($y_down - $y_up))/$il);
	$position += $y_up;
	if(defined $window){
		attron($$window, COLOR_PAIR(6));
		vline($$window, $y_up, $x_long-2, ACS_VLINE, $y_down - $y_up);
		attron($$window, COLOR_PAIR(3));
    		addch($$window, $position, $x_long-2, ACS_DIAMOND);
		attroff($$window, COLOR_PAIR(3));
	} else {
		attron(COLOR_PAIR(6));
		vline($y_up, $x_long-2, ACS_VLINE, $y_down - $y_up);
		attron(COLOR_PAIR(3));
    		addch($position, $x_long-2, ACS_DIAMOND);
		attroff(COLOR_PAIR(3));
	}
}
	
sub logo{
	erase();
	my $posx = int(($x / 2) - 21);
	my $posy = int(($y / 2) - 5);
	addstr($y - 2, 2, _("Reading packages..."));
	refresh();
	my $win_log = newwin(9, 41, $posy, $posx);
	attron($win_log, COLOR_PAIR(4) | A_BOLD);
	addstr($win_log, 1, 5, '             _     _');           
	addstr($win_log, 2, 5, ' _ __   ___ | | __| | _____  __');
	addstr($win_log, 3, 5, '|  _ \ / _ \| |/ _` |/ _ \ \/ /');
	addstr($win_log, 4, 5, '| |_) | (_) | | (_| |  __ >  <'); 
	addstr($win_log, 5, 5, '| .__/ \___/|_|\____|\___/_/\_\\');
	addstr($win_log, 6, 5, '|_|');
	addstr($win_log, 7, 31, 'v 0.17.3');
	box($win_log, '*', '*');
	refresh($win_log);
}

sub verify{
	&info(_("Verifying packages..."));
	my $broken_dep = `poldek @sn -V`;
	my $il = 0;
	$broken_dep =~ s/ //g;
	my @broken = split("\n", $broken_dep);
	foreach (keys %packets){
		$packets{$_}[12] = '';
	}
	foreach (@broken){
		if(exists $packets{$_}){
			$packets{$_}[12] = 'b';
			$il++;
		}
	}
	&info(_("Finded ") . $il . _(" unsatisfied deps!"));
	sleep 2;
}

sub poldek{
	def_prog_mode();
	endwin();
	system('clear');
	system(
		($options{dont_su}
			? ($options{sudo} 
				? ('sudo', 'poldek', @sn)
				: ())
			: "su -c \"poldek @sn\"")
	);
	print $kzie;
	print "\n\n  ", _("Verifying packages..."), "\n";
	print $kbia;
	&read_poldek;
	%all_packets = %packets;
	&chkinstalled;
  	reset_prog_mode();
	refresh();
}
	
END {
	if ($init_curses_performed) {
		&end_curses;
		print "\033[0m";
	}
}

