--
-- luaConvert.lua - This converts *.cxx files generated by FLUID to murgaLua
--                  See murgaLua tutorials for usage examples.
--
-- Copyright (C) 2007 Markku Kotiaho
-- 
-- Based on convertFluidToMurga.sh -- (C) 2006 John Murga
-- 
-- 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.
--


function converterCustomPrint(...)
	local str=""
	local i=1
	while arg[i]~= nil do
		if str=="" then
			str=tostring(arg[i])
		else
			str=str.."	"..tostring(arg[i])
		end
		i=i+1
	end
	gConverterString=gConverterString..str.."\n"
end

function convertFluidToIg3d(theFluidFile)
	----this is a function which iGame3D uses to automatically convert fluid .fl files to .lua files
	parsedFile=string.sub(theFluidFile, 1, -4)..".lua"
	parseFluid(theFluidFile, parsedFile)
	return parsedFile
end

function convertCxxToIg3d(theCxxFile)
----this is a function now which iGame3D uses to automatically convert fluid .cxx files to .lua files
if (not theCxxFile) then
   print("\n" ..
         "luaConvert.lua usage:\n" ..
	 "  murgaLua luaConvert.lua <FLUID GENERATED FILE>.cxx > <murgaLua File>.lua")
   return nil
end

--keep in mind the old print() function because here for later restoring, because we will redirect it :-P
gConverterString=""
local rememberedPrint=print
print=converterCustomPrint




function split(Line) 
   R = {}
   if (string.len(Line) < 1) then
      return R
   end
   for w in string.gmatch(Line, "%S+") do --iterate over all non-space sequences in Line
      table.insert(R,w)
   end
   return R
end

Marker     = -2
PrefixFlag =  0
touchCode  =  false

for line in io.lines(theCxxFile) do

   currentLine = string.gsub(line,"\n$", "") --get rid of newline

   Fld = split(currentLine)

   -- Ignore everything before the main function
   if (Fld[2] == 'make_window()' or Marker > -2) then
      Marker = Marker + 1
   end

	

   -- This is the part of the file we are interested in
   if (Marker >= 0) then

      -- Make sure that we have not come to end of the window definition
      if string.find(currentLine, "Fl_Double_Window%(") then
      	 touchCode=true
      end
      
      
      if string.find(currentLine, "\} // Fl_Double_Window%* [%w_]*") then
         -- Is this the place to leave?
         touchCode=false
         print("  end\n")
      end
	  
	  -- If we are in the fluid-generated part
	  if touchCode then
	
      	-- If there is a "\" at the end of line it is a continuation    
      	where,ending = string.find(currentLine, '\\$') 
      	if (where and where > 1) then
      	   PrefixFlag = 1
      	else
      	   -- If this flag was set it means this is a string continuation line
       	  if (PrefixFlag == 1) then
       	     currentLine = "\"" .. currentLine
       	  end
      	   PrefixFlag = 0
      	end

      	-- Replace the continuation with a LUA string concatenation
      	-- (I am assuming that FLUID only wraps long strings)
      	currentLine = string.gsub(currentLine, '\\$', "\" .. ")

      	-- Do some basic replacements in code (definitions/boundaries)
      	currentLine = string.gsub(currentLine, 'Fl_.* o = new ', "local object = fltk:")
      	currentLine = string.gsub(currentLine, 'new Fl_', "fltk:Fl_")
      	currentLine = string.gsub(currentLine, '\{', "do")
      	currentLine = string.gsub(currentLine, '\}', "end")

      	-- Convert object notation
      	currentLine = string.gsub(currentLine, 'o%->', "object:")
      	
      	currentLine = string.gsub(currentLine, '%(%o%)', "(object)")
      
      	-- Convert Fl_Text_Editor to Fl_Multiline_Input
     	 currentLine = string.gsub(currentLine, "Fl_Text_Editor", "Fl_Multiline_Input")
     	 
     	-- Convert Fl_Text_Display to Fl_Multiline_Output
     	currentLine = string.gsub(currentLine, "Fl_Text_Display", "Fl_Multiline_Output")
      
      	-- Convert object notation of named objects
      	currentLine = string.gsub(currentLine, '[%w_]+%->', "%1:")
      	currentLine = string.gsub(currentLine, '->:', ":")
      	-- handle special case where custom object name ends with o (all o's get replaced with object, so need that in the constructor as well)
      	currentLine = string.gsub(currentLine, "o = fltk:Fl_", "object = fltk:Fl_")
      
      	-- Convert :: or -> to :
      	currentLine = string.gsub(currentLine, "::", ":")
      	currentLine = string.gsub(currentLine, "->", ":")
      
     	 -- Remove <objectname>:end()
      	currentLine = string.gsub(currentLine, "[%w_]*:end%(%)%;", "Fl_Group:current(Fl_Group:current():parent());")
      
      	-- Logical ORs can be replaced with arithmetic ADDs
      	currentLine = string.gsub(currentLine, '\|FL_', "+FL_")
      	-- Convert the namespace to the used in murgaLua
      	currentLine = string.gsub(currentLine, 'FL_', "fltk.FL_")

      	-- Remove casts with pointers as they are not required in LUA
     	 currentLine = string.gsub(currentLine, "%(Fl_%w*%*%)", "")
     	 -- Remove casts without pointers as they are not required in LUA
     	 currentLine = string.gsub(currentLine, "%(Fl_%w*%)", "")
     	 
     	 -- Replace C++ comments with Lua ones
      	currentLine = string.gsub(currentLine, '//', "--")
    
      	-- Change the initial window declaration
      	currentLine = string.gsub(currentLine, 'w = o', "window = object")

	  end

      -- Output the converted line
      print(currentLine)

   end
   
end



      

gConverterString=string.gsub(gConverterString, "Fl_Double_Window%* w;\n", "")
gConverterString=string.gsub(gConverterString, "\} // Fl_Double_Window%* [%w_]*", "")
local winname="window"
local s,e=string.find(gConverterString, "  return [%w_]*;")
if s~=nil and string.find(gConverterString, "window = object;")== nil then
	winname=string.sub(gConverterString, s+9, e-1)
end

gConverterString=string.gsub(gConverterString, "return [%w_]*;\n\}", "")


   print("  "..winname..":show();")
         print("  ig3d_RebuildMacMenubar();")
         print("  if game_func==nil then")
         print("  	function runner()")
         --print("    	if not click(\"-\") then")
         print("      	fltk_update();")
         --print("    	end")
         print("  	end")
         print("  	game_func=runner;")
         print("  end")
         print("  Fl:scheme(\"plastic\")")
         print("--Fl:run();")



print=rememberedPrint --reset the print function
--ok, by now the conversion is done, now print the remembered stuff to the .lua file
theLuaFile=string.sub(theCxxFile, 1, -4).."lua"

f=io.open(theLuaFile, "w")
f:write(gConverterString)
f:close()
return theLuaFile
end









function converterDofile(theFile)
	if theFile==nil then
		return actualdofile()
	end
	
	--remember the loaded file
	if #theFile>#getSceneInfo(IG3D_ROOT) then
		ig3d_AddFileToLoadedList_s(string.sub(theFile, #getSceneInfo(IG3D_ROOT)+1, -1))
	end

	if string.sub(theFile, -4,-1)==".cxx" then
		return actualdofile(convertCxxToIg3d(theFile))
	else
		if string.sub(theFile, -3,-1)==".fl" then
			local result=actualdofile(convertFluidToIg3d(theFile))
			ig3d_RebuildMacMenubar()
			return result
		else
			return actualdofile(theFile)
		end
	end
end

--overwrite default dofile
actualdofile=dofile
dofile=converterDofile