#include <iostream>
using namespace std;

#include <windows.h>
#include <conio.h>
#include <gl\gl.h>

#include "nVec.h"

long lPreIt = 10000;		// iterations before drawing
long lIt	= 8192;			// iterations while drawing
#define _STEP .1			// what should be the difference between 2 different u ? shouldnt be 1, because then we'd get a jagged line at steep slopes

float _START = 3.4;	// start value of u
float _END = 4;		// end value of u

/*#define _START 3.856
#define _END   3.858*/

#define VEC_STEP 1024

#define _SIZE 5000			// size of our little picture

int saveBMP(const char *szName,unsigned char *ucpData,int ixSize,int iySize){
	if(!ucpData){
		cerr << "sry, got no data" << endl;
		return 0;
	}

	int bmp_width;
	int bmp_height,x;

	bmp_width = ixSize;
	bmp_height = iySize;

	BITMAPFILEHEADER header;
	BITMAPINFOHEADER info;

	header.bfType = 'MB';
	header.bfOffBits = sizeof( header ) + sizeof( info );
	header.bfSize = sizeof( header ) + sizeof( info ) + ( bmp_width * bmp_height * 3 );
	header.bfReserved1 = 0;
	header.bfReserved2 = 0;

	info.biBitCount = 24;
	info.biClrImportant = 0;
	info.biClrUsed = 0;
	info.biCompression = 0;
	info.biHeight = bmp_height;
	info.biWidth = bmp_width;
	info.biPlanes = 1;
	info.biSize = sizeof( info );
	info.biSizeImage = bmp_width * bmp_height * 3;
	info.biXPelsPerMeter = 2952;
	info.biYPelsPerMeter = 2952;

	FILE *fhd;

	if( !(fhd = fopen(szName,"wb")) )
	{
		cerr << "failed to open file : " << szName << endl;
		return -1;
	}

	fwrite( &header, sizeof( header ) ,1,fhd);
	fwrite( &info, sizeof( info ) ,1,fhd );

	for(x=0; x < bmp_width * bmp_height * 3 ; x+=3){
		// rgb to bgr
		fwrite( &(ucpData[x+2]),1 ,1,fhd);
		fwrite( &(ucpData[x+1]),1 ,1,fhd);
		fwrite( &(ucpData[x+0]),1 ,1,fhd);
	}

	fclose(fhd);

	return 1;
}

void couthelp(void){
	cout << "usage:"<<endl;
	cout << "-e Ende ( default : 3.4 )"<<endl;
	cout << "-s Start ( default : 4 )"<<endl;
	cout << "-pi iterationen vor eigentlicher ausgabe ( default : 10000 )"<<endl;
	cout << "-i iterationen bei eigentlicher ausgabe ( default : 8192 )"<<endl;

	/*cout << endl<<"press any key to continue" << endl;
	getch();*/
}

int main(int iArgs, char **ppArgs){
	int i;
	if(iArgs == 1)
		couthelp();

	for(i=1; i < iArgs; i++){
		if(ppArgs[i][0] == '-'){		// it's a switch
			if(!strcmp(ppArgs[i],"-h")
				||!strcmp(ppArgs[i],"--help")){
					couthelp();
					return 0;
				}
				if(!strcmp(ppArgs[i],"-s")){
					if(i+1<iArgs){
						i++;
						float fTemp;
						sscanf(ppArgs[i],"%f",&fTemp);
						_START = fTemp;
						if(_START >= 4.f){
							cout << "start has to be lower than 4, resetting it to 3" << endl;
							_START = 3;
						}
						continue;
					}
				}
				if(!strcmp(ppArgs[i],"-e")){
					if(i+1<iArgs){
						i++;
						float fTemp;
						sscanf(ppArgs[i],"%f",&fTemp);
						_END = fTemp;
						if(_START > _END){
							cout << "end has to be higher than start, resetting it to 4" << endl;
							_END = 4;
						}
						continue;
					}
				}
				if(!strcmp(ppArgs[i],"-pi")){
					if(i+1<iArgs){
						i++;
						int iIt;
						sscanf(ppArgs[i],"%i",&iIt);
						lPreIt = iIt;
						continue;
					}
				}
				if(!strcmp(ppArgs[i],"-i")){
					if(i+1<iArgs){
						i++;
						int iIt;
						sscanf(ppArgs[i],"%i",&iIt);
						lIt = iIt;
						continue;
					}
				}
		}
	}

	cout << "allocating memory" << endl;
	unsigned char *bmp = new unsigned char[_SIZE*_SIZE*3+10];
	cout << "Clearing memory" << endl;
	memset(bmp, 0,sizeof(unsigned char) * (_SIZE*_SIZE*3));
	cout << "starting calc" << endl;

	nVec VValue(VEC_STEP),Vmu(VEC_STEP),VTemp(VEC_STEP);
	double dxschl;
	int ischl,iIndex,iRow,iColumn;
	long lschl;
	int ixSize,iySize;

	ixSize = iySize = _SIZE;
	VValue = 0;
	Vmu = 0;
	VTemp = 0;

	for(dxschl=0;dxschl < ixSize;dxschl+= _STEP*VEC_STEP){
		cout << dxschl << endl;
		VValue = .5;
		for(ischl = 0; ischl < VEC_STEP; ischl ++){
			Vmu[ischl] = (double)(dxschl + ischl * _STEP) / (double)(ixSize) * (_END-_START) + _START;
		}
		//dx = (double)(dxschl) / (double)(ixSize) * (_END-_START) + _START;
		for(lschl=0;lschl < lPreIt;lschl++){
			//dValue = dx * dValue * (1.0-dValue);
			VTemp = VValue;
			VTemp._sminusv(1);
			VTemp._smult(VValue,VTemp);
			VValue._smult(VTemp,Vmu);
		}
		for(lschl=0;lschl < lIt;lschl++){
			VTemp = VValue;
			VTemp._sminusv(1);
			VTemp._smult(VValue,VTemp);
			VValue._smult(VTemp,Vmu);

			for(ischl = 0; ischl < VEC_STEP; ischl ++){
				//SetPixel(hdc,dxschl+ischl * _STEP,iySize-1-(int)(VValue[ischl] * iySize),RGB(lschl*8,lschl,lschl/16));
				iRow = (dxschl + (double)ischl * _STEP);
				iColumn = (VValue[ischl] * (double)iySize);
				if(iRow < _SIZE && iColumn < _SIZE){
					iIndex = 3* int( iRow + ixSize * iColumn );
					bmp[iIndex + 0] = 255;
					bmp[iIndex + 1] = 255;
					bmp[iIndex + 2] = 255;
				}
			}
		}
	}

	saveBMP("test.bmp",bmp,_SIZE,_SIZE);
	delete [] bmp;
}
