package Locale::Simple;
BEGIN {
  $Locale::Simple::AUTHORITY = 'cpan:GETTY';
}
{
  $Locale::Simple::VERSION = '0.007';
}
# ABSTRACT: Functions for translate text based on gettext data, also in JavaScript

use strict;
use warnings;

use Exporter 'import';
use Locale::gettext_pp qw(:locale_h :libintl_h);

use IO::All -utf8;

our @EXPORT = qw(
	
	l_dir
	l_lang
	l_dry
	l_nolocales

	l
	ln
	lp
	lnp
	ld
	ldn
	ldp
	ldnp
	
	ltd

);

my $dry;
my $nowrite;
my $nolocales;

my %tds;
my $dir;

sub l_nolocales { $nolocales = shift }
sub l_dry { $dry = shift; $nowrite = shift; $nolocales = 1 if $dry }

sub gettext_escape {
	my ( $content ) = @_;
	$content =~ s/\n/\\n/g;
	$content =~ s/"/\\"/g;
	return $content;
}

sub coderef_hash {{
	l => sub { l(@_) },
	ln => sub { ln(@_) },
	lp => sub { lp(@_) },
	lnp => sub { lnp(@_) },
	ld => sub { ld(@_) },
	ldn => sub { ldn(@_) },
	ldp => sub { ldp(@_) },
	ldnp => sub { ldnp(@_) },
}}

sub l_dir { $dir = shift }

sub l_lang {
	my $primary = shift;
	$ENV{LANG} = $primary;
	$ENV{LANGUAGE} = $primary;
	$ENV{LC_ALL} = $primary;
}

# write dry
sub wd { io($dry)->append(join("\n",@_)."\n\n") if !$nowrite }

# l(msgid,...)
sub l { return ldnp('',undef,shift,undef,undef,@_) }
# ln(msgid,msgid_plural,count,...)
sub ln { return ldnp('',undef,@_) }
# lp(msgctxt,msgid,...)
sub lp { return ldnp('',shift,shift,undef,undef,@_) }
# lnp(msgctxt,msgid,msgid_plural,count,...)
sub lnp { return ldnp('',shift,shift,shift,shift,@_) }
# ld(domain,msgid,...)
sub ld { return ldnp(shift,undef,shift,undef,undef,@_) }
# ldn(domain,msgid,msgid_plural,count,...)
sub ldn { return ldnp(shift,undef,shift,shift,shift,@_) }
# ldp(domain,msgctxt,msgid,...)
sub ldp { return ldnp(shift,shift,shift,undef,undef,@_) }
# ldnp(domain,msgctxt,msgid,msgid_plural,count,...)
sub ldnp {
	die "please set a locale directory with l_dir() before using other translate functions" unless $dir || $nolocales;
	my ($td, $ctxt, $id, $idp, $n) = (shift,shift,shift,shift,shift);
	my @args = @_;
	unshift @args, $n if $idp;
	my $return;
	if ($dry) {
		if (!$nowrite) {
			my @save;
			push @save, '# domain: '.$td if $td;
			push @save, 'msgctxt "'.gettext_escape($ctxt).'"' if $ctxt;
			push @save, 'msgid "'.gettext_escape($id).'"';
			push @save, 'msgid_plural "'.gettext_escape($idp).'"' if $idp;
			wd(@save);
		}
		$return = sprintf($idp && $n != 1 ? $idp : $id, @args);
	} else {
		$return = sprintf(dnpgettext($td, $ctxt, $id, $idp, $n),@args);
	}
	# Fixing bad utf8 handling
	utf8::decode($return);
	return $return;
}

sub ltd {
	die "please set a locale directory with l_dir() before using other translate functions" unless $dir || $nolocales;
	my $td = shift;
	unless (defined $tds{$td}) {
		bindtextdomain($td,$dir);
		bind_textdomain_codeset($td,'utf-8');
		$tds{$td} = 1;
	}
	textdomain($td);
}

1;


__END__
=pod

=head1 NAME

Locale::Simple - Functions for translate text based on gettext data, also in JavaScript

=head1 VERSION

version 0.007

=head1 SYNOPSIS

  use Locale::Simple;

  l_dir('data/locale');
  ltd('test');
  l_lang('de_DE');

  print l("Hello"); # "Hallo"
  print ln("You have %d message","You have %d messages",4); # 'Du hast 4 Nachrichten'

Usage in JavaScript:

  <script language="javascript" src="../../share/js/sprintf.js"></script>
  <script language="javascript" src="../../share/js/gettext/Gettext.js"></script>
  <script language="javascript" src="../../share/js/locale_simple.js"></script>
  <script language="javascript" src="locale/de_DE/LC_MESSAGES/test.json"></script>

  ltd('test');

  l("Hello");
  ln("You have %d message","You have %d messages",4);

Sample PO file, in this case data/locale/test.po

  msgid ""
  msgstr ""
  "Language: de_DE\n"
  "MIME-Version: 1.0\n"
  "Content-Type: text/plain; charset=UTF-8\n"
  "Content-Transfer-Encoding: 8bit\n"
  "Plural-Forms: nplurals=2; plural=n != 1;"

  msgid "You have %d message"
  msgid_plural "You have %d messages"
  msgstr[0] "Du hast %d Nachricht"
  msgstr[1] "Du hast %d Nachrichten"

  msgid "Hello"
  msgstr "Hallo"

=head1 DESCRIPTION

This is a small wrapper around Gettext functionality that integrates sprintf and makes
it a bit more easy to setup the internationalization. It ONLY supports UTF8 data, and in
or output, that is a fixed setup (and always will be).

Gettext in Perl requires compiled po files, so called mo files. You can generate those
with the following command (if you have gettext in general installed on your system):

  msgfmt -o data/locale/test.mo data/locale/test.po

The Gettext implementation in JavaScript which is wrapped, requires a json file to be
generated out of the po. This can be achieved with po2json which is delivered with
this package. Sadly it only generates the json and doesnt integrate it into the
translation storage in the JavaScript. To generate this you can do:

  echo -n "locale_data['test'] = " >data/locale/test.json
  po2json data/locale/test.po >>data/locale/test.json
  echo ";" >>data/locale/test.json

B<WARNING> it could be that the way how to integrate this in JavaScript might change
in future version. Please check this place here on every upgrade for further informations.

=encoding utf8

=head1 SEE ALSO

=head2 L<Locale::Messages>

=head1 SUPPORT

Repository

  http://github.com/Getty/p5-locale-simple
  Pull request and additional contributors are welcome

Issue Tracker

  http://github.com/Getty/p5-locale-simple/issues

=head1 AUTHOR

Torsten Raudssus <torsten@raudss.us>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by DuckDuckGo, Inc. L<http://duckduckgo.com/>, Torsten Raudssus <torsten@raudss.us>.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut

