#ifndef FSFW_CONTAINER_FIFOBASE_TPP_
#define FSFW_CONTAINER_FIFOBASE_TPP_

#ifndef FSFW_CONTAINER_FIFOBASE_H_
#error Include FIFOBase.h before FIFOBase.tpp!
#endif

template<typename T>
inline FIFOBase<T>::FIFOBase(T* values, const size_t maxCapacity):
		maxCapacity(maxCapacity), values(values){};

template<typename T>
inline ReturnValue_t FIFOBase<T>::insert(T value) {
	if (full()) {
		return FULL;
	} else {
		values[writeIndex] = value;
		writeIndex = next(writeIndex);
		++currentSize;
		return HasReturnvaluesIF::RETURN_OK;
	}
};

template<typename T>
inline ReturnValue_t FIFOBase<T>::retrieve(T* value) {
	if (empty()) {
		return EMPTY;
	} else {
		if (value == nullptr){
			return HasReturnvaluesIF::RETURN_FAILED;
		}
		*value = values[readIndex];
		readIndex = next(readIndex);
		--currentSize;
		return HasReturnvaluesIF::RETURN_OK;
	}
};

template<typename T>
inline ReturnValue_t FIFOBase<T>::peek(T* value) {
	if(empty()) {
		return EMPTY;
	} else {
		if (value == nullptr){
			return HasReturnvaluesIF::RETURN_FAILED;
		}
		*value = values[readIndex];
		return HasReturnvaluesIF::RETURN_OK;
	}
};

template<typename T>
inline ReturnValue_t FIFOBase<T>::pop() {
	T value;
	return this->retrieve(&value);
};

template<typename T>
inline bool FIFOBase<T>::empty() {
	return (currentSize == 0);
};

template<typename T>
inline bool FIFOBase<T>::full() {
	return (currentSize == maxCapacity);
}

template<typename T>
inline size_t FIFOBase<T>::size() {
	return currentSize;
}

template<typename T>
inline size_t FIFOBase<T>::next(size_t current) {
	++current;
	if (current == maxCapacity) {
		current = 0;
	}
	return current;
}

template<typename T>
inline size_t FIFOBase<T>::getMaxCapacity() const {
	return maxCapacity;
}


template<typename T>
inline void FIFOBase<T>::setContainer(T *data) {
	this->values = data;
}

#endif