#!/usr/bin/env python3

"""
Definitions of binary codes for the .dtg file format.

See the Tektronix Programmer's Manual for details.

.. This file is a part of MAHOS project, which is released under the 3-Clause BSD license.
.. See included LICENSE file or https://github.com/ToyotaCRDL/mahos/blob/main/LICENSE for details.

"""

import numpy as np


interior = 0x8000
leaf = 0x0000

RECIDS = {
    "DTG_ROOT_RECID": 0x0001 | interior,
    "DTG_MAGIC_RECID": 0x0002 | leaf,
    "DTG_TB_OPERATION_RECID": 0x0003 | leaf,
    "DTG_TB_RUNMODE_RECID": 0x0004 | leaf,
    "DTG_TB_BURSTCOUNT_RECID": 0x0005 | leaf,
    "DTG_TB_CLOCKSOURCE_RECID": 0x0006 | leaf,
    "DTG_TB_CLOCKSETTYPE_RECID": 0x005D | leaf,
    "DTG_TB_CLOCK_RECID": 0x0007 | leaf,
    "DTG_TB_JITTERINPUT_RECID": 0x0008 | leaf,
    "DTG_TB_LONGDELAY_RECID": 0x0009 | leaf,
    "DTG_TB_CLOCKRANGE_RECID": 0x000A | leaf,
    "DTG_TB_DELAYOFFSET_RECID": 0x000B | leaf,
    "DTG_TB_CLOCKOUTPUT_RECID": 0x000C | leaf,
    "DTG_TB_CLOCKOUTPUTAMPLITUDE_RECID": 0x000D | leaf,
    "DTG_TB_CLOCKOUTPUTOFFSET_RECID": 0x000E | leaf,
    "DTG_TB_CLOCKOUTPUTTERMZ_RECID": 0x0061 | leaf,
    "DTG_TB_CLOCKOUTPUTTERMV_RECID": 0x0062 | leaf,
    "DTG_TRIGGER_SOURCE_RECID": 0x000F | leaf,
    "DTG_TRIGGER_SLOPE_RECID": 0x0010 | leaf,
    "DTG_TRIGGER_LEVEL_RECID": 0x0011 | leaf,
    "DTG_TRIGGER_IMPEDANCE_RECID": 0x0012 | leaf,
    "DTG_TRIGGER_INTERVAL_RECID": 0x0013 | leaf,
    "DTG_EVENT_INPUTPOLARITY_RECID": 0x0014 | leaf,
    "DTG_EVENT_INPUTTHRESHOLD_RECID": 0x0015 | leaf,
    "DTG_EVENT_INPUTIMPEDANCE_RECID": 0x0016 | leaf,
    "DTG_SEQ_MODE_RECID": 0x0017 | leaf,
    "DTG_SEQ_JUMPMODE_RECID": 0x0018 | leaf,
    "DTG_SEQ_JUMPTIMING_RECID": 0x0019 | leaf,
    "DTG_JITTER_GENERATION_RECID": 0x001A | leaf,
    "DTG_JITTER_MODE_RECID": 0x001B | leaf,
    "DTG_JITTER_LOGICALCH_RECID": 0x001C | leaf,
    "DTG_JITTER_GATINGSOURCE_RECID": 0x001D | leaf,
    "DTG_JITTER_EDGE_RECID": 0x001E | leaf,
    "DTG_JITTER_FREQUENCY_RECID": 0x001F | leaf,
    "DTG_JITTER_AMPUNITSETTYPE_RECID": 0x005E | leaf,
    "DTG_JITTER_AMPMODESETTYPE_RECID": 0x005F | leaf,
    "DTG_JITTER_AMPLITUDE_RECID": 0x0020 | leaf,
    "DTG_DCOUTPUT_RECID": 0x0021 | leaf,
    "DTG_DCOUTPUTTABLE_RECID": 0x0022 | leaf,
    "DTG_ASSIGN_RECID": 0x0023 | leaf,
    "DTG_GROUP_RECID": 0x0024 | interior,
    "DTG_ID_RECID": 0x0025 | leaf,
    "DTG_NAME_RECID": 0x0026 | leaf,
    "DTG_NBITS_RECID": 0x0027 | leaf,
    "DTG_LOGICALCHANNEL_RECID": 0x0028 | leaf,
    "DTG_RADIX_RECID": 0x0029 | leaf,
    "DTG_SIGNED_RECID": 0x002A | leaf,
    "DTG_MAGNITUDE_RECID": 0x002B | leaf,
    "DTG_LOGICALCH_RECID": 0x002C | interior,
    "DTG_TERMZ_RECID": 0x002E | leaf,
    "DTG_TERMV_RECID": 0x002F | leaf,
    "DTG_LIMIT_RECID": 0x0030 | leaf,
    "DTG_LIMITHIGH_RECID": 0x0031 | leaf,
    "DTG_LIMITLOW_RECID": 0x0032 | leaf,
    "DTG_LEVELSETTYPE_RECID": 0x0060 | leaf,
    "DTG_LEVELHIGHORAMP_RECID": 0x0033 | leaf,
    "DTG_LEVELLOWOROFFSET_RECID": 0x0034 | leaf,
    "DTG_OUTPUT_RECID": 0x0037 | leaf,
    "DTG_POLARITY_RECID": 0x0038 | leaf,
    "DTG_JITTERRANGE_RECID": 0x0064 | leaf,
    "DTG_FORMAT_RECID": 0x0039 | leaf,
    "DTG_DELAYUNIT_RECID": 0x003A | leaf,
    "DTG_DELAYDATA_RECID": 0x003B | leaf,
    "DTG_WIDTHUNIT_RECID": 0x003C | leaf,
    "DTG_WIDTHDATA_RECID": 0x003D | leaf,
    "DTG_SLEWRATE_RECID": 0x003E | leaf,
    "DTG_CHMIX_RECID": 0x003F | leaf,
    "DTG_DTO_RECID": 0x0040 | leaf,
    "DTG_DTOOFFSET_RECID": 0x0041 | leaf,
    "DTG_PULSERATE_RECID": 0x0042 | leaf,
    "DTG_CROSS_POINT_RECID": 0x0063 | leaf,
    "DTG_BLOCK_RECID": 0x0043 | interior,
    "DTG_SIZE_RECID": 0x0046 | leaf,
    "DTG_SUBSEQUENCE_RECID": 0x0047 | interior,
    "DTG_SUBSEQUENCESTEP_RECID": 0x0049 | interior,
    "DTG_SUBNAME_RECID": 0x004A | leaf,
    "DTG_REPEATCOUNT_RECID": 0x004B | leaf,
    "DTG_MAINSEQUENCE_RECID": 0x004C | interior,
    "DTG_LABEL_RECID": 0x004D | leaf,
    "DTG_WAITTRIGGER_RECID": 0x004E | leaf,
    "DTG_JUMPTO_RECID": 0x0051 | leaf,
    "DTG_GOTO_RECID": 0x0052 | leaf,
    "DTG_PATTERN_RECID": 0x0053 | interior,
    "DTG_GROUPID_RECID": 0x0054 | leaf,
    "DTG_BLOCKID_RECID": 0x0055 | leaf,
    "DTG_PATTERNDATA_RECID": 0x0056 | leaf,
    "DTG_VIEW_RECID": 0x0057 | interior,
    "DTG_BLOCKLIST_RECID": 0x0058 | leaf,
    "DTG_GROUPLIST_RECID": 0x0059 | leaf,
    "DTG_BYCHANNELLIST_RECID": 0x005A | leaf,
    "DTG_BYGROUPLIST_RECID": 0x005B | leaf,
    "DTG_SUBSEQLIST_RECID": 0x005C | leaf,
}


def is_interior(id_) -> bool:
    return id_ & interior


# existing types:
# np.bytes_: char* in C for names.
# np.int8: char* in C for pattern data.
# np.int16: short in C for many of numbers.
# np.int32: long in C for a few large numbers.
# np.float64: double in C for voltage value etc.

LEAF_TYPES = {
    "DTG_MAGIC_RECID": np.int16,
    "DTG_TB_OPERATION_RECID": np.int16,
    "DTG_TB_RUNMODE_RECID": np.int16,
    "DTG_TB_BURSTCOUNT_RECID": np.int32,
    "DTG_TB_CLOCKSOURCE_RECID": np.int16,
    "DTG_TB_CLOCKSETTYPE_RECID": np.int16,
    "DTG_TB_CLOCK_RECID": np.float64,
    "DTG_TB_JITTERINPUT_RECID": np.int16,
    "DTG_TB_LONGDELAY_RECID": np.int16,
    "DTG_TB_CLOCKRANGE_RECID": np.int16,
    "DTG_TB_DELAYOFFSET_RECID": np.float64,
    "DTG_TB_CLOCKOUTPUT_RECID": np.int16,
    "DTG_TB_CLOCKOUTPUTAMPLITUDE_RECID": np.float64,
    "DTG_TB_CLOCKOUTPUTOFFSET_RECID": np.float64,
    "DTG_TB_CLOCKOUTPUTTERMZ_RECID": np.int32,
    "DTG_TB_CLOCKOUTPUTTERMV_RECID": np.float64,
    "DTG_TRIGGER_SOURCE_RECID": np.int16,
    "DTG_TRIGGER_SLOPE_RECID": np.int16,
    "DTG_TRIGGER_LEVEL_RECID": np.float64,
    "DTG_TRIGGER_IMPEDANCE_RECID": np.int16,
    "DTG_TRIGGER_INTERVAL_RECID": np.float64,
    "DTG_EVENT_INPUTPOLARITY_RECID": np.int16,
    "DTG_EVENT_INPUTTHRESHOLD_RECID": np.float64,
    "DTG_EVENT_INPUTIMPEDANCE_RECID": np.int16,
    "DTG_SEQ_MODE_RECID": np.int16,
    "DTG_SEQ_JUMPMODE_RECID": np.int16,
    "DTG_SEQ_JUMPTIMING_RECID": np.int16,
    "DTG_JITTER_GENERATION_RECID": np.int16,
    "DTG_JITTER_MODE_RECID": np.int16,
    # no data in manual! DTG_JITTER_PATTERN_RECID is in manual instead:
    "DTG_JITTER_LOGICALCH_RECID": np.int16,
    "DTG_JITTER_GATINGSOURCE_RECID": np.int16,
    "DTG_JITTER_EDGE_RECID": np.int16,
    "DTG_JITTER_FREQUENCY_RECID": np.float64,
    "DTG_JITTER_AMPUNITSETTYPE_RECID": np.int16,
    "DTG_JITTER_AMPMODESETTYPE_RECID": np.int16,
    "DTG_JITTER_AMPLITUDE_RECID": np.float64,
    "DTG_DCOUTPUT_RECID": np.int16,
    # 26 * 8 bit data. Should be more proper?:
    "DTG_DCOUTPUTTABLE_RECID": np.int16,
    # 2 * 5 * (number of grouped logical chs) bit data. Should be more proper?:
    "DTG_ASSIGN_RECID": np.int16,
    "DTG_ID_RECID": np.int16,
    "DTG_NAME_RECID": np.bytes_,
    "DTG_NBITS_RECID": np.int16,
    "DTG_LOGICALCHANNEL_RECID": np.int16,
    "DTG_RADIX_RECID": np.int16,
    "DTG_SIGNED_RECID": np.int16,
    "DTG_MAGNITUDE_RECID": np.int16,
    "DTG_TERMZ_RECID": np.int32,
    "DTG_TERMV_RECID": np.float64,
    "DTG_LIMIT_RECID": np.int16,
    "DTG_LIMITHIGH_RECID": np.float64,
    "DTG_LIMITLOW_RECID": np.float64,
    "DTG_LEVELSETTYPE_RECID": np.int16,
    "DTG_LEVELHIGHORAMP_RECID": np.float64,
    "DTG_LEVELLOWOROFFSET_RECID": np.float64,
    "DTG_OUTPUT_RECID": np.int16,
    "DTG_POLARITY_RECID": np.int16,
    "DTG_JITTERRANGE_RECID": np.int16,
    "DTG_FORMAT_RECID": np.int16,
    "DTG_DELAYUNIT_RECID": np.int16,
    "DTG_DELAYDATA_RECID": np.float64,
    "DTG_WIDTHUNIT_RECID": np.int16,
    "DTG_WIDTHDATA_RECID": np.float64,
    "DTG_SLEWRATE_RECID": np.float64,
    "DTG_CHMIX_RECID": np.int16,
    "DTG_DTO_RECID": np.int16,
    "DTG_DTOOFFSET_RECID": np.float64,
    "DTG_PULSERATE_RECID": np.int16,
    "DTG_CROSS_POINT_RECID": np.int16,
    "DTG_SIZE_RECID": np.int32,
    "DTG_SUBNAME_RECID": np.bytes_,
    "DTG_REPEATCOUNT_RECID": np.int32,
    "DTG_LABEL_RECID": np.bytes_,
    "DTG_WAITTRIGGER_RECID": np.int16,
    "DTG_JUMPTO_RECID": np.bytes_,
    "DTG_GOTO_RECID": np.bytes_,
    "DTG_GROUPID_RECID": np.int16,
    "DTG_BLOCKID_RECID": np.int16,
    "DTG_PATTERNDATA_RECID": np.int8,
    "DTG_BLOCKLIST_RECID": np.int16,  # no data in manual. but maybe OK.
    "DTG_GROUPLIST_RECID": np.int16,  # no data in manual. but maybe OK.
    "DTG_BYCHANNELLIST_RECID": np.int16,
    "DTG_BYGROUPLIST_RECID": np.int16,
    "DTG_SUBSEQLIST_RECID": np.int16,
}
