#include <msp430.h>
#include <stdint.h>
#include <stdbool.h>

namespace lib {

typedef volatile unsigned char * const reg8;
typedef const volatile unsigned char * const creg8;
typedef volatile unsigned int * const reg16;
typedef const volatile unsigned int * const creg16;

template <int mhz>
struct _ClockConfig { };

template <>
struct _ClockConfig<1> {
    static creg8 bcsctl1, dcoctl;
};

creg8 _ClockConfig<1>::bcsctl1 = &CALBC1_1MHZ;
creg8 _ClockConfig<1>::dcoctl = &CALDCO_1MHZ;

template <int mhz> void setup() {
    WDTCTL = WDTPW | WDTHOLD;

    BCSCTL1 = *_ClockConfig<mhz>::bcsctl1;
    DCOCTL = *_ClockConfig<mhz>::dcoctl;
}

struct Port1 {
    static reg8 dir, out;
    static creg8 in;
};

reg8 Port1::dir = &P1DIR;
creg8 Port1::in = &P1IN;
reg8 Port1::out = &P1OUT;

const uint8_t Pin0 = BIT0,
              Pin1 = BIT1,
              Pin2 = BIT2,
              Pin3 = BIT3,
              Pin4 = BIT4,
              Pin5 = BIT5,
              Pin6 = BIT6,
              Pin7 = BIT7;

template <typename port, int pin>
struct Output {
    Output() {
        *port::dir |= pin;
    }

    void on() {
        *port::out |= pin;
    }
    
    void off() {
        *port::out &= ~pin;
    }

    void toggle() {
        *port::out ^= pin;
    }
};

void sleep(uint16_t ms) {
    while (ms--)
        __delay_cycles(1000);
}

}
