#ifndef ENGINE_CORE_H
#define ENGINE_CORE_H 1

namespace Connf {
	const uint32_t	RESET = 0, // initial state
			FAILED = 1, // cannot connect to server
			DISCONNECTING = 2, // this socket is about to disconnect
			WSREQUESTED = 4, // WebSocket request sent
			WSACCEPTED = 8; // WebSocket accepted by server
};

static std::string base64_encode(const std::string &in) {
	std::string out;

	int val = 0, valb = -6;
	for(uint8_t c : in) {
		val = (val << 8) + c;
		valb += 8;
		while(valb >= 0) {
		out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs"
				"tuvwxyz0123456789+/"[(val>>valb)&0x3F]);
			valb -= 6;
		}
	}

	if(valb > -6) {
		out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs"
			"tuvwxyz0123456789+/"[((val<<8)>>(valb+8))&0x3F]);
		while(out.size() % 4) {
			out.push_back('=');
		}
	}
	return out;
}


static std::string base64_decode(const std::string &in) {
	std::string out;

	std::vector<int> T(256, -1);
	for(int i = 0; i < 64; i++) {
		T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs"
				"tuvwxyz0123456789+/"[i]] = i;
	}

	int val = 0, valb = -8;
	for(uint8_t c : in) {
		if(T[c] == -1) {
			break;
		}
		val = (val << 6) + T[c];
		valb += 6;
		if(valb >= 0) {
			out.push_back(char((val >> valb) & 0xFF));
			valb -= 8;
		}
	}
	return out;
}

#endif
