#include "DataChannelSimulation.h"
#include <iostream>

#define REG_CONFIG_OFFSET 0
#define REG_EMPTY_OFFSET 1
#define REG_FULL_OFFSET 2
#define REG_LEVEL_OFFSET 3
#define REG_SINK_OFFSET 4
#define REG_SOURCE_OFFSET 5
#define REG_CLEAR_OFFSET 6

DataChannelSimulation::DataChannelSimulation()
    : config ( 0 )
{
}

DataChannelSimulation::~DataChannelSimulation() {
}

uint32_t DataChannelSimulation::read( uint32_t offset ) {
    switch ( offset ) {
    case REG_CONFIG_OFFSET: return config;
    case REG_EMPTY_OFFSET: return isEmpty();
    case REG_FULL_OFFSET: return isFull();
    case REG_LEVEL_OFFSET: return fifo.size();
    case REG_SOURCE_OFFSET: return read();
    }
    return static_cast< uint32_t >( -1 );
}

void DataChannelSimulation::write( uint32_t offset, uint32_t value ) {
    switch ( offset ) {
    case REG_CONFIG_OFFSET: config = value; break;
    case REG_SINK_OFFSET: write( value ); break;
    case REG_CLEAR_OFFSET: clear(); break;
    }
}

uint32_t DataChannelSimulation::read() {
    uint32_t value = static_cast< uint32_t >( -1 );
    if ( fifo.size() ) {
        value = fifo.front();
        fifo.pop_front();
    }
    return value;
}

void DataChannelSimulation::write( uint32_t value ) {
    if ( not isFull() ) {
        fifo.push_back( value );
    }
}

uint32_t DataChannelSimulation::isEmpty() const {
    return fifo.size() == 0;
}

uint32_t DataChannelSimulation::isFull() const {
    return fifo.size() == MAX_SIZE;
}

void DataChannelSimulation::clear() {
    fifo.clear();
}

