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

#include "symbols_peripherals.h"

struct mt_BCPeripheral parsestruct_mt_BCPeripheral (
	uint8_t (*get)(void),
	void (*err)(const char *errmsg, ...))
{
	struct mt_BCPeripheral r;
	r.cons = get();
	switch (r.cons) {
	case mt_BCPeripheral_BCDHT:
		r.data.mt_BCDHT.cons = get();
		switch (r.data.mt_BCDHT.cons) {
		case mt_DHTInfo_DHT_DHT:
			r.data.mt_BCDHT.data.mt_DHT_DHT.f0.cons = get();
			switch (r.data.mt_BCDHT.data.mt_DHT_DHT.f0.cons) {
			case mt_Pin_AnalogPin:
				r.data.mt_BCDHT.data.mt_DHT_DHT.f0.data.mt_AnalogPin = get();
				break;
			case mt_Pin_DigitalPin:
				r.data.mt_BCDHT.data.mt_DHT_DHT.f0.data.mt_DigitalPin = get();
				break;
			default:
				err("Unknown constructor: ", r.data.mt_BCDHT.data.mt_DHT_DHT.f0.cons);
			}
			r.data.mt_BCDHT.data.mt_DHT_DHT.f1 = get();
			break;
		case mt_DHTInfo_DHT_SHT:
			r.data.mt_BCDHT.data.mt_DHT_SHT = get();
			break;
		default:
			err("Unknown constructor: ", r.data.mt_BCDHT.cons);
		}
		break;
	case mt_BCPeripheral_BCLEDMatrix:
		r.data.mt_BCLEDMatrix.dataPin.cons = get();
		switch (r.data.mt_BCLEDMatrix.dataPin.cons) {
		case mt_Pin_AnalogPin:
			r.data.mt_BCLEDMatrix.dataPin.data.mt_AnalogPin = get();
			break;
		case mt_Pin_DigitalPin:
			r.data.mt_BCLEDMatrix.dataPin.data.mt_DigitalPin = get();
			break;
		default:
			err("Unknown constructor: ", r.data.mt_BCLEDMatrix.dataPin.cons);
		}
		r.data.mt_BCLEDMatrix.clockPin.cons = get();
		switch (r.data.mt_BCLEDMatrix.clockPin.cons) {
		case mt_Pin_AnalogPin:
			r.data.mt_BCLEDMatrix.clockPin.data.mt_AnalogPin = get();
			break;
		case mt_Pin_DigitalPin:
			r.data.mt_BCLEDMatrix.clockPin.data.mt_DigitalPin = get();
			break;
		default:
			err("Unknown constructor: ", r.data.mt_BCLEDMatrix.clockPin.cons);
		}
		break;
	case mt_BCPeripheral_BCI2CButton:
		r.data.mt_BCI2CButton = get();
		break;
	case mt_BCPeripheral_BCLightSensor:
		r.data.mt_BCLightSensor = get();
		break;
	case mt_BCPeripheral_BCAirQualitySensor:
		r.data.mt_BCAirQualitySensor = get();
		break;
	default:
		err("Unknown constructor: ", r.cons);
	}
	return r;
}

void printstruct_mt_BCPeripheral (
	struct mt_BCPeripheral r, void (*putc)(uint8_t))
{
	putc(r.cons);
	switch (r.cons) {
	case mt_BCPeripheral_BCDHT:
		putc(r.data.mt_BCDHT.cons);
		switch (r.data.mt_BCDHT.cons) {
		case mt_DHTInfo_DHT_DHT:
			putc(r.data.mt_BCDHT.data.mt_DHT_DHT.f0.cons);
			switch (r.data.mt_BCDHT.data.mt_DHT_DHT.f0.cons) {
			case mt_Pin_AnalogPin:
				putc(r.data.mt_BCDHT.data.mt_DHT_DHT.f0.data.mt_AnalogPin);
				break;
			case mt_Pin_DigitalPin:
				putc(r.data.mt_BCDHT.data.mt_DHT_DHT.f0.data.mt_DigitalPin);
				break;
			}
			putc(r.data.mt_BCDHT.data.mt_DHT_DHT.f1);
			break;
		case mt_DHTInfo_DHT_SHT:
			putc(r.data.mt_BCDHT.data.mt_DHT_SHT & 0xff);
			break;
		}
		break;
	case mt_BCPeripheral_BCLEDMatrix:
		putc(r.data.mt_BCLEDMatrix.dataPin.cons);
		switch (r.data.mt_BCLEDMatrix.dataPin.cons) {
		case mt_Pin_AnalogPin:
			putc(r.data.mt_BCLEDMatrix.dataPin.data.mt_AnalogPin);
			break;
		case mt_Pin_DigitalPin:
			putc(r.data.mt_BCLEDMatrix.dataPin.data.mt_DigitalPin);
			break;
		}
		putc(r.data.mt_BCLEDMatrix.clockPin.cons);
		switch (r.data.mt_BCLEDMatrix.clockPin.cons) {
		case mt_Pin_AnalogPin:
			putc(r.data.mt_BCLEDMatrix.clockPin.data.mt_AnalogPin);
			break;
		case mt_Pin_DigitalPin:
			putc(r.data.mt_BCLEDMatrix.clockPin.data.mt_DigitalPin);
			break;
		}
		break;
	case mt_BCPeripheral_BCI2CButton:
		putc(r.data.mt_BCI2CButton & 0xff);
		break;
	case mt_BCPeripheral_BCLightSensor:
		putc(r.data.mt_BCLightSensor & 0xff);
		break;
	case mt_BCPeripheral_BCAirQualitySensor:
		putc(r.data.mt_BCAirQualitySensor & 0xff);
		break;
	}
}