#include <iostream>
#include <complex>
using namespace std;

#include <windows.h>
#include <gl\gl.h>

// thx to nehe.gamedev.net for the bmp save routine

// quadratic size of the picture
#define _SIZE 5000

complex<double> f(complex<double> z){
	return z*z*z*z - z*z - 11./36.;
}

complex<double> fs(complex<double> z){
	return complex<double>(4,0)*z*z*z - complex<double>(2,0)*z;
}

int saveBMP(const char *szName,unsigned char *ucpData,int ixSize,int iySize){
	if(!ucpData)
		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")) )
	{
		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;
}


main(){
	int i;
	complex <double> iter = complex<double>(1./sqrt(6)+.1,0);

	for(i=0; i < 100; i++){
		iter = iter - f(iter)/fs(iter);
		cout <<iter<<endl;
	}
	//return;

	cout << "allocating memory" << endl;
	unsigned char *bmp = new unsigned char[_SIZE*_SIZE*3];
	int ix,iy;
	long lschl;
	complex <double> last,lastlast;

	for(ix=0; ix < _SIZE; ix++){
		cout << ix << endl;
		memset(&(bmp[ix*_SIZE*3]),0,sizeof(unsigned char)*_SIZE*3);
		for(iy=0; iy < _SIZE; iy++){
			iter = complex<double>(double(ix)/_SIZE*2.-1.+1./sqrt(6),
				double(iy)/_SIZE*2.-1.);

			last = lastlast = 1000000.;

			for(lschl = 0; lschl < 1000; lschl ++){
				lastlast = last;
				last = iter;
				iter = iter - f(iter)/fs(iter);					

				if(abs(iter-last) < .00001){
					break;
				}
				if(abs(iter-lastlast)<.00001){		// um rechenzeit zu sparen ... springt iter immer zwischen 2 werten ?
					bmp[ix*_SIZE*3+iy*3] = lschl*16;
					bmp[ix*_SIZE*3+iy*3+1] = lschl*4;
					bmp[ix*_SIZE*3+iy*3+2] = 0;
					break;
				}
			}
			if(lschl == 1000){
				bmp[ix*_SIZE*3+iy*3] = 0;
				bmp[ix*_SIZE*3+iy*3+1] = 0;
				bmp[ix*_SIZE*3+iy*3+2] = 0;
			}
		}
	}
	saveBMP("test.bmp",bmp,_SIZE,_SIZE);
	delete [] bmp;
}
