#!/usr/bin/env perl
use strict;
use far2l;

my $feed_file = shift;
die "Usage: farlng.pl .../farlang.templ [.../output/directory]" if !defined($feed_file);

my $out_dir = shift;
if (!defined($out_dir) || $out_dir eq '') {
	$out_dir = '.' ;
} else {
	mkdir($out_dir);
	chdir($out_dir);
}


my $feed;
open($feed, '<', $feed_file) or die "$feed_file: $!";

my $hpp_file = Unquote(FeedExpression(1));
my $tmp = "$hpp_file.tmp";
my $langs_count = FeedExpression(1);
die "No languages in $feed_file" if $langs_count <= 0;
die "No HPP file in $feed_file" if $hpp_file eq '';

my $hpp;
open($hpp, '>', "$out_dir/$tmp") or die "$out_dir/$tmp: $!";
#print $hpp "// This C++ include file was generated by far2l .LNG Generator\n";
my @langs;
for (my $i = 0; $i < $langs_count; ++$i) {
	my $lng_file = Unquote(FeedExpression(1));
	my $lng_name = Unquote(FeedExpression(1));
	my $lng_description = Unquote(FeedExpression(1));
	my $lang;
	open($lang, '>', "$out_dir/$lng_file") or die "$out_dir/$lng_file: $!";
	#print $lang "// This .lng file was generated by far2l .LNG Generator\n";
	print $lang ".Language=$lng_name,$lng_description\n\n";
	push(@langs, $lang);
}

my $hhead = FeedComments("hhead:");
my $htail = FeedComments("htail:");
my $enum = FeedComments("enum:");

print $hpp $hhead;
print $hpp "/* FarLang  - start */\n";

for (my $msg_index = 0;;++$msg_index) {
	FeedComments("h:");
	FeedComments("he:");
	my $msg_id = FeedExpression(1);
	last if $msg_id eq '';
	print $hpp "DECLARE_FARLANGMSG($msg_id, $msg_index)\n";
	my $lng_comments = FeedComments("l:");
	my $elng_comments = FeedComments("le:");
	for my $lang (@langs) {
		my $specific_lng_comments = FeedComments("ls:");
		print $lang $lng_comments;
		print $lang $specific_lng_comments;
		$specific_lng_comments = FeedComments("lse:");
		my $lng_string = FeedExpression(1);
		if (index($lng_string, "upd:") == 0) {
			$lng_string = substr($lng_string, 4);
			print $lang "// need translation:\n";
		}
		print $lang "//[$msg_id]\n";
		print $lang "$lng_string\n";
		print $lang $elng_comments;
		print $lang $specific_lng_comments;
	}
}
print $hpp "/* FarLang  - end */\n";
print $hpp $htail;

close($hpp);
close($feed);

for my $lang (@langs) {
	close($lang);
}

far2l::UpdateFromTmp($tmp, $hpp_file);

#############################################

my $line_from_feed = '';

sub FeedComments
{
	my ($prefix) = (@_);
	my $l = length($prefix);
	my $out = '';
	for (;;) {
		$line_from_feed = FeedLine() if $line_from_feed eq '';
		last if length($line_from_feed) < $l || substr($line_from_feed, 0, $l) ne $prefix;

		$out.= substr($line_from_feed, $l);
		$out.= "\n";

		$line_from_feed = '';
	}
	return $out;
}

sub FeedExpression
{
	my ($process_escape) = (@_);
	for (;;) {
		$line_from_feed = FeedLine() if $line_from_feed eq '';
		return '' if $line_from_feed eq '';
		my ($i, $l, $quoted, $escaped) = (0, length($line_from_feed), undef, undef);

		for (; $i < $l; ++$i) {
			my $c = substr($line_from_feed, $i, 1);
			if ($process_escape) {
				$quoted = !$quoted if !$escaped && $c eq '"';
				last if !$quoted && ($c eq ' ' || $c eq "\t");
				$escaped = !$escaped && $quoted && $c eq "\\";
			}
			last if $c eq "\r" || $c eq "\n";
		}

		my $out = substr($line_from_feed, 0, $i);
		$line_from_feed = TrimLeft(substr($line_from_feed, $i + 1));
		return $out;
	}
}

sub FeedLine
{
	while (<$feed>) {
		chop($_);
		$_ = TrimLeft($_);
		next if $_ eq '' || substr($_, 0, 1) eq '#';

		return $_;
	}

	return '';
}

sub Unquote
{
	my ($s) = (@_);
	my $l = length($s);
	if ($l > 1 && substr($s, 0, 1) eq '"' && substr($s, $l - 1, 1) eq '"') {
		return substr($s, 1, $l - 2);
	}
	return $s;
}

sub TrimLeft
{
	my ($s) = (@_);
	my ($i, $l) = (0, length($s));
	for (; $i < $l; ++$i) {
		my $c = substr($s, $i, 1);
		last if $c ne ' ' && $c ne "\t" && $c ne "\r" && $c ne "\n";
	}

	return substr($s, $i);
}
