# 먼저 실행하시오(기반 함수들)

def str_chunk(data, size):
    return [data[i:i+size] for i in range(0, len(data), size)]

# 주어진 정수를 n비트 단위로 쪼갬
def bit_chunk(data: int, bit, size=0, significant='MSB') -> list:
    res = []
    while data > 0:
        res.append(data % (2 ** bit))
        data = data // (2 ** bit)
    
    while len(res) < size:
        res.append(0)
    
    if significant == 'MSB':
        res.reverse()
    return res

# 주어진 정수를 바이트 단위로 쪼개서 bytes로 만듬 (bit_chunk의 바이트 단위 문법 설탕)
def byte_chunk(data, size=2, significant='MSB') -> bytes:
    return bytes(bit_chunk(data, 8, size, significant))

# PDI 연산값(파라미터) 생성기. 단수형과 2,3차원 복수형을 지원
def param(a, chunk=3, upper=True) -> bytes:
    if type(a) == int:
        a = [a]
    
    baah = []
    if len(a) == 1:
        chunk_bits = 6
    else: chunk_bits = (8-2)//len(a)  # by default, 2-dimension is by 2 values in 3 chunks of *3 bits*(total of 8 + a signbit)
    for c in a:
        # sign bit
        signbit = False
        if c < 0:
            signbit = True
            c = 2**(chunk_bits*chunk-1)-1 + c + 1
        # if c > 127:
        #     signbit = not signbit
        #     c %= 128
        
        # bit chunk
        chunks = bit_chunk(c, chunk_bits, chunk, 'MSB')
        if signbit:
            chunks[0] += signbit << (chunk_bits - 1)
        
        baah.append(chunks)

    out = b''
    for ba in zip(*baah):
        base = 0x40 + (0x80 if upper else 0)
        for i, n in enumerate(ba):
            # 0b00xx-xyyy or 0x00xx-yyzz
            base += n << (len(a)-1-i)*chunk_bits
        out += byte_chunk(base, 1)
    
    return out

# 좌표값을 위한 PDI 연산값(파라미터) 생성기. 0-1의 실수로 입력
def xy(x, y, w=255, h=199):
    # KS X 3057, 48p : x[0-1] y[0-.7825]
    x = round(x * w)
    y = round(y * h)
    return param((x, y))