@echo off


rem ====================================================================================================
rem Jar Application Launcher Script - v30 / RINEARN 2024
rem ====================================================================================================


rem 処理終了後に環境変数やカレントディレクトリが元に戻るようにローカル化
setlocal

rem アプリケーションに応じた設定値
rem (注: %CD% 参照箇所はドライブルート時に末尾が「\」になるため、「"」をエスケープしないよう「\\」で置き換えた %CD:\=\\% を使用)
set JAR_FILE_NAME=VCSSL_Editor.jar
set DEFAULT_OPTIONS=--dir "%CD:\=\\%"
set MEMORY_FILE_NAME=etc\VCSSL_Memory.ini
set ENCODING_FILE_NAME=etc\VCSSL_Encoding.ini
set SOFTWARE_NAME=VCSSL Editor
set SOFTWARE_DIR="%~dp0"
set JRE_PATH_FILE=.\jre\JRE_Path_Setting.txt
set JRE_DOWNLOADER=.\jre\JRE_Downloader.bat
set HANDLES_ARGS_AS_FILEPATHS=FALSE
rem ※VCSSLエディタでは先頭引数のみがファイルパス、残りは単純に扱うべき文字列引数なので、ワイルドカード展開などは行わない


rem コマンドライン実行用に、引数にプレフィックスを付加したい場合の、付加内容を指定
rem (プレフィックスは結合後にダブルクォーテーションで囲われるため、この時点では囲ってはいけない)
set ARGUMENTS_PREFIX=

rem プレフィックス付加対象を指定 / NONE: なし、ONLY_FIRST: 最初の引数のみ、ALL: 全ての引数
set ARGUMENTS_PREFIX_TARGET=NONE


rem --------------------------------------------------------------------------------
rem 引数の処理（ワイルドカード展開などがあるので、cd する前に行う必要がある）
rem --------------------------------------------------------------------------------

rem 引数を1個ずつ読み、必要に応じて変換を加えながら、以下の ARGUMENTS_BUFFER に追記して控える
set ARGUMENTS_BUFFER=

rem 引数にファイルパスを想定している場合は、ワイルドカードの展開等を反映させるために for 文を使う
if "%HANDLES_ARGS_AS_FILEPATHS%" == "TRUE" (
	rem 「%」が含まれていると展開されてしまうため、他のいくつかの文字も含めて、まず存在を検査する
	rem （遅延展開適用対象の処理はなるべく少なくしたいため、後続の for 文とは統一しない）
	for %%a in ( %* ) do (
		setlocal enabledelayedexpansion
		rem 下記注意: "%%a" だと " が二重になったりする場合があり、~ で防いでいる
		echo "%%~a" | findstr "%% ! | ^ > < & $" >nul
		if !ERRORLEVEL! == 0 (
			echo エラー：開く対象のファイル名や、コマンドライン引数の中に、使用できない文字が含まれています。
			goto END
		)
		endlocal
	)
	rem 引数の登録処理
	for %%a in ( %* ) do call :REGISTER_ARG %%a
	goto REGISTER_ARGS_BREAK
)

rem 引数がファイルパスではない（計算式などの）場合は、ワイルドカード展開等を行わず素直に処理するために、 
rem goto を使って while 風に「引数がある限りで取り出して変換する」処理を行う
rem (「%数字」での数字変化による取り出しは、対応可能な引数の数が限られてしまう懸念も生じるため、shift で毎回ずらして取り出す)
rem その際、「%」が含まれていると展開されてしまうため、他のいくつかの文字も含めて、それらの存在も検査する
:REGISTER_NEXT_ARG
if "%~1" == "" goto REGISTER_ARGS_BREAK
echo "%~1" | findstr "%% ! | ^ > < & $" >nul
if %ERRORLEVEL% == 0 (
	echo エラー：開く対象のファイル名や、コマンドライン引数の中に、使用できない文字が含まれています。
	goto END
)
rem 引数1個を登録し、次の引数へ
call :REGISTER_ARG %1
shift
goto REGISTER_NEXT_ARG

rem for 文での場合も goto での場合も、全引数を処理し終えたらここに飛ぶ
:REGISTER_ARGS_BREAK

rem --------------------------------------------------------------------------------


rem 実行対象ファイルのある場所（このバッチファイルのある場所の一階層上）へ移動
cd /d %SOFTWARE_DIR%
cd ..


goto LOAD_MEMORY


rem --------------------------------------------------------------------------------
rem メモリー使用量の入力
rem --------------------------------------------------------------------------------
:LOAD_MEMORY
set MEMORY_LINE=
if exist %MEMORY_FILE_NAME% (
	for /F "delims=" %%a in (%MEMORY_FILE_NAME%) do (
		set MEMORY_LINE=%%a
		goto MEMORY_READ_END
	)
) else (
	echo.
	echo  - %SOFTWARE_NAME% -
	echo.
	echo ----------------------------------------------------------------------
	echo.
	echo   - ようこそ -
	echo.
	echo   実行に使用するメモリー容量を MB（メガバイト）単位で入力し、
	echo   Enter キーを押してください。
	echo.
	echo   標準設定値を使用する場合は、そのまま Enter キーを押してください。
	echo.
	echo ======================================================================
	echo.
	set /P MEMORY_LINE="使用するメモリー容量 [ MB ] = "
	echo.
	echo 使用するメモリー容量を、上記の値に設定しました。
	echo この値は、設定ファイル「 %MEMORY_FILE_NAME% 」に記載されています。
	echo.
	echo.
)

:MEMORY_READ_END

set /A MEMORY_LINE_NUM = MEMORY_LINE + 0
if not "%MEMORY_LINE%"=="%MEMORY_LINE_NUM%" (
	set MEMORY_LINE=DEFAULT
)

set /A MEMORY_LINE_NUM = MEMORY_LINE + 0
if "%MEMORY_LINE%"=="%MEMORY_LINE_NUM%" (
	set MEMORY_LINE= -Xmx%MEMORY_LINE%m 
) else (
	set MEMORY_LINE=  
)

goto LOAD_ENCODING


rem --------------------------------------------------------------------------------
rem 文字コード設定の読み込み
rem --------------------------------------------------------------------------------
:LOAD_ENCODING

set ENCODING_LINE=
if exist %ENCODING_FILE_NAME% (
	for /F "delims=" %%a in (%ENCODING_FILE_NAME%) do (
		set ENCODING_LINE=%%a
	)
)

goto JRE_TEST


rem --------------------------------------------------------------------------------
rem javaコマンドが使用可能か確認し、不可能ならJREをダウンロード
rem --------------------------------------------------------------------------------
:JRE_TEST

java -version 2> NUL
if %ERRORLEVEL%==0 (
	rem javaコマンドが使用可能になっている場合は、ダウンロードは不要
	goto JRE_ADD_PATH
) else (
	rem 使用できない場合は、ユーザーが許可すればJREをダウンロードする
	goto :JRE_DOWNLOAD
)

:JRE_DOWNLOAD
if exist %JRE_DOWNLOADER% (
	call %JRE_DOWNLOADER%
	@echo off
)
goto JRE_ADD_PATH


rem --------------------------------------------------------------------------------
rem jre/JRE_Path_Setting.txt にJREのパスが指定されていれば一時的に環境変数PATHに追加
rem （ jre/JRE_Path_Setting.txt が存在しなければ何もしない ）
rem --------------------------------------------------------------------------------
:JRE_ADD_PATH
if exist %JRE_PATH_FILE% (
	for /F %%a in (%JRE_PATH_FILE%) do (
		set JRE_PATH=.\jre\%%a
	)
) else (
	goto RUN
)
rem 以下のパス設定行は括弧の中には入れてはいけない
rem （ 内容に「 ( 」や「 ) 」等の構文的な文字を含むため、まとめず単体で処理するべき ）
set "PATH=%JRE_PATH%;%PATH%"
goto RUN


rem --------------------------------------------------------------------------------
rem 実行
rem --------------------------------------------------------------------------------
:RUN
java -Duser.language=ja -Duser.country=JP %MEMORY_LINE% %ENCODING_LINE% -jar %JAR_FILE_NAME% %DEFAULT_OPTIONS% %ARGUMENTS_BUFFER%
goto SAVE


rem --------------------------------------------------------------------------------
rem 実行後処理
rem --------------------------------------------------------------------------------
:SAVE

if not exist "%MEMORY_FILE_NAME%" (
	if %MEMORY_LINE_NUM%==0 (
		echo. >>"%MEMORY_FILE_NAME%"
	) else (
		echo %MEMORY_LINE_NUM%>>"%MEMORY_FILE_NAME%"
	)
)

rem 終了コード0は正常終了、2はコマンドラインモードでの想定エラーなのでメッセージ出力済み
rem 従って 0 と 2 の場合は追加メッセージを出さずに終了する
rem 終了コード1の場合は、GUIモードでのエラーや、例外が出た場合なので、案内メッセージを出す

set EXIT_STATUS_IS_0_OR_2=FALSE
if %ERRORLEVEL%==0 (
	set EXIT_STATUS_IS_0_OR_2=TRUE
)
if %ERRORLEVEL%==2 (
	set EXIT_STATUS_IS_0_OR_2=TRUE
)

if %EXIT_STATUS_IS_0_OR_2%==TRUE (
	rem この場合は何もせず終了
) else (
	echo.
	echo ======================================================================
	echo.
	echo - 起動に失敗したか、動作中にエラーが発生しました。
	echo.
	echo ※ 普通に使用している最中に「メモリーエラー」等と表示された場合は、
	echo    このソフトの動作に割り当てるメモリー容量が不足しています。
	echo    同梱の「 メモリー容量設定 」を実行し、容量を増やしてみてください。
	echo.
	echo ※ メモリー使用量の設定直後にこのエラーが発生した場合は、
	echo    逆に設定値が大きすぎた可能性があります。
	echo    同梱の「 メモリー容量設定 」を実行し、容量を減らしてみてください。
	echo.
	echo ※ 初めて使う際に、起動に失敗した場合は、
	echo    Java^(R^)言語の実行環境（JRE）の有無や古さに起因する場合があります。
	echo    同梱の「 実行環境（JRE）の更新.bat 」を実行すると、解決する可能性があります。
	echo.
	echo ※ または、処理に必要な権限が不足している可能性もあります。
	echo    その場合、このバッチファイルを右クリックし、メニューから
	echo    「 管理者として実行 」を選択すると解決するかもしれません。
	echo.
	echo ※ 一部環境では、フォルダ名（親階層フォルダ含む）に日本語等が含まれていると、
	echo    起動に失敗してしまうようです。このパターンに該当する場合は、
	echo    親階層も含めてフォルダ名が全て半角英数字である場所に配置してみてください。
	echo.
	echo ※ その他、以下のページに、問題解決のための参考情報を掲載しています：
	echo.
	echo    [ 主なRINRARN製ソフト（VCSSL以外）の場合はこちら ]
	echo      https://www.rinearn.com/ja-jp/info/other/help
	echo.
	echo    [ VCSSLの場合はこちら ]
	echo      https://www.vcssl.org/ja-jp/info/help
	echo.
	echo    また、なかなか解決できない場合や、その他のご質問などは、
	echo    RINEARNのお問い合わせページから御気軽にお尋ねください：
	echo.
	echo      https://www.rinean.com/ja-jp/contact/
	echo.
	echo ----------------------------------------------------------------------
	echo ※ OracleとJavaは、Oracle Corporation 及びその子会社、
	echo    関連会社の米国及びその他の国における登録商標です。
	echo    文中の社名、商品名等は各社の商標または登録商標である場合があります。
	echo ----------------------------------------------------------------------
	echo.

	if exist "%MEMORY_FILE_NAME%" (
		del "%MEMORY_FILE_NAME%"
	)

	echo ======================================================================
	echo.
	pause
)
goto END


:END
exit /b


rem --------------------------------------------------------------------------------
rem 引数1個（%~1）に必要な変換を加えた上で、ARGUMENTS_BUFFER に追記登録する
rem --------------------------------------------------------------------------------
:REGISTER_ARG

	rem プレフィックスと結合する対象が「NONE(なし)」に指定されている場合、初回結合前にプレフィックスをクリアする
	if "%ARGUMENTS_PREFIX_TARGET%"=="NONE" (
		set ARGUMENTS_PREFIX=
	)

	rem プレフィックスと結合しつつダブルクォーテーションで囲う
	set PROCESSED_ARG="%ARGUMENTS_PREFIX%%~1"

	rem フォルダ区切りの「\」が引数 %~1 の末尾にあった場合、
	rem さらに末尾に付加したダブルクォーテーションをエスケープしていると（コマンド実行時に）解釈される場合があるため、
	rem 「\」は全て「\\」で置き換える
	set PROCESSED_ARG=%PROCESSED_ARG:\=\\%

	rem プレフィックスと結合する対象が最初の引数のみに指定されている場合、初回結合後にプレフィックスをクリアする
	if "%ARGUMENTS_PREFIX_TARGET%"=="ONLY_FIRST" (
		set ARGUMENTS_PREFIX=
	)

	rem ARGUMENTS_BUFFER の内容の末尾に、処理済みの引数を追記する
	set APPENDED_BUFFER=%ARGUMENTS_BUFFER% %PROCESSED_ARG%
	set ARGUMENTS_BUFFER=%APPENDED_BUFFER%

