#! /usr/bin/tclsh

#   Copyright (C) 1987-2015 by Jeffery P. Hansen
#   Copyright (C) 2015-2018 by Andrey V. Skvortsov
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, write to the Free Software Foundation, Inc.,
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#

package require cmdline

########################################################################
#
# Parse string of the messages file
# State machine with state variables currentKey and currentValue
# \param line: text line to parse
# \param sourceLine
# \param msgHash: Hash id to use
#
# You need tcl-tcllib installed
#
proc parseString {line sourceLine msgHash} {

	global messagesHash
	global messagesLine2Key
	global currentKey
	global currentValue

	# New key found
	if {[string equal $currentKey ""]} {
		set start [string first "\t" $line]
		set stop [string last "\t" $line]
		if {$start > 0} {
			set currentKey [string range $line 0 [expr {$start-1}]]
			lappend messagesLine2Key($msgHash) [list $sourceLine $currentKey]
			set value [string trim [string range $line $stop [string length $line]]]
			if {([string equal $value "-fillbegin-"] == 0) &&
			    ([string equal $value "-begin-"] == 0)} {
				set currentValue $value
				set messagesHash($currentKey,$msgHash) $currentValue
				set currentKey ""
			} else {
				set currentValue ""
			}
		}
	# Next line of the current value
	} else {
		if {[string equal $line "-end-"]} {
			set messagesHash($currentKey,$msgHash) $currentValue
			set currentKey ""
			set currentValue ""
		} else {
			if {[string length $currentValue] > 0} {
				set currentValue "$currentValue\n"
			}
			set currentValue "$currentValue$line"
		}
	}
}

proc parseFile {msgFile msgHash} {
	set sourceLine 1

	while {1} {
		set line [gets $msgFile]
		if {[eof $msgFile]} {
			close $msgFile
			break
		}
		# trim line and reject of the comment and service lines
		set line [string trim $line]
		if {([string index $line 0] != "#") &&
		    ([string index $line 0] != "@") &&
		    ([string index $line 0] != "\\") &&
		    ([string length $line] > 0)} {
			parseString $line $sourceLine $msgHash
		}
		incr sourceLine
	}
}

global messagesHash
global messagesLine2Key
global currentKey
global currentValue

set parameters {
	{m.arg "" "Base messages file with all messages (english locale)"}
	{l.arg "" "Translated message file (possibly partial translated)"}
	{po.arg "" "Gettext portable object file for locale"}
	{lang.arg "" "Short name of language (en, ru, .etc)"}
}

set usage "Convert TkGate messages files into gettext portable objects \
\nUsage: tkgatemsg2po\n\t-m <english message file>\n\t-l <localized message file> \
\n\t-po <locale file>\n\t-lang <short name of language> (optional)"

array set options [cmdline::getoptions ::argv $parameters $usage]

if {$argc == 0} {
	puts $usage
	exit 0
}

set currentKey ""
set currentValue ""

# try to open original (english) messages file
set f [open $options(m) r]
puts "Messages file '$options(m)' opened"

# try to open locale messages file
set fLocMsg [open $options(l) r]
puts stderr "Locale messages '$options(l)' opened"

# try to open locale output file
set fLoc [open $options(po) w]
puts stderr "Locale output '$options(po)' opened"

parseFile $f m
parseFile $fLocMsg l

puts $fLoc "# This file is part of TkGate project"
puts $fLoc "# Copyright (C) 1987-2015 by Jeffery P. Hansen"
puts $fLoc "# Copyright (C) 2015-2018 by Andrey V. Skvortsov"
puts $fLoc "# This file is distributed under the same license as the TkGate package."
puts $fLoc "#"
puts $fLoc "# ##############################################################################"
puts $fLoc "# Generated by messages2po script"
puts $fLoc "# ##############################################################################"
puts $fLoc "#"
puts $fLoc "# Translators:"
puts $fLoc "# Andrey V. Skvotsov <starling13@gmail.com>, 2015"
puts $fLoc "msgid \"\""
puts $fLoc "msgstr \"\""
puts $fLoc "\"Project-Id-Version: tkgate\\n\""
puts $fLoc "\"Report-Msgid-Bugs-To: starling13@gmail.com\\n\""
puts $fLoc "\"POT-Creation-Date: [clock format [clock seconds] -format {%Y-%m-%d %H:%M}]+0300\\n\""
puts $fLoc "\"PO-Revision-Date: [clock format [clock seconds] -format {%Y-%m-%d %H:%M}]+0300\\n\""
puts $fLoc "\"Last-Translator: Andrey Skvortsov <starling13@gmail.com>\\n\""
puts $fLoc "\"Language-Team: LANGUAGE <LL@li.org>\\n\""
puts $fLoc "\"Language: $options(lang)\\n\""
puts $fLoc "\"MIME-Version: 1.0\\n\""
puts $fLoc "\"Content-Type: text/plain; charset=UTF-8\\n\""
puts $fLoc "\"Content-Transfer-Encoding: 8bit\\n\""
puts $fLoc "\"X-Generator: tkgatemsg2po script\\n\""

foreach pair $messagesLine2Key(l) {
	
	set str [lindex $pair 0]
	set keyName [lindex $pair 1]
	set msgVal $messagesHash($keyName,l)
	regsub -all "\"" $msgVal "\\\"" msgVal
	set origMsgVal $messagesHash($keyName,m)
	regsub -all "\"" $origMsgVal "\\\"" origMsgVal

	puts $fLoc ""
	puts $fLoc "#: $options(l):$str"
	puts $fLoc "msgctxt \"$keyName\""
	
	# Put original message
	set line "msgid "
	set strList [split $origMsgVal "\n"]
	if {[llength $strList] > 1} {
		set line "$line\"\"\n\"[join $strList \\n\"\n\"]\""
	} else {
		set line "$line\"[lindex $strList 0]\""
	}
	puts $fLoc $line
	
	# Put translated message
	set line "msgstr "
	set strList [split $msgVal "\n"]
	if {[llength $strList] > 1} {
		set line "$line\"\"\n\"[join $strList \\n\"\n\"]\""
	} else {
		set line "$line\"[lindex $strList 0]\""
	}
	puts $fLoc $line
}

close $fLoc
