# $Id: FolderTree.pm,v 1.9 2001/08/22 09:37:42 muhri Exp $
# -*- perl -*-
package Pronto::FolderTree;
use strict;
use vars qw( @new_count @msg_count %parent );

use SelfLoader;

sub insert_a_folder_node {
	my(@row)=@_; 
	my ($cp_menuitem,$mv_menuitem, $cp_menuitem2, $mv_menuitem2 ,$title);
        $main::foldernametoid{$row[0]} = $row[1];
        $main::folderidtoname{$row[1]} = $row[0];
        $parent{$row[1]} = $row[3];
        $title = [ $row[0] , "" , "" ];
        if (($row[2] == 65535) and (not defined $row[3] or $row[3] == -1)) {
                $main::ft_node[$row[1]] = $main::folder_tree->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
        } elsif ($row[2] == 65535) {
                $main::ft_node[$row[1]] = $main::folder_tree->insert_node($main::ft_node[$row[3]],undef,$title,5,undef,undef,undef,undef,0,1);
	} elsif (not defined $row[3] or $row[3] == -1) {
                $main::ft_node[$row[1]] = $main::folder_tree->insert_node(undef,$main::ft_node[$row[2]],$title,5,undef,undef,undef,undef,0,1);
        } else {
                $main::ft_node[$row[1]] = $main::folder_tree->insert_node($main::ft_node[$row[3]],$main::ft_node[$row[2]],$title,5,undef,undef,undef,undef,0,1);
        }
        if(defined $row[4] && $row[4] eq "n") {
                $main::folder_tree->collapse($main::ft_node[$row[1]]);
        }
        $main::ft_id{$main::ft_node[$row[1]]} = $row[1];
}

sub insert_folder_nodes {
	my($parent,$sibling)=@_;
	my($sql,$query,@row);
	if(not defined $sibling) {
		$sibling = 65535;
	}
	if(not defined $parent) {
		$sql = "select  name,id,sibling,parent from boxlist where ((sibling=?) and ((parent=-1) or (parent is NULL)))";
		$query = $main::conn->prepare($sql);
		$query->execute($sibling);
	}
	else {
		$sql = "select  name,id,sibling,parent from boxlist where ((sibling=?) and (parent=?))";
		$query = $main::conn->prepare($sql);
		$query->execute($sibling,$parent);
	}
	if(@row=$query->fetchrow_array()) {
		&insert_a_folder_node(@row);
		&insert_folder_nodes($row[1]);
		if(not defined $parent) {
			&insert_folder_nodes(undef,$row[1]);
		}
		else {
			&insert_folder_nodes($parent,$row[1]);
		}
	}
}

sub pack_box_onto_column_widget
{
	my ($hbox, $button, $label);
	$hbox = new Gtk::HBox(0,0);
	$button = new Gtk::Button("^");
	$button->set_usize(10,10);
	$button->signal_connect("clicked", 
		sub {
			if ($Pronto::MainWindow::FTDetach->sensitive()) {
				&Pronto::MainWindow::DetachFolderTree();
			} else {
				&Pronto::MainWindow::ReAttachFolderTree();
      			}
		}
		);	
	$label = new Gtk::Label(_("New"));
	$hbox->pack_start($label,0,0,0);
	$hbox->pack_start($button,0,0,0);
	$hbox->show_all();
	$main::folder_tree->set_column_widget(2,$hbox);
	return;
}	


sub fix_boxlist
{
	my($parent) = @_;
	my($sql,$query,$query2,@row,$lastid);
	if(defined $parent) {
		$sql = "select id,sibling,parent from boxlist where parent=? order by id desc";
		$query=$main::conn->prepare($sql);
		$query->execute($parent);
	}
	else {
		$sql = "select id,sibling,parent from boxlist where (parent=-1 or parent is NULL) order by id desc";
		$query=$main::conn->prepare($sql);
		$query->execute();
	}
	$lastid=65535;
	while(@row=$query->fetchrow_array()) {
		$sql = "update boxlist set sibling=? where id=?";
		$query2=$main::conn->prepare($sql);
		$query2->execute($lastid,$row[0]);
		$lastid=$row[0];
		&fix_boxlist($row[0]);
	}
}



sub init_folder_tree {
 	my ($sql, $query, @row);
        my @titles = ( _("Folder"), _("Msg"), _("New") );
# 	$sql = "select name,id,sibling,parent from boxlist order by id";
# 	$query = $main::conn->prepare($sql);
# 	$query->execute();
 	$main::folder_tree = new_with_titles Gtk::CTree(0,@titles);
 	$main::folder_tree->set_expander_style($main::prefs{'expander'});
	$main::folder_tree->set_line_style($main::prefs{'threadstyle'});
	if (not defined $main::prefs{'FolderTreeColWidth0'}) { $main::folder_tree->set_column_width(0,130); }
 	if (not defined $main::prefs{'FolderTreeColWidth1'}) { $main::folder_tree->set_column_width(1,30); }
 	pack_box_onto_column_widget();
	if($main::prefs{'msgcolumn'} eq "n") { 
		$main::folder_tree->set_column_visibility(1,0); 
 	}
 	else {
		$main::folder_tree->set_column_visibility(1,1);
 	}
 	if (not defined $main::prefs{'FolderTreeColWidth2'}) { $main::folder_tree->set_column_width(2,20); }
 	if($main::prefs{'newcolumn'} eq "n") { 
		$main::folder_tree->set_column_visibility(2,0); 
 	}
 	else {
		$main::folder_tree->set_column_visibility(2,1);
 	}
 	for (my $i = 0; $i < 3; $i++) {
 		if (defined $main::prefs{'FolderTreeColWidth' . $i}) {
			$main::folder_tree->set_column_width($i, $main::prefs{'FolderTreeColWidth' . $i});
		}
 	}
 	$main::folder_tree->signal_connect("select_row", sub { 
	 				if ($main::prefs{'messageview'} eq "clist") {
	 					&Pronto::MessageList::refresh_messages;
	 				} else { 
						&Pronto::MessageList::refresh_ctree("switch") 
					}
	 
	 				if($main::prefs{'onfolderchange'} eq 'top') {
						&Pronto::MessageList::goto_top;
	 				}
	 				elsif($main::prefs{'onfolderchange'} eq 'next unread') {
						&Pronto::MessageList::goto_next_unread_msg;
	 				}
	 				&Pronto::Read::clear_widget;
	 				});
		 
       	$main::folder_tree->signal_connect("unselect_row", sub { 
			        # CHANGE $main::message_list->refresh()
 					$main::message_clist->clear; 
					if ($main::root_window->{'button'}->visible) { 
						foreach(keys(%main::folderidtoname)) {
						if ($_ >= 1000) {
							$main::folder_tree->node_set_text($main::ft_node[$_],1,"");
							$main::folder_tree->node_set_text($main::ft_node[$_],2,"");
	  					}
					}
					$main::root_window->{'button'}->hide;}
					&Pronto::Read::clear_widget;});
	
	if (!$main::prefs{'Drag'}) {
		$main::folder_tree->set_reorderable(1);
	 	$main::folder_tree->signal_connect("tree_move", \&folder_moved);
	} else {
		&main::set_folder_tree_drag_signals();
	}			
	
	$main::folder_tree->signal_connect("resize-column" => sub {my ($d, $c, $w)=@_; $main::prefs{'FolderTreeColWidth'. $c}=$w;});
 	%main::foldernametoid = ();
 	%main::folderidtoname = ();
# 	while (@row=$query->fetchrow_array()) {
#  		my ($cp_menuitem,$mv_menuitem, $cp_menuitem2, $mv_menuitem2 ,$title);
#  		$main::foldernametoid{$row[0]} = $row[1];
#  		$main::folderidtoname{$row[1]} = $row[0];
#  		$parent{$row[1]} = $row[3];
#  		$title = [ $row[0] , "" , "" ];
#  		if (($row[2] == 65535) and ($row[3] == -1)) {
#    			$main::ft_node[$row[1]] = $main::folder_tree->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
#   		} elsif ($row[2] == 65535) {
#    			$main::ft_node[$row[1]] = $main::folder_tree->insert_node($main::ft_node[$row[3]],undef,$title,5,undef,undef,undef,undef,0,1);
#   		} else {
#    			$main::ft_node[$row[1]] = $main::folder_tree->insert_node($main::ft_node[$row[3]],$main::ft_node[$row[2]],$title,5,undef,undef,undef,undef,0,1);
#   		}
#   		if(defined $row[4] && $row[4] eq "n") {
#			$main::folder_tree->collapse($main::ft_node[$row[1]]);
#   		}
#  		$main::ft_id{$main::ft_node[$row[1]]} = $row[1];
#	}
	
	&insert_folder_nodes();
	#check that the boxlist table is correct, and all folders were inserted
	$sql = "select name,id,sibling,parent from boxlist order by parent,sibling";
 	$query = $main::conn->prepare($sql);
        $query->execute();
        while(@row=$query->fetchrow_array()) {
		if(not defined $main::ft_node[$row[1]]) {
			print _("oops, $row[0] folder was missed, make sure boxlist table is correct\n");
			$main::folder_tree->destroy();
			&fix_boxlist();
			&init_folder_tree();			
#			&insert_a_folder_node(@row);
		}
	}

	$main::folder_tree->signal_connect('button_press_event', \&rightclick, 1);
 	$main::folder_tree->{'popup'} =  new Gtk::Menu;
 	$main::folder_tree->{'popup'}->{'sep'} = new Gtk::MenuItem;
 	$main::folder_tree->{'popup'}->{'sep'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'sep'});
 	$main::folder_tree->{'popup'}->{'new'} = new Gtk::MenuItem(_("New Folder"));
 	$main::folder_tree->{'popup'}->{'new'}->signal_connect("activate" => \&Pronto::FolderTree::new_folder);
 	$main::folder_tree->{'popup'}->{'new'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'new'});
 	$main::folder_tree->{'popup'}->{'refilter'} = new Gtk::MenuItem(_("Refilter Folder"));
 	$main::folder_tree->{'popup'}->{'refilter'}->signal_connect("activate" => \&Pronto::FolderTree::refilter_folder);
 	$main::folder_tree->{'popup'}->{'refilter'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'refilter'});
 	$main::folder_tree->{'popup'}->{'delete'} = new Gtk::MenuItem(_("Delete Folder"));
 	$main::folder_tree->{'popup'}->{'delete'}->signal_connect("activate" => \&Pronto::FolderTree::delete_folder);
 	$main::folder_tree->{'popup'}->{'delete'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'delete'});
 	$main::folder_tree->{'popup'}->{'rename'} = new Gtk::MenuItem(_("Rename Folder"));
 	$main::folder_tree->{'popup'}->{'rename'}->signal_connect("activate" => \&Pronto::FolderTree::rename_folder);
 	$main::folder_tree->{'popup'}->{'rename'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'rename'});
 	$main::folder_tree->{'popup'}->{'sep2'} = new Gtk::MenuItem;
 	$main::folder_tree->{'popup'}->{'sep2'}->show;
	$main::folder_tree->{'popup'}->{'markasread'} = new Gtk::MenuItem(_("Mark as Read"));
	$main::folder_tree->{'popup'}->{'markasread'}->show();
	$main::folder_tree->{'popup'}->{'markasread'}->signal_connect("activate" => \&mark_folder_as_read);
 	$main::folder_tree->{'popup'}->{'new_view'} = new Gtk::MenuItem(_("Open in a new View"));
	$main::folder_tree->{'popup'}->{'new_view'}->show();
	$main::folder_tree->{'popup'}->{'new_view'}->signal_connect("activate", sub { &Pronto::CListView::new() });
	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'sep2'});
	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'markasread'});
	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'new_view'});
	$main::folder_tree->{'popup'}->{'sep3'} = new Gtk::MenuItem();
	$main::folder_tree->{'popup'}->{'sep3'}->show();
	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'sep3'});	
	$main::folder_tree->{'popup'}->{'import'} = new Gtk::MenuItem(_("Import into Folder"));
 	$main::folder_tree->{'popup'}->{'import'}->signal_connect("activate" => \&Pronto::FolderTree::init_import_folder);
 	$main::folder_tree->{'popup'}->{'import'}->show;
       	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'import'});
 	$main::folder_tree->{'popup'}->{'export'} = new Gtk::MenuItem(_("Export Folder"));
 	$main::folder_tree->{'popup'}->{'export'}->signal_connect("activate" => \&Pronto::FolderTree::init_export_folder);
 	$main::folder_tree->{'popup'}->{'export'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'export'});
 	$main::folder_tree->{'popup'}->{'sep3'} = new Gtk::MenuItem;
 	$main::folder_tree->{'popup'}->{'sep3'}->show;    
       	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'sep3'});
 	$main::folder_tree->{'popup'}->{'emptydeleted'} = new Gtk::MenuItem(_("Empty Deleted Items"));
	$main::folder_tree->{'popup'}->{'emptydeleted'}->signal_connect("activate"=>\&Pronto::FolderTree::empty_trash);
 	$main::folder_tree->{'popup'}->{'emptydeleted'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'emptydeleted'});
 	$main::folder_tree->{'popup'}->{'emptyfolder'} = new Gtk::MenuItem(_("Empty Selected folder"));
 	$main::folder_tree->{'popup'}->{'emptyfolder'}->signal_connect("activate" => \&Pronto::FolderTree::empty_folder);
 	$main::folder_tree->{'popup'}->{'emptyfolder'}->show;
 	$main::folder_tree->{'popup'}->append($main::folder_tree->{'popup'}->{'emptyfolder'});

}


sub get_folder_id
{
	my (@selection) = $main::folder_tree->selection();
	if (!@selection) { return undef }
	my $id = $main::ft_id{$selection[0]};
	return $id;
}

sub refresh_folder_tree {
	my ($play) = @_;
	my ($sql, $query, @row, $style);
	my ($oldnewcount) = $main::folder_tree->node_get_text($main::ft_node[0],2);
	@new_count = ();
	@msg_count = ();
	$sql = "select newmsg, boxid from messages";
        $query = $main::conn->prepare($sql);
        $query->execute();
        while (@row=$query->fetchrow_array()) {
               	if (($row[0]) and ($row[0] eq "y")) {
                       	$new_count[$row[1]]++;
                       	$new_count[0]++;
               	}
               	$msg_count[$row[1]]++;
               	$msg_count[0]++;
        }
	if($main::prefs{'RecMsgCount'} eq 'y') {
		$new_count[0]=0;
		$msg_count[0]=0;
		&main::message_count(0,\@msg_count,\@new_count);
	}
	$main::folder_tree->freeze;
	foreach (keys(%main::folderidtoname)) {
		if ($_ >= 1000) { next }
		if (!$msg_count[$_]) { $msg_count[$_] = 0;}
		if (!$new_count[$_]) { $new_count[$_] = 0;}
		$main::folder_tree->node_set_text($main::ft_node[$_], 1, $msg_count[$_]);
		$main::folder_tree->node_set_text($main::ft_node[$_], 2, $new_count[$_]);
		if ($new_count[$_] != 0 or ($msg_count[$_] != 0 and $_ == 2)) {
			if($main::prefs{'FolderNewBold'} eq "y" && $_ != 2) {
				
				$main::folder_tree->node_set_row_style($main::ft_node[$_], $main::bold);
			}
			if($main::prefs{'newcolumn'} eq 'n' and $main::prefs{'msgcolumn'} eq 'y') {
				my $temp = $main::folder_tree->node_get_text($main::ft_node[$_],1);
				$temp =~ s/\(*\)//g;
				$main::folder_tree->node_set_text($main::ft_node[$_],1,"$temp\($new_count[$_]\)");
			}
			if($main::prefs{'newcolumn'} eq 'n' and $main::prefs{'msgcolumn'} eq 'n') {
				if($_ == 2) {

					$main::folder_tree->node_set_text($main::ft_node[$_], 0,$main::folderidtoname{$_} . "($msg_count[$_])");
				} 
				else {
					$main::folder_tree->node_set_text($main::ft_node[$_], 0,$main::folderidtoname{$_} . "($new_count[$_])");
				}
			}

		} else {

			$main::folder_tree->node_set_row_style($main::ft_node[$_], $main::normal);
			my $temp = $main::folder_tree->node_get_text($main::ft_node[$_],1);
                        $temp =~ s/\(*\)//g;
                        $main::folder_tree->node_set_text($main::ft_node[$_],1,$temp);
			$main::folder_tree->node_set_text($main::ft_node[$_],0,$main::folderidtoname{$_});
		}
	}


	$main::folder_tree->thaw;
	my $newcount = $main::folder_tree->node_get_text($main::ft_node[0],2);
	if ($oldnewcount ne "" && defined $play && $play == 1) {
		if (($main::prefs{'PlaySound'} eq "y") && ($newcount > $oldnewcount)) {
			system("$main::prefs{'SndCmd'} $main::prefs{'SndFl'}");
		}	
	}
	&main::set_win_title;
	return 1;
}

sub numerically { $a <=> $b; }

1;

__DATA__

sub new_folder {
  	
	my ($virtual,$querycontent,$body) = @_;
  	my ($fldr_dlg, $fd_hbox, $fd_label, $fd_button, $fd_ok, $fd_entry,
      	$fldr_ctree, $fldr_scroll, $fd_label2, %lparent, @nf_node, $sql,
      	$query, %lft_id, @row, $title,$selected);
  	my @fldr_sel = $main::folder_tree->selection;
  	if (@fldr_sel) { $selected = $main::ft_id{$fldr_sel[0]} }
  	$fldr_dlg = new Gtk::Dialog;
  	$fldr_dlg->set_default_size(&main::get_win_size("fldrdlg",300,300));
  	$fldr_dlg->position(-mouse);
  	$fldr_dlg->signal_connect("destroy" => sub { $fldr_dlg->destroy; });
  	$fldr_dlg->signal_connect("delete_event" => \&Gtk::false);
  	$fldr_dlg->set_title(_("Enter Folder Name..."));
  	$fldr_dlg->border_width(0);
  	$fd_hbox=new Gtk::HBox(0,0);
  	$fd_hbox->border_width(10);
  	$fldr_dlg->vbox->pack_start($fd_hbox,0,1,0);
  	$fd_hbox->show;
  	$fd_label=new Gtk::Label _("Folder Name: ");
  	$fd_label->set_alignment(0.5,0.5);
  	$fd_hbox->pack_start($fd_label,0,1,0);
  	$fd_label->show;
  	$fd_entry=new Gtk::Entry;
  	$fd_entry->set_text('');
  	$fd_entry->set_editable('1');
  	$fd_hbox->pack_start($fd_entry,1,1,0);
  	$fd_entry->show;
  	$fd_label2=new Gtk::Label _("Create new folder in:");
  	$fd_label2->set_alignment(0.0,0.5);
  	$fldr_dlg->vbox->pack_start($fd_label2,0,1,0);
  	$fd_label2->show;
  	$fldr_ctree = new Gtk::CTree(1,0);
  	$fldr_ctree->set_column_width(0,130);
  	$sql = "select name,id,sibling,parent from boxlist order by parent,sibling";
  	$query = $main::conn->prepare($sql);
  	$query->execute();
  	while (@row=$query->fetchrow_array()) {
   		$title = [ $row[0] ];
   		if (($row[2] == 65535) and ($row[3] == -1)) {
    			$nf_node[$row[1]] = $fldr_ctree->insert_node(undef,undef,$title,5,undef,undef,undef,undef,0,1);
   		} elsif ($row[2] == 65535) {
    			$nf_node[$row[1]] = $fldr_ctree->insert_node($nf_node[$row[3]],undef,$title,5,undef,undef,undef,undef,0,1);
   		} else {
    			$nf_node[$row[1]] = $fldr_ctree->insert_node($nf_node[$row[3]],$nf_node[$row[2]],$title,5,undef,undef,undef,undef,0,1);
   		}
   		$lft_id{$nf_node[$row[1]]} = $row[1];
  		if (@fldr_sel && $selected == $row[1]) { $selected = $nf_node[$row[1]] }
  	}
  	if (@fldr_sel) { $fldr_ctree->select($selected); }
  	$fldr_ctree->show;
  	$fldr_scroll = new Gtk::ScrolledWindow(undef,undef);
  	$fldr_scroll->set_policy('automatic', 'automatic');
  	$fldr_scroll->show;
  	$fldr_scroll->add($fldr_ctree);
  	$fldr_dlg->vbox->pack_start($fldr_scroll,1,1,0);
  	$fd_ok=new Gtk::Button _("Ok");
  	$fd_ok->can_default(1);
  	$fd_ok->show;
  	$fldr_dlg->action_area->pack_start($fd_ok,1,1,0);
  	$fd_button=new Gtk::Button _("Cancel");
  	$fd_button->signal_connect("clicked", sub { $fldr_dlg->destroy; });
  	$fldr_dlg->action_area->pack_start($fd_button,1,1,0);
  	$fd_button->show;
  	$fldr_dlg->show;
  		if (defined $virtual and $virtual eq "y") {
   		$fd_ok->signal_connect("clicked" => \&add_new_folder, $fd_entry,
   			$fldr_dlg, $fldr_ctree, \%lft_id, $virtual, $querycontent,$body);
   		$fd_entry->signal_connect("activate" => \&add_new_folder, $fd_entry,
   			$fldr_dlg, $fldr_ctree, \%lft_id, $virtual, $querycontent,$body);
   		} else {
  		$fd_ok->signal_connect("clicked" => \&add_new_folder, $fd_entry,
     			$fldr_dlg, $fldr_ctree, \%lft_id);
  		$fd_entry->signal_connect("activate" => \&add_new_folder, $fd_entry,
     			$fldr_dlg, $fldr_ctree, \%lft_id);
  		}
  	$fldr_dlg->signal_connect("size-request" => \&main::save_win_size, "fldrdlg", $fldr_dlg->window);
	$fd_entry->grab_focus();  	
	return 1;
}


sub folderlist_drag_data_received {
	my ($widget, $context, $x, $y, $data, $info, $time) = @_;
	if (($data->length >= 0) && ($data->format == 8)) {
		
		if (!@main::dragged) {
			&Pronto::Data::Message::move(get_folder_id,$data->data);
		} else {
			&Pronto::Data::Message::move(get_folder_id,@main::dragged);
		}
		
		&Pronto::MessageList::refresh();
		&Pronto::FolderTree::refresh_folder_tree();
		$context->finish (1, 0, $time);
		return 1;
	}
	$context->finish (0, 0, $time);
}

sub folderlist_drag_motion 
{
        my ($widget, $context, $x, $y, $time) = @_;
	my ($row, $column) = $widget->get_selection_info($x,$y);
	$widget->select_row($row,$column);
	$context->status ($context->suggested_action, $time);
	return 1;
}	
					

sub folder_moved {
 	my ($widget, $node1, $node2, $node3) = @_;
 	my ($folder, $new_parent, $new_sib, $sql, $query);
 	if (defined $node1) { $folder = $main::ft_id{$node1}; }
 	if (defined $node2) { $new_parent = $main::ft_id{$node2}; }
 	if (defined $node3) {
  		$new_sib = $main::ft_id{$node3}; 
 	} else {
  		$new_sib = 65535;
 	}
 	$sql = "select sibling from boxlist where id = ?";
 	$query=$main::conn->prepare($sql);
 	$query->execute($folder);
 	my ($old_sib) = $query->fetchrow_array();
 	$sql = "select id from boxlist where sibling = ?";
 	$query=$main::conn->prepare($sql);
 	$query->execute($folder);
 	my ($old_pre) = $query->fetchrow_array();
 	$sql = "select id from boxlist where ((sibling = ?) and (parent = ?))";
 	$query=$main::conn->prepare($sql);
 	$query->execute($new_sib, $new_parent);
 	my ($new_pre) = $query->fetchrow_array();
 	$sql = "update boxlist set sibling = ? where id = ?";
 	$query=$main::conn->prepare($sql);
 	$query->execute($old_sib,$old_pre);
 	if (defined $new_pre) { $query->execute($folder,$new_pre); }
 	$sql = "update boxlist set parent = ?, sibling = ? where id = ?";
 	$query=$main::conn->prepare($sql);
 	$query->execute($new_parent,$new_sib,$folder);
 	$parent{$folder} = $new_parent;
 	if($folder < 1000) {
		$Pronto::FolderMenus::mv_menu_menus{0}->detach;
        	$Pronto::FolderMenus::pmv_menus{0}->detach;
		$Pronto::FolderMenus::cp_menu_menus{0}->detach;
        	$Pronto::FolderMenus::pcp_menus{0}->detach;
        	$Pronto::FolderMenus::mv_menu_menus{0}->destroy;
        	$Pronto::FolderMenus::pmv_menus{0}->destroy;
		$Pronto::FolderMenus::cp_menu_menus{0}->destroy;
        	$Pronto::FolderMenus::pcp_menus{0}->destroy;

		($Pronto::FolderMenus::mv_menu_menus{0},$Pronto::FolderMenus::pmv_menus{0},$Pronto::FolderMenus::cp_menu_menus{0},$Pronto::FolderMenus::pcp_menus{0})=&Pronto::FolderMenus::mvcp_menu(0);
        	$Pronto::FolderMenus::mv_menu_items{0}->set_submenu($Pronto::FolderMenus::mv_menu_menus{0});
                $Pronto::FolderMenus::pmv_items{0}->set_submenu($Pronto::FolderMenus::pmv_menus{0});
		$Pronto::FolderMenus::cp_menu_items{0}->set_submenu($Pronto::FolderMenus::cp_menu_menus{0});
        	$Pronto::FolderMenus::pcp_items{0}->set_submenu($Pronto::FolderMenus::pcp_menus{0});
 	}
 	&set_folder_style;
 	&refresh_folder_tree;

 return 1;
}

sub rename_folder {
	my ($sql, $query, $foldername, $curfolder, @row, $win,$hbox, $ok, $cancel, $lbl, $entry, $newfoldername);
	$curfolder = get_folder_id();
	if (!$curfolder) { &main::err_dialog("Select a folder first!"); return 1; }
	$foldername = $main::folderidtoname{$curfolder};
	$win = new Gtk::Dialog;
	$win->set_title(_("Rename Folder ") ."$foldername");
	$win->signal_connect("destroy" => sub  { $win->destroy });
	$win->signal_connect("delete_event" => \&Gtk::false);
	$win->set_default_size('300','90');
	$win->set_policy(1,1,0);
	$win->position(-mouse);
	$hbox = new Gtk::HBox(0,5);
	$win->vbox->pack_start($hbox,1,1,0);
	$hbox->show;
	$win->show;
	$lbl = new Gtk::Label(_("Rename ") ."$foldername to: ");
	$lbl->set_alignment(0.0,0.5);
	$lbl->show;
	$hbox->pack_start($lbl,0,0,5);
	$entry = new Gtk::Entry;
	$entry->set_editable('1');  
	$entry->show;
	$hbox->pack_start($entry,1,0,1);
	$ok = new Gtk::Button _("Ok");
	$ok->can_default(0);
	$ok->signal_connect("clicked", sub { 
					$newfoldername = $entry->get_text;
					if ($newfoldername eq '') { 
						&main::err_dialog(_("enter a name please!"));
						return 1; 
					} else {
						$sql = "update boxlist set name = '$newfoldername' where id ='$curfolder'";
						$query = $main::conn->prepare($sql);
						$query->execute();
						$win->destroy;
						&refresh_folder_name($curfolder, $newfoldername, $foldername);
					}
				});
	$ok->show;
	$win->action_area->pack_start($ok,1,1,0);
	$cancel = new Gtk::Button _("Cancel");
	$cancel->signal_connect("clicked", sub { $win->destroy; });
	$cancel->can_default(1);
	$win->action_area->pack_start($cancel, 1, 1, 0);
	$cancel->grab_default;
	$cancel->show;
	return 1;
}

sub refresh_folder_name {

 	my ($folderid, $newfoldername, $oldname) = @_;
 	$main::folder_tree->freeze;
 	$main::folder_tree->node_set_text($main::ft_node[$folderid], 0, "$newfoldername");
 	$main::folder_tree->thaw;
 	if ($folderid < 1000) {
		# $cp_menu_items{$folderid}->destroy;
 		$Pronto::FolderMenus::mv_menu_items{$folderid}->destroy;
		# $pcp_items{$folderid}->destroy;
 		$Pronto::FolderMenus::pmv_items{$folderid}->destroy; 
       		delete $main::folderidtoname{$folderid};
		delete $main::foldernametoid{$oldname};
 		$main::folderidtoname{$folderid} = $newfoldername;
 		$main::foldernametoid{$newfoldername} = $folderid;
		if($parent{$folderid} < 1000) {
		        $Pronto::FolderMenus::mv_menu_menus{$parent{$folderid}}->detach;
			$Pronto::FolderMenus::pmv_menus{$parent{$folderid}}->detach;
			$Pronto::FolderMenus::cp_menu_menus{$parent{$folderid}}->detach;
        		$Pronto::FolderMenus::pcp_menus{$parent{$folderid}}->detach;	
			$Pronto::FolderMenus::mv_menu_menus{$parent{$folderid}}->destroy;
			$Pronto::FolderMenus::pmv_menus{$parent{$folderid}}->destroy;
			$Pronto::FolderMenus::cp_menu_menus{$parent{$folderid}}->destroy;
        		$Pronto::FolderMenus::pcp_menus{$parent{$folderid}}->destroy;
			($Pronto::FolderMenus::mv_menu_menus{$parent{$folderid}},$Pronto::FolderMenus::pmv_menus{$parent{$folderid}},$Pronto::FolderMenus::cp_menu_menus{$parent{$folderid}},$Pronto::FolderMenus::pcp_menus{$parent{$folderid}})= &Pronto::FolderMenus::mvcp_menu($parent{$folderid});
			$Pronto::FolderMenus::mv_menu_items{$parent{$folderid}}->set_submenu($Pronto::FolderMenus::mv_menu_menus{$parent{$folderid}});
			$Pronto::FolderMenus::pmv_items{$parent{$folderid}}->set_submenu($Pronto::FolderMenus::pmv_menus{$parent{$folderid
			}});
			$Pronto::FolderMenus::cp_menu_items{$parent{$folderid}}->set_submenu($Pronto::FolderMenus::cp_menu_menus{$parent{$folderid}});
        		$Pronto::FolderMenus::pcp_items{$parent{$folderid}}->set_submenu($Pronto::FolderMenus::pcp_menus{$parent{$folderid
			}});
 		}
 	}
	&main::set_win_title;

return 1;
}
	      
sub delete_folder {
	my ($widget, $curfolder) = @_;
	my (@foldersel, $sql, $query);
	if (!$curfolder) {
		$curfolder = get_folder_id();
		if (!$curfolder) { return }
		
	}
	if ($curfolder <= 4) { return; }
	if ($parent{$curfolder} == 4) {
		$main::folder_tree->remove_node($main::ft_node[$curfolder]);
		$sql = "delete from boxlist where id=$curfolder";
		$main::conn->do($sql);
		$sql = "delete from filters where boxid=$curfolder and type != 6";
		$main::conn->do($sql);
		$sql = "select id from messages where boxid=?";
		$query = $main::conn->prepare($sql);
		$query->execute($curfolder);
		while (my ($msgid)=$query->fetchrow_array()) {
			&Pronto::Data::Message::delete($msgid);
		}	
		if ($curfolder < 1000) {
			$Pronto::FolderMenus::mv_menu_menus{0}->detach;
        		$Pronto::FolderMenus::pmv_menus{0}->detach;
			$Pronto::FolderMenus::cp_menu_menus{0}->detach;
                        $Pronto::FolderMenus::pcp_menus{0}->detach;
        		$Pronto::FolderMenus::mv_menu_menus{0}->destroy;
        		$Pronto::FolderMenus::pmv_menus{0}->destroy;
			$Pronto::FolderMenus::cp_menu_menus{0}->destroy;
                	$Pronto::FolderMenus::pcp_menus{0}->destroy;
			($Pronto::FolderMenus::mv_menu_menus{0},$Pronto::FolderMenus::pmv_menus{0},$Pronto::FolderMenus::cp_menu_menus{0},$Pronto::FolderMenus::pcp_menus{0})= &Pronto::FolderMenus::mvcp_menu(0);
        		$Pronto::FolderMenus::mv_menu_items{0}->set_submenu($Pronto::FolderMenus::mv_menu_menus{0});
        		$Pronto::FolderMenus::pmv_items{0}->set_submenu($Pronto::FolderMenus::pmv_menus{0});
			$Pronto::FolderMenus::cp_menu_items{0}->set_submenu($Pronto::FolderMenus::cp_menu_menus{0});
                	$Pronto::FolderMenus::pcp_items{0}->set_submenu($Pronto::FolderMenus::pcp_menus{0});
		}
		if ($foldersel[0]) {
			delete $main::ft_id{$foldersel[0]};
		}
		delete $main::foldernametoid{$main::folderidtoname{$curfolder}};
		delete $main::folderidtoname{$curfolder};
	} else {
		$main::folder_tree->move($main::ft_node[$curfolder],$main::ft_node[4],undef);
		$parent{$curfolder} = 4;
		$sql = "select id from boxlist where sibling=$curfolder";
		$query = $main::conn->prepare($sql);
		$query->execute();
		if ($query->rows() == 1) {
			# previous sibling
			my ($prev_sibling) = $query->fetchrow();

			$sql = "select sibling from boxlist where id=$curfolder";
			$query = $main::conn->prepare($sql);
			$query->execute();
			if ($query->rows() > 1) {
				# big error! somehow our id doesn't exist
				return 0;
			}
			my ($next_sibling) = $query->fetchrow();

			$sql = "update boxlist set sibling=$next_sibling where id=$prev_sibling";
			$main::conn->do($sql);
		} elsif ($query->rows() > 1) {
			# somehow we have multiple siblings pointing to us = bad
			return 0;
		}

		$sql = "select id from boxlist where parent=4 and sibling=65535";
		$query = $main::conn->prepare($sql);
		$query->execute();
		if (my ($deleted_sibling) = $query->fetchrow()) {
			$sql = "update boxlist set sibling=$curfolder where id=$deleted_sibling";
			$main::conn->do($sql);
		}
		$sql = "update boxlist set parent=4,sibling=65535 where id=$curfolder";
		$main::conn->do($sql);



	}
	return 1;
}

sub add_new_folder {
	
	my ($widget, $entry, $win, $fldr_ctree, $ftidref,$virtual,$querycontent,$body) = @_;
	my ($nfparent, $foldername, @sel, %lft_id);
	$foldername = $entry->get_text;
	if ($foldername eq '') { &main::err_dialog(_("Enter a name first !")); return 1; }
	foreach (keys(%main::foldernametoid)) {
		if (lc($foldername) eq lc($_)) {
			&main::err_dialog(_("Unique names please!"));
			return 1;
		}
	}

	%lft_id = %{$ftidref};
 	@sel = $fldr_ctree->selection();
 	if (@sel) {
  		$nfparent = $lft_id{$sel[0]};
 	} else {
  		$nfparent = 0;
 	}
 	$win->destroy;	
	my ($sql, $query, $sort, $id);
 	$sql="select id from boxlist where ((parent = ?) and (sibling = 65535))";
 	$query = $main::conn->prepare($sql);
 	$query->execute($nfparent);
 	my ($oldtail) = $query->fetchrow_array();
 	if (not defined $virtual) {
 		$sql="insert into boxlist (id, name, parent, sibling) values (?,?,?,?)";
  		$query = $main::conn->prepare($sql);
 		$id = &main::newid_folder('boxlist', $main::conn);
 		$query->execute($id, $foldername,$nfparent,65535);
 	} else {
 		$sql = "insert into boxlist (id,name,parent,sibling,query,body) values (?,?,?,?,?,?)";
 		$query = $main::conn->prepare($sql);
 		$id = &main::newid1000('boxlist',$main::conn);
 		$query->execute($id,$foldername,$nfparent,65535,$querycontent,$body);
 	}
 	if (defined $oldtail) {
  		$sql="update boxlist set sibling = ? where id = ?";
  		$query = $main::conn->prepare($sql);
  		$query->execute($id,$oldtail);
 	}
 	my ($title);
 	$main::foldernametoid{$foldername} = $id;
 	$main::folderidtoname{$id} = $foldername;
 	$title = [ $foldername , "" ];
 	$main::ft_node[$id] = $main::folder_tree->insert_node($main::ft_node[$nfparent],undef,$title,5,undef,undef,undef,undef,0,1);
 	$main::ft_id{$main::ft_node[$id]} = $id;
 	$parent{$id}=$nfparent;
 	if (not defined $virtual) {
  		if(defined $Pronto::FolderMenus::mv_menu_menus{$parent{$id}}) {
			$Pronto::FolderMenus::mv_menu_menus{$parent{$id}}->detach;
  			$Pronto::FolderMenus::pmv_menus{$parent{$id}}->detach;
			$Pronto::FolderMenus::cp_menu_menus{$parent{$id}}->detach;
        		$Pronto::FolderMenus::pcp_menus{$parent{$id}}->detach;
  			$Pronto::FolderMenus::mv_menu_menus{$parent{$id}}->destroy;
  			$Pronto::FolderMenus::pmv_menus{$parent{$id}}->destroy;
			$Pronto::FolderMenus::cp_menu_menus{$parent{$id}}->destroy;
        		$Pronto::FolderMenus::pcp_menus{$parent{$id}}->destroy;
  		}

		($Pronto::FolderMenus::mv_menu_menus{$parent{$id}},$Pronto::FolderMenus::pmv_menus{$parent{$id}},$Pronto::FolderMenus::cp_menu_menus{$parent{$id}},$Pronto::FolderMenus::pcp_menus{$parent{$id}})= &Pronto::FolderMenus::mvcp_menu($parent{$id});
  		$Pronto::FolderMenus::mv_menu_items{$parent{$id}}->set_submenu($Pronto::FolderMenus::mv_menu_menus{$parent{$id}});
  		$Pronto::FolderMenus::pmv_items{$parent{$id}}->set_submenu($Pronto::FolderMenus::pmv_menus{$parent{$id}});
  		$Pronto::FolderMenus::cp_menu_items{$parent{$id}}->set_submenu($Pronto::FolderMenus::cp_menu_menus{$parent{$id}});
  		$Pronto::FolderMenus::pcp_items{$parent{$id}}->set_submenu($Pronto::FolderMenus::pcp_menus{$parent{$id}});
 	}
 	$win->destroy;
 	&refresh_folder_tree;
 	if ($id > 1000) {
 		&set_folder_style
 	}
 
 	return 1;
}


sub init_export_folder {
 
 	my ($widget, $listwidget)=@_;
 	my ($fs_window, $sql, $query, $curfolder, $foldername);
        $curfolder = get_folder_id();	
	if (!$curfolder) {
		&main::err_dialog(_("Please select a folder first!")); 
		return 1; 
       }
 
 	$sql = "select name from boxlist where id = '$curfolder'";
 	$query=$main::conn->prepare($sql);
 	$query->execute();
 	$foldername = $query->fetchrow_array();
 	$fs_window = new Gtk::FileSelection (_("Choose Directory to export folder ") ."($foldername) to  ...");
 	$fs_window->position(-mouse);
 	$fs_window->file_list->set_sensitive(0);
 
 	$fs_window->signal_connect("destroy", sub {$fs_window->destroy;});
   	$fs_window->signal_connect("delete_event" => \&Gtk::false);
    	$fs_window->ok_button->signal_connect("clicked", \&main::export_folder, $fs_window, $listwidget, $main::conn, $curfolder, $foldername);
    	$fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;});
     	$fs_window->show;
      	return 1;
}
      
sub init_import_folder {

 	my ($widget, $listwidget)=@_;
 	my ($fs_window, $sql, $query, $curfolder, $foldername);
  	$curfolder = get_folder_id();
	if (!$curfolder) {
	 	&main::err_dialog(_("Please select a folder first!"));
		return 1; 
	}
 
  	$sql = "select name from boxlist where id = '$curfolder'";		     
  	$query=$main::conn->prepare($sql);
  	$query->execute();
  	$foldername = $query->fetchrow_array();
 	$fs_window = new Gtk::FileSelection (_("Choose File to import into folder ") . "($foldername)  ...");
 	$fs_window->position(-mouse);
 	$fs_window->signal_connect("destroy", sub {$fs_window->destroy;});
 	$fs_window->signal_connect("delete_event" => \&Gtk::false);
 	$fs_window->ok_button->signal_connect("clicked", \&main::import_folder, $fs_window, $listwidget, $main::conn, $curfolder, $foldername);
 	$fs_window->cancel_button->signal_connect("clicked", sub {$fs_window->destroy;});
 	$fs_window->show;
      	return 1;
}

sub refilter_folder 
{
	&Pronto::Data::Message::refilter("folder");
	return 1;
}	

sub empty_folder {

     	my ($sql, $sql2, $query,$curfolder, @row);
     
     		$curfolder = get_folder_id();
		if (!$curfolder) { &main::err_dialog(_("Please select a folder first!")); return 1; }
     		if ($curfolder == 4) { &main::err_dialog(_("Use Empty deleted items for the trash folder")); return 1;}
       		$sql = "select id from messages where boxid = '$curfolder'";
		$query=$main::conn->prepare($sql);
		$query->execute();
		while (@row = $query->fetchrow_array()) {
			$sql = "update messages set boxid = 4  where id = @row";
        		$main::conn->do($sql);
			if ($main::prefs{'DeleteMarksAsRead'} eq "y") { 
				$sql2 = "update messages set newmsg = 'n' where id = @row";
				$main::conn->do($sql2);
			}
			
			if ($main::prefs{'EmptyNoBlock'}) {
				while (Gtk->events_pending()) {
					Gtk->main_iteration();
				}	
			}	
		}
	&refresh_folder_tree;
	$main::message_clist->clear;
	if (get_folder_id() == $curfolder) {
		&Pronto::Read::clear_widget();
	}	
	return 1;
}

sub set_folder_style {
	my($sp,$sm,$vp,$vm);
	if(-f "$main::prefs{'PixmapDir'}/search.xpm") {
		($sp,$sm)=Gtk::Gdk::Pixmap->create_from_xpm($main::root_window->window,$main::root_window->style->bg('normal'),"$main::prefs{'PixmapDir'}/search.xpm");
	} else {
		($sp,$sm)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::root_window->window,$main::root_window->style->bg('normal'),@main::dummy_pixmap);
       }
	if (-f "$main::prefs{'PixmapDir'}/vfolder.xpm") {
		($vp,$vm)=Gtk::Gdk::Pixmap->create_from_xpm($main::root_window->window,$main::root_window->style->bg('normal'),"$main::prefs{'PixmapDir'}/vfolder.xpm");
	} else {
		($vp,$vm)=Gtk::Gdk::Pixmap->create_from_xpm_d($main::root_window->window,$main::root_window->style->bg('normal'),@main::dummy_pixmap);
       }
       

	foreach(keys(%main::folderidtoname)) {	
		if ($_ == 1000) { 
			$main::folder_tree->node_set_pixtext($main::ft_node[$_],0,$main::folderidtoname{$_},2,$sp,$sm);
		}
      		elsif ($_ > 1000) {  
			$main::folder_tree->node_set_pixtext($main::ft_node[$_],0,$main::folderidtoname{$_},2,$vp,$vm);
		}
	}
	
return 1;
}

sub empty_trash {
	my ($widget,$at_exit) = @_;
	my ($sql, $query, @foldersel, $curfolder,@row);
	$sql = "select id from boxlist where parent = 4";
	$query=$main::conn->prepare($sql);
	$query->execute();
	while (@row=$query->fetchrow_array()) {
		&delete_folder(undef, $row[0]);
	}
	$sql = "select id from messages where boxid = 4";
	$query=$main::conn->prepare($sql);
	$query->execute();
	while (my ($msgid)=$query->fetchrow_array()) {
		&Pronto::Data::Message::delete($msgid);
		if ($main::prefs{'EmptyNoBlock'}) {
			while (Gtk->events_pending()) {
				Gtk->main_iteration();
			}	
		}
	}
	$curfolder = &get_folder_id();
	if ($curfolder) {
		if ($curfolder == 4) { 
			$main::message_clist->clear;
			&Pronto::Read::clear_widget();
		}
	}
	if (!$at_exit) {
		&Pronto::FolderTree::refresh_folder_tree; 
	}
	return 1;
}




sub rightclick {

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

sub mark_folder_as_read
{
	my $folder = get_folder_id();
	if (!$folder) { return 1; }
	my $sql = "update messages set newmsg = 'n' where boxid = $folder";
	$main::conn->do($sql);
	&Pronto::MessageList::refresh();
	&refresh_folder_tree;
	return 1;
}	


1;
