#!/usr/bin/perl -w
#
#    Poldex
#    v 0.16.5
#    Simple frontend to great POLDEK.
#    
#==============================================================================
#    Copyright (C) 2003 Zbigniew Banasik (zban@intermedia.net.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;

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;

# Read the packets descriptions from poldek
&read_poldek;
%all_packets = %packets;

# Start curses
initscr(); 
if(has_colors()){
	start_color();
	&my_colors;
}
noecho();
cbreak();
keypad(stdscr, 1);
curs_set(0);
getmaxyx(stdscr ,my $y, my $x);

# 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";

# Initialisation
&chkinstalled;
@packets_list = sort keys %packets;
$num_p = @packets_list;
&table;
&men_key;

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

# End curses 
endwin(); 
system('clear');

sub key{
	my $key = getch();
	return $key;
}

sub help{
}

sub table{
	my $ilosc = 0;
	my $yy = 3;
	my $gl = ' ' x $x;
	my $wsk = '';
        $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 inst.) ($size_p/$size_pinst MB) ";
	}else{addstr(1, ($x / 4) - 15, " Packages (");
		printw "$num_p/$num_pinst 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];
		   if($packets{$packets_list[$j]}[0] eq 'I'){$b = ' Installed';
		   }else{$b = $packets{$packets_list[$j]}[0]};
		   $c = $packets{$packets_list[$j]}[2];
		   if(length($a) > int($x / 2) - 8){$a = substr($a, 0, (int($x / 2) - 8))}
		   if(length($c) > int($x / 2) + 8){$c = substr($c, 0, (($x - 2) - (int($x / 2) + 8)))}
		   addstr($yy, 0, $gl);
		   addstr($yy, 2, "$a");
		   if($b eq 'To  Install'){attron(COLOR_PAIR(1))}
		   if($b eq 'To Uninstall'){attron(COLOR_PAIR(4))}
		   if($b eq 'To Reinstall'){attron(COLOR_PAIR(2))}
		   addstr($yy, int($x / 2) - 6, "$b");
		   if($j == $index){attron(COLOR_PAIR(2))}
		   else{attroff(COLOR_PAIR(1) | COLOR_PAIR(4))}
		   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);
}

sub read_poldek{
	my $ind = -1;
	my $pack = '';	
	system('clear');
	&if_poldek;
	print "\n\n     Wczytuj opisy pakietw...\n\n";
	@desc=`/usr/bin/poldek --shcmd 'desc *'` or die "\n\n\n     Gdzie jest POLDEK? Dobre pytanie :-)\n\n";
	my $dl = @desc;
	print "\n     Przetwarzam opisy...\n\n";
	while(++$ind < $dl){
		if($desc[$ind] =~ /^Package:\s*(\S.*\S)/){$pack = $1; $ind++}
		if($desc[$ind] =~ /^Summary:\s*(\S.*\S)/){($packets{$pack}[1]) = $1; $ind++}
		if($desc[$ind] =~ /^Group:\s*(\S.*\S)/){($packets{$pack}[2]) = $1; $ind++}
		if($desc[$ind] =~ /^Vendor:\s*(\S.*\S)/){($packets{$pack}[3]) = $1; $ind++}
		if($desc[$ind] =~ /^License:\s*(\S.*\S)/){($packets{$pack}[4]) = $1; $ind++}
		if($desc[$ind] =~ /^Arch\/OS:\s*(\S.*\S)/){($packets{$pack}[5]) = $1; $ind++}
		if($desc[$ind] =~ /^URL:\s*(\S.*\S)/){($packets{$pack}[6]) = $1; $ind++}
		if($desc[$ind] =~ /^Built:\s*(\S.*\S)/){($packets{$pack}[7]) = $1; $ind++}
		if($desc[$ind] =~ /^Size:\s*(\S.*\((\d*) B\))/){($packets{$pack}[8]) = $1; $size_p += $2; $ind++}
		if($desc[$ind] =~ /^Package size:\s*(\S.*\S)/){($packets{$pack}[9]) = $1; $ind++}
		if($desc[$ind] =~ /^Path:\s*(\S.*\S)/){($packets{$pack}[10]) = $1; $ind++}
		if($desc[$ind] =~ /^Description:/){
			while(++$ind < $dl && $desc[$ind] !~ /Package:/ ){
				$desc[$ind] =~ s/^\n$//;
				if(defined $packets{$pack}[11]){
				$packets{$pack}[11] .= $desc[$ind];
				}else{$packets{$pack}[11] = $desc[$ind]}
			}
			$ind--;	
			next;
		}
	}
	$size_p = int $size_p/1000000;
}

sub on_key{
	if ($input eq KEY_DOWN){$index++; &table; &men_key;}
	if ($input eq KEY_UP){$index--; &table; &men_key}
	if ($input eq ' '){$index += $th + 1; $i += $th + 1; erase; &table; &men_key}
	if ($input eq 'b'){$index -= $th + 1; $i += $th + 1; erase; &table; &men_key}
	if ($input eq 'i'){
		if($packets{$packets_list[$index]}[0] eq ' ' && !grep /^\Q$packets_list[$index]\E$/, @to_install){
			$packets{$packets_list[$index]}[0] = 'To  Install';
			push @to_install, $packets_list[$index];
			&table();
			&men_key;
		}
		if($packets{$packets_list[$index]}[0] eq 'To Uninstall'){
			grep s/^\Q$packets_list[$index]\E$/ /, @to_uninstall;
			$packets{$packets_list[$index]}[0] = 'I';
			&table;
			&men_key;
		}
	}
	if ($input eq 'u'){
		if($packets{$packets_list[$index]}[0] eq 'I' && !grep /^\Q$packets_list[$index]\E$/, @to_uninstall){
			$packets{$packets_list[$index]}[0] = 'To Uninstall';
			push @to_uninstall, $packets_list[$index];
			&table();
			&men_key;
		}
		if($packets{$packets_list[$index]}[0] eq 'To  Install'){
			grep s/^\Q$packets_list[$index]\E$/ /, @to_install;
			$packets{$packets_list[$index]}[0] = ' ';
			&table;
			&men_key;
		}
	}
	if ($input eq 's'){
		$index = 0;
		if($sort < 5){$sort++;
		}else{$sort = 0}
		&my_sort;
		&table();
		&men_key;
	}
	if ($input eq 'r'){
		if($packets{$packets_list[$index]}[0] eq 'I' && !grep /^\Q$packets_list[$index]\E$/, @to_reinstall){
			$packets{$packets_list[$index]}[0] = 'To Reinstall';
			push @to_reinstall, $packets_list[$index];
			&table();
			&men_key;
		}
		elsif($packets{$packets_list[$index]}[0] eq 'To Reinstall'){
			grep s/^\Q$packets_list[$index]\E$/ /, @to_reinstall;
			$packets{$packets_list[$index]}[0] = 'I';
			&table;
			&men_key;
		}
	}	
	if ($input eq 'p'){	
		my $packets_to_inst = '';
		my $packets_to_uninst = '';
		my $packets_to_reinst = '';
		def_prog_mode();
		endwin();
		system('clear');
		if(grep /\S/, @to_install or grep /\S/, @to_uninstall or grep /\S/, @to_reinstall){
			if(grep /\S/, @to_reinstall){
				print $kzie;
				print "\n\n   Pakiety do przeinstalowania:\n\n";
				foreach my $a (@to_reinstall){
					if($a ne ' '){
						print " $a\n";
						$packets_to_reinst = join(' ', ($packets_to_reinst, $a));
					}
				}
				print $kbia;
				print "\n Poldek do dziea...\n\n";
				system("poldek --shcmd \'install --reinstall $packets_to_reinst\'");
				@to_reinstall = ();
			}
			if(grep /\S/, @to_uninstall){
				print $kcze;
				print "\n\n   Pakiety do odinstalowania:\n\n";
				foreach my $a (@to_uninstall){
					if($a ne ' '){
						print " $a\n";
						$packets_to_uninst = join(' ', ($packets_to_uninst, $a));
					}
				}
				print $kbia;
				print "\n Poldek do dziea...\n\n";
				system("poldek --shcmd \'uninstall $packets_to_uninst\'");
				@to_uninstall = ();
			}
			if(grep /\S/, @to_install){
				print $kzie;
				print "\n\n   Pakiety do zainstalowania:\n\n";
				foreach my $a (@to_install){
					if($a ne ' '){
						print " $a\n";
						$packets_to_inst = join(' ', ($packets_to_inst, $a));
					}
				}
				print $kbia;
				print "\n Poldek do dziea...\n\n";
				system("poldek --shcmd \'install $packets_to_inst\'");
				@to_install = ();
			}
			&chkinstalled;
			print $kcze;
			print "\n\n [KEY]\n";
			print $kbia;
			&key();
		}
	  	reset_prog_mode();
		refresh();
		&table;
		&men_key;
	}
	if ($input eq chr(10)){
		$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;
	}
	if ($input eq 'g'){
		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 ($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);
			}
			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 [UP/DOWN] [SPACE/B] [ENTER]-Group");
			attron($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]; $sort = 4;}
			if ($input eq KEY_DOWN){$indexg++}
			if ($input eq KEY_UP){$indexg--}
			if ($input eq ' '){$indexg += $ny - 6; $i += $ny - 6}
			if ($input eq 'b'){$indexg -= $ny - 6; $i += $ny - 6}
		}
		delwin($win_gr);
		$i = $index;
		$input = '';
		erase;
		&table;
		&men_key;
	}
	if ($input eq 'z'){
		my $ii = 0;
		my $gi = 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);
				addstr($win_sour, $y, 5, $sources_list[$j]);
				addstr($win_sour, $y, $nx - 12, $sources{$sources_list[$j]}[0]);
				attron($win_sour, COLOR_PAIR(1));
				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 - 6);
			vline($win_sour, 3, $nx - 8, ACS_VLINE, $ny - 6);
			vline($win_sour, 3, $nx - 13, ACS_VLINE, $ny - 6);
			hline($win_sour, $ny - 3, 0, ACS_HLINE, $nx);
			attron($win_sour, COLOR_PAIR(1));
			addstr($win_sour, $ny - 2, $nx / 2 - 31, "[Q]-Exit [UP/DOWN] [SPACE/B] [U]-Upa [ENTER][X]-Dis/Activate");
			attron($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 ' '){$indexg += $ny - 6; $i += $ny - 6}
			if ($input eq 'b'){$indexg -= $ny - 6; $i += $ny - 6}
			if ($input eq 'u'){&poldek_upa($sources_list[$indexg])}
			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;
				}
			}
		}
		delwin($win_sour);
  		%packets = ();		
		foreach my $key (sort keys %all_packets){
			if($sources{$all_packets{$key}[10]}[1] eq 'ACTIVE'){
 				$packets{$key} = $all_packets{$key};
			}
		}
		@packets_list = sort keys %packets;
		$i = 0;
		$index = 0;
		$input = '';
		erase;
		&table;
		&men_key;
	}
	if ($input eq 'f'){
		@packets_list = sort keys %packets;
		&table;
		my $buf = '';
		my $print_buf = '';
		my $del = 0;
		&clr;
		addstr($y-3, 5, " Find>$print_buf");
		&find_inf;			
		$input = &key;
		SO: while($input ne chr(10)){
			my $ind = 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;
				my $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, 5, " Find file>$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, 5, " Find file>/$print_buf");
						&find_inf;			
					}
					&info("Asking Poldek...");
					my @temp = `/usr/bin/poldek --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> $print_buf");
					}else{addstr($win_fi, 1, 5, "Find package> $print_buf");}
				     	addstr($win_fi, 1, $nx - 20, "Matched: $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'){
							addstr($win_fi, $yy, $nx - 12, "Installed");
							}else{addstr($win_fi, $yy, $nx - 12, $packets{$find_list[$j]}[0]);}
						}
						$yy++;
						attroff($win_fi,COLOR_PAIR(8) | A_REVERSE);
					}
					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 -14, 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, 5, " Find>$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, 5, " Find>$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{
			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();
		}
	}
	if($input eq 'd'){
		&desc_packets;
		$input = '';
		&table;
		&men_key;
	}
}

sub chkinstalled{
	@installed = `rpm -qa`;
	$num_pinst = 0;
	foreach my $b (keys %packets){$packets{$b}[0] = ' '}
	foreach my $a (@installed){
		chomp $a;
		if(exists $packets{$a}){
			$packets{$a}[0] = 'I';
			$num_pinst++;
			if($packets{$a}[8] =~ /\((\d*) B\)/){
				$size_pinst += $1;
			}
		}
	}
	$size_pinst = int $size_pinst / 1000000;
}

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) = @_;
	def_prog_mode();
	endwin();
	system('clear');
	system("poldek -s $sr/ --upa");
  	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]-FullDesc [S]-Sort [G]-ChGrp [I][U][R]-In/Un/Re-install [P]-Process");
	addstr($y - 2, $x / 2 - 39, "[Z]-Source [F]-Find [D]-Files [DOWN]-Next [UP]-Up [SPACE]-PgDown [B]-PgUp [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_RED, COLOR-BLACK);
#	init_pair(11, COLOR_RED, COLOR-BLACK);
}	

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}
	if($sort == 1){@packets_list= reverse sort keys %packets}
	if($sort == 2){@packets_list= sort {$packets{$b}[0] cmp $packets{$a}[0] || $a cmp $b}  keys %packets}
	if($sort == 3){@packets_list= sort {$packets{$a}[0] cmp $packets{$b}[0] || $a cmp $b} sort keys %packets}
	if($sort == 4){@packets_list= sort {$packets{$a}[2] cmp $packets{$b}[2] || $a cmp $b} sort keys %packets}
	if($sort == 5){@packets_list= sort {$packets{$b}[2] cmp $packets{$a}[2] || $a cmp $b} sort 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 --shcmd 'desc -f $mfile'`
	}
	my $il = @desc_f;
	my %tekst = ();
	foreach my $a (@desc_f){
		if($a !~ /^(Wczytyw|Przeczyt|adowa|Weryfik|uwaga|Usuni)/){
			$tekst{$ind} = $a;
			$ind++;
		}else{$il--}
	}
	$ind = 0;
	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 $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);
		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_UP){
			if($ind > 0){$ind--}
		}
		erase($win_op);		
	}while($input eq KEY_UP or $input eq KEY_DOWN);
		
}

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