/*
 * * * Compile_AHK SETTINGS BEGIN * * *

[AHK2EXE]
Exe_File=%In_Dir%\..\FKPortableCompiler.exe
Execution_Level=2
[VERSION]
Set_Version_Info=1
Company_Name=Framakey.org
File_Description=Compilateur pour lanceur
File_Version=0.2.5.1
Inc_File_Version=0
Internal_Name=FKCompiler
Legal_Copyright=2011 Framakey.org
Product_Version=1.1.5.1
Set_AHK_Version=1
[ICONS]
Icon_1=%In_Dir%\FKPortableCompiler.ico

* * * Compile_AHK SETTINGS END * * *
*/

; ================================================================================
; 								FKPortableCompiler
; ================================================================================
;
; 	By fat115
; 	License : GNU/GPL v2
; 	This app is a specific compiler for Framakey's portable launchers
;	Original AutoHotkeySC.bin is patched (VersionInfo and icons) before
;	adding portable launcher' script as RCDATA.
; 	It is not intended to replace finc's Ahk2Exe compiler which was a great resource to build this app.

; 	Compiler: AutoHotkey_L (http://www.autohotkey.com/).
; 	$id=FKPortableCompile.ahk $date=2011-10-31
;
; --------------------------------------------------------------------------------
;						Copyright (C) 2010-2011 Framakey

;						Website: http://www.framakey.org

/*
Changelog :
2011-10-31 : v 0.2.5.1
	Launcher is named according to script's name

2011-10-20 : v 0.2.5
	console mode : messages are redirected to StdOut
	Read-Only and Network option : create specific launchers

2011-08-29 : v 0.2
	All-in-one utility : upx and original AutoHotkeySC.bin are included using FileInstall
	resources are included directly using DllCall/UpdateResource
	Anolis Resourcer is replaced by ChangeIcon.ahk
	Ahk2Exe is replaced by a light version of finc's Ahk2Exe *.ahk scripts

2011-08-06 : v 0.1
	initial release with external resources : upx, Anolis Resourcer, Ahk2Exe 1.1.1.0
	FKPortableSC.bin is a patched version of AutoHotkeySC.bin (prefilled VI, removed icons)
*/
#NoEnv
; On force le répertoire des includes à être celui du script
#Include %A_ScriptDir%
#Include Functions.ahk
#Include ini.ahk
#Include VersionInfo.ahk
#Include ResCompileU.ahk
#Include ScriptCompileU.ahk
#Include ChangeIcon.ahk
SetWorkingDir %A_ScriptDir%
OnExit, QuitCompiler
FileEncoding, UTF-8

; création d'un dossier temporaire et extraction des fichiers contenus
Process, Exist
i_PID := ErrorLevel
p_PluginsDir := A_Temp "\FKPortableCompiler." i_PID
FileCreateDir, %p_PluginsDir%
FileInstall, upx.exe, %p_PluginsDir%\upx.exe
FileInstall, AutoHotkeySC.bin, %p_PluginsDir%\AutoHotkeySC.bin

; Définitions des éléments pour la récupération des IconGroups
CallB := RegisterCallback( "EnumResNameProc" )
IconGroups := ""

; Vérification des paramètres
If 0 = 0
	Msg_Error("Cette application requiert au minimum un script AutoHotkey en argument !")
Else
	{
	Loop, %0%
		{
		_param := %A_Index%
		If (A_Index = 1)
			f_ScriptAhk := _param
		_param := StringLower(_param)
		IfInString, _param, console
			b_ConsoleMode := True
		IfInString, _param, readonly
			b_ReadOnlyLauncher := True
		IfInString, _param, network
			b_NetworkLauncher := True
		If _param contains help,-h,/?
			b_ShowHelp := True
		}
	If b_ShowHelp
		{
		_message =
			( LTrim
			Usage : FKPortableCompiler nom_du_script options
			Les options acceptées sont les suivantes :
			-console, /console : renvoi des messages vers StdOut
			-readonly, /readonly : crée un lanceur pour média en lecture seule
			-network, /network : crée un lanceur pour utilisation réseau
			-h,-help,/help,/? : affiche cette aide
			)
		Msg_Error(_message)
		}
	}

IfNotExist, %f_ScriptAhk%
	Msg_Error("Cette application requiert un script AutoHotkey en argument !")

f_UpxExe := p_PluginsDir "\upx.exe"
f_AhkBin := p_PluginsDir "\AutoHotkeySC.bin"
f_RES_File := p_PluginsDir "\RCFile.res"

_spos := StringGetPos(f_ScriptAhk, "\", "R3")
p_BaseScriptDir := StringLeft(f_ScriptAhk, _spos)
f_AppInfo := p_BaseScriptDir "\App\AppInfo\appinfo.ini"
f_AppIcon := p_BaseScriptDir "\App\AppInfo\appicon.ico"

ini_load(s_AppInfoIniFile, f_AppInfo, "UTF-8")
s_PortableAppName := ini_getValue(s_AppInfoIniFile, "Details", "AppID")
SplitPath, f_ScriptAhk,,,, s_LauncherName
FileRead, s_ScriptAhk, %f_ScriptAhk%
s_Needle = m)^_SCRIPTVER := \"(.*)\"
RegExMatch(s_ScriptAhk, s_Needle, _result)

o_Tableau := Object()
o_Tableau.CommaFileVersion := StringReplace(ini_getValue(s_AppInfoIniFile, "Version", "PackageVersion"), ".", ",", "All")
o_Tableau.CommaProductVersion := StringReplace(_result1, ".", ",", "All")

o_Tableau.Comments := "Pour plus d'informations, visitez le site http://www.framakey.org"
o_Tableau.LegalCopyright := "© 2005-" A_Year " Framakey.org"
o_Tableau.CompanyName := "Framakey.org"
o_Tableau.FileDescription := s_PortableAppName " - " ini_getValue(s_AppInfoIniFile, "Details", "Description")
o_Tableau.FileVersion := ini_getValue(s_AppInfoIniFile, "Version", "PackageVersion")
o_Tableau.ProductVersion := _result1
o_Tableau.InternalName := s_PortableAppName " " ini_getValue(s_AppInfoIniFile, "Version", "DisplayVersion")
o_Tableau.LegalTrademarks := ""
o_Tableau.OriginalFilename := ini_getValue(s_AppInfoIniFile, "Control", "Start")
o_Tableau.ProductName := s_PortableAppName
o_Tableau.BuildID := A_NowUTC

f_OutExe := p_BaseScriptDir "\" s_LauncherName ".exe"
f_TempExe := p_PluginsDir "\TempExe.exe"

; modification si des lanceurs spéciaux sont demandés en paramètres (ne modifie pas le script enregistré !)
If b_ReadOnlyLauncher
	s_ScriptAhk := RegExReplace(s_ScriptAhk, "m)^;_READONLYL", "_READONLYL")
If b_NetworkLauncher
	s_ScriptAhk := RegExReplace(s_ScriptAhk, "m)^;_NETWORKL", "_NETWORKL")

; tests pour les lanceurs spéciaux
If RegExMatch(s_ScriptAhk, "m)^_READONLYL")
	{
	f_OutExe := p_BaseScriptDir "\" s_LauncherName "_RO.exe"
	o_Tableau.FileDescription := StringReplace(o_Tableau.FileDescription, s_PortAppName, s_PortAppName " - Édition CD/DVD")
	}
Else If RegExMatch(s_ScriptAhk, "m)^_NETWORKL")
	{
	f_OutExe := p_BaseScriptDir "\" s_LauncherName "_N.exe"
	o_Tableau.FileDescription := StringReplace(o_Tableau.FileDescription, s_PortAppName, s_PortAppName " - Édition Réseau")
	}

; on crée la chaine hexadecimale
s_VSVersion := CreateRESString(o_Tableau)

; on convertit en binaire
_nbBytes := StrLen(s_VSVersion) // 2
VarSetCapacity(_memdata, _nbBytes)
Loop, % _nbBytes
	_memadd := NumPut("0x" SubStr(s_VSVersion, (A_Index * 2) -1, 2), _memdata, A_Index-1, "UChar")

; on récupère les noms des IconGroups présents dans le binaire
_hModule := DllCall( "LoadLibraryEx", Str,f_AhkBin, UInt,0, UInt,0x2 )
DllCall("EnumResourceNames", UInt,_hModule, UInt,14, UInt,CallB, UInt,0 )
DllCall("FreeLibrary", UInt,_hModule )

; on patche le binaire
	_hModule := DllCall("BeginUpdateResource", Str, f_AhkBin, UInt, 0, Ptr)
	; mise en place de VERINFO
	DllCall("UpdateResource", Ptr, _hModule, Ptr, 16, Ptr, 1, UInt, 1033, Ptr, &_memdata, UInt, _nbBytes, UInt)
	; on boucle sur tous les groupes d'icones et on efface tout sauf le premier
	Loop, parse, IconGroups, |
	{
		If A_Index = 1
			{
			i_FirstIconID := A_LoopField
			Continue
			}
		DeleteIcons(_hmodule, A_LoopField, 1033, f_AhkBin)
	}
	; on met en place le premier groupe d'icone
	ReplaceIcons(_hmodule, f_AppIcon, i_FirstIconID, 1033, f_AhkBin)
DllCall("EndUpdateResource", Ptr, _hModule, UInt, 0)
VarSetCapacity(_memdata, 0)

; on compile
_compilsuccess := BundleAhkScript(f_ScriptAhk, f_TempExe, f_AhkBin)
If !_compilsuccess
	Msg_Error("La compilation a échoué.")

FileDelete, %f_OutExe%
RunWait, %f_UpxExe% -o"%f_OutExe%" "%f_TempExe%", , Hide
MsgBox, 64, Framakey Compiler, La création du lanceur est terminée., 3

Exit

;===============================================================================
; 							Subroutines
;===============================================================================

QuitCompiler:
	; On efface le dossier temporaire
	FileRemoveDir, %p_PluginsDir%, 1
ExitApp

;===============================================================================
; 							Functions
;===============================================================================

EnumResNameProc( hModule, lpszType, lpszName, lParam )
{ 
	Global IconGroups
	IconGroups .= ( ( IconGroups!="" ) ? "|" : "" ) lpszName 
	Return True 
}

Msg_Error(_txt, _options=16)
{
	Global b_ConsoleMode
	If b_ConsoleMode
		FileAppend, %_txt%, *
	Else
		MsgBox, %_options%, Framakey Compiler, %_txt%
	ExitApp, 1
}
