/***************************************************************************

  BionxControl
  © 2025 -2026 christoph holzheuer
  christoph.holzheuer@gmail.com

  Using:

  mhs_can_drv.c
  © 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
  Klaus Demlehner, klaus@mhs-elektronik.de
  @see www.mhs-elektronik.de

  Based on Bionx data type descriptions from:

  BigXionFlasher USB V 0.2.4 rev. 97
  © 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
  @see www.bigxionflasher.org

  Bionx Bike Info
  © 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
  @see www.ts-soft.de

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 3 of the License, or
  (at your option) any later version.
  @see https://github.com/bikemike/bionx-bikeinfo

 ***************************************************************************/


#ifndef BCDRIVER_H
#define BCDRIVER_H

#include <QObject>
#include <expected>
#include <bcvalue.h>

/*
int32_t   CanInitDriver(char *options);
void      CanDownDriver(void);
int32_t   CanSetOptions(char *options);
int32_t   CanDeviceOpen(uint32_t index, char *parameter);
int32_t   CanDeviceClose(uint32_t index);

int32_t   CanSetMode(uint32_t index, unsigned char can_op_mode, uint16_t can_command);

int32_t   CanTransmit(uint32_t index, struct TCanMsg *msg, int32_t count);
void      CanTransmitClear(uint32_t index);
uint32_t  CanTransmitGetCount(uint32_t index);
int32_t   CanTransmitSet(uint32_t index, uint16_t  cmd, uint32_t  time);
int32_t   CanReceive(uint32_t index, struct TCanMsg *msg, int32_t count);
void      CanReceiveClear(uint32_t index);
uint32_t  CanReceiveGetCount(uint32_t index);

int32_t   CanSetSpeed(uint32_t index, uint16_t speed);
int32_t   CanSetSpeedUser(uint32_t index, uint32_t value);
char*     CanDrvInfo(void);
char*     CanDrvHwInfo(uint32_t index);
int32_t   CanSetFilter(uint32_t index, struct TMsgFilter *msg_filter);
int32_t   CanGetDeviceStatus(uint32_t index, struct TDeviceStatus *status);
void      CanSetPnPEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, int32_t status));
void      CanSetStatusEventCallback(void (DRV_CALLBACK_TYPE *event)  (uint32_t  index, struct TDeviceStatus *device_status) );
void      CanSetRxEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index,  struct TCanMsg *msg, int32_t count) );

void      CanSetEvents( uint16_t  events );
uint32_t  CanEventStatus(void);
*/

struct CBCItem;
class  BCDriverStatus;

/**
 * @Abstrakte Basisklasse für alle CAN-Bus Treiber.
 * Das Bionx CAN-Bus System kann auf verschiedenen Wegen
 * angesprochen werden, etwa den über BBI USB2CAN Controller,
 * über den TinyCAN Adapter oder ggf. über einen ELM327 Stecker.
 *
 * Die hier relevante Implementierung über das TinyCan System
 * findet sich in der Unterklasse 'BCDriverTinyCan'.
 *
 * @see BCDriverTinyCan
 */


class BCDriver
{
  Q_GADGET

public:

  // Die möglichen Zustände beim Laden
  // des CAN-Bus Treibers.

  enum class DriverState : uint8_t
  {    
    NotPresent,
    Error,
    Loaded,
    Initialized,
    Opened,      // bis hierher: dll vorhanden, Treiber geladen
    DeviceReady  // hier: devices connectable, wir können arbeiten.
  };
  Q_ENUM(DriverState)

  // Enthält den Treiberzustand oder einen Fehlerstring
  using DriverStateResult = std::expected<DriverState,QString>;

  explicit BCDriver() = default;
  virtual ~BCDriver() = default;

  virtual BCDriver::DriverStateResult loadAndStartDriver() = 0;

  // Gibt den aktuelle Zustand des Treibers zurück. Der DriverState
  // muss auf DeviceReady stehen, um Werte lesen & schreiben zu können.
  // Dazu muss das Bionx-System eingeschaltet sein.

  DriverState getDriverState() const;

  // Abstrakte Methoden für das tatsächliche Lesen & Schreiben über den CAN-Bus. In der Implementierungs-
  // Klasse 'BCDriverTinyCan' werden die C-Funktionen der Treiber DLL gekapselt.

  virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
  virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;

protected:

  DriverState _driverState{DriverState::NotPresent};

};



/// -----------------------------------------------------------------------------------
/// -----------------------------------------------------------------------------------


class BCDriverDummy : public BCDriver
{

public:

  BCDriver::DriverStateResult loadAndStartDriver() override;

  TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
  TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;


};

#endif // BCDRIVER_H
