# Simple Photo Gallery
# (c) 2003--2012 Martin Mares <mj@ucw.cz>

package UCW::Gallery;

use strict;
use warnings;

use Storable;

### Class methods ###

sub new($) {
	my ($class) = @_;
	my $self = { };
	$self->{cfg} = {
		# Directories
		OrigDir => '.',			# Original images
		PhotoDir => 'photo',		# Scaled-down photos for web
		CacheDir => 'cache',		# Cache with meta-data and thumbnails

		# URL prefixes
		PhotoUrlPrefix => 'photo/',
		ThumbUrlPrefix => 'thumb/',
		ThemeUrlPrefix => 'gal/',

		# Processing machinery settings
		ScanDefaultTransform => 's',
		PhotoMaxWidth => 1024,
		PhotoMaxHeight => 1024,
		ThumbFormats => {},		# Set up by themes

		# Titles and navigation
		Title => 'An Unnamed Gallery',
		SubTitle => "",
		ParentURL => '../',
		BackURL => "",
		FwdURL => "",
	};
	return bless $self, $class;
}

sub load_config($) {
	my $cfg = "./gallery.cf";
	my $self = do $cfg;
	unless (defined $self) {
		if ($@) {
			die "Error parsing $cfg: $@";
		} elsif ($!) {
			die "Cannot load $cfg: $!\n";
		} else {
			die "Cannot load $cfg, check that it returns true\n";
		}
	}
	return $self;
}

### Object methods ###

sub get($$) {
	my ($self, $key) = @_;
	if (exists $self->{cfg}->{$key}) {
		my $val = $self->{cfg}->{$key};
		defined $val or warn "Gallery: Config item $key is not set\n";
		return $val;
	} else {
		warn "Gallery: Config item $key does not exist\n";
		return;
	}
}

sub def($@) {
	my $self = shift;
	while (my $key = shift @_) {
		my $val = shift @_;
		!exists $self->{cfg}->{$key} or warn "Gallery: Re-definining config item $key\n";
		$self->{cfg}->{$key} = $val;
	}
}

sub set($@) {
	my $self = shift;
	while (my $key = shift @_) {
		my $val = shift @_;
		exists $self->{cfg}->{$key} or warn "Gallery: Config item $key does not exist\n";
		$self->{cfg}->{$key} = $val;
	}
}

sub get_config_keys($) {
	my ($self) = @_;
	return keys %{$self->{cfg}};
}

sub require_thumbnails($$$) {
	my ($self, $w, $h) = @_;
	my $fmt = "${w}x${h}";
	$self->{cfg}->{ThumbFormats}->{$fmt} = 1;
	return $fmt;
}

sub write_list($$$) {
	my ($self, $file, $images) = @_;
	open my $fh, '>:utf8', "$file.new" or die "Cannot create $file.new: $!\n";
	for my $i (@$images) {
		print $fh join("\t",
			$i->{file},
			$i->{id},
			$i->{orientation},
			$i->{xfrm},
			($i->{title} eq '' ? '-' : $i->{title}),
		), "\n";
	}
	close $fh;
	rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
}

sub read_list($$) {
	my ($self, $file) = @_;
	my @images = ();
	open my $fh, '<:utf8', $file or return;
	while (<$fh>) {
		chomp;
		/^$/ and next;
		/^#/ and next;
		my $i = {};
		($i->{file}, $i->{id}, $i->{orientation}, $i->{xfrm}, $i->{title}) = split /\t/;
		if ($i->{title} eq '-') { $i->{title} = ""; }
		push @images, $i;
	}
	close $fh;
	return \@images;
}

sub write_meta($$) {
	my ($self, $file, $meta) = @_;
	open my $fh, '>', "$file.new" or die "Cannot create $file.new: $!\n";
	Storable::nstore_fd($meta, $fh);
	close $fh;
	rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
}

sub read_meta($) {
	my ($self, $file) = @_;
	open my $fh, '<', $file or die "Cannot read $file: $!\n";
	my $meta = Storable::fd_retrieve($fh) or die "Cannot parse $file\n";
	close $fh;
	return $meta;
}

1;
