from __future__ import print_function
import io, sys, struct
import scx

for_main_text = False

def parse_expr(content, pos):
	args = []
	print("[", end='')
	while True:
		type_ = content[pos]
		pos += 1
		if type_ == 0:
			break
		if args:
			print(" ", end='')
		if type_ & 0x80: # field_8 = 0xFF
			data = 0
			if (type_ & 0x60) == 0:
				data = type_ & 0x1F
				if data & 0x10:
					data -= 0x20
			elif (type_ & 0x60) == 0x20:
				data = (type_ & 0x1F) << 8
				data += content[pos]
				pos += 1
				if data & 0x1000:
					data -= 0x2000
			elif (type_ & 0x60) == 0x40:
				data = (type_ & 0x1F) << 16
				data += content[pos]
				data += content[pos + 1] << 8
				pos += 2
				if data & 0x100000:
					data -= 0x200000
			else:
				#if type_ != 0x60:
				#	print("{nonzero ignored bits}", end='')
				data = struct.unpack_from('<i', content, pos)[0]
				pos += 4
			# ignored byte
			pos += 1
			args.append((data, 0, 0xFF))
			print("%d" % data, end='')
		else:
			priority = content[pos]
			pos += 1
			args.append((None, priority, type_ & 0x7F))
			#print(" special(%d,%d)" % (data, type_), end='')
			ops = {1:'*', 2:'/', 3:'+', 4:'-', 5:'%', 6:'<<', 7:'>>', 8:'&', 9:'^', 10:'|', 11:'~', 12:'==', 13:'!=', 14:'<=', 15:'>=', 16:'<', 17:'>',
				20:'=', 21:'*=', 22:'/=', 23:'+=', 24:'-=', 25:'%=', 26:'<<=', 27:'>>=', 28:'&=', 29:'|=', 30:'^=', 32:'++', 33:'--',
				40:'vars[]', 41:'flags[]', 45:'regs[]', 51:'random()'
				}
			if type_ in ops:
				print("(%s,%d)" % (ops[type_], priority), end='')
			else:
				print("(op%d,%d)" % (type_, priority), end='')
	print("]", end='')
	return pos



scx.load_characters_data('input_map.bin', True)
if for_main_text:
	scx.setup_for_main_text(False)
data = scx.ScxData(sys.argv[1])

pos = data.eip
content = data.content
labels_set = {x:i+1 for i,x in enumerate(data.labels)}
switch_labels = {}
last_label = 0
mail_labels = [-1, -1, -1, -1, -1, -1]
mail_list_labels = {}
while pos < data.strings_table:
	if pos in labels_set:
		last_label = labels_set[pos]
		print("label%d:" % labels_set[pos])
		if last_label in switch_labels:
			print("word ", end='')
			#pos += 2
			first = True
			while (first or pos not in labels_set) and struct.unpack_from('<H', content, pos)[0] < len(data.labels):
				if first:
					first = False
				else:
					print(", ", end='')
				print("label%d" % struct.unpack_from('<H', content, pos)[0], end='')
				pos += 2
			print()
			continue
		if last_label == mail_labels[1] or last_label == mail_labels[2]:
			print("word %d" % struct.unpack_from('<H', content, pos)[0])
			pos += 2
			continue
		if last_label == mail_labels[0]:
			id_ = 0
			while struct.unpack_from('<H', content, pos)[0] != 0xFF:
				print("# mail %d" % id_)
				id_ += 1
				maildata = struct.unpack_from('<15H', content, pos)
				print("mail1 %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," % maildata[0:12], end='')
				print('"' + scx.text_to_string(data.parse_text(maildata[12])) + '"', end='')
				print(",", end='')
				print('"' + scx.text_to_string(data.parse_text(maildata[13])) + '"', end='')
				print(",\\\n\t", end='')
				print('"' + scx.text_to_string(data.parse_text(maildata[14])) + '"', end='')
				print()
				pos += 30
			print("word 255")
			pos += 2
			continue
		if last_label == mail_labels[3]:
			while struct.unpack_from('<H', content, pos)[0] != 0xFF:
				print("mail2 %d,label%d" % struct.unpack_from('<2H', content, pos))
				mail_list_labels[struct.unpack_from('<H', content, pos+2)[0]] = True
				pos += 4
			print("word 255")
			pos += 2
			continue
		if last_label in mail_list_labels:
			print("word ", end='')
			first = True
			while True:
				n = struct.unpack_from('<H', content, pos)[0]
				pos += 2
				if first:
					first = False
				else:
					print(", ", end='')
				print(n, end='')
				if n == 255:
					break
			print()
			continue
		if last_label == mail_labels[4]:
			while struct.unpack_from('<H', content, pos)[0] != 0xFFFF:
				print("mail3 %d,%d,%d,%d" % struct.unpack_from('<4H', content, pos))
				pos += 8
			print("word 0xFFFF")
			pos += 2
			continue
		if last_label == mail_labels[5]:
			while struct.unpack_from('<H', content, pos)[0] != 0xFFFF:
				print("mail3 %d,%d,%d" % struct.unpack_from('<3H', content, pos))
				pos += 6
			print("word 0xFFFF")
			pos += 2
			continue
	if pos + 12 < data.strings_table and struct.unpack_from('<BIII', content, pos) == (0, 0xAC, 0xAD, 0xAE): # hack
		print("byte 0")
		print("dword 0xAC, 0xAD, 0xAE")
		pos += 13
		continue
	byte1 = content[pos]
	if byte1 == 0xFE:
		pos += 1
		print("eval ", end='')
		pos = parse_expr(content, pos)
		print()
	else:
		byte2 = content[pos + 1]
		pos += 2
		cmd = (byte1 << 8) | byte2
		if cmd not in scx.commands:
			print("unknown command 0x%X at 0x%X" % (cmd, pos - 2))
			if last_label < len(data.labels):
				pos = data.labels[last_label]
				continue
			break
		if type(scx.commands[cmd]) == dict:
			if content[pos] not in scx.commands[cmd]:
				print("unknown command 0x%X" % ((cmd << 8) | content[pos]))
				break
			optypes = scx.commands[cmd][content[pos]]
			cmd = (cmd << 8) | content[pos]
			print("cmd%06X" % cmd, end='')
			pos += 1
		else:
			print("cmd%04X" % cmd, end='')
			optypes = scx.commands[cmd]
		opnumber = 0
		for optype in optypes:
			if opnumber:
				print(",", end='')
			print(" ", end='')
			if optype == scx.OPTYPE_EXPR:
				pos = parse_expr(content, pos)
			elif optype == scx.OPTYPE_LABEL:
				label = struct.unpack_from('<H', content, pos)[0]
				print("label%d" % label, end='')
				pos += 2
				if cmd == 0x0008:
					switch_labels[label] = True
					if (pos % 2) and content[pos] == 0:
						pos += 1
				if cmd == 0x103704:
					mail_labels[opnumber] = label
			elif optype == scx.OPTYPE_BYTE:
				print("%d" % struct.unpack_from('<b', content, pos)[0], end='')
				pos += 1
			elif optype == scx.OPTYPE_WORD:
				print("%d" % struct.unpack_from('<h', content, pos)[0], end='')
				pos += 2
			elif optype == scx.OPTYPE_TEXTPTR:
				ptr = struct.unpack_from('<H', content, pos)[0]
				pos += 2
				print('"' + scx.text_to_string(data.parse_text(ptr)) + '"', end='')
			elif optype == scx.OPTYPE_2BOR2EXPR:
				if content[pos] == 99:
					pos += 1
					pos = parse_expr(content, pos)
					print(", ", end='')
					pos = parse_expr(content, pos)
				else:
					print("%d, %d" % (content[pos], content[pos + 1]), end='')
					pos += 2
			elif optype == scx.OPTYPE_CMD0023:
				print("%d" % struct.unpack_from('<b', content, pos)[0], end='')
				if content[pos] != 2:
					pos += 1
					print(", ", end='')
					pos = parse_expr(content, pos)
					print(", ", end='')
					pos = parse_expr(content, pos)
				else:
					pos += 1
			elif optype == scx.OPTYPE_CMD010C:
				flags = content[pos]
				pos += 1
				if flags & 0xFC:
					print("{unrecognized flags}", end='')
				if flags & 1:
					pos = parse_expr(content, pos) # defaults to -1
					print(", ", end='')
				pos = parse_expr(content, pos)
				if flags & 2:
					print(", ", end='')
					pos = parse_expr(content, pos)
			elif optype == scx.OPTYPE_CMD1004FIRST:
				cmd1004first = struct.unpack_from('<B', content, pos)[0]
				print("%d" % cmd1004first, end='')
				pos += 1
			elif optype == scx.OPTYPE_CMD1004SECOND:
				if cmd1004first >= 4:
					pos = parse_expr(content, pos)
			opnumber += 1
		print()
		if data.strings_table - pos <= 3 and content[pos:data.strings_table] == bytearray((0,) * (data.strings_table - pos)):
			break
