#include "ii2c.hpp"
#include <memory>
#include <iostream>
//
// implementation
//

/**
 * dummy implementation version
 */
class I2C::I2C_impl
{
	public:
		I2C_impl()
		{
			std::cout << "dummy I2C Ctor" << std::endl;
		}
		uint8_t readByte(const uint8_t& address,
			         const uint8_t& reg)
		{
			std::cout << "dummy I2C readByte()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\treturning 0" << std::endl;
			return 0;
		}


		void writeByte(const uint8_t& address,
			       const uint8_t& reg,
			       const uint8_t& byte)
		{
			std::cout << "dummy I2C writeByte()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\tbyte   : " << static_cast<int>(byte) << std::endl;
		}

	
		uint16_t readWord(const uint8_t& address,
			      const uint8_t& reg)
		{
			std::cout << "dummy I2C readWord()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\treturning 0" << std::endl;
			
			return 0;
		}

		void writeWord(const uint8_t& address,
			       const uint8_t& reg,
			       const uint16_t& word)
		{
			std::cout << "dummy I2C writeWord()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\tword   : " << static_cast<int>(word) << std::endl;		
		}

		void readBuffer(const uint8_t& address,
				const uint8_t& reg,
				uint8_t data[],
				uint8_t len)
		{
			uint8_t i = 0;

			std::cout << "dummy I2C readBuffer()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\tfilling array..." << std::endl;
			for(i = 0; i < len; i++) {
				data[i] = i;
			}
			std::cout << "\t...done!" << std::endl;
		}

		void writeBuffer(const uint8_t& address,
				const uint8_t& reg,
				const uint8_t data[],
				uint8_t len)
		{
			uint8_t i = 0;

			std::cout << "dummy I2C writeBuffer()" << std::endl;
			std::cout << "\taddress: " << static_cast<int>(address) << std::endl;
			std::cout << "\treg    : " << static_cast<int>(reg) << std::endl;
			std::cout << "\twriting array..." << std::endl;
			for(i = 0; i < len; i++) {
				std::cout << "\t" << static_cast<int>(data[i]) << std::endl;
			}
	
		}

};

//
// information relay
//

I2C::I2C() :
	impl{std::make_unique<I2C_impl>()}
{

}

I2C::~I2C()
{

}

uint8_t I2C::readByte(const uint8_t& address,
		      const uint8_t& reg)
{
	return impl->readByte(address,
		       	      reg);
}

void I2C::writeByte(const uint8_t& address,
	            const uint8_t& reg,
	            const uint8_t& word)
{
	impl->writeByte(address,
			reg,
			word);
}

	
uint16_t I2C::readWord(const uint8_t& address,
	      const uint8_t& reg)

{
	return impl->readWord(address,
			      reg);
}

void I2C::writeWord(const uint8_t& address,
	       const uint8_t& reg,
	       const uint16_t& word)
{
	impl->writeWord(address,
			reg,
			word);
}

void I2C::readBuffer(const uint8_t& address,
		const uint8_t& reg,
		uint8_t data[],
		uint8_t len)
{
	impl->readBuffer(address,
			reg,
			data,
			len);
}

void I2C::writeBuffer(const uint8_t& address,
 		 const uint8_t& reg,
		 const uint8_t data[],
 		 uint8_t len)
{
	impl->writeBuffer(address,
			reg,
			data,
			len);
}
