#! /usr/local/bin/perl
#
# ace file manager
#
# 19-Jul-1995 Created -- SD
#
#
#######################################################################
# This software has been created by Genome Research Limited (GRL).    # 
# GRL hereby grants permission to use, copy, modify and distribute    # 
# this software and its documentation for non-commercial purposes     # 
# without fee at the user's own risk on the basis set out below.      #
# GRL neither undertakes nor accepts any duty whether contractual or  # 
# otherwise in connection with the software, its use or the use of    # 
# any derivative, and makes no representations or warranties, express #
# or implied, concerning the software, its suitability, fitness for   #
# a particular purpose or non-infringement.                           #
# In no event shall the authors of the software or GRL be responsible # 
# or liable for any loss or damage whatsoever arising in any way      # 
# directly or indirectly out of the use of this software or its       # 
# derivatives, even if advised of the possibility of such damage.     #
# Our software can be freely distributed under the conditions set out # 
# above, and must contain this copyright notice.                      #
#######################################################################




#############################################################
#
#
#
#
#############################################################
package Ace_Manager;
$debug = 1;

sub AMFindFileVersion {
    package Ace_Manager;
    local($vers);
    local($root) = @_;
    
    $vers = -1;
    foreach ( <$directory/$root.*> ) {
	if (/\.(\d+)$/) {
	    if ($vers < $1) { $vers = $1; }
	}
    }

    $vers;
}

sub AMFindLogFileVersion {
    package Ace_Manager;

    &AMFindFileVersion("log");
}

sub AMFindNewLogFile {
    package Ace_Manager;

    $version = &AMFindLogFileVersion();
    $version++;

    $log = "$directory/log.$version";
    `touch $log`;
    $? == 0 || die "AMNewVersion: Could not create log file for new version: $log: $!\n";

    return $version;
}


sub AMFindLogFile {
    package Ace_Manager;

    $version = &AMFindLogFileVersion();

    $log = "$directory/log.$version";

    return $version;
}




sub AMFindAceFileVersion {
    package Ace_Manager;
    local($type) = @_;

    &AMFindFileVersion("$type.$version");
}


sub AMFindAceFile {
    package Ace_Manager;
    local($type) = @_;
    local($vers);
    local($file);

    $vers = &AMFindAceFileVersion($type);

    $file = "$directory/$type.$version.$vers";

    return (-f $file) ? $file : "";
}


sub AMFindNewAceFile {
    package Ace_Manager;
    local($type) = @_;
    local($vers);
    local($file);

    $vers = &AMFindAceFileVersion($type);
    $vers++;

    $file = "$directory/$type.$version.$vers";
}


sub AMFindLockFile {
    package Ace_Manager;
    local(@locks);

    @locks = <$directory/lock.$version.*>;
    if ($#locks == -1) {
	$lock = "none";
    } else {
	if ($#locks > 0) {
	    warn "AMFindLockFile: more than one lock file present\n";
	}

	($lock) = ($locks[0] =~ /\.([^.]*)$/);
    }

    $lock;
}



sub AMFindDir {
    package Ace_Manager;
    local($dir);

    chop($dir = `pwd`);
    $dir .= "/Ace";
    
    -d $dir || mkdir($dir,0775) || die "acemanager.pl: AMFindDir: could not create directory: $!\n";
    return $dir;
}





sub AMMakePadded {
    package Ace_Manager;
    local($loose) = @_;
    local($padded);

    $padded = &AMFindNewAceFile("padded");

    system("aceloose2padded -AM $directory -in $loose -out $padded");

    &AMLock("any");
    
    $padded;
}




sub AMMakeLoose {
    package Ace_Manager;
    local($padded) = @_;
    local($loose);

    $loose = &AMFindNewAceFile("loose");

    system("acepadded2loose -AM $directory -in $padded -out $loose");
    
    &AMLock("any");

    $loose;
}



sub AMFindPaddedOrLoose {

    local($padded);
    local($loose);
    local($have);
    local($file);

    $have = $lock;

    # Default for "any" is "loose"
    if ($have eq "any") { $have = "loose"; }

    if ($have eq "padded" || $have eq "loose") {
	$file = &AMFindAceFile($have);
    } else {
	$have = "none";
	$file = "";
    }

    ($have,$file);

}




sub AMFindPaddedOrLoose_old {

    local($padded);
    local($loose);
    local($have);

    # Find padded
    $padded = &AMFindAceFile("padded");

    # Find loose
    $loose = &AMFindAceFile("loose");

    if ($padded eq "" && $loose eq "") {
	# Complain if we have neither
	die "AMFindPaddedOrLoose: Could not find ace files\n";
    } elsif ($padded eq "") {
	$have = "loose";
    } elsif ($loose eq "") {
	$have = "padded";
    } else {
	$have = (-C $loose < -C $padded) ? "loose" : "padded";
    }

    return ($have, ($have eq "padded") ? $padded : $loose);
}



sub AMLock {
    local($old) = "$directory/lock.$version.$lock";
    ($lock) = @_;
    local($new) = "$directory/lock.$version.$lock";

    if (-f "$old") { unlink "$old" || die "AMLock: Cannot remove old lock file\n"; }
    system("touch $new");

    print "Ace Lock file = $lock\n" if $Ace_Manager'debug; #'
}



############################################################
# GLOBAL SCOPED THINGS
############################################################

package main;

sub AMStart {
    package Ace_Manager;
    ($directory) = @_;

    if ($directory eq "") {
	$directory = &AMFindDir();
    }
    print "Ace Manager Directory = $directory\n" if $Ace_Manager'debug; #'

    &AMFindLogFile();
    print "Ace File Version = $version\n" if $Ace_Manager'debug; # '

    &AMFindLockFile();
    print "Ace Lock file = $lock\n" if $Ace_Manager'debug; #'

    $done++;
}




sub AMNeedAceInput {
    package Ace_Manager;
    local($type) = @_;
    local($have);
    local($file);
    local($newfile);

    $done || &AMStart();

    if ($type eq "none") {
	return;
    } elsif ($type eq "padded" || $type eq "loose" || $type eq "any") {

	($have, $file) = &AMFindPaddedOrLoose();

	# If we want any we already have it!
	if ($have eq "none") {
	    die "AMFindAcefile: Could not make files type $type\n";
	} elsif ($type eq "any" || $type eq $have) {
	    # We have what we want
	    $newfile = $file;
	    ;
	} elsif ( $type eq "padded") {
	    # Need padded but have loose
	    $newfile = &AMMakePadded($file);
	} else {
	    # Need loose but have padded
	    $newfile = &AMMakeLoose($file);
	}


    } else {
	$newfile = &AMFindAceFile($type);
	if ($newfile eq "") {
	    die "AMFindAcefile: Could not find files type $type\n";
	}
    }

    return $newfile;
}





sub AMNeedAceOutput {
    package Ace_Manager;
    local($type) = @_;
    local($have);
    local($file);
    local($newfile);

    $done || &AMStart();

    if ($type eq "none") {
	return;
    } elsif ($type eq "any") {
	($type, $file) = &AMFindPaddedOrLoose();
	$newfile = &AMFindNewAceFile($type);
    } else {
	$newfile = &AMFindNewAceFile($type);
    }

    if ($type eq "loose" || $type eq "padded") {
	&AMLock($type);
    }

    

    return $newfile;
}



############################################################
# Add things to command line option parsing (see BadgerGetOpts module)
# &AMAugmentOpts($prog,$usage,$opts);
# 
############################################################


sub AMAugmentOpts {

    return if $#_ != 2;

    # Augment $usage
    if ($_[1] !~ /-AM/) {
	$_[1] =~ s/\]([^\]]*)$/] [ -AM dir | [ [-in ace] [-out ace] ] ]$1/;
    }

    # Augment $opts
    if (! defined $_[2]->{"-AM"}) {
	$_[2]->{"-AM"} = {
	    "type" => "text",
	    "var" => \$AM_dir,
	    "help" => "Ace Manager directory",
	};
    }

    if (! defined $_[2]->{"-in"}) {
	$_[2]->{"-in"} = {
	    "type" => "text",
	    "var" => \$acein,
	    "help" => "Use ace file as input",
	};
    }

    if (! defined $_[2]->{"-out"}) {
	$_[2]->{"-out"} = {
	    "type" => "text",
	    "var" => \$aceout,
	    "help" => "Create ace file as output",
	};
    }

}



############################################################
# Set-up input and output files
############################################################

sub AMSetupIO {
    local($in,$out) = @_;
    local(*LOGFILE);

    if (defined $AM_dir) {
	&AMStart($AM_dir);
	if (! defined $acein) { $acein  = &AMNeedAceInput($in); }
	if (! defined $aceout) { $aceout = &AMNeedAceOutput($out); }

	system("echo $prog -in $acein -out $aceout -- `date` -- `whoami`>> $Ace_Manager'log");
    }

    if (! defined $acein) { $acein = "-"; }
    if (! defined $aceout) { $aceout = "-"; }

    # reopen for standard input
    if ($acein ne "-") {
	open(STDIN, "$acein") || die "$prog: Could not open file $acein for input: $!\n";
    }

    # reopen for standard output
    if ($aceout ne "-") {
	open(STDOUT, ">$aceout") || die "$prog: Could not open file $aceout for output: $!\n";
    }

}





1;
############# end of file ###############
# Local Variables:
# mode:perl
# End:
############# end of file ###############
