// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

///|
pub(all) enum NativeEventTag {
  Connected
  Disconnected
  ButtonPressed
  ButtonReleased
  AxisChanged
  ButtonChanged
}

///|
pub struct NativeEvent {
  tag : NativeEventTag
  id : Int
  code : Code
  value : Double
  time_ms : Int64
}

///|
fn read_u32_le(b : Bytes, off : Int) -> Int {
  let b0 = b[off + 0].to_int()
  let b1 = b[off + 1].to_int()
  let b2 = b[off + 2].to_int()
  let b3 = b[off + 3].to_int()
  b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
}

///|
fn read_u64_le(b : Bytes, off : Int) -> UInt64 {
  let mut out : UInt64 = 0UL
  for i in 0..<8 {
    let v = b[off + i].to_uint64()
    out = out | (v << (i * 8))
  }
  out
}

///|
pub fn decode_native_event(b : Bytes) -> NativeEvent? {
  if b.length() == 0 {
    return None
  }
  if b.length() < 32 {
    return None
  }
  let tag_i = read_u32_le(b, 0)
  let id = read_u32_le(b, 4)
  let code = read_u32_le(b, 8)
  let value_bits = read_u64_le(b, 16)
  let time_bits = read_u64_le(b, 24)
  let value = UInt64::reinterpret_as_double(value_bits)
  let time_ms = UInt64::reinterpret_as_int64(time_bits)
  let tag = match tag_i {
    0 => NativeEventTag::Connected
    1 => Disconnected
    2 => ButtonPressed
    3 => ButtonReleased
    4 => AxisChanged
    5 => ButtonChanged
    _ => return None
  }
  Some({ tag, id, code, value, time_ms })
}