#!/usr/bin/perl
#use #{{{
	use strict;
	use feature ':5.14'; #say()
	use utf8::all;
	use File::Slurp::Unicode;
	use Data::Dumper; # print Dumper([@y],[@x]);
	use Getopt::Std;
#}}}

sub createSentenceSegments {#{{{
	my $f=read_file("$_[0]");
	my @blocks=split(/\n{2,}#/, $f);						# .po contain BLOCKS separated by \n and then leading #
	my $output=$blocks[0]."\n\n";							# output starts with a file header
	my @allowedTypes=('abstract', 'document', 'Content of');	# this list has to be extended and tested
	for (my $i=1; $i<=$#blocks; $i++) {						# each blocks[$i] is bHead+bMsgid+bMsgstr 
		chomp($blocks[$i]);									# drop the \n on the very last element
		my $bricks=parseBlock("#$blocks[$i]");				# lost the `#' during initial split
		my ($bHead, $bMsgid, $bMsgstr)=@$bricks;
		my @h=split(/: /, $bHead);
		my $type=$h[1];										# eg. abstract, document, Content of, ...
		my $eol; if($i!=$#blocks) { $eol="\n\n"; } else { $eol=""; } # we don't need those two newlines at EOF
	
		if (grep(/$type/, @allowedTypes)) {					# only allowed sections can be split into sentences
			(my $lastSentence=$bMsgid)=~s/.*\. (.*\w.*)/$1/;
			my @sentences=split(/\. /, $bMsgid);
			pop(@sentences);								# lastSentence in a block is special: finished with dot? space?
			$bMsgstr=~s/(.*)/\n"$1"/ if ($bMsgstr);			# msgstr: I like separate line for msgstr (under)
			for (@sentences) {
				$output.="# _BLOCK_ID_:$i\n${bHead}\nmsgid \"\"\n\"$_.\"\nmsgstr \"\"${bMsgstr}\n\n";
			}
			$output.="# _BLOCK_ID_:$i\n${bHead}\nmsgid \"\"\n\"$lastSentence\"\nmsgstr \"\"${bMsgstr}$eol";
		} else {											# not allowed environments, eg. latex verbatim won't be segmented 
			$output.="# _BLOCK_ID_:$i\n${bHead}\nmsgid \"\"\n\"${bMsgid}\"\nmsgstr \"\"${bMsgstr}$eol";
		}
	}
	#say $output;
	write_file("$_[1]", $output);
}
#}}}
sub sentencesBackToBlocks {#{{{
	my $f=read_file("$_[0]");
	my @blocks=split(/# _BLOCK_ID_:/, $f);
	my $output=$blocks[0];										# output starts with a file header
	my $blkIDold='';
	my ($bHead, $bMsgid, $bMsgstr);
	for (my $i=1; $i<=$#blocks+1; $i++) {							# each blocks[$i] is bHead+bMsgid+bMsgstr
		my @ii=split(/\n/, $blocks[$i], 2);
		my $eol; if($i!=$#blocks+1) { $eol="\n\n"; } else { $eol=""; } # we don't need those two newlines at EOF
		my $blkID=$ii[0];
		$ii[1]=~s/\n+$//;										# block prepared 
		if($blkID ne $blkIDold) {								# ne not == (0 vs undef test). Blocks are meged here
			$bMsgid=~s/ $//g; 
			$bMsgstr=~s/ $//g;
			$bMsgstr=~s/(.*)/\n"$1"/ if ($bMsgstr);				# msgstr: I like separate line for msgstr (under)
			$output.="${bHead}\nmsgid \"\"\n\"${bMsgid}\"\nmsgstr \"\"${bMsgstr}$eol" if($blkIDold);
			$bMsgid=$bMsgstr="";
			$blkIDold=$blkID;
		}
		my $bricks=parseBlock($ii[1]);							# array of 3: 0(bHead), 1(bMsgid), 2(bMsgstr)
		$bHead="$$bricks[0]"; 
		$bMsgid.="$$bricks[1] " if $$bricks[1];
		$bMsgstr.="$$bricks[2] " if $$bricks[2];
	}
	#say $output;
	write_file("$_[1]", "$output\n");
}
#}}}
sub parseBlock() {#{{{
	my $blk="$_[0]";
	#say "========================== IN  ==========================\n".Dumper($blk);
	my @i=split(/\nmsgid|\nmsgstr/, $blk); # array of 3: 0(bHead), 1(bMsgid), 2(bMsgstr)
	for (@i[1..2]) { # msgid and msgstr
		s/"\n"//g;
		s/^ "//g;
		s/"$//g;
	}
	#say "========================== OUT ==========================\n".Dumper(\@i)."\n=========================================================\n=========================================================\n";
	return \@i;										# array of 3: 0(bHead), 1(bMsgid), 2(bMsgstr)
}
#}}}
# getopts#{{{
getopts('SMi:o:h'); 
our($opt_h, $opt_S, $opt_M, $opt_i, $opt_o);
#if ($opt_h) {
if ($opt_h || !($opt_i && $opt_o)) {
	print " 
Usage:
    po4a-segment.pl -SM -i *in.po* -o *out.po*

    (-S is for 'split blocks into sentences'. The in.po must be generated by po4a-gettextize)
    (-M is for 'merge sentences back into blocks'. The in.po is the sentence segmented file)

";
	exit;
}
if ($opt_S) { createSentenceSegments($opt_i, $opt_o); }
if ($opt_M) { sentencesBackToBlocks($opt_i, $opt_o); }
#createSentenceSegments("po_odf.po", "sentences.po"); 
#sentencesBackToBlocks("sentences.po", "back.po"); 
#}}}
