"""
HWP 파일 포맷 상수 정의

한글문서파일형식_5.0_revision1.3.txt 참고
"""

from enum import Enum, IntEnum


class RecordTag(IntEnum):
    """레코드 태그 ID (HWP 5.0 스펙 기준)

    각 태그는 HWP 파일의 특정 데이터 구조를 나타냅니다.
    태그 ID는 10비트로 표현되며, 문서의 구조를 정의하는 데 사용됩니다.
    """

    HWPTAG_BEGIN = 0x10

    # DocInfo 레코드 (0x10~0x1B)
    HWPTAG_DOCUMENT_PROPERTIES = 0x10  # 16: 문서 속성
    HWPTAG_ID_MAPPINGS = 0x11  # 17: 아이디 매핑 헤더
    HWPTAG_BIN_DATA = 0x12  # 18: 바이너리 데이터
    HWPTAG_FACE_NAME = 0x13  # 19: 글꼴
    HWPTAG_BORDER_FILL = 0x14  # 20: 테두리/배경
    HWPTAG_CHAR_SHAPE = 0x15  # 21: 글자 모양
    HWPTAG_TAB_DEF = 0x16  # 22: 탭 정의
    HWPTAG_NUMBERING = 0x17  # 23: 문단 번호
    HWPTAG_BULLET = 0x18  # 24: 글머리표
    HWPTAG_PARA_SHAPE = 0x19  # 25: 문단 모양
    HWPTAG_STYLE = 0x1A  # 26: 스타일
    HWPTAG_DOC_DATA = 0x1B  # 27: 문서 데이터

    # BodyText 레코드 (실제: 0x42~, 문서 스펙: 0x40~)
    # 주의: 문서 스펙과 실제 구현이 다름. 실제 HWP 파일은 아래 값 사용
    HWPTAG_PARA_HEADER = 0x42  # 66: 문단 헤더 (실제: 0x42, 스펙: 0x40)
    HWPTAG_PARA_TEXT = 0x43  # 67: 문단 텍스트 (실제: 0x43, 스펙: 0x41)
    HWPTAG_PARA_CHAR_SHAPE = 0x44  # 68: 문단의 글자 모양 (실제: 0x44, 스펙: 0x42)
    HWPTAG_PARA_LINE_SEG = 0x45  # 69: 문단의 레이아웃 (실제: 0x45, 스펙: 0x43)
    HWPTAG_PARA_RANGE_TAG = 0x46  # 70: 문단의 영역 태그 (실제: 0x46, 스펙: 0x44)
    HWPTAG_CTRL_HEADER = 0x47  # 71: 컨트롤 헤더 (실제: 0x47, 스펙: 0x4B)
    HWPTAG_LIST_HEADER = 0x48  # 72: 문단 리스트 헤더 (실제: 0x48, 스펙: 0x4C)
    HWPTAG_PAGE_DEF = 0x49  # 73: 페이지 정의
    HWPTAG_FOOTNOTE_SHAPE = 0x4A  # 74: 각주 모양
    HWPTAG_PAGE_BORDER_FILL = 0x4B  # 75: 페이지 테두리/배경
    HWPTAG_SHAPE_COMPONENT = 0x4C  # 76: 개체 공통 속성
    HWPTAG_TABLE = 0x4D  # 77: 표 개체

    # 개체별 상세 태그 (Tag ID 추정)
    HWPTAG_SHAPE_COMPONENT_PICTURE = 0x4E  # 78: 그림 개체 속성
    HWPTAG_SHAPE_COMPONENT_OLE = 0x50  # 80: OLE 개체 속성
    HWPTAG_EQEDIT = 0x51  # 81: 수식 개체
    HWPTAG_CTRL_DATA = 0x52  # 82: 컨트롤 임의의 데이터 (스펙: 0x4D, 중복 방지로 분리)


class HistoryRecordType(IntEnum):
    """문서 이력 관리 레코드 타입 (DocHistory Storage)"""

    STAG = 0x10  # 16: 히스토리 아이템 정보 시작
    ETAG = 0x11  # 17: 히스토리 아이템 정보 끝
    VERSION = 0x20  # 32: 히스토리 아이템 버전
    DATE = 0x21  # 33: 히스토리 날짜
    WRITER = 0x22  # 34: 히스토리 작성자
    DESCRIPTION = 0x23  # 35: 히스토리 설명
    DIFFDATA = 0x30  # 48: 비교 정보 (DiffML)
    LASTDOCDATA = 0x31  # 49: 가장 마지막 문서 (HWPML)


class ExtendedControlCode(IntEnum):
    """확장 제어 문자 코드 (16바이트 구조: 2바이트 코드 + 12바이트 데이터 + 2바이트 반복)"""

    TABLE = 1  # 테이블/표
    PICTURE = 2  # 그림
    OLE = 3  # OLE 객체
    EQUATION = 11  # 수식
    FOOTNOTE = 14  # 각주
    ENDNOTE = 15  # 미주
    HYPERLINK = 16  # 하이퍼링크
    FOOTNOTE_OR_ENDNOTE = 17  # 각주/미주 (HWP 3.x 호환)
    HEADER_OR_FOOTER = 18  # 머리말/꼬리말 (HWP 3.x 호환)
    COMMENT = 21  # 메모/주석
    SHAPE = 22  # 도형/그리기 개체
    SHAPE_COMPONENT = 23  # 도형 구성 요소


class CharControlCode(IntEnum):
    """제어 문자 코드 (2바이트만 사용)"""

    UNUSABLE = 0  # 사용 불가 문자
    LINE_BREAK = 10  # 줄바꿈 (\n)
    PARA_BREAK = 13  # 문단바꿈 (\r, CR)
    HYPHEN = 24  # 하이픈
    RESERVED_25 = 25  # 예약
    RESERVED_26 = 26  # 예약
    RESERVED_27 = 27  # 예약
    RESERVED_28 = 28  # 예약
    RESERVED_29 = 29  # 예약
    KEEP_WORD_SPACE = 30  # 묶음 빈칸
    FIXED_WIDTH_SPACE = 31  # 고정폭 빈칸


class InlineControlCode(IntEnum):
    """인라인 제어 문자 코드 (16바이트 구조, 별도 객체 불필요)"""

    FIELD_START = 4  # 필드 시작
    FIELD_END = 5  # 필드 끝
    BOOKMARK = 6  # 책갈피
    FIELD_UNKNOWN = 7  # 필드 관련
    FIELD_DATE = 8  # 날짜 필드
    TAB = 9  # 탭
    PAGE_HIDE = 12  # 쪽 번호 위치
    PAGE_NUMBER = 19  # 쪽 번호
    PAGE_COUNT = 20  # 총 쪽 수


class HeaderConstants(IntEnum):
    """FileHeader 스트림 관련 상수"""

    TOTAL_SIZE = 256  # 헤더 전체 크기
    SIGNATURE_SIZE = 32  # 서명 크기
    VERSION_OFFSET = 0x20  # 버전 정보 오프셋 (32)
    FLAGS_OFFSET = 0x24  # 플래그 정보 오프셋 (36)
    FLAGS_END = 0x28  # 플래그 읽기 종료 (40)


class RecordBitMask(IntEnum):
    """레코드 헤더 비트 마스크 상수"""

    TAG_ID_MASK = 0x3FF  # 10비트 마스크 (Tag ID)
    LEVEL_MASK = 0x3FF  # 10비트 마스크 (Level)
    SIZE_MASK = 0xFFF  # 12비트 마스크 (Size)
    SIZE_EXTENDED = 0xFFF  # 확장 크기 플래그
    LEVEL_SHIFT = 10  # Level 비트 시프트
    SIZE_SHIFT = 20  # Size 비트 시프트


class CharConstants(IntEnum):
    """문자 처리 관련 상수"""

    CONTROL_BOUNDARY = 31  # 제어 문자 경계 (> 31: 일반 문자)
    CONTROL_DATA_SIZE = 12  # 확장/인라인 제어 데이터 크기
    CODE_SIZE = 2  # 문자 코드 크기 (UTF-16)
    SURROGATE_START = 0xD800  # UTF-16 Surrogate 시작
    SURROGATE_END = 0xDFFF  # UTF-16 Surrogate 끝


class ParagraphConstants(IntEnum):
    """문단 관련 상수"""

    PAGE_BREAK_TYPE_OFFSET = 7  # page_break_type 오프셋
    MIN_HEADER_SIZE = 8  # 헤더 최소 크기
    CONTROL_ID_SIZE = 4  # control_id 크기


class PageBreakType(IntEnum):
    """페이지 구분 타입 (단 나누기 종류)"""

    NORMAL = 0  # 일반 문단
    COLUMN_BREAK = 1  # 단 나누기
    PAGE_BREAK = 2  # 쪽 나누기
    SECTION_BREAK = 3  # 구역 나누기


class ControlID(IntEnum):
    """확장 제어 Control ID (control_data 첫 4바이트, 리틀엔디언 UINT32)"""

    TABLE = 0x74626C20  # ' lbt' → 'tbl ' (리틀엔디언)
    AUTO_NUMBER = 0x61746E6F  # 'onta' → 'atno' (리틀엔디언) 자동 번호
    NEW_NUMBER = 0x6E776E6F  # 'onwn' → 'nwno' (리틀엔디언) 새 번호 지정
    PAGE_NUM_POS = 0x70676E70  # 'pngp' → 'pgnp' (리틀엔디언) 쪽 번호 위치
    HEADER = 0x64616568  # 'daeh' → 'head' (리틀엔디언) 머리말
    FOOTER = 0x746F6F66  # 'toof' → 'foot' (리틀엔디언) 꼬리말


# ---------------------------------------------------------------------------
# 공통 외부 인터페이스 Enum (helper_hwp.constants 에서 re-export)
#
# 내부 파싱 태그(RecordTag, ExtendedControlCode 등)와 분리하여
# 외부 API는 포맷에 관계없이 동일한 ElementType / IterMode 를 사용합니다.
#
# v50 내부 태그 → 외부 ElementType 매핑 예시:
#   RecordTag.HWPTAG_TABLE (0x4D)         -> ElementType.TABLE
#   ExtendedControlCode.PICTURE (2)       -> ElementType.PICTURE
#   PageBreakType.PAGE_BREAK (2)          -> ElementType.PAGE_BREAK
#   CharControlCode.LINE_BREAK (10) 등    -> (내부 처리, 외부 노출 안 함)
# ---------------------------------------------------------------------------
from helper_hwp.constants import ElementType, IterMode  # noqa: F401  (re-export)
