#!/usr/bin/env texlua
--
-- global constants
--
VERSION = "0.9.2"
FILE_SUFFIX="_chtr"
PMX_CMD="pmxab"

--[[
   pmxchords.lua: transpose chords (\ch.C.\) and process pmxab

   (c) Copyright 2013 Ondrej Fafejta <fafejtao@gmail.com>
       https://github.com/fafejtao/pmxChords

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.

--]]

--[[
  ChangeLog:

    version 0.9.2 2013-12-13 - fixed: stop processing when pmxab fail. 
                             - Do not remove file pmxaerr.dat.

    version 0.9.1 2013-12-09 - added some options. Improved processing.

    version 0.9   2013-12-05 - rewritted code from perl to lua...
--]]

function usage()
  print("Usage:  [texlua] pmxchords.lua  basename[.pmx] ")
  print("     1. transpose chords into new file basename"..FILE_SUFFIX..".pmx")
  print("     2. call pmxab on transposed file basename"..FILE_SUFFIX..".pmx")
  print("     3. rename basename"..FILE_SUFFIX..".tex to basename.tex")
  print("options: -v  version")
  print("         -h  help")
  print("         -s  stop after fist step. e.g. generate only transposed basename"..FILE_SUFFIX..".pmx file")
end

function whoami ()
  print("This is pmxchords.lua version ".. VERSION)
end

whoami()
if #arg == 0 then
  usage()
  os.exit(0)
end

kpse.set_program_name("luatex")
require "ChordsTr"

function parseInputSignature(line)
   -- parse input signature from pmx digits line. Only one line digits format is supported!
   -- e.g.
   --    1      1       2     4      2      4        0    -1
   -- signature is -1 : F major
   local res =  string.match(line, "^%s*[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+[0-9]+%s+([%+%-]?[0-9]+)%s*$")
   return tonumber(res)
end

function parseOutputSignature(line)
   -- parse output signature from pmx
   -- e.g.
   -- K-2+2
   -- output signature is +2 : D major
   local res =  string.match(line, "^K[%+%-]?[0-9]+([%+%-]?[0-9]+)")
   return tonumber(res)
end

function handleErr(msg)
   io.stderr:write(msg.."\n")
   os.exit(2)
end

--
-- get file name without .pmx suffix
--
function getBaseFileName(fileName)
   if fileName ~= "" and string.sub(fileName, -4, -1) == ".pmx" then
	  return string.sub(fileName, 1, -5)
   else
	  return fileName
   end
end

--
-- Make chords transposition. Generates new pmx file with transposed chords.
--
-- param baseName input file name without .pmx suffix
-- return outputBaseName transposed pmx file name without .pmx suffix
-- 
function makeChordsTransposition(baseName)
   local inputFileName = baseName..".pmx"
   local inputFile = io.open(inputFileName, "r")
   if(inputFile == nil) then
      handleErr("File does not exist: "..inputFileName)
   end

   local outputBaseName = baseName..FILE_SUFFIX   -- output base name without suffix. Used for renaming generated .tex file ...
   local outputFileName = outputBaseName..".pmx"
   local outputFile = io.open(outputFileName, "w")
   if(outputFile == nil) then
      handleErr("Can not create temporary file: ".. outputFileName)
   end

   --
   -- transpose chords from inputFile into outputFile
   --
   -- input and output signature will be parsed from input pmx file
   --
   local iSig = nil  -- input signature
   local chTr = nil  -- chords transposition class

   for line in inputFile:lines() do
      if(chTr ~= nil) then
		 outputFile:write(chTr:lineTranspose(line).."\n")
      else
		 outputFile:write(line.."\n")
      end
      if(iSig == nil) then
		 iSig = parseInputSignature(line)
		 if(iSig ~= nil) then
			io.stderr:write("Chords: input signature detected: "..iSig .."\n")
		 end
      elseif(chTr == nil) then
		 local oSig = parseOutputSignature(line)
		 if(oSig ~= nil) then
			io.stderr:write("Chords: output signature detected: "..oSig .."\n")
			chTr = ChordsTr(iSig, oSig)
		 end
      end
   end
   inputFile:close()
   outputFile:close()

   return outputBaseName
end

--
-- Make pmxab process.
-- param baseName input file name without .pmx suffix
-- param outputBaseName transposed pmx file name without .pmx suffix
--
function pmxabProcess(baseName, outputBaseName)
   --
   -- call pmxab to generate .tex file
   --
   os.execute(PMX_CMD .. " " .. outputBaseName )
   -- check error
   local pmxaerr = io.open("pmxaerr.dat", "r")
   if (not pmxaerr) then
       handleErr("No log file.")
   end
   linebuf = pmxaerr:read()
   err = tonumber(linebuf)
   pmxaerr:close()
   if (err ~= 0 ) then
      handleErr("PMX process fail! "..outputBaseName..".pmx")
   end

   os.rename(outputBaseName..".tex", baseName..".tex")

   -- remove temporary files
   os.remove(outputBaseName..".pmx")
   os.remove(outputBaseName..".pml")
end

narg = 1
onlyTranspose = false

repeat
   this_arg = arg[narg]
   if this_arg == "-v" then
      os.exit(0)
   elseif this_arg == "-h" then
      usage()
      os.exit(0)
   elseif this_arg == "-s" then
      onlyTranspose = true
   else
      local baseName = getBaseFileName(this_arg)
      local outputBaseName = makeChordsTransposition(baseName)

      if (onlyTranspose) then
		 os.exit(0)
      end
      pmxabProcess(baseName, outputBaseName)
   end

   narg = narg + 1
until narg > #arg

