#!/bin/bash
. bean_func.fnc

if [ $(Bean_CmdExist yad) -gt 0 ] ; then
	echo パッケージ yad をインストールしてください。
	exit 1
fi
if [ $(Bean_CmdExist winepath) -gt 0 ] ; then
	yad --title="エラー" --text "パッケージ wine をインストールしてください。" \
	--window-icon=wine-winetricks --image=application-exit --on-top --center
	exit 1
fi
if [ $(Bean_CmdExist wrestool) -gt 0 ] ; then
	yad --title="エラー" --text "パッケージ icoutils をインストールしてください。" \
	--window-icon=wine-winetricks --image=application-exit --on-top --center
	exit 1
fi
if [ $(Bean_CmdExist convert) -gt 0 ] || [ $(Bean_CmdExist identify) -gt 0 ] ; then
	yad --title="エラー" --text "パッケージ imagemagick をインストールしてください。" \
	--window-icon=wine-winetricks --image=application-exit --on-top --center
	exit 1
fi

filelist=""
br="
"

if [ $# -gt 0 ] ; then
	for i in "$@" ; do
		filelist="${filelist}${br}${i}"
	done
	filelist=$(echo "${filelist}" | tail -n +2 | grep --ignore-case -e "\.com$" -e "\.exe$")
else
	filelist=$(yad --title="linuxBean Wine 簡単インストール" \
	--window-icon=wine-winetricks --image=wine-winetricks \
	--borders=10 --width=600 --on-top --center --dnd \
	--text "このウインドウにexeをドロップした後、OKを押してみてください。\n\n自動的に必要な情報を抽出し、「スタートメニュー＞Wine＞プログラム」内部に配置します。\n\n生成されたランチャーは、左のパネルに登録（右クリック＞\"アプリケーション・ランチャー\" の設定）する事でドラッグ＆ドロップからファイルを開けるようになります。\n\nまた、ファイルを右クリックして「アプリケーションで開く」を選択するのも便利な使い方の一つです。\n\nコマンドラインからアプリケーションを起動したい場合は、\n<span foreground='#000000' background='#FFFF66'>bean_wine [exeのパス] [exeのオプション] [開きたいファイルのパス]</span>\nを実行してみてください。ファイルパスを自動でWin形式に変換して起動します。\n\n<span foreground='#cc0000'>※インストーラーではなく、アプリケーション本体をドロップしてください。\n※exeを移動・リネームするとリンクが切れてしまうので、再度ドロップし直してください。</span>")
	
	if [ $? -gt 0 ] ; then
		exit 1
	fi
	
	filelist=$(Bean_PathConv "${filelist}" | uniq | grep --ignore-case -e "\.com$" -e "\.exe$")
fi

if [ "${filelist}" == "" ] ; then
	exit 1
fi

#================================================================================

# バージョン情報のバイナリデータから文字列を抽出する
Ver2Txt()
{
	# 特殊文字の置換
	local tab="	"
	local br="
"
	
	# 念のため変数の宣言
	local i=0
	local all=""
	local raw
	local hex
	local big
	local int
	local all
		
	# バイナリーを文字列に変換するループ
	while true ; do
		
		# 2バイトずつ読み込む
		raw=$(printf "$1" | od -x "$1" -j${i} -N2 2>/dev/null)
		
		# 終端まで達したらループ脱出
		if [ $? -gt 0 ] ; then
			break
		fi
		
		# 必要な部分だけ切り出す
		hex=$(echo ${raw} | awk '{print $2}')
		
		# アルファベット (1byte) ならバイトの並び順を逆転
		if [ "${hex:0:2}" == "00" ] ; then
			big=${hex:0:2}${hex:2:2}
		
		# 日本語 (2byte) ならバイトの並び順を逆転しない
		else
			big=${hex}
		fi
		
		# 10進数に変換
		int=$(printf '%d' 0x${big} 2>/dev/null)
		
		# \0→改行
		if [ ${int} -eq 0 ] ; then
			all="${all}${br}"
			
		# \1→判別用ビーコン
		elif [ ${int} -eq 1 ] ; then
			all="${all}#@#%#"
			
		# \2-\1F→削除
		elif [ ${int} -lt 32 ] ; then
			all="${all}"
		
		# その他→文字に変換
		else
			all="${all}$(echo \&\#${int}\; | nkf --numchar-input)"
		fi
		
		# カウンターを進める
		i=$(expr ${i} + 2)
	done
	
	# 念のため変数の宣言
	local startrec=0
	local prevtitle=0
	local txt=""
	local line
	local title
	
	# 区切り文字を改行に設定
	_IFS="${IFS}";IFS="${br}"
	
	# 文字列を整形するループ
	for line in $(echo "${all}") ; do
		
		# \1が含まれる場合
		if [ $(echo "${line}" | grep --text -o "#@#%#" | wc -l) -gt 0 ] ; then
			
			# ビーコンから改行までを取り出す
			title=$(echo "${line}" | sed -e 's/^.*#@#%#//')
			
			# 記録開始フラグを立て、前の行がタイトルだった事を記録
			if \
			[ "${title}" == "Comments" ]         || \
			[ "${title}" == "CompanyName" ]      || \
			[ "${title}" == "FileDescription" ]  || \
			[ "${title}" == "FileVersion" ]      || \
			[ "${title}" == "InternalName" ]     || \
			[ "${title}" == "LegalCopyright" ]   || \
			[ "${title}" == "LegalTrademarks" ]  || \
			[ "${title}" == "OriginalFilename" ] || \
			[ "${title}" == "PrivateBuild" ]     || \
			[ "${title}" == "ProductName" ]      || \
			[ "${title}" == "ProductVersion" ]   || \
			[ "${title}" == "SpecialBuild" ] ; then
				startrec=1
			fi
				
			# 前の行もタイトルだったなら、適当に改行を空けてから記録
			if [ $startrec -gt 0 ] ; then
				if [ $prevtitle -gt 0 ] ; then
					txt="${txt}${br}${title}${tab}"
				else
					txt="${txt}${title}${tab}"
				fi
				prevtitle=1
			fi
		
		# \0は飛ばす
		elif [ "${line}" == "" ] ; then
			continue
			
		# タイトルでない普通の行
		else
			# 記録開始フラグと前の行がタイトルだったフラグが立っていれば記録
			if [ $startrec -gt 0 ] && [ $prevtitle -gt 0 ] ; then
				txt="${txt}${line}${br}"
			fi
			
			# 前の行がタイトルじゃなかったフラグ
			prevtitle=0
		fi
	done
	
	# 区切り文字を戻す
	IFS="${_IFS}"
	
	echo "${txt}" | head -n -1
}


#================================================================================


Main()
{
	echo 0
	
	# 改行の設定
	local br="
"
	
	# フォルダが無ければ作成
	icotmp="${HOME}/__icotmp__"
	mkdir -p "${icotmp}"
	
	icopath="${HOME}/.local/share/icons/hicolor"
	#itempath="${HOME}/.local/share/applications/wine/Programs"
	itempath="${HOME}/.local/share/applications"
	menupath="${HOME}/.config/menus/applications-merged"
	dirpath="${HOME}/.local/share/desktop-directories"
	assocpath="${HOME}/.local/share/applications"
	mimepath="${HOME}/.local/share/mime/packages"
	winepath="${HOME}/.wine"
	progpath="${HOME}/.wine/drive_c/Program Files"
	portal="${HOME}/Wine-Dirs"
	desktop=$(Bean_UserDirs DESKTOP)
	
	mkdir -p "${icopath}"
	mkdir -p "${itempath}"
	mkdir -p "${menupath}"
	mkdir -p "${dirpath}"
	mkdir -p "${assocpath}"
	mkdir -p "${mimepath}"
	mkdir -p "${portal}"
	
	ln -sfT "${icopath}"   "${portal}/Icons"
	ln -sfT "${itempath}"  "${portal}/StartMenu-Entries"
	ln -sfT "${menupath}"  "${portal}/StartMenu-Merge"
	ln -sfT "${dirpath}"   "${portal}/StartMenu-Folders"
	ln -sfT "${assocpath}" "${portal}/Association"
	ln -sfT "${mimepath}"  "${portal}/MIME-Type"
	ln -sfT "${winepath}"  "${portal}/Wine"
	ln -sfT "${progpath}"  "${portal}/Program-Files"
	
	_IFS="$IFS";IFS="$br"
	
	for i in $@ ; do
		
		# フルパスに変換
		j=$(Bean_PathConv "${i}")
		j=$(Bean_FullPath "${j}")
		
		# ファイル名を抽出
		wdir=$(Bean_FullDir "${j}")
		exe=$(basename "${j}")
		exe_=$(echo "${exe}" | sed -e 's/ /_/igm')
		base=$(Bean_NoExt "${exe}")
		base_=$(Bean_NoExt "${exe_}")
		
		# アイコンの保存先を作成
		mkdir -p "${icotmp}/${exe_}"
		
		# exeからicoを抽出
		wrestool -x "${j}" -t 14 -o "${icotmp}/${exe_}"
		
		# exeからバージョン情報のバイナリデータを抽出
		wrestool -x "${j}" -t 16 --raw -o "${icotmp}/${exe_}/version.res"
		
		# バージョン情報のバイナリデータから文字列を抽出する
		verdata=$(Ver2Txt "${icotmp}/${exe_}/version.res")
		
		# Name
		appname=$(echo "${verdata}" | grep "ProductName" | awk -F"\t" '{print $2}')
		if [ "$appname" == "" ] ; then
			appname=$(echo "${verdata}" | grep "InternalName" | awk -F"\t" '{print $2}')
			if [ "$appname" == "" ] ; then
				appname="${base}"
			fi
		fi
		
		# Comment
		appdesc=$(echo "${verdata}" | grep "FileDescription" | awk -F"\t" '{print $2}')
		if [ "$appdesc" == "" ] ; then
			appdesc="${exe} を起動します"
		fi
		
		# GenericName
		appgene=$(echo "${verdata}" | grep "InternalName" | awk -F"\t" '{print $2}')
		if [ "$appgene" == "" ] ; then
			appgene="${base_}"
		fi
		
		# 区切り文字を改行に
		_IFS="$IFS";IFS="$br"
		
		# 書き出されたicoをリストアップし、全てpngに変換
		cd "${icotmp}/${exe_}"
		for ico in $(find . | grep "${exe}" | grep ".ico$") ; do
			in="${icotmp}/${exe_}/${ico}"
			out=$(echo ${ico} | sed -e 's/ /_/igm')
			out="${icotmp}/${exe_}/$(Bean_NoExt "${out}").png"
			convert "${in}" "${out}"
			rm -f "${in}"
		done
		
		# 区切り文字を戻す
		IFS="$_IFS"
		
		# 0番のアイコンの中で最も大きいものを抽出
		ico0name="$(find . | grep ".png$" | sort -V | head -n 1 | \
				sed -e 's/-[0-9]*.png$//igm' -e 's/^\.\///')"
			
		# それ以外は削除
		ls | grep -v "${ico0name}" | xargs rm -f
	
		# 区切り文字を改行に
		_IFS="$IFS";IFS="$br"
		
		# アイコンをhicolor以下に移動
		for line in $(identify -format "%z %wx%h %f\n" * \
						| head -n -1 | sort -V) ; do
			size=$(echo "${line}" | awk '{print $2}')
			in=$(echo "${line}" | awk '{print $3}')
			#out="${icopath}/${size}/apps/${ico0name}.png"
			out="${icopath}/${size}/apps/${appgene}.png"
			mkdir -p "${icopath}/${size}/apps/"
			cp -f "${in}" "${out}"
		done
		
		# 区切り文字を戻す
		IFS="$_IFS"
		
		# .desktopファイルに書き出す
		echo "[Desktop Entry]
Name=${appname}
Comment=${appdesc}
Exec=bean_wine \"${j}\"
Path=${wdir}
Icon=${appgene}
Terminal=false
Type=Application
GenericName=${appgene}
" > "${itempath}/wine-Programs-${appgene}.desktop"
		
		cp "${itempath}/wine-Programs-${appgene}.desktop" "${desktop}/wine-Programs-${appgene}.desktop"
		
		# .menuファイルに書き出す
		echo "<!DOCTYPE Menu PUBLIC \"-//freedesktop//DTD Menu 1.0//EN\"
\"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd\">
<Menu>
  <Name>Applications</Name>
  <Menu>
    <Name>wine-wine</Name>
    <Directory>wine-wine.directory</Directory>
    <Include>
      <Category>Wine</Category>
    </Include>
    <Menu>
      <Name>wine-Programs</Name>
      <Directory>wine-Programs.directory</Directory>
      <Include>
        <Filename>wine-Programs-${appgene}.desktop</Filename>
      </Include>
    </Menu>
  </Menu>
</Menu>" > "${menupath}/wine-Programs-${appgene}.menu"
	
	done
	
	IFS="$_IFS"
	
	rm -rf "${icotmp}"
}


#================================================================================


Main "${filelist}" | \
yad --title="変換中" --window-icon=wine --image=wine --on-top --center \
--text "Windowsアプリケーションの情報を抽出しています。\nかなり時間が掛かりますので気長にお待ちください。\n（※ボタンを押すとウィンドウを隠します）" --progress --pulsate --auto-close

yad --title="完了" --window-icon=wine --image=wine --on-top --center --width=600 \
--text "変換が完了しました。\n\nアイコンが正しく表示されない場合は、一旦ログアウトしてから再度ログインしてみてください。"

