// Uebung4.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <conio.h>
#include <iostream.h>
#include <math.h>

void printValue(int iValue)
{
		cout << "Integer value: " << iValue << endl ;
}


void printValue(char* pszChar)
{
		cout << "String value: " << pszChar << endl ;
}


void printValue(double lfValue)
{
		cout << "double value: " << lfValue << endl ;
}


//function prototype, eg. in header file
void printString(char* pszString, int iNofChars = 8);



void printString(char* pszString, int iNofChars)
{
	cout << "String: ";

	while ( *pszString && iNofChars-- > 0)
	{
		cout << *(pszString++);
	}

	cout << endl;

}

//4-3: CMyPoint

//CMyPoint declaration
class CMyPoint
{
	private:
		int miX;
		int miY;

	public:
		CMyPoint();
		CMyPoint(int iX, int iY);
		~CMyPoint();
		int iGetDistance(const CMyPoint& rCMyPoint);
		void print(void);
}; //don't forget this ';' !!!


//CMyPoint implementation


CMyPoint::CMyPoint()
: miX(0),miY(0) //init coordinates to zero
{
	cout << "CMyPoint::CMyPoint(): default constructor called" << endl;
}



CMyPoint::CMyPoint(int iX, int iY)
: miY(iY), miX(iX)
{
	cout << "Konstruktor CMyPoint::CMyPoint(" << iX << " ," << iY <<") called" << endl;
}

CMyPoint::~CMyPoint()
{
	//no action required, just print something
	cout << "CMyPoint::~CMyPoint(): destructor called" << endl;
}

int CMyPoint::iGetDistance(const CMyPoint& rCMyPoint)
{
	cout << "CMyPoint::iGetDistance() called" << endl;
	int iDX = miX - rCMyPoint.miX;
	int iDY = miY - rCMyPoint.miY;
	return (iDX*iDX + iDY*iDY);	
}

void CMyPoint::print()
{
	cout << "(" << miX << " , " << miY << " )" << endl;
}


//4-4: Hausaufgabe

class CSignal
{
private:
		double *mplfBuffer;
		int miLength;
public:
		CSignal();
		CSignal(int iNofSamples);
		~CSignal();
		int	iGetLength() {return miLength;};
		int iSetSinus(int iFrequency, int iSamplingRate);
		void vPrint(int iLength = 5);
};

//implementation CSignal

CSignal::CSignal()
: mplfBuffer(NULL), miLength(0)
{
	//nothing to do here
	cout << "default constructor CSignal::CSignal() called" << endl;
}


CSignal::CSignal(int iNofSamples)
: mplfBuffer(NULL), miLength(0)
{
	cout << "constructor CSignal::CSignal(" << iNofSamples << ") called" << endl;
	mplfBuffer = new double[iNofSamples];
	if (mplfBuffer == NULL)
	{
		//mplfBuffer == NULL
		//and
		//miLength == 0;
		return;
	}
	miLength = iNofSamples;
}

CSignal::~CSignal()
{
	cout << "destructor CSignal::~CSignal() called. Signal buffer length:" << miLength << endl;
	//delete on NULL Pointer is allowed
	delete [] mplfBuffer;
	mplfBuffer = NULL;
}

int CSignal::iSetSinus(int iFrequency, int iSamplingRate)
{
	if (miLength == 0 || mplfBuffer == NULL)
	{
		cerr << "CSignal::iSetSinus called for signal with zero buffer size" << endl;
		return -1;
	}

	double lfIncrement = 2.0*3.141592654*(double)iFrequency / (double)iSamplingRate;
	double lfArgument = 0.0;
	for (int i = 0; i < miLength; i++)
	{
		mplfBuffer[i] = sin(lfArgument);
		lfArgument += lfIncrement;
	}

	return 0;
}

void CSignal::vPrint(int iLength)
{
	if (miLength == 0 || mplfBuffer == NULL)
	{
		cout << "signal with zero buffer size !" << endl;
		return;
	}
	
	//get maximum index to print
	int iMax = (miLength < iLength) ? miLength : iLength;
	for (int i = 0; i < iMax; i++)
	{
		cout << "CSignal[" << i <<"]: " << mplfBuffer[i] << endl;
	}
}

//end of implementation CSignal


int main(int argc, char* argv[])
{
	cout << "Aufgabe4" << endl;

	int i = 42;
	double lfPi = 3.14;

	char* pString = "Hello World";
	printValue(i);
	printValue(pString);
	printValue(lfPi);


	printString("Dies ist ein Test",6); 
	printString("Dies",6); 
	printString("Dies ist ein langer String"); 


	cout << "\n\nCMyPoint example:" << endl;
	cout << "---------------------------" << endl;

	{//block
		CMyPoint  cPointDefault;

		CMyPoint cPoint1(1,2);
		CMyPoint cPoint2(3,3);

		CMyPoint* pcPoint = NULL;

		pcPoint = new CMyPoint(3,6);
		delete pcPoint;


		cPoint1.print();

		cPoint2.print();

		cout << "distance: " << cPoint1.iGetDistance(cPoint2) << endl;


		cout << "Array erzeugen" << endl;
		CMyPoint Array[3];
	}


	cout << "\n\nAufgabe 4-4" << endl;
	cout << "---------------------------" << endl;

	{
		//definition of block to ensure the destructor will be called before getch() 
		CSignal cEmptySignal;
		CSignal cSinusSignal(8);
		
		cEmptySignal.iSetSinus(1000,8000);
		cEmptySignal.vPrint();

		cSinusSignal.iSetSinus(1200,8000);
		cSinusSignal.vPrint(9);

	}


	getch();
	return 0;
}


