/*******************************************************************************
 *	BCondInt.h	BCondInt Class
 *			T.Barnaby,	BEAM Ltd,	10/12/02
 *	Copyright (c) 2012 All Right Reserved, Beam Ltd, http://www.beam.ltd.uk
 *******************************************************************************
 */
#ifndef BCONDINT_H
#define BCONDINT_H	1

#include <BTypes.h>
#include <pthread.h>

/// Thread conditional value
class BCondInt {
public:
			BCondInt();
			~BCondInt();
	
	void		setValue(BInt value);			///< Set the value. Wakes waiting
	BInt		value() const;				///< Current value

	BInt		increment(BInt v = 1);			///< Increment. Wakes waiting
	BInt		decrement(BInt v = 1);			///< Decrement. Wakes waiting

	Bool		waitMoreThanOrEqual(BInt v, Bool decrement = 0, BTimeout timeoutUs = BTimeoutForever);	///< Wait until value is at least the value given
	Bool		waitLessThanOrEqual(BInt v, Bool increment = 0, BTimeout timeoutUs = BTimeoutForever);	///< Wait until value is equal to or below the value given
	Bool		waitLessThan(BInt v, BTimeout timeoutUs = BTimeoutForever);					///< Wait until value is equal to or below the value given

	void		operator+=(int v);			///< Add to value. Wakes waiting
	void		operator-=(int v);			///< Subtract from value. Wakes waiting
	void		operator++(int);			///< Increment value. Wakes waiting
	void		operator--(int);			///< Decrement value. Wakes waiting

private:
	pthread_mutex_t	omutex;
	pthread_cond_t	ocond;
	BInt		ovalue;
};

inline void BCondInt::operator+=(BInt v){
	increment(v);
}

inline void BCondInt::operator-=(BInt v){
	decrement(v);
}

inline void BCondInt::operator++(int){
	increment(1);
}

inline void BCondInt::operator--(int){
	decrement(1);
}


/// Thread conditional value
class BCondValue {
public:
			BCondValue();
			~BCondValue();
	
	void		setValue(int value);			///< Set the value. Wakes waiting
	int		value();				///< Current value

	int		increment(int v = 1);			///< Increment. Wakes waiting
	int		decrement(int v = 1);			///< Decrement. Wakes waiting

	int		waitMoreThanOrEqual(int v, int decrement = 0, int timeOutUs = 0);	///< Wait until value is at least the value given
	int		waitLessThanOrEqual(int v, int increment = 0, int timeOutUs = 0);	///< Wait until value is equal to or below the value given
	int		waitLessThan(int v, int timeOutUs = 0);					///< Wait until value is equal to or below the value given

	void		operator+=(int v);			///< Add to value. Wakes waiting
	void		operator-=(int v);			///< Subtract from value. Wakes waiting
	void		operator++(int);			///< Increment value. Wakes waiting
	void		operator--(int);			///< Decrement value. Wakes waiting
private:
	pthread_mutex_t	omutex;
	pthread_cond_t	ocond;
	int		ovalue;
};

inline void BCondValue::operator+=(int v){
	increment(v);
}

inline void BCondValue::operator-=(int v){
	decrement(v);
}

inline void BCondValue::operator++(int){
	increment(1);
}

inline void BCondValue::operator--(int){
	decrement(1);
}

/// Thread conditional boolean
class BCondBool {
public:
			BCondBool();
			~BCondBool();
	
	int		set();					///< Set value. Wakes waiting
	int		clear();				///< Clear Value
	int		value();				///< Current value
	int		wait();					///< Wait until value is true
	int		timedWait(int timeOutUs);		///< Wait until set, with timeout
	
			operator int(){	return value();	}
private:
	pthread_mutex_t	omutex;
	pthread_cond_t	ocond;
	int		ovalue;
};


class BCondWrap {
public:
			BCondWrap();
			~BCondWrap();
	
	void		setValue(uint32_t value);			///< Set the value. Wakes waiting
	uint32_t	value();					///< Current value

	uint32_t	increment(uint32_t v = 1);			///< Increment. Wakes waiting
	uint32_t	decrement(uint32_t v = 1);			///< Decrement. Wakes waiting

	int		waitMoreThanOrEqual(uint32_t v, uint32_t decrement = 0, uint32_t timeOutUs = 0);	///< Wait until value is at least the value given
	int		waitLessThanOrEqual(uint32_t v, uint32_t increment = 0, uint32_t timeOutUs = 0);	///< Wait until value is equal to or below the value given
	int		waitLessThan(uint32_t v, uint32_t timeOutUs = 0);				///< Wait until value is equal to or below the value given

	void		operator+=(int v);			///< Add to value. Wakes waiting
	void		operator-=(int v);			///< Subtract from value. Wakes waiting
	void		operator++(int);			///< Increment value. Wakes waiting
	void		operator--(int);			///< Decrement value. Wakes waiting
private:
	int		diff(uint32_t v);
	
	pthread_mutex_t	omutex;
	pthread_cond_t	ocond;
	uint32_t	ovalue;
};

inline void BCondWrap::operator+=(int v){
	increment(v);
}

inline void BCondWrap::operator-=(int v){
	decrement(v);
}

inline void BCondWrap::operator++(int){
	increment(1);
}

inline void BCondWrap::operator--(int){
	decrement(1);
}

/// Resource lock
class BCondResource {
public:
			BCondResource();
			~BCondResource();
	
	int		lock(uint32_t timeOutUs = 0);		///< Lock the resource, will wait for all usage to be 0
	int		unlock();				///< Unlock the resource

	int		start(uint32_t timeOutUs = 0);		///< Start using the resource
	int		end();					///< Finish using the resource
	
	int		locked();
	int		inUse();
private:
	pthread_mutex_t	omutex;
	pthread_cond_t	ocond;
	int		olock;
	int		ouse;
};

#endif
