# Album Plugin: images/xy_cache
# For info:     'album -plugin_info images/xy_cache'
# For usage:    'album -plugin_usage images/xy_cache'
use strict;

sub start_plugin {
  my ($opt) = @_;

  # Setup the options
  album::add_option(1, 'file', album::OPTION_STR, default=>'album.xy',
                    usage=>'Location of xy cache');

  # Setup the hooks
  album::hook($opt,'get_xy', \&get_xy);

  return {
    author => 'David Ljung Madison',
    href => 'http://MarginalHacks.com/',
    version => '1.0',
    description => <<DESC,
Caches the image size information in a database to speedup album generation.
Bug: The xy database never gets cleaned.  If you move images or alter them,
it will just continue to grow.  Remove it if it gets too big.

Thanks to Johann Botha [joe frogfoot com] for the suggestion!
DESC
  };

}

my %CACHE;

sub read_cache {
	my ($opt, $cache) = @_;

	return if $CACHE{read}{$cache}++;

	# Read the cache file
	if (open(CACHE,"<$cache")) {
		while (<CACHE>) {
			chomp;
			my ($x,$y,$i) = split(/\t/,$_,3);
			$CACHE{xy}{$i} = [$x,$y] if $x && $y && $i;
		}
		close CACHE;
	}
}

sub add_cache {
	my ($opt, $cache,$img,$x,$y) = @_;
	$CACHE{xy}{$img} = [$x,$y];
	return unless open(CACHE,">>$cache");
	print CACHE "$x\t$y\t$img\n";
	close CACHE;
}

sub get_xy {
  my ($opt, $hookname, $img) = @_;
  
	my $tn = album::option($opt,'dir');
	my $cache = album::option($opt,'file');

	my ($dir,$file) = album::split_path($opt, $img);
	$dir =~ s|/$tn$||;	# Remove 'tn'
	return undef unless -d $dir;
	$cache = "$dir/$cache";

	# If the cache exists (and is newer than the image):
	if (-f $cache && -M $cache < -M $img) {
		# Have we read the cache?
		read_cache($opt,$cache);

		# Is it in our memory cache?
		return @{$CACHE{xy}{$img}} if $CACHE{xy}{$img};
	}

	album::uncall_plugin($opt);
	my ($x,$y) = album::get_xy($opt,$img);
	album::recall_plugin($opt);

	add_cache($opt,$cache,$img,$x,$y);
}

# Plugins always end with:
1;
