@echo off
setlocal disabledelayedexpansion
call :start %*
goto :eof

:start

rem --- Get parameters of the project and the build ---------------------------
call "%~dp0prepare.bat" %*

rem --- Decide compiler executable --------------------------------------------
set compexe=dcc32
if "%compiler%"=="delphi" (
  if "%target%"=="x86" (
    set compexe=dcc32
  ) else (
    set compexe=dcc64
  )
)
if "%compiler%"=="fpc" (
  if "%target%"=="x86" (
    set compexe=fpc
  ) else (
    set compexe=ppcrossx64
  )
)

rem --- Detect compiler version -----------------------------------------------
set is_fpc=0
call "%~dp0get_delphi_version.bat" init
if "%compiler%"=="fpc" (
  set is_fpc=1
) else if "%compiler%"=="delphi" (
  call "%~dp0get_delphi_version.bat" check "%compexe%" 2>nul
)

rem --- Prepare command line --------------------------------------------------
set defs=-dPEPAK -dPEPAK_%project%
if "%release%"=="1" (
  set params=%params% -$D- -$L- -$Y- -$C-
  set defs=%defs% -dRELEASE
  set debug=0
)
if "%debug%"=="1" (
  set defs=%defs% -dDEBUG -dFULLDEBUGMODE -dCLEARLOGFILEONSTARTUP
    rem -dFULLDEBUGMODE -dCLEARLOGFILEONSTARTUP are for FastMM
  set release=0
)
if "%fastmm%"=="1" (
  set defs=%defs% -dFASTMM
)
if "%map%"=="1" (
  if "%compiler%"=="delphi" (
    set params=%params% -GD
  )
)
if "%has_namespaces%"=="1" (
  set params=%params% -NSSystem;System.Win;WinApi;Vcl;Xml
)
call "info" defines

rem --- Delete compiled units -------------------------------------------------
del /q "%srcdir%Units\*.*"

rem --- Build the library units -----------------------------------------------
set lib=.

if not "%extralib%"=="" (
  set lib=%lib%;%extralib%
)

rem Pepak
if exist "%srcdir%lib\Pepak\." (
  set lib=%lib%;%srcdir%lib\Pepak;%srcdir%lib\Pepak\ApiForm
)
if exist "%srcdir%lib\Pepak\." (
  if "%is_delphi5%"=="1" (
    set lib=%lib%;%srcdir%lib\Pepak\delphi5
  )
)

rem FastMM4
if exist "%exedir%FastMM_FullDebugMode.dll" del "%exedir%FastMM_FullDebugMode.dll"
if exist "%srcdir%lib\FastMM\." (
  if "%fastmm%"=="1" (
    if not "%is_fpc%"=="1" (
      set lib=%lib%;%srcdir%lib\FastMM
      if "%debug%"=="1" (
        if not exist "%exedir%FastMM_FullDebugMode.dll" copy "%srcdir%lib\fastmm\FastMM_FullDebugMode.dll" "%exedir%FastMM_FullDebugMode.dll"
      )
    )
  )
)

rem DxGetText
if exist "%srcdir%lib\DxGetText\." (
  if "%is_fpc%"=="1" (
    set lib=%lib%;%srcdir%lib\DxGetText\fpc
  ) else if "%is_delphi5%"=="1" (
    set lib=%lib%;%srcdir%lib\DxGetText\delphi5
  ) else if "%has_unicode%"=="1" (
    set lib=%lib%;%srcdir%lib\DxGetText\delphi2009
  ) else (
    set lib=%lib%;%srcdir%lib\DxGetText
  )
)

rem DCPCrypt
if exist "%srcdir%lib\DCPCrypt\." (
  set lib=%lib%;%srcdir%lib\DCPCrypt;%srcdir%lib\DCPCrypt\ciphers;%srcdir%lib\DCPCrypt\hashes
)

rem FAR
if exist "%srcdir%lib\FAR\." (
  set lib=%lib%;%srcdir%lib\FAR
)

rem PerlRegEx
if exist "%exedir%pcrelib.dll" del "%exedir%pcrelib.dll"
if exist "%srcdir%lib\PerlRegEx\." (
  if not "%target%"=="x64" (
    set lib=%lib%;%srcdir%lib\PerlRegEx
    if "%is_fpc%"=="1" (
      if not exist "%exedir%pcrelib.dll" copy "%srcdir%lib\perlregex\pcrelib.dll" "%exedir%pcrelib.dll"
    )
  )
)

rem LkJSON
if exist "%srcdir%lib\lkJSON\." (
  set lib=%lib%;%srcdir%lib\lkJSON
)

rem NativeXml
if exist "%srcdir%lib\NativeXml\." (
  set lib=%lib%;%srcdir%lib\NativeXml
)

rem OXml
if exist "%srcdir%lib\OXml\." (
  set lib=%lib%;%srcdir%lib\OXml\units
)

rem SevenZip
if exist "%srcdir%lib\SevenZip\." (
  set lib=%lib%;%srcdir%lib\SevenZip
)

rem SciZipFile
if exist "%srcdir%lib\SciZipFile\." (
  set lib=%lib%;%srcdir%lib\SciZipFile
)

rem SqliteWrapper
if exist "%srcdir%lib\SqliteWrapper\." (
  set lib=%lib%;%srcdir%lib\SqliteWrapper
)

rem SuperObject
if exist "%srcdir%lib\SuperObject\." (
  set lib=%lib%;%srcdir%lib\SuperObject
)

rem Synapse
if exist "%srcdir%lib\Synapse\source\lib\." (
  set lib=%lib%;%srcdir%lib\Synapse\source\lib
)

rem SynEdit
if exist "%srcdir%lib\SynEdit\Source\." (
  set lib=%lib%;%srcdir%lib\SynEdit\Source
)

rem --- Build the program -----------------------------------------------------
call "info" prebuild

if exist "%project%.cfg" (
  ren "%srcdir%%project%.cfg" "%project%.cfg._"
)
if exist "%project%.dof" (
  ren "%srcdir%%project%.dof" "%project%.dof._"
)

if exist "%srcdir%%project%.rc" updver.exe -b -bak- "%srcdir%%project%.rc" >nul
if exist "%srcdir%%project%.res" updver.exe -b -bak- "%srcdir%%project%.res" >nul
if exist "%srcdir%%project%.rc" call :resource "%srcdir%%project%.rc"
call :%compiler% "%srcdir%%project%.dpr"

if exist "%project%.cfg._" (
  ren "%srcdir%%project%.cfg._" "%project%.cfg"
)
if exist "%project%.dof._" (
  ren "%srcdir%%project%.dof._" "%project%.dof"
)

rem --- Finalize the exe file -------------------------------------------------
ren "%exedir%%project%%ext%" "%project%%ext%"

set gitcommit=
if not "%commit%"=="0" (
  for /f "usebackq" %%i in (`call git rev-parse HEAD 2^>nul`) do (
    set gitcommit=%%i
  )
)
if not "%gitcommit%"=="" (
  updver.exe -s "PrivateBuild=%gitcommit%" -bak- "%exedir%%project%%ext%" >nul
  if errorlevel 1 (
    echo Failed to Git-stamp "%exedir%%project%%ext%"
    ver >nul
  )
)

if "%upx%"=="1" (
  set upx=
  upx --best --lzma --brute --compress-icons=1 "%exedir%%project%%ext%"
  set upx=1
)

call "info" postbuild
goto :eof

rem --- Compile with Delphi ---------------------------------------------------
:delphi
if "%~1"=="" goto :eof
for %%i in (%~1) do (
  echo.
  echo Compiling: %%i
  if "%is_delphixe4_up%"=="1" (
    call "%compexe%" -B -E%exedir% -NU"%srcdir%Units" -U"%srcdir%Units;%lib%" -I"%lib%" %defs% %params% -Q "%%i"
  ) else (
    call "%compexe%" -B -E%exedir% -N"%srcdir%Units" -U"%srcdir%Units;%lib%" -I"%lib%" %defs% %params% -Q "%%i"
  )
  if errorlevel 1 goto :halt
)
goto :eof

rem --- Compile with FreePascal -----------------------------------------------
:fpc
if "%~1"=="" goto :eof
for %%i in (%~1) do (
  echo.
  call "%compexe%" -B -Mdelphi -FE"%exedir%" -Fu"%srcdir%Units;%lib%" -FU"%srcdir%Units" %defs% %params% "%%i"
  if errorlevel 1 goto :halt
)
goto :eof

rem --- Compile resources -----------------------------------------------------
:resource
if "%compiler%"=="delphi" (
  rem brcc32 %1
  rem Note: BRCC32 is buggy. Use GoRC (FreePascal) or RC (Delphi 2009+) if possible
  if "%is_delphi2009_up%"=="1" (
    call "rc" %1
  ) else (
    call "gorc" /r %1 2>nul
    if errorlevel 1 call "brcc32" %1
  )
) else (
  call "gorc" /r %1
)
goto :eof

rem --- Stop compile process prematurely --------------------------------------
:halt
set savederrorlevel=%errorlevel%
if exist "%srcdir%%project%.cfg._" ren "%srcdir%%project%.cfg._" "%project%.cfg"
if exist "%srcdir%%project%.dof._" ren "%srcdir%%project%.dof._" "%project%.dof"
exit %savederrorlevel%
echo Compilation failed.
pause
goto :eof

rem --- Syntax ----------------------------------------------------------------
:help
echo Possible arguments:
echo    delphi/fpc ...... Build using Delphi/FreePascal.
echo    x86/x64 ......... Build for Win32/Win64.
echo    debug/nodebug ... Include/exclude debug code.
call "info" help
goto :eof
