#include <boost/thread.hpp>
#include <iostream>
#include <iomanip>

class Temp {
private:
	double temp;
	bool switch_;
	boost::mutex& display;
	void read();
	void write();
	void control();
	Temp(const Temp& r);
public:
	Temp(boost::mutex& m);
	void operator()();
};

class Pres {
	double pres, dac;
	boost::mutex& display;
	void read();
	void write();
	void control();
	Pres(const Pres& r);
public:
	Pres(boost::mutex& m);
	void operator()();
};
	
Temp::Temp(boost::mutex& m): temp(0), switch_(false), display(m) {
}

void Temp::read() {
//	dummy: should read temperature from ADC
	static double val=0.0;
	val+=0.5;
	if (val>20.0)
		val=0.0;	
	temp=val;
}

void Temp::write() {
//	dummy: should write switch_ to switch
}

void Temp::control() {
//	dummy: should use better algorithm
	boost::this_thread::sleep(boost::posix_time::milliseconds(10));
	switch_= temp>10.0;
}

void Temp::operator()() {
	while (1) {
		read();
		{
			boost::lock_guard<boost::mutex> lock(display);
			std::cout<<"temperature = "<<std::fixed<<std::setw(4)<<std::setprecision(1)<<temp<<", ";
			control();
			std::cout<<"switch = "<<switch_<<std::endl;
		}
		write();
		boost::this_thread::sleep(boost::posix_time::seconds(3));
	}
}

Pres::Pres(boost::mutex& m): pres(0), dac(0), display(m) {
}

void Pres::read() {
//	dummy: should read pressure from ADC
	static double val=20.0;
	val-=0.4;
	if (val<0.0)
		val=20.0;	
	pres=val;
}

void Pres::write() {
//	dummy: should write dac to DAC
}

void Pres::control() {
//	dummy: should use better algorithm
	boost::this_thread::sleep(boost::posix_time::milliseconds(10));
	dac=10.0-pres;
}

void Pres::operator()() {
	while (1) {
		read();
		{
			boost::lock_guard<boost::mutex> lock(display);
			std::cout<<"presure = "<<std::fixed<<std::setw(4)<<std::setprecision(1)<<pres;
			control();
			std::cout<<", DAC = "<<std::fixed<<std::setw(5)<<std::setprecision(1)<<dac<<std::endl;
		}
		write();
		boost::this_thread::sleep(boost::posix_time::seconds(1));
	}
}

int main() {
	boost::mutex m;
	Temp t(m);
	Pres p(m);
	boost::thread t1(boost::ref(t)); 
	boost::thread t2(boost::ref(p)); 
	t1.join();
	t2.join();
	std::cin.get();
	return 0; 
}