#ifndef _DEVICE_HPP_
#define _DEVICE_HPP_

#include "../utils/BitField.hpp"

#include <iostream>
#include <stdint.h>

class Device
{
    public:
        Device();

        void doSomething();

        void status();

    private:

        //
        //  Register declarations
        //
#ifdef EXAMPLE_CODE_FOR_REFERENCE
        union Control {
            struct OPM{
                typedef Bits<uint16_t, 10, 2> bits;
                enum { NO_CHANGE = 0, AS_STANDBY = 1};
            };
            struct CTRL_BR{
                enum { NO_CHANGE = 0, BRANCH_NORMAL = 1};
            };
            struct CTRL_BR1 : CTRL_BR{
                typedef Bits<uint16_t, 8, 2> bits;
            };
            struct CTRL_BR2 : CTRL_BR{
                typedef Bits<uint16_t, 6, 2> bits;
            };

            union Bits {
                Control::OPM::bits OPM;
                Control::CTRL_BR1::bits CTRL_BR1;
                Control::CTRL_BR2::bits CTRL_BR2;
            } bits;
            uint16_t raw;
        };
#endif
        union Reg_Control
        {
            // bit 4
            struct POWER_DEV{
                typedef BitField<uint8_t, 7, 1> Bits;
                enum{TURN_OFF = 0, TURN_ON = 1};
            };
            // bits 2-3
            struct SPEED{
                typedef BitField<uint8_t, 2, 2> Bits;
                enum{STAND_STILL = 0,
                     SLOW = 1,
                     NORMAL = 2,
                     FAST = 3};
            };
            union Bits{
                Reg_Control::POWER_DEV::Bits POWER_DEV;
                Reg_Control::SPEED::Bits SPEED;
            } bits;
            // raw value. all bitfields will be "unified" here ;)
            uint8_t raw;
            // union Ctor with default value set to 0x00
            Reg_Control(uint8_t v = 0x00) : raw(v) {}
            // raw value extraction of register
            operator uint8_t() {return raw;}
            // used for updating software immage of hardware register
            void operator = (uint8_t v) {raw = v;}
        };

        union Reg_MotorStatus
        {
            struct POWER{
                typedef BitField<uint8_t,0,1> Bits;
                enum{OFF = 0, ON = 1};
            };
            struct STATUS{
                typedef BitField<uint8_t, 2,3>Bits;
                enum{STANDSTILL = 0,
                     ACCELERATING_CW = 1,
                     DEACCELERATING_CW = 2,
                     ACCELERATING_CCW = 3,
                     DEACCELERATING_CCW = 4,
                     CONSTANT_SPEED = 5,
                     BLOCKED = 6};
            };
            union Bits
            {
                // is set const because it only used for status indication
                const Reg_MotorStatus::POWER::Bits POWER;
                const Reg_MotorStatus::STATUS::Bits STATUS;
            }bits;
            uint8_t raw;

            Reg_MotorStatus(uint8_t v = 0x00) : raw(v) {}
            operator uint8_t() {return raw;}
            void operator = (uint8_t v) {raw = v;}   
        };

        Reg_Control reg_control;

        Reg_MotorStatus reg_motorStatus;



};

#endif // _DEVICE_HPP_
