import json
import os
import subprocess
import sys
import zlib
import struct
import platform

def main():
	DataFolderName = sys.argv[1]

	ImageFolderNameList = sys.argv[2].split(',')

	OutputJsonData = { 'version': 0, 'filelist': [] }

	# 出力フォルダ作成
	OutputFolderName = os.path.join(DataFolderName, "CompImageList")
	os.makedirs(OutputFolderName, exist_ok=True)

	# プラットフォームを見て拡張子や区切り文字を変更する
	Punct = ""
	ExeExtension = ""

	pf = platform.system()

	if(pf == 'Windows'):
		Punct = "\\"
		ExeExtension = ".exe"

		print("Platform is Win.")
	elif(pf == 'Darwin'):
		Punct = "/"
		ExeExtension = ""

		print("Platform is Mac.")
	elif(pf == 'Linux'):
		Punct = "/"
		ExeExtension = ""

		print("Platform is Linux.")

	#
	for ImageFolderName in ImageFolderNameList:
		FileNameList = get_files_in_directory(DataFolderName, ImageFolderName, ".png")

		for FileName in FileNameList:
			#print(FileName)

			width, height, bpp, color_type = get_png_info(os.path.join(DataFolderName, FileName))

			#print(f"{width}, {height}, {bpp}, {color_type}")

			if not is_power_of_two(width) or not is_power_of_two(height):
				print(f"{FileName} is not POW2")
				continue

			if bpp != 8:
				print(f"{FileName} bit depth is not 8")
				continue

			alpha = False

			if color_type == 2:
				alpha = False
			elif color_type == 6:
				alpha = True
			else:
				print(f"{FileName} is unsupported color_type")
				continue

			OutputJsonData['filelist'].append([ FileName.replace('\\', '/'), width, height, alpha ])

			# ETC
			OutFileName = "etc" + Punct + FileName.replace(".png", ".pvr")

			ETCType = ""

			if alpha:
				ETCType = "ETC2_RGBA"
			else:
				ETCType = "ETC2_RGB"

			# 出力フォルダを生成する
			OutFolderName = os.path.join(OutputFolderName, os.path.dirname(OutFileName))
			os.makedirs(OutFolderName, exist_ok=True)

			# テクスチャ圧縮をおこなう
			SaveETCFileName = os.path.join(OutputFolderName, OutFileName)

			ETCRunCommand = "PVRTexToolCLI" + ExeExtension + " -i \"" + os.path.join(DataFolderName, FileName) + "\" -o \"" + SaveETCFileName + "\" -m 16 -f " + ETCType + ",UBN,sRGB"

			subprocess.call(ETCRunCommand, shell=True)

			# zlib圧縮をおこなう
			compress_file(SaveETCFileName, SaveETCFileName.replace(".pvr", ".zlb"))

			# 元ファイルを削除する
			os.remove(SaveETCFileName)

			#ASTC
			OutFileName = "astc" + Punct + FileName.replace(".png", ".pvr")

			# 出力フォルダを生成する
			OutFolderName = os.path.join(OutputFolderName, os.path.dirname(OutFileName))
			os.makedirs(OutFolderName, exist_ok=True)

			# テクスチャ圧縮をおこなう
			SaveASTCFileName = os.path.join(OutputFolderName, OutFileName)

			ASTCRunCommand = "PVRTexToolCLI" + ExeExtension + " -i \"" + os.path.join(DataFolderName, FileName) + "\" -o \"" + SaveASTCFileName + "\" -m 16 -f " + "ASTC_4x4" + ",UBN,sRGB"

			subprocess.call(ASTCRunCommand, shell=True)

			# zlib圧縮をおこなう
			compress_file(SaveASTCFileName, SaveASTCFileName.replace(".pvr", ".zlb"))

			# 元ファイルを削除する
			os.remove(SaveASTCFileName)


	# json保存
	with open(os.path.join(OutputFolderName, "CompImageList.json"), 'w') as file:
		file.write(json.dumps(OutputJsonData))


#フォルダを再帰検索してファイル名一覧を取得する
def get_files_in_directory(DataFolderName, ImageFolderName, extension):
	path = os.path.join(DataFolderName, ImageFolderName)

	file_list = []

	for dirpath, _, filenames in os.walk(path):
		for filename in filenames:
			if filename.endswith(extension):
				FullPathFileName = os.path.join(dirpath, filename)
				FilePath = FullPathFileName[len(DataFolderName) + 1:]
				file_list.append(FilePath)

	return file_list


# PNGの情報を取得する
def get_png_info(filename):
	with open(filename, 'rb') as f:
		# ヘッダの確認
		header = f.read(8)
		if header != b'\x89PNG\r\n\x1a\n':
			return 0,0,0,0

		# IHDRチャンクの長さ (常に0x0000000d または 13)
		chunk_length = f.read(4)
		if chunk_length != b'\x00\x00\x00\r':
			raise ValueError("Unexpected IHDR chunk length")

		# IHDRチャンクタイプの確認
		chunk_type = f.read(4)
		if chunk_type != b'IHDR':
			return 0,0,0,0

		# IHDRデータの取得
		ihdr_data = f.read(13)

		# Width (4 bytes), Height (4 bytes)
		width = int.from_bytes(ihdr_data[:4], byteorder='big')
		height = int.from_bytes(ihdr_data[4:8], byteorder='big')

		# Bit depth (1 byte)
		bpp = ihdr_data[8]

		# Color type (1 byte)
		color_type = ihdr_data[9]

		return width, height, bpp, color_type


# ２の累乗かどうか調べる
def is_power_of_two(n):
	if n <= 0:
		return False
	return (n & (n - 1)) == 0


# zlib圧縮
def compress_file(input_file, output_file):
	with open(input_file, 'rb') as f:
		data = f.read()
		compressed_data = zlib.compress(data)

	original_size = struct.pack('I', len(data))
	version = struct.pack('I', 0)

	compressed_data = b"zlb\0" + version + original_size + compressed_data

	with open(output_file, 'wb') as f:
		f.write(compressed_data)


##
main()

