# -*- coding: utf-8 -*-
import re
import os
import sys

# ===================== 命令行参数解析 =====================
if len(sys.argv) < 2:
    print("=" * 70)
    print("              OLED 字模转 HEX 工具（含MAP地址表）")
    print("=" * 70)
    print(" 使用方法:")
    print("   python oled.py  字模文件.h                  (默认偏移地址 0x00)")
    print("   python oled.py  字模文件.h  偏移地址        (支持十进制 或 0x 开头十六进制)")
    print()
    print(" 示例:")
    print("   python oled.py  oledfont.h")
    print("   python oled.py  oledfont.h 0x1000")
    print("=" * 70)
    sys.exit(1)

# 自动获取脚本所在目录
script_dir = os.path.dirname(os.path.abspath(__file__))
data_file = os.path.join(script_dir, sys.argv[1])

# 偏移地址
if len(sys.argv) >= 3:
    offset_str = sys.argv[2]
    try:
        if offset_str.startswith("0x") or offset_str.startswith("0X"):
            current_offset = int(offset_str, 16)
        else:
            current_offset = int(offset_str)
    except:
        print("❌ 偏移地址格式错误！")
        sys.exit(1)
else:
    current_offset = 0

# ===================== 【自动编码识别：UTF-8 + GBK 双兼容】 =====================
try:
    # 先尝试 UTF-8
    with open(data_file, "r", encoding="utf-8") as f:
        code_str = f.read()
except:
    try:
        # 失败再尝试 GBK (ANSI)
        with open(data_file, "r", encoding="gbk") as f:
            code_str = f.read()
    except Exception as e:
        print(f"❌ 无法打开文件: {data_file}")
        print(f"🔍 错误信息: {str(e)}")
        sys.exit(1)

# ==================== 【核心：万能自动解析所有数组】 ====================
def extract_all_arrays(code):
    arrays = []
    pattern = re.compile(r'''
        (?:unsigned\s+char|const)\s+code\s+
        ([A-Za-z0-9_]+)
        \s*\[.*?\]\s*=\s*\{
        (.*?)
        \}\s*;
    ''', re.DOTALL | re.VERBOSE)

    for match in pattern.finditer(code):
        name = match.group(1)
        data_content = match.group(2)
        hex_list = re.findall(r'0x[0-9a-fA-F]{2}', data_content)
        bytes_data = [int(h, 16) for h in hex_list]
        arrays.append((name, bytes_data))
    return arrays

# ==================== 自动计算所有数组：偏移 + 长度 ====================
arrays = extract_all_arrays(code_str)
all_data = []
base_address = current_offset
map_list = []

print("=" * 70)
print("                字模数组自动解析结果")
print("=" * 70)
print(f"📌 全局起始偏移: 十进制 {current_offset}  |  十六进制 0x{current_offset:04X}")
print("-" * 70)

for name, data in arrays:
    size = len(data)
    end_addr = current_offset + size - 1
    print(f"📌 数组名: {name}")
    print(f"   长度: {size} 字节")
    print(f"   起始地址: 十进制 {current_offset}  |  十六进制 0x{current_offset:04X}")
    print(f"   结束地址: 十进制 {end_addr}  |  十六进制 0x{end_addr:04X}")
    print("-" * 70)
    
    map_list.append({
        "name": name,
        "size": size,
        "start": current_offset,
        "end": end_addr
    })
    
    all_data.extend(data)
    current_offset += size

# ==================== 输出文件名 ====================
out_name = os.path.splitext(os.path.basename(data_file))[0]
hex_file = os.path.join(script_dir, f"{out_name}.hex")
map_file = os.path.join(script_dir, f"{out_name}.map")

# ==================== 生成 HEX ====================
def generate_hex(data, filename, base_addr=0):
    with open(filename, "w", encoding="utf-8") as f:
        addr = base_addr
        for i in range(0, len(data), 16):
            chunk = data[i:i+16]
            length = len(chunk)
            checksum = length + (addr >> 8) + (addr & 0xFF)
            line = f":{length:02X}{addr:04X}00"
            for b in chunk:
                line += f"{b:02X}"
                checksum += b
            checksum = (-checksum) & 0xFF
            f.write(f"{line}{checksum:02X}\n")
            addr += length
        f.write(":00000001FF\n")

generate_hex(all_data, hex_file, base_addr=base_address)

# ==================== 生成 MAP ====================
with open(map_file, "w", encoding="utf-8") as f:
    f.write("="*60 + "\n")
    f.write("           字模数组地址映射表 (.map)\n")
    f.write("="*60 + "\n")
    f.write(f"全局起始偏移: 0x{base_address:04X}\n")
    f.write("="*60 + "\n\n")
    
    for item in map_list:
        f.write(f"数组名: {item['name']}\n")
        f.write(f"  长度:      {item['size']} 字节\n")
        f.write(f"  起始地址:  0x{item['start']:04X}  (十进制 {item['start']})\n")
        f.write(f"  结束地址:  0x{item['end']:04X}  (十进制 {item['end']})\n")
        f.write("-"*50 + "\n")

print(f"\n✅ 总字节数: {len(all_data)} 字节")
print(f"✅ 已生成: {hex_file}")
print(f"✅ 已生成: {map_file}")