#include <afxmt.h>

class Bar
{
public:
	Bar() { m_Value=1; m_Direction=1; m_Threading=0; m_IsChanging=0;};
	// Functions for controlling appearance, and value
	int GetValue() 
	{ 
		int Ret;
		m_Critical.Lock();
		Ret = m_Value;
		m_Critical.Unlock();
		return( Ret ); 
	}
	int CanMove() 
	{ 
		m_Critical.Lock();
		int Ret = m_Direction; 
		m_Critical.Unlock();
		return( Ret != 0 ); 
	}
	void Freeze() 
	{ 
		m_Critical.Lock();
		m_Direction=0; 
		m_Critical.Unlock();
	}
	int GetHeight( int WindowHeight ) 
	{    
		m_Critical.Lock();
		int Ret = (int)((m_Value/100.0) * WindowHeight); 
		m_Critical.Unlock();
		return( Ret ); 
	}
	void Move() 
	{
		m_Critical.Lock();
		if( m_Value+m_Direction<1 ) 
			{ m_Value=1;m_Direction=1; } 
		else if( m_Value+m_Direction>100 ) 
			{ m_Value=100;m_Direction=-1; } 
		else
			m_Value += m_Direction;
		m_Critical.Unlock();
	}

	// Functions to assist in threading
	void SetThreading( int Mode ) 
	{ 
		m_Critical.Lock();
		m_Threading=Mode; 
		m_Critical.Unlock();
	};
	int GetThreading() 
	{ 
		m_Critical.Lock();
		int Ret = m_Threading; 
		m_Critical.Unlock();
		return( Ret );
	}
		
private:
	// Note use of volatile, to work around certain compiler optimzations
	volatile int m_Value, // Current value for bar
		m_Direction, //Direction of bar, 1 = up, -1 = down, 0 = not moving
		m_Threading, // Indicates that Bar is being acted upon by a thread
		m_IsChanging; // Indicates that the values inside the bar are changing (synchronization)
	CCriticalSection m_Critical;

};

