package com.laseroptek.raman.const

import androidx.compose.ui.graphics.Color
import com.laseroptek.raman.R
import com.laseroptek.raman.data.model.IconButtonItem
import com.laseroptek.raman.data.model.Preset
import com.laseroptek.raman.data.model.serial.SprayDcd
import com.laseroptek.raman.utils.ext.formatWithThousandComma

///////////////////////////////////////////////////////////
// GLOBAL CONST

const val SHOW_ENERGY_DETECT_CLOSE = true
const val SHOW_ENERGY_DETECT = true

const val DATABASE_VERSION = 1
const val ENGINEER_PIN_NUNBER = "064589"
const val txRepeatMillis = 1 * 1000L    // tx repeat (millis) : 1 sec  (for real) vs 60 sec (for dev)
const val preHeatingMillis =  5 * 60 * 1000L    // 5 * 60 * 1000L
const val SERIAL_PORT_NAME = "/dev/ttyS0"
const val SERIAL_BAUDRATE = 38400


///////////////////////////////////////////////////////////
// MIN MAX DEFAULT CONST

const val MIN_GUIDE_BEAM = 0
const val DEFAULT_GUIDE_BEAM = 1000
const val MAX_GUIDE_BEAM = 2000

const val MAX_LAMP_COUNT = 999999999
const val MAX_LASER_COUNT = 999999999
const val MAX_OP_TIME = 999999999

const val MAX_CHART_COLUMN_DATA_SIZE = 25

const val DEFAULT_LIFETIME_LAMP = 1000000
const val DEFAULT_LIFETIME_HP = 1000000
const val DEFAULT_LIFETIME_DETECTOR = 999999
const val DEFAULT_LIFETIME_WATER = 999999

const val MAX_LIFETIME_LAMP = 1000000
const val MAX_LIFETIME_HP = 1000000
const val MAX_LIFETIME_DETECTOR = 999999
const val MAX_LIFETIME_WATER = 999999

const val DEFAULT_REFER2_GOOD = 0.10f
const val DEFAULT_REFER2_ACCEPTABLE = 0.25f
const val DEFAULT_REFER2_BAD = 0.25f

const val MAX_REFER2_VALUE = 100   // 100% (= 1.0f)

const val MAX_TEMP_INT_DIGIT = 3        // 3 자리수 (xxx)
const val MAX_TEMP_DECIMAL_DIGIT = 1    // 1 자리수 (.x)
const val MAX_TEMP_VALUE = 100.0f       // 최대 값

const val DEFAULT_Q_SWITCH_VALUE = 000.0f
const val MIN_Q_SWITCH_VALUE = 000.0f
const val MAX_Q_SWITCH_VALUE = 250.0f

const val MAX_REFER1_VALUE = 99999999   // 8 byte ascii (ENERGY DETECT MEASURED VALUE)
const val DEFAULT_REFER1_VALUE = 0      // initial state

const val DEFAULT_DCD_GAS_PRESSURE = 06.5f
const val DEFAULT_SPAY_DCD_TIME = 10
const val DEFAULT_SPAY_DCD_DELAY = 10

const val MAX_LOG_COUNT = 259200  // 약 1개월 정도 (30일/5초 * 3600 * 12)

const val RX_TIMEOUT_THRESHOLD = 5000L  // 5 초

object CMD {
    const val VERSION = 0x01
    const val LASER_STATUS = 0x03
    const val PURGE_BUBBLE = 0x05
    const val DCD_GAS = 0x06
    const val SPRAY_DCD = 0x07
    const val HAND_PIECE = 0x08
    const val GUIDE_BEAM = 0x09
    const val HP_SHOT_COUNT = 0x0A
    const val ENERGE_METER = 0x0B
    const val TEMPERATURE = 0x0C
    const val OVEN = 0x0D
    const val Q_SWITCH = 0x0F
    const val ERROR = 0x10
    const val WARNING = 0x11
    const val ENERGY_DETECT = 0x14
    const val UPDATE_FIRMWARE = 0x20
    const val CMD_FLAG = 0x80
    const val WRITE_FLAG = 0x40
    const val STX = 0x21
    const val ETX = 0x0D
    const val TIMEOUT = 0x01F4  // 500
}

object LASER_STATUS {
    const val STAND_BY = 0x53   // (S)tandBy
    const val READY = 0x52      // (R)eady
    const val LASER_ON = 0x4C   // (L)aserOn
    const val INTERVAL = 0x49   // (I)nterval
}

object PURGE_STATUS {
    const val ACCEPT = 0x41       // Activate (or Accept)
    const val COMPLTE = 0x42       // Completed
    const val FAIL = 0x46         // Defuse
    const val INIT = 0x00
}

object DCD_STATUS {
    const val ON = 0x41     // A
    const val OFF = 0x44    // D
    const val PRESSURE = 0x50
}

object SPRAY_STATUS {
    const val ON = 0x41     // A
    const val OFF = 0x44    // D
    const val PRESSURE = 0x50
}

enum class READ_WRITE {
    READ, WRITE, NONE
}

enum class TX_RX {
    TX, RX, NONE
}

enum class AlertType {
    WARNING,
    ERROR
}


val ERROR_TABLE: List<Int> = listOf (
    R.string.err_none,                          // 00
    R.string.err_ps_comm,
    R.string.err_head_comm,
    R.string.err_simmer,
    R.string.err_charge,
    R.string.err_discharge,
    R.string.err_optical_system,
    R.string.err_water_level,
    R.string.err_water_flow,
    R.string.err_e_detect_system,
    R.string.err_ktp_temp,                      // 10
    R.string.err_chamber_temp,
    R.string.err_baseplate_temp,
    R.string.err_water_temp,
    R.string.err_dcd_temp,
    R.string.err_dcd_pressure,
    R.string.err_shutter1,
    R.string.err_shutter2,
    R.string.err_not_defined,
    R.string.err_interlock,
    R.string.err_other,                 // 20
)

val WARNING_TABLE: List<Int> = listOf (
    R.string.warn_none,                             // 00
    R.string.warn_water_level,
    R.string.warn_optical_energy,
    R.string.warn_dcd_gas_shortage,
    R.string.warn_dcd_bubble,
    R.string.warn_internal_temp_high,
    R.string.warn_internal_temp_low,
    R.string.warn_humidity_1,
    R.string.warn_humidity_2,
    R.string.warn_hp_tip,
    R.string.warn_lamp_count,           // 10
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,
    R.string.warn_not_defined,                      // 20
)

val handPieceTypes = listOf<String> (
    "NONE",
    "5x5",
    "7x7",
    "10x10",
    "12x12",
    "3x15",
    "NONE",
    "NONE",
)
val validHandPieceTypes = handPieceTypes.filter { it != "NONE" }

val lifeTimeTypes = listOf<String> (
    "Lamp",
    "HP 5x5",
    "HP 7x7",
    "HP 10x10",
    "HP 12x12",
    "HP 3x15",
    "Detector",
    "Water",
)

val temperatureTypes = listOf<String> (
    "KTP",
    "Chamber 1",
    "Chamber 2",
    "Baseplate",
    "Water",
    "Reserved",
    "Reserved",
    "Reserved",
)

// PulseDurations (= Pulse Width): xx.xf (ms), 12단계
val PulseDurations: List<Float> = listOf (
    0.5f,
    1.0f,
    1.5f,
    3.0f,
    5.0f,
    10.0f,
    15.0f,
    20.0f,
    25.0f,
    30.0f,
    35.0f,
    40.0f
)

// Fluences (= Energy): xxx (J/cm²),
// FluenceTable_0 (PulseWith: 0.5)
val Fluences: List<Float> = listOf (
    2.0f,
    2.1f,
    2.2f,
    2.3f,
    2.4f,
    2.5f,
    2.6f,
    2.7f,
    2.8f,
    2.9f,
    3.0f,
    3.2f,
    3.4f,
    3.6f,
    3.8f,
    4.0f,
    4.2f,
    4.4f,
    4.6f,
    4.8f,
    5.0f,
    5.5f,
    6.0f,
    6.5f,
    7.0f,
    7.5f,
    8.0f,
)

// Energy (J) - Fixed Energy List
val Energies: List<Float> = listOf (
    00.5f,
    01.0f,
    02.0f,
    03.0f,
    04.0f,
    05.0f,
    06.0f,
    07.0f,
    08.0f,
    09.0f,
    10.0f
)

// Repetitions (= Frequency): xx.xf (Hz)
val Repetitions: List<Float> = listOf (
    01.0f,
    02.0f,
    03.0f,
    04.0f,
    05.0f,
    06.0f,
    07.0f,
    08.0f,
    09.0f,
    10.0f
)

// Define integer keys for your lists
// You can choose any integers that make sense for your application
const val KEY_GREEN = 0
const val KEY_BLUE = 1
const val KEY_YELLOW = 2
const val KEY_RED = 3
const val KEY_GRAY = 4

// Combined map
// eg. get RepetitionList by Key.
// val repetitionList: List<Float>? = RepetitionsByColorKey[KEY_GRAY]
val RepetitionsByColorKey: Map<Int, List<Float>> = mapOf(
    KEY_GREEN to listOf (
        01.0f,
        02.0f,
        03.0f,
        04.0f,
        05.0f,
        06.0f,
        07.0f,
        08.0f,
        09.0f,
        10.0f
    ),
    KEY_BLUE to listOf (
        01.0f,
        02.0f,
        03.0f,
        04.0f,
        05.0f,
    ),
    KEY_YELLOW to listOf (
        01.0f,
        02.0f,
        03.0f,
    ),
    KEY_RED to listOf (
        01.0f,
        02.0f,
    ),
    KEY_GRAY to listOf (
        01.0f,
    )
)

enum class LaserParameter {
    PulseWidth,
    Fluence,
    Repetition,
}

enum class UpDownState {
    Up,
    Down
}

enum class GASCanValueState {
    On,
    Off
}

enum class PurgeState {
    On,
    Off,
    Disabled
}

enum class GasSettingState {
    On,
    Off
}

enum class MinMaxUpDownState {
    MinUp,
    MinDown,
    MaxUp,
    MaxDown,
    MinLongUp,
    MinLongDown,
    MaxLongUp,
    MaxLongDown,
}

enum class LaserStatusType {
    PULSE_DURATION,
    FLUENCE,
    REPETITION,
    SKIN_TEMP,
}

enum class PresetButtonType {
    SAVE,
    LOAD,
}

val engineerModeButtonLists: List<IconButtonItem> = listOf(
    IconButtonItem(
        title = R.string.update_title,
        image = R.drawable.ic_update,
        containerColor = Color(26,51,81),
        contentColor = Color(255,255,255)
    ),
    IconButtonItem(
        title = R.string.default_title,
        image = R.drawable.ic_default,
        containerColor = Color(36,67,105),
        contentColor = Color(255,255,255)
    ),
    IconButtonItem(
        title = R.string.save_title,
        image = R.drawable.ic_save,
        containerColor = Color(35,35,33),
        contentColor = Color(243,205,81)
    ),
    IconButtonItem(
        title = R.string.load_title,
        image = R.drawable.ic_load,
        containerColor = Color(46,103,59),
        contentColor = Color(255,255,255)
    ),
    IconButtonItem(
        title = R.string.import_title,
        image = R.drawable.ic_import,
        containerColor = Color(47,51,57),
        contentColor = Color(255,255,255)
    ),
    IconButtonItem(
        title = R.string.export_title,
        image = R.drawable.ic_export,
        containerColor = Color(47,51,57),
        contentColor = Color(255,255,255)
    ),
    IconButtonItem(
        title = R.string.log_title,
        image = R.drawable.ic_log,
        containerColor = Color(255,255,255),
        contentColor = Color(0,0,0)
    ),
)

// Product Serial Number
// eg. LO-3ND-BU-OCL-D
//     LO : 회사 약호
//     3ND : 제품 기호
//     BU : 제조년도 (끝2자리)
//     OCL: 생산수량
//     D : 제조월
// 제조연도 (십의자리) 또는 생산수량 (십의자리)
private val productYearOrQuantityTenthRange = 'A' .. 'J'
val productYearOrQuantityTenthRangeList = productYearOrQuantityTenthRange.toList().map{it.toString()}

// 제조연도 (일의자리)
private val productYearOrQuantityOnethRange = 'L' .. 'U'
val productYearOrQuantityOnethRangeList = productYearOrQuantityOnethRange.toList().map{it.toString()}

// 생산수량 (백의 자리)
private val productQuantityHundredthRange = '0' .. '9'
val productQuantityHundredthRangeList = productQuantityHundredthRange.toList().map{it.toString()}

// 제조월 (1월 ~ 12월)
val productMonthLists = listOf("L", "A", "S", "E", "R", "O", "P", "T", "2", "K", "N", "D")

val dcdCanTypeLists = listOf(350, 700) // listOf( 100, 300, 500, 700, 1000)
val dcdCanTypeFormatedLists = dcdCanTypeLists.map{ it.formatWithThousandComma() + " ml" }

val dcdLifeSpanAdjustLists = listOf( 0.5f, 0.7f, 0.9f, 1.0f, 1.1f, 1.2f )
val dcdLifeSpanAdjustStringLists = dcdLifeSpanAdjustLists.map{ it.toString() }

val dcdSprayValues = listOf(10, 20, 30, 40, 50, 60, 70, 80, 90, 100).map{ it.toString() }
val dcdDelayValues = listOf(10, 20, 30, 40, 50, 60, 70, 80, 90, 100).map{ it.toString() }

// default spray dcd list for options
val SprayDcdList = listOf<SprayDcd>(
    SprayDcd(status = 0x44, sprayTime = 10, sprayDelay = 10), // default
    SprayDcd(status = 0x44, sprayTime = 10, sprayDelay = 10),
    SprayDcd(status = 0x44, sprayTime = 20, sprayDelay = 20),
    SprayDcd(status = 0x44, sprayTime = 30, sprayDelay = 20),
    SprayDcd(status = 0x44, sprayTime = 40, sprayDelay = 40),
    SprayDcd(status = 0x44, sprayTime = 50, sprayDelay = 50),
    SprayDcd(status = 0x44, sprayTime = 60, sprayDelay = 60),
)

val PresetList = listOf<Preset>(
    /*
    Preset(id = 0, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 0, name = "00"),
    Preset(id = 1, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 1, name = "01"),
    Preset(id = 2, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 2, name = "02"),
    Preset(id = 3, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 3, name = "03"),
    Preset(id = 4, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 4, name = "04"),
    Preset(id = 5, handPieceType = 0, pulseWidth = 0.5f, fluence = 2.0f, repetition = 1.0f, priority = 5, name = "05"),
    ...
    */
)



