package Lirama::Loc3;

use strict;
use warnings;

our $VERSION = '3.05';

sub loc($) {
	my $this = shift;
	# get one value from a hash of multiple options
	# if it isn't, we're done already:
	ref $_[0] eq "HASH" or return $_[0];
	# localize to most preferred language
	defined $_[0]{$_} and return $_[0]{$_} for @{$this->{-langorder}};
} # loc

sub TIEHASH {
	#todo: set -path
	return bless $_[1], $_[0];  # bless the l10n hash
}

sub FETCH {
	my ($this, $id) = @_;
	# get setting (denoted by leading dash)
	return $this->{$id} if $id =~ /^-/;
	# array ref used for passing arguments
	my @args;
	($id, @args) = @$id if ref $id eq "ARRAY";
	# add leading base path unless specified absolute
	$id = $this->{-path} . $id
		if defined $this->{-path} and not $id =~ s/^\Q$this->{-seperator}//;
	# get localized string by identifier
	if (exists $this->{$id}) {
		$id = $this->loc($this->{$id});
		# adaptive string (code)
		$id = $id->(@args) if ref $id eq "CODE";
	} else {
		# not found: strip path and use literal identifier
		$id =~ s/.*\Q$this->{-seperator}//s if defined $this->{-seperator};
	}
	# static output if no arguments given
	return $id unless @args;  # unnecessary but faster for common case
	# dynamic output
	return sprintf $id, @args;
} # FETCH

sub langorder($$) {
	my $this = shift;
	my %index = %{$this->{-langs}}; # overall index
	defined $index{$_} and $index{$_} *= $this->{-langpref}{$_}
		for keys %{$this->{-langpref}};
	return [ sort {$index{$b} <=> $index{$a}} keys %index ];
} # langorder

sub STORE {
	my ($this, $option, $val) = @_;
	if ($option eq "-langpref") {
		# set preference index of languages
		$this->{$option} = $val;
		$this->{-langorder} = $this->langorder;
	} # -langpref
	elsif ($option eq "-langorder") {
		# set order of languages (prefered language first)
		$this->{$option} = $val;
	} # -langorder
	elsif ($option eq "-seperator") {
		$this->{-path} =~ s/\Q$this->{$option}/$val/g
			if defined $this->{$option}; # replace old occurances
		$this->{$option} = $val;
	} # -seperator
	else {
		$val .= $this->{-seperator} if $option eq "-path" and $val ne '';
		$this->{$option} = $val;
#		$_[0]->{$_[1]} = $_[2];
	}
} # STORE

sub EXISTS   {
	my ($this, $id) = @_;
	$id = $this->{-path} . $id
		if defined $this->{-path} and not $id =~ s/^\Q$this->{-seperator}//;
	return exists $this->{$id};
} # EXISTS

#todo: make path-aware
sub FIRSTKEY { my $a = scalar keys %{$_[0]}; each %{$_[0]} }
sub NEXTKEY  { each %{$_[0]} }

1;

__END__


=head1 NAME

Lirama::Loc3 - Localize strings

=head1 SYNOPSIS

	use Lirama::Loc3;

	tie my %loc, "Lirama::Loc3", {
		-langs => {eo => 100, en => 95},
		-seperator => '_',
		test => {
			eo => "cxi tio estas testo",
			en => "this is a test",
		},
	};

	$loc{-langpref} = {nl => 100, en => 50};  # prefer I<nl> (dutch) texts
	print $loc{test};  # "this is a test", since dutch is unavailable

=head1 DESCRIPTION

Returns a text in the most preferred language available.
Mainly intended for translation of different strings on a website.

=over 4

=item C<langpref>

Shared so we only have to set one var to change all translations;
may yet be a very bad idea (does it work correctly in modperl?)

=item C<tie>

=item C<loc>

=item C<exists>

True if identifier is localized;
even though non-existing strings still return themselves.

=back

=head1 SEE ALSO

L<Lirama::Loc3::Auto|Lirama::Loc3::Auto>

L<Locale::Maketext|Locale::Maketext>

=head1 AUTHOR

Mischa POSLAWSKY <shiar@shiar.org>

Copyright 2005 Mischa POSLAWSKY. All rights reserved.

=cut
