#include <classConfiguration.h>

char * __ClassNames[TOTAL_CLASS_COUNT] 			= { "opengl", "unsignedIntegerArray", "vector2", "vector3", "text", "array", "char", "floatArray", "shader", "uniform", "attribute", "fileSystem", "consoleManager", "http", "headerManager", "header", "request", "mimeTypes", "mesh", "address", "toolset", "b", "a", "inherit", "classA", "classB", "int", "sqlite", "triangle", "user" };

int __ClassPropertyCount[TOTAL_CLASS_COUNT] 	= { 13, 3, 2, 3, 4, 3, 0, 3, 2, 3, 3, 0, 0, 9, 1, 2, 9, 2, 9, 2, 0, 1, 2, 3, 1, 1, 0, 4, 3, 5 };

char * __ClassPropertyNames[TOTAL_CLASS_COUNT][30] 	= {
														{ "mainDisplay" ,  "mainWindow" ,  "MainScreen" ,  "RootWindow" ,  "lastTime" ,  "deltaTime" ,  "startTime" ,  "frameCount" ,  "vertexbuffer" ,  "indexBuffer" ,  "currentShader" ,  "quads" ,  "image[HEIGHT][WIDTH]" }, 
														{ "capacity" ,  "total" ,  "items" }, 
														{ "x" ,  "y" }, 
														{ "x" ,  "y" ,  "z" }, 
														{ "value" ,  "usevalue" ,  "length" ,  "capacity" }, 
														{ "capacity" ,  "total" ,  "items" }, 
														{ }, 
														{ "capacity" ,  "total" ,  "items" }, 
														{ "uniforms" ,  "attributes" }, 
														{ "name[64]" ,  "location" ,  "type" }, 
														{ "name[64]" ,  "location" ,  "type" }, 
														{ }, 
														{ }, 
														{ "socket" ,  "hostAddress" ,  "hostAddresslength" ,  "filesystem" ,  "mimetypes" ,  "headers" ,  "useSSL" ,  "sslContext" ,  "requestCallback" }, 
														{ "headers" }, 
														{ "name" ,  "value" }, 
														{ "connection" ,  "address" ,  "port" ,  "url" ,  "method" ,  "version" ,  "mimeType" ,  "extension" ,  "headers" }, 
														{ "extensions" ,  "mimeTypes" }, 
														{ "indices" ,  "textureCoordinates" ,  "vertexCoordinates" ,  "normalCoordinates" ,  "indexBuffer" ,  "vertexbuffer" ,  "textureCoordinateBuffer" ,  "meshIndexBuffer" ,  "uvBuffer" }, 
														{ "street" ,  "number" }, 
														{ }, 
														{ "propertyFromB" }, 
														{ "propertyFromA" ,  "propertyFromB" }, 
														{ "propertyFromC" ,  "propertyFromA" ,  "propertyFromB" }, 
														{ "propertyFromC" }, 
														{ "propertyFromC" }, 
														{ }, 
														{ "db" ,  "res" ,  "value" ,  "selectedModel" }, 
														{ "a" ,  "b" ,  "c" }, 
														{ "username" ,  "id" ,  "userlevel" ,  "hash" ,  "addresses" }
													};

int __ClassPropertyOffsets[TOTAL_CLASS_COUNT][30] 	= {
														{ offsetof(  opengl, mainDisplay ) ,  offsetof(  opengl, mainWindow ) ,  offsetof(  opengl, MainScreen ) ,  offsetof(  opengl, RootWindow ) ,  offsetof(  opengl, lastTime ) ,  offsetof(  opengl, deltaTime ) ,  offsetof(  opengl, startTime ) ,  offsetof(  opengl, frameCount ) ,  offsetof(  opengl, vertexbuffer ) ,  offsetof(  opengl, indexBuffer ) ,  offsetof(  opengl, currentShader ) ,  offsetof(  opengl, quads ) ,  offsetof(  opengl, image[HEIGHT][WIDTH] ) }, 
														{ offsetof(  unsignedIntegerArray, capacity ) ,  offsetof(  unsignedIntegerArray, total ) ,  offsetof(  unsignedIntegerArray, items ) }, 
														{ offsetof(  vector2, x ) ,  offsetof(  vector2, y ) }, 
														{ offsetof(  vector3, x ) ,  offsetof(  vector3, y ) ,  offsetof(  vector3, z ) }, 
														{ offsetof(  text, value ) ,  offsetof(  text, usevalue ) ,  offsetof(  text, length ) ,  offsetof(  text, capacity ) }, 
														{ offsetof(  array, capacity ) ,  offsetof(  array, total ) ,  offsetof(  array, items ) }, 
														{ }, 
														{ offsetof(  floatArray, capacity ) ,  offsetof(  floatArray, total ) ,  offsetof(  floatArray, items ) }, 
														{ offsetof(  shader, uniforms ) ,  offsetof(  shader, attributes ) }, 
														{ offsetof(  uniform, name[64] ) ,  offsetof(  uniform, location ) ,  offsetof(  uniform, type ) }, 
														{ offsetof(  attribute, name[64] ) ,  offsetof(  attribute, location ) ,  offsetof(  attribute, type ) }, 
														{ }, 
														{ }, 
														{ offsetof(  http, socket ) ,  offsetof(  http, hostAddress ) ,  offsetof(  http, hostAddresslength ) ,  offsetof(  http, filesystem ) ,  offsetof(  http, mimetypes ) ,  offsetof(  http, headers ) ,  offsetof(  http, useSSL ) ,  offsetof(  http, sslContext ) }, 
														{ offsetof(  headerManager, headers ) }, 
														{ offsetof(  header, name ) ,  offsetof(  header, value ) }, 
														{ offsetof(  request, connection ) ,  offsetof(  request, address ) ,  offsetof(  request, port ) ,  offsetof(  request, url ) ,  offsetof(  request, method ) ,  offsetof(  request, version ) ,  offsetof(  request, mimeType ) ,  offsetof(  request, extension ) ,  offsetof(  request, headers ) }, 
														{ offsetof(  mimeTypes, extensions ) ,  offsetof(  mimeTypes, mimeTypes ) }, 
														{ offsetof(  mesh, indices ) ,  offsetof(  mesh, textureCoordinates ) ,  offsetof(  mesh, vertexCoordinates ) ,  offsetof(  mesh, normalCoordinates ) ,  offsetof(  mesh, indexBuffer ) ,  offsetof(  mesh, vertexbuffer ) ,  offsetof(  mesh, textureCoordinateBuffer ) ,  offsetof(  mesh, meshIndexBuffer ) ,  offsetof(  mesh, uvBuffer ) }, 
														{ offsetof(  address, street ) ,  offsetof(  address, number ) }, 
														{ }, 
														{ offsetof(  b, propertyFromB ) }, 
														{ offsetof(  a, propertyFromA ) ,  offsetof(  a, propertyFromB ) }, 
														{ offsetof(  inherit, propertyFromC ) ,  offsetof(  inherit, propertyFromA ) ,  offsetof(  inherit, propertyFromB ) }, 
														{ offsetof(  classA, propertyFromC ) }, 
														{ offsetof(  classB, propertyFromC ) }, 
														{ }, 
														{ offsetof(  sqlite, db ) ,  offsetof(  sqlite, res ) ,  offsetof(  sqlite, value ) ,  offsetof(  sqlite, selectedModel ) }, 
														{ offsetof(  triangle, a ) ,  offsetof(  triangle, b ) ,  offsetof(  triangle, c ) }, 
														{ offsetof(  user, username ) ,  offsetof(  user, id ) ,  offsetof(  user, userlevel ) ,  offsetof(  user, hash ) ,  offsetof(  user, addresses ) }
													};

int __ClassPropertyDatatypeIndices[TOTAL_CLASS_COUNT][30] 	= {
														{1 , 1 , -5 , 1 , -5 , 1 , 1 , -5 , 1 , 1 , 8 , 18 , -2 }, 
														{-5 , -5 , -5 }, 
														{1 , 1 }, 
														{1 , 1 , 1 }, 
														{-3 , -5 , -5 , -5 }, 
														{-5 , -5 , 1 }, 
														{ }, 
														{-5 , -5 , 1 }, 
														{5 , 5 }, 
														{-2 , 1 , 1 }, 
														{1 , 1 , 1 }, 
														{ }, 
														{ }, 
														{-5 , 1 , -5 , 11 , 17 , 14 , -5 , 1 , 1 }, 
														{5 }, 
														{-3 , -3 }, 
														{-3 , -3 , -5 , -3 , -3 , -3 , -3 , -3 , 14 }, 
														{5 , 5 }, 
														{1 , 7 , 7 , 7 , 1 , 1 , 1 , 1 , 1 }, 
														{-3 , -5 }, 
														{ }, 
														{-5 }, 
														{-5 , -5 }, 
														{-5 , -5 , -5 }, 
														{-5 }, 
														{-5 }, 
														{ }, 
														{1 , 1 , -3 , -3 }, 
														{2 , 2 , 2 }, 
														{-3 , -5 , -5 , -3 , 5 }
													};

void getArrayByClassIndex( int size, void * * voidArray, int * structByteSize, int classIndex ) {

	switch( classIndex ) {

		case 0:

			voidArray 				= ( void ** ) ( struct opengl * ) malloc( sizeof( struct opengl ) * size );

			*structByteSize			= sizeof( struct opengl );

		break;

		case 1:

			voidArray 				= ( void ** ) ( struct unsignedIntegerArray * ) malloc( sizeof( struct unsignedIntegerArray ) * size );

			*structByteSize			= sizeof( struct unsignedIntegerArray );

		break;

		case 2:

			voidArray 				= ( void ** ) ( struct vector2 * ) malloc( sizeof( struct vector2 ) * size );

			*structByteSize			= sizeof( struct vector2 );

		break;

		case 3:

			voidArray 				= ( void ** ) ( struct vector3 * ) malloc( sizeof( struct vector3 ) * size );

			*structByteSize			= sizeof( struct vector3 );

		break;

		case 4:

			voidArray 				= ( void ** ) ( struct text * ) malloc( sizeof( struct text ) * size );

			*structByteSize			= sizeof( struct text );

		break;

		case 5:

			voidArray 				= ( void ** ) ( struct array * ) malloc( sizeof( struct array ) * size );

			*structByteSize			= sizeof( struct array );

		break;

		case 7:

			voidArray 				= ( void ** ) ( struct floatArray * ) malloc( sizeof( struct floatArray ) * size );

			*structByteSize			= sizeof( struct floatArray );

		break;

		case 8:

			voidArray 				= ( void ** ) ( struct shader * ) malloc( sizeof( struct shader ) * size );

			*structByteSize			= sizeof( struct shader );

		break;

		case 9:

			voidArray 				= ( void ** ) ( struct uniform * ) malloc( sizeof( struct uniform ) * size );

			*structByteSize			= sizeof( struct uniform );

		break;

		case 10:

			voidArray 				= ( void ** ) ( struct attribute * ) malloc( sizeof( struct attribute ) * size );

			*structByteSize			= sizeof( struct attribute );

		break;

		case 11:

			voidArray 				= ( void ** ) ( struct fileSystem * ) malloc( sizeof( struct fileSystem ) * size );

			*structByteSize			= sizeof( struct fileSystem );

		break;

		case 12:

			voidArray 				= ( void ** ) ( struct consoleManager * ) malloc( sizeof( struct consoleManager ) * size );

			*structByteSize			= sizeof( struct consoleManager );

		break;

		case 13:

			voidArray 				= ( void ** ) ( struct http * ) malloc( sizeof( struct http ) * size );

			*structByteSize			= sizeof( struct http );

		break;

		case 14:

			voidArray 				= ( void ** ) ( struct headerManager * ) malloc( sizeof( struct headerManager ) * size );

			*structByteSize			= sizeof( struct headerManager );

		break;

		case 15:

			voidArray 				= ( void ** ) ( struct header * ) malloc( sizeof( struct header ) * size );

			*structByteSize			= sizeof( struct header );

		break;

		case 16:

			voidArray 				= ( void ** ) ( struct request * ) malloc( sizeof( struct request ) * size );

			*structByteSize			= sizeof( struct request );

		break;

		case 17:

			voidArray 				= ( void ** ) ( struct mimeTypes * ) malloc( sizeof( struct mimeTypes ) * size );

			*structByteSize			= sizeof( struct mimeTypes );

		break;

		case 18:

			voidArray 				= ( void ** ) ( struct mesh * ) malloc( sizeof( struct mesh ) * size );

			*structByteSize			= sizeof( struct mesh );

		break;

		case 19:

			voidArray 				= ( void ** ) ( struct address * ) malloc( sizeof( struct address ) * size );

			*structByteSize			= sizeof( struct address );

		break;

		case 20:

			voidArray 				= ( void ** ) ( struct toolset * ) malloc( sizeof( struct toolset ) * size );

			*structByteSize			= sizeof( struct toolset );

		break;

		case 21:

			voidArray 				= ( void ** ) ( struct b * ) malloc( sizeof( struct b ) * size );

			*structByteSize			= sizeof( struct b );

		break;

		case 22:

			voidArray 				= ( void ** ) ( struct a * ) malloc( sizeof( struct a ) * size );

			*structByteSize			= sizeof( struct a );

		break;

		case 23:

			voidArray 				= ( void ** ) ( struct inherit * ) malloc( sizeof( struct inherit ) * size );

			*structByteSize			= sizeof( struct inherit );

		break;

		case 24:

			voidArray 				= ( void ** ) ( struct classA * ) malloc( sizeof( struct classA ) * size );

			*structByteSize			= sizeof( struct classA );

		break;

		case 25:

			voidArray 				= ( void ** ) ( struct classB * ) malloc( sizeof( struct classB ) * size );

			*structByteSize			= sizeof( struct classB );

		break;

		case 27:

			voidArray 				= ( void ** ) ( struct sqlite * ) malloc( sizeof( struct sqlite ) * size );

			*structByteSize			= sizeof( struct sqlite );

		break;

		case 28:

			voidArray 				= ( void ** ) ( struct triangle * ) malloc( sizeof( struct triangle ) * size );

			*structByteSize			= sizeof( struct triangle );

		break;

		case 29:

			voidArray 				= ( void ** ) ( struct user * ) malloc( sizeof( struct user ) * size );

			*structByteSize			= sizeof( struct user );

		break;

	}

}



// #include "sqlite.h"

int getPropertyIndexOfClassIndex( int propertyCount, char ** propertyNames ) {

	int propertyIdOfIndex		= -1;

	for ( int i = 0; i < propertyCount; ++i )
	{
		char * propertyName	= propertyNames[i];

		//printf("propertyName: %s\n", propertyName);

		if( strcmp( propertyName, "id" ) == 0 ) {

			propertyIdOfIndex = i;

			break;

		}

	}

	return propertyIdOfIndex;

}

/*
void getArrayByClassIndex( int items, void * * voidArray, int * structByteSize, int classIndex ) {

	struct user * array;

	switch( classIndex ) {

		case 8:

			array 	= ( struct user * ) malloc( sizeof( struct user ) * 1000 );

			voidArray				= ( void ** ) array;

			*structByteSize			= sizeof( struct user );

		break;

		default:

			array 	= ( struct user * ) malloc( sizeof( struct user ) * 1000 );

			voidArray				= ( void ** ) array;

			*structByteSize			= sizeof( struct user );

	}

}*/

char * getClassName( int classIndex ) {

	return __ClassNames[ classIndex ];

}


int getClassIndexByClassName( char * className ) {

	for (int i = 0; i < TOTAL_CLASS_COUNT; ++i)
	{
		char * currentClassName = __ClassNames[ i ];

		if( strcmp( className, currentClassName ) == 0 ) {

			//printf("find classname: %s\n", className);

			return i;

		}

	}

	return -1;

}

int getPropertyCountByClassIndex( int classIndex ) {

	return __ClassPropertyCount[ classIndex ];

}

char * * getPropertiesByClassIndex( int classIndex ) {

	return __ClassPropertyNames[ classIndex ];

}

int * getPropertyOffsetsByClassIndex( int classIndex ) {

	return __ClassPropertyOffsets[ classIndex ];

}

int getPropertyOffsetByPropertyIndex( int * propertyOffsets, int propertyIndex ) {

	return propertyOffsets[ propertyIndex ];

}

int * getPropertyDatatypeIndexesByClassIndex( int classIndex ) {

	return __ClassPropertyDatatypeIndices[ classIndex ];

}

int getPropertyDatatypeIndex( int * propertyDatatypeIndices, int propertyIndex ) {

	return propertyDatatypeIndices[ propertyIndex ];

}


int getPropertyIndexByPropertyName( int classID, char * propertyName ) {

	int propertyCount			= getPropertyCountByClassIndex( classID );

	char * * propertyNames		= getPropertiesByClassIndex( classID );

	for (int i = 0; i < propertyCount; ++i)
	{

		char * propertyNameCompare = propertyNames[i];

		if( strcmp( propertyName, propertyNameCompare ) == 0 ) {

			return i;

		}

	}

	return -1;

}