#include "config.h"

#include "abc800_func.h"


namespace abc800 {

	void std_abc800::getmac_b(String mac, uint8_t *mac_b)
	{
		char firstchar;
		char secchar;
		uint8_t position = 0;

		for (int i = 0; i < 6; i++)
		{
			firstchar = mac.charAt(position);
			position++;
			secchar = mac.charAt(position);
			mac_b[i] = hex_to_ascii(firstchar, secchar);
			position++;
		}
	}

	int std_abc800::hex_to_int(char c) {
		int first = c / 16 - 3;
		int second = c % 16;
		int result = first * 10 + second;
		if (result > 9) result--;
		return result;
	}

	int std_abc800::hex_to_ascii(char c, char d) {
		int high = hex_to_int(c) * 16;
		int low = hex_to_int(d);
		return high + low;
	}
	void std_abc800::reverse8(uint8_t *buf, int size, uint8_t *rev)
	{
		for (int i = 0; i < size; i++) {
			rev[size - 1 - i] = buf[i];
		}
	}
	void std_abc800::hex2bin(uint8_t *out, const char *in, size_t *size)
	{
		size_t sz = 0;
		while (*in) {
			while (*in == ' ') in++;  // skip spaces
			while (*in == ',') in++;  // skip spaces
			while (*in == ' ') in++;  // skip spaces
			if (!*in) break;
			uint8_t c = *in>='a' ? *in-'a'+10 : *in>='A' ? *in-'A'+10 : *in-'0';
			in++;
			c <<= 4;
			if (!*in) break;
			c |= *in>='a' ? *in-'a'+10 : *in>='A' ? *in-'A'+10 : *in-'0';
			in++;
			*out++ = c;
			sz++;
		}
		//size = sz;
	}
	String std_abc800::hexaddr(uint8_t *buf) {

		String output = "";
		for (uint8_t i = 0; i < 8; i++)
		{
			output += "0x";
			if (buf[i] < 0x10) output += "0";
			output += String(buf[i], HEX);
			if (i < 7) output += (", ");
		}
		return output;
	}

	void std_abc800::serial_empty(HardwareSerial *port) {
		HardwareSerial * _port;
		_port = port;
		_port->read();
		_port->read();
		_port->read();
		_port->read();
		_port->flush();
	}

	String std_abc800::hex_to_string(uint8_t *buf, int size, String separator) {

		String output = "";
		for (int i = 0; i < size; i++) {
			if (buf[i] < 0x10)
				output += "0";
			output += String(buf[i], HEX);
			if (separator != "") {
				output += separator;
			}
		}
		return output;
	}
	void std_abc800::processutf8(uint8_t b,utf8decodedata *data)
	{
		if (data->state == 0x01) {
			// Expect a continuation byte
			if ((b & 0xc0) == 0x80) {
			// Continuation byte
			data->acc <<= 6;
			data->acc |= (uint16_t) (b & 0x3f);
			data->left--;
			if (data->left == 0) {
				// Last continuation byte in sequence
				data->data=data->acc;
				data->state = 0x00;
				return;
			}
			} else {
			// Invalid byte; retry from here in INIT state
			data->error = 0x01;
			data->state = 0x00;
			}
		}
		if (data->state == 0x00) {
			// Expect an initial byte
			if ((b & 0x80) == 0x00) {
			// Ascii byte
			data->data=((uint16_t) b);
			} else if ((b & 0xe0) == 0xc0) {
			// Start of two-byte sequence
			data->state = 0x01;
			data->acc = (uint16_t) (b & 0x1f);
			data->left = 1;
			} else if ((b & 0xf0) == 0xe0) {
			// Start of three-byte sequence
			data->state = 0x01;
			data->acc = (uint16_t) (b & 0x0f);
			data->left = 2;
			} else {
			// Too large sequence for this implementation or invalid byte
			data->error;
			}
		}
	}

	uint8_t std_abc800::processutf8String(const uint8_t* s,uint8_t len,uint8_t* d)
	{
		uint8_t p;
		utf8decodedata data;
		data.state=0x00;
		uint8_t i=0;
		for (p = 0; p < len; p++) {
			processutf8(s[p],&data);
			if (data.data !=0x00){
				d[i]=data.data;
				data.data = 0x00;
				i++;
			}
		}
		d[i]=0x00;
		return (i-1);
	}

}