package Frlchooser;

use strict;
use Tk;
require Tk::Dialog;
use vars qw(@ISA @EXPORT);
use Exporter;
@ISA = ('Exporter','Dialog');
@EXPORT = qw(&chooser);
#@ISA = qw(Tk::Exporter,Tk::Dialog);
#@EXPORT = qw(&chooser);
use Cwd;

# Fonts
my ($title_f, $entry_f, $button_f, $label_f);


sub chooser {
# The var to change on MAIN
    my ($mainWindow,$file_sel, $file_lock, $save_mode, $wait,$ext); # Locking mechanism
    ($mainWindow, $title_f, $entry_f, $button_f, $label_f, $file_sel, $file_lock,$save_mode,$ext) = @_;

    if ($ext !~ /^\.\S+/){
	$ext=".".$ext;
    }

# If save is selected, the following variables are set
    my $skip;
    my $save_file;

    if ($save_mode eq 'save'){
        $skip = 0;
	$save_file = $ext;
#        $save_file = ".frl";
    }

# Set the directory to the user's current directory
    my $directory = ".";

# Change directories and get the current full path
    chdir ($directory);
    $directory = cwd();
    
    
# Open the directory and read the contents.
    opendir (DIR, ".");
    my @contents = readdir (DIR);
    closedir (DIR);

# New toplevel window
    my $chooser;
    my $title;
    if ($save_mode eq 'save'){
        $title='Save to file';
    }else{
        $title='Chooser';
    }

    $chooser = $mainWindow->Toplevel;
    $chooser->configure (-title => $title);
    $chooser->grab;

    my $menuBar=$chooser->Frame;
    $menuBar->pack(-side => 'top', -fill => 'x');
    $menuBar->configure (-bg => 'grey77',);

    my $saveChoose; 
    my $up_f;
    my $update_screen;

# The update window at the bottom of the chooser window.
        $up_f = $chooser->Frame()->pack(-side => 'bottom', -fill => 'x');
        $update_screen = $up_f->ScrlListbox (
                                                -font => $button_f,
                                                -bg => 'white', 
                                                -scrollbars => 'e',
                                                -height => 3,
                                                -width => 40
                                                )->pack(-side => 'top', -fill => 'x');

# To select a file to save as (for the save mode)       
    if ($save_mode eq 'save'){
        $saveChoose = $chooser->Frame;
        $saveChoose->pack(-side => 'bottom', -fill => 'x');
        my $sLabel = $saveChoose->Label(-text => 'Save as file :');
        $sLabel->pack(-side=> 'top');
        my $sEntry = $saveChoose->Entry(-textvariable => \$save_file, -background => 'lemonchiffon2');
        $sEntry->pack(-side => 'top');
        $sEntry->bind ('<Return>' => sub { 
            $wait = &save($save_file,$mainWindow);
        });
        
        $sEntry->configure (-width => 70);	
        
    }

    # Scrolling listbox
    my $filelist = $chooser->ScrlListbox (-font => $button_f,
					  -scrollbars => 'e',
					  -label => "Current Directory: $directory",
					  -height => 10,
					  -width => 40
					  )->pack(-side => 'top', -expand => 1, -fill => 'both');

    if ($save_mode eq 'save'){ 
        
# Fill the list with the contents of the directory 
#(for saver module - as double clicking imports data, so this functionality removed for this.)
        
        $filelist->insert('end', sort(@contents));
        
        $filelist->bind ('<Double-Button-1>'=>sub {
            my $filename = $filelist->get('active');
            ############################################################
            # if it's a directory -> cd to it
            ############################################################
            if (-d $filename){
                my $changeto = "$directory"."/$filename";
                ($directory) = &changedir($changeto, $filelist, $directory, $update_screen);
            } else {
                &update($update_screen, "Cannot access $filename.");
                &update($update_screen, "Permission denied.");
            }
        });
        
    }else{
        
# Fill the list with the contents of the directory (for chooser module)
        $filelist->insert('end', sort(@contents));
        
        $filelist->bind ('<Double-Button-1>' => sub {
            my $filename = $filelist->get('active');
            ############################################################
            # if it's a directory -> cd to it
            # if it's a readable file -> return it to the main program
            ############################################################
            if (-d $filename){
                my $changeto = "$directory"."/$filename";
                ($directory) = &changedir($changeto, $filelist, $directory, $update_screen);
            } elsif (-r $filename){
                my $return = "$directory"."/$filename";
                ########################################################
                # Now need to get the filename back to the main program
                ########################################################
                
                $$file_sel = $return;
                $$file_lock = 0;
                $chooser->destroy;
                
            } else {
                &update($update_screen, "Cannot access $filename.");
                &update($update_screen, "Permission denied.");
            }
        });

    }
    
# File-menu
    my $fileMenu = $menuBar->Menubutton(-font => $button_f, -text => 'File', -underline => 0);
    $fileMenu->configure(-menu => $fileMenu ->Menu(-tearoff => 0));
    
    if ($save_mode eq 'save'){
        $fileMenu->command(-font => $button_f, 
                           -label => 'Save', 
                           -underline => 0, 
                           -command => sub {
                               $wait = &save($save_file,$mainWindow);
                               });
    }
    
    $fileMenu->command(-font => $button_f, 
		       -label => 'Close', 
		       -underline => 0, 
		       -command => sub {
			   $$file_lock = 0;
			   $chooser->destroy; 
		       });
    $fileMenu->pack(-side => 'left');
    $fileMenu->configure (-bg => 'grey77');
    
    
    # Update
    my $updateMenu = $menuBar->Menubutton(-font => $button_f, -bg => 'grey77', -text => 'Update Window', -underline => 0);
    $updateMenu->configure(-menu => $updateMenu ->Menu(-tearoff => 0));
    $updateMenu->command(-font => $button_f, -label => 'Clear the update window',-underline => 0, -command =>sub {
                             &update_clear($update_screen);
                             $update_screen->update('idletasks');
                         });
    $updateMenu->pack(-side => 'left');
    
    
    my $filterMenu = $menuBar->Menubutton(-font => $button_f, 
					  -text => 'Filter', 
					  -underline => 1);
    $filterMenu->configure(-menu => $filterMenu ->Menu(-tearoff => 0));
    $filterMenu->command(-font => $button_f, 
			 -label => 'Filter for '.$ext.' files', 
			 -underline => 0, 
			 -command => sub {
			     opendir (DIR, ".");
			     @contents = grep /$ext/, readdir (DIR);
			     closedir (DIR);	
			     &filldir($filelist, $directory, \@contents);
			 });

    $filterMenu->command(-font => $button_f, 
			 -label => 'No Filter', 
			 -underline => 0, 
			 -command => sub {
			     opendir (DIR, ".");
			     @contents = readdir (DIR);
			     closedir (DIR);
			     &filldir($filelist, $directory, \@contents);
			 });
    $filterMenu->pack(-side => 'left');
    $filterMenu->configure (-bg => 'grey77');

    
    
# Direct directory access
    my $changedirectory = $directory;
    my $dirChoose = $chooser->Frame;
    $dirChoose->pack(-side => 'top', -fill => 'x');
    my $dirLabel = $dirChoose->Label(-font => $button_f, -text => 'Change Directory : ');
    $dirLabel->pack(-side=> 'top');
    my $dirEntry = $dirChoose->Entry(-font => $entry_f, -textvariable => \$changedirectory,-background => 'lemonchiffon2');
    $dirEntry->pack(-side => 'top');
    $dirEntry->bind ('<Return>' => sub {
        
	($directory) = &changedir($changedirectory, $filelist, $directory, $update_screen);
	
    } );
    
    $dirEntry->configure (-width => 70);

    $chooser->grab();
    $chooser->waitVisibility;
    $chooser->update;

    $chooser->waitVariable(\$wait);  
    return ($wait,$file_lock,$chooser);
}


sub save {
    my ($save_file,$mainWindow)=@_;

    # Need to test that $save_file doesn't already exist and that the directory
    # can be written to.print "$save_file\n";
    my ($DIALOG1);
    if (-e $save_file) {	#if this file exists
	my($ok, $can) = ('OK', 'Cancel');
	if (not Exists($DIALOG1)) {
	    $DIALOG1 = $mainWindow->Dialog(
					   -title          => 'Warn',
					   -text           => '',
#                                          -bitmap         => 'info',
					   -default_button => $can,
					   -buttons        => [$ok, $can],
					   );
	    $DIALOG1->configure(
				-wraplength => '4i',
				-text       => 'Warning! This file already exists. Overwrite ? ',
				);
	}
	my $button = $DIALOG1->Show;
	if ($button eq $can) {
	    #print "You pressed Cancel\n";
	    return();

	} elsif ($button eq $ok) {
	    #print "You pressed Ok-1\n";            
	    return ($save_file);

	}
    } else {
	#warn "--> $save_file does not exist \n";
	return ($save_file);
	
    }

    
} #end of save sub



sub changedir {
    my ($changedirectory, $filelist, $directory, $update_screen) = @_;

    if ( chdir ($changedirectory) ){
	opendir (DIR, ".");
	my @contents =readdir (DIR);
	closedir (DIR);
	&filldir($filelist, $directory, \@contents);
	$directory = $changedirectory;
	$filelist->configure(-font => $button_f, -label => "Current Directory: $directory");
	&update_clear($update_screen);
    } else {
	    &update($update_screen, "Cannot change to this directory.");
	    &update($update_screen, "$!.");
	    &update($update_screen, "Permission denied.");
    }
    return ($directory);
}

sub filldir {
    my ($filelist, $directory, $contents) = @_;
    $filelist->configure(-font => $button_f, -label => "Current Directory: $directory");
    $filelist->delete('0', 'end');
    $filelist->insert('end', sort(@$contents));
    $filelist->pack(-side => 'top', -expand => 1, -fill => 'both');
}

sub update_clear{
    my ($update_screen) = @_;
    $update_screen->delete ('0', 'end');
    &update($update_screen, "Window cleared.");
}

sub update {
    my ($update_screen, @update_contents)=@_;
    $update_screen->insert('end', @update_contents);
    $update_screen->see('end'); 
    $update_screen->pack(-side => 'left', -expand => 1, -fill => 'both');
}


1;
