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

  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 BCVALUE_H
#define BCVALUE_H

#include <QObject>
#include <QString>
#include <QList>
#include <QVariant>

#include <expected>
#include <bc.h>


/*
  Werte haben verschiedene Längen (1,2 und 4 Byte) und werder auf unterschiedliche Art und Weise
  ausgelesen und geschrieben (Siehe BCValueTypeWord). Sie können also Wert-Typen zugeordnet werden. Ein Werttyp
  lässet über eine ID identifizieren, die mit der phyikalische Einheit des Wertes überschneiden kann,
  aber nicht muss: : Km/h, kWh, BCValueTypeWord ... bilden eigene Typen, SoC, Assistence Level sind auch eigene Typen,
  Teilen sich jedoch die Einheit '%'.

  Das ist natürlich annalog zu den ItemTypes:
  - ein Value hat einen ValueType, der bestimmt folgendes:
    - long or short or quad
    - unit (mm, km/h, odo ... )
    -
*/

using OptDouble = std::optional<double>;

// Enthält den gelesenen Wert oder einen Fehlerstring
using TransmitResult = std::expected<uint32_t,QString>;
// Funktionsobject, um Werte aus der Transmitterschicht zu holden
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;

class BCValue
{

public:

  // Aus dem Type ergibt sich
  // später der Editor
  enum class ValueType : uint8_t
  {
    Plain,
    Bool,
    Number,
    Float
  };

  enum class State : uint8_t
  {
    NoState  = 0x00,
    ReadMe   = 0x01,
    WriteMe  = 0x02,
    ReadOnly = 0x04,
    Locked   = 0x08,
    Failed   = 0x10,
    InSync   = 0x20,
    OK       = 0x40
  };
  Q_DECLARE_FLAGS(States, State )

  BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );

  QString formatValue( uint32_t value ) const;
  void    dumpValue() const;

  mutable States  state{BCValue::State::ReadOnly};
  BCDevice::ID    deviceID{BCDevice::ID::Invalid};
  BC::ID          registerID{BC::ID::Invalid};
  ValueType       valueType{ValueType::Plain};
  int             indexRow{-1};
  QString         label;
  mutable QString visibleValue;
  bool            isWord{false};
  QString         unitLabel;
  double          factor{1};
  OptDouble       min;
  OptDouble       max;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(BCValue::States)



//Q_DECLARE_METATYPE(const BCValue&)

using BCValuePtr      = std::shared_ptr<BCValue>;
using BCValuePtrConst = std::shared_ptr<const BCValue>;

//using BCValueList = QList<BCValue>;
using BCValueList = QList<BCValuePtr>;

Q_DECLARE_METATYPE(const BCValuePtr)


Q_DECLARE_METATYPE(BCValueList)



#endif // BCVALUE_H
