#ifndef HEADERS_H
#define HEADERS_H

// stringify
#define STRINGIFY_HELPER(x)			#x
#define STRINGIFY(x)				STRINGIFY_HELPER(x)

// concatenate
#define CONCAT_HELPER(x, y)			x ## y
#define CONCAT(x, y)				CONCAT_HELPER(x, y)

// get argument
#define ARG_1(v1, v2)				v1
#define ARG_2(v1, v2)				v2
#define GET_PORT(args)				ARG_1 args
#define GET_BIT(args)				ARG_2 args

// actions on registers
#define SET(register, bit)			register |= 1 << bit
#define CLEAR(register, bit)		register &= ~(1 << bit)
#define TEST(register, bit)			register & 1 << bit
#define TOGGLE(register, bit)		register ^= 1 << bit

// actions on elements
#define SET_ELEM(elem)				SET(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
#define CLEAR_ELEM(elem)			CLEAR(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
#define TEST_ELEM(elem)				TEST(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
#define TOGGLE_ELEM(elem)			TOGGLE(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem))
#define MODE_OUTPUT(elem)			SET(CONCAT(DDR, GET_PORT(elem)), GET_BIT(elem))
#define MODE_INPUT(elem)			CLEAR(CONCAT(DDR, GET_PORT(elem)), GET_BIT(elem))
#define TOGGLE_PIN(elem)			SET(CONCAT(PIN, GET_PORT(elem)), GET_BIT(elem))
#define TEST_PIN(elem)				(TEST(CONCAT(PIN, GET_PORT(elem)), GET_BIT(elem)))
#define IS_PIN_SET(elem)			(TEST_PIN(elem) == 0)
#define IS_PIN_CLEAR(elem)			(TEST_PIN(elem) == 1)

// bits
#define D1	0
#define D2	1
#define D3	2
#define D4	4
#define SW1	2
#define SW2	4

// elements (port, bit)
#define LED1	(B, D1)
#define LED2	(B, D2)
#define LED3	(B, D3)
#define LED4	(B, D4)
#define BUTTON1	(D, SW1)
#define BUTTON2	(D, SW2)

#define BUTTON(id)	

#endif