#ifndef TwoWire_h
#define TwoWire_h
#include "Arduino.h"
#include "RingBuffer.h"

// WIRE_HAS_END means Wire has end()
#define WIRE_HAS_END 1

class TwoWire
{
  public:

    TwoWire(uint8_t pinSDA, uint8_t pinSCL);

#ifdef ARDUINO_GENERIC
    void setPins(uint8_t pinSDA, uint8_t pinSCL);
#endif // ARDUINO_GENERIC
    void begin();

    void end();
    void setClock(uint32_t);

    void beginTransmission(uint8_t);
    uint8_t endTransmission(bool stopBit, uint32_t timeOut=100000);
    uint8_t endTransmission(void);

    uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit);
    uint8_t requestFrom(uint8_t address, size_t quantity);

    size_t write(uint8_t data);
    size_t write(const uint8_t * data, size_t quantity);

    virtual int available(void);
    virtual int read(void);
    virtual int peek(void);
    virtual void flush(void);

  private:

    uint8_t _uc_pinSDA;
    uint8_t _uc_pinSCL;

    bool master;
    bool receiving;
    bool transmissionBegun;
    bool suspended;

    // RX Buffer
    RingBuffer rxBuffer;

    // TX buffer
    RingBuffer txBuffer;
    uint8_t txAddress;

    // Callback user functions
    void (*onRequestCallback)(void);
    void (*onReceiveCallback)(int);

    // TWI clock frequency
    static const uint32_t TWI_CLOCK = 100000;
};

extern TwoWire Wire;

#endif
