// Een object georienteerde oplossing ... wel HERBRUIKBAAR wel AANPASBAAR wel UITBREIDBAAR

#include <iostream>
#include <iomanip>
using namespace std;

class ADCCard {
public:
	ADCCard();
	virtual ~ADCCard();
	virtual void selectChannel(int channel) =0;
	int getChannel() const;
	virtual void setAmplifier(double factor) =0;
	double read() const;
protected:
	void rememberChannel(int channel);
	void rememberAmplifier(double factor);
private:
	double f; // amplifying factor
	int c;    // selected channel
	virtual int sample() const =0;
};

class AD178: public ADCCard {
public:
	AD178();
	virtual void selectChannel(int channel);
	virtual void setAmplifier(double factor);
private:
	virtual int sample() const;
};

class NI323: public ADCCard {
public:
	NI323();
	virtual void selectChannel(int channel);
	virtual void setAmplifier(double factor);
private:
	virtual int sample() const;
};

ostream& operator<<(ostream& out, const ADCCard& card) {
	return out<<setprecision(5)<<card.read()<<" V.";
}

ADCCard::ADCCard(): f(1.0), c(1) {
	// voor alle kaarten benodigde code
	cout<<"initialisatie is gestart."<<endl;
}
ADCCard::~ADCCard() {
}
int ADCCard::getChannel() const {
	return c;
}
double ADCCard::read() const {
	return sample()*f/6553.5;
}
void ADCCard::rememberChannel(int channel) {
	c=channel;
}
void ADCCard::rememberAmplifier(double factor) {
	f=factor;
}

AD178::AD178() {
	// de specifieke voor de AD178 benodigde code
	cout<<"AD178 is geinitialiseeerd."<<endl;
}
void AD178::selectChannel(int channel) {
	rememberChannel(channel);
	// de specifieke voor de AD178 benodigde code
	cout<<"Kanaal "<<channel<<" van AD178 is geselecteerd."<<endl;
}
void AD178::setAmplifier(double factor) {
	rememberAmplifier(factor);
	// de specifieke voor de AD178 benodigde code
	cout<<"Versterkingsfactor van AD178 is "<<factor<<"."<<endl;
}
int AD178::sample() const {
	// de specifieke voor de AD178 benodigde code
	return 0x7FFF; // +5*f V
}

NI323::NI323() {
	// de specifieke voor de NI323 benodigde code
	cout<<"NI323 is geinitialiseeerd."<<endl;
}
void NI323::selectChannel(int channel) {
	rememberChannel(channel);
	// de specifieke voor de NI323 benodigde code
	cout<<"Kanaal "<<channel<<" van NI323 is geselecteerd."<<endl;
}
void NI323::setAmplifier(double factor) {
	rememberAmplifier(factor);
	// de specifieke voor de NI323 benodigde code
	cout<<"Versterkingsfactor van NI323 is "<<factor<<"."<<endl;
}
int NI323::sample() const {
	// de specifieke voor de NI323 benodigde code
	return 0x8000; // -5*f V
}

void doIt(ADCCard& c) {
	c.setAmplifier(10);
	c.selectChannel(3);
	cout<<"Kanaal "<<c.getChannel()<<" = "<<c<<endl;
}

int main() {
	AD178 card1;
	doIt(card1);
	NI323 card2;
	doIt(card2);

	cin.get();
	return 0;
}
