#include <classConfiguration.h>

char * __ClassNames[TOTAL_CLASS_COUNT] 			= { "array", "text", "char", "user", "address", "consoleManager", "vector2" };

int __ClassMethodCount[TOTAL_CLASS_COUNT] 	= { 12, 12, 12, 1, 1, 5, 6 };

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

char * __ClassPropertyNames[TOTAL_CLASS_COUNT][30] 	= {
														{ "capacity" ,  "total" ,  "items" }, 
														{ "value" ,  "usevalue" ,  "length" ,  "capacity" }, 
														{ }, 
														{ "username" ,  "id" ,  "userlevel" ,  "hash" ,  "addresses" }, 
														{ "street" ,  "number" }, 
														{ }, 
														{ "x" ,  "y" }
													};

char * __ClassMethodNames[TOTAL_CLASS_COUNT][30] 	= {
														{ "length" ,  "data" ,  "get" ,  "set" ,  "resize" ,  "add" ,  "join" ,  "delete" ,  "array_push" ,  "unshift" ,  "pop" ,  "includes" }, 
														{ "operator_compare" ,  "operator_add" ,  "constructor" ,  "get" ,  "resize" ,  "append" ,  "appendBinary" ,  "appendObject" ,  "concatenate" ,  "toNative" ,  "whiteSpace" ,  "free" }, 
														{ "operator_compare" ,  "operator_add" ,  "operator_plus" ,  "compare" ,  "concatenate" ,  "includes" ,  "clone" ,  "copy" ,  "split" ,  "removeWhitespaceLeft" ,  "removeWhitespaceRight" ,  "removeWhitespace" }, 
														{ "constructor" }, 
														{ "someMethod" }, 
														{ "whiteSpace" ,  "logObject" ,  "log" ,  "error" ,  "createHorisontalLine" }, 
														{ "constructor" ,  "operator_plus" ,  "operator_add" ,  "add" ,  "subtract" ,  "length" }
													};

int __ClassPropertyOffsets[TOTAL_CLASS_COUNT][30] 	= {
														{ offsetof(  array, capacity ) ,  offsetof(  array, total ) ,  offsetof(  array, items ) }, 
														{ offsetof(  text, value ) ,  offsetof(  text, usevalue ) ,  offsetof(  text, length ) ,  offsetof(  text, capacity ) }, 
														{ }, 
														{ offsetof(  user, username ) ,  offsetof(  user, id ) ,  offsetof(  user, userlevel ) ,  offsetof(  user, hash ) ,  offsetof(  user, addresses ) }, 
														{ offsetof(  address, street ) ,  offsetof(  address, number ) }, 
														{ }, 
														{ offsetof(  vector2, x ) ,  offsetof(  vector2, y ) }
													};

int __ClassPropertyDatatypeIndices[TOTAL_CLASS_COUNT][30] 	= {
														{-5 , -5 , 1 }, 
														{-3 , -5 , -5 , -5 }, 
														{ }, 
														{-3 , -5 , -5 , -3 , 0 }, 
														{-3 , -5 }, 
														{ }, 
														{1 , 1 }
													};

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

	switch( classIndex ) {

		case 0:

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

			*structByteSize			= sizeof( struct array );

		break;

		case 1:

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

			*structByteSize			= sizeof( struct text );

		break;

		case 3:

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

			*structByteSize			= sizeof( struct user );

		break;

		case 4:

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

			*structByteSize			= sizeof( struct address );

		break;

		case 5:

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

			*structByteSize			= sizeof( struct consoleManager );

		break;

		case 6:

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

			*structByteSize			= sizeof( struct vector2 );

		break;

	}

}

void callMethodOfClass( int classIndex, int methodIndex, void * object ) {

	switch( classIndex ) {

		case 0:

			switch( methodIndex ) {

				case 0:

					array_length( object );

				break;

 				case 1:

					array_data( object );

				break;

 				case 10:

					array_pop( object );

				break;

 			}

		break;

		case 1:

			switch( methodIndex ) {

				case 9:

					text_toNative( object );

				break;

 				case 11:

					text_free( object );

				break;

 			}

		break;

		case 3:

			switch( methodIndex ) {

				case 0:

					user_constructor( object );

				break;

 			}

		break;

		case 4:

			switch( methodIndex ) {

				case 0:

					address_someMethod( object );

				break;

 			}

		break;

		case 5:

			switch( methodIndex ) {

				case 4:

					consoleManager_createHorisontalLine( object );

				break;

 			}

		break;

		case 6:

			switch( methodIndex ) {

				case 5:

					vector2_length( object );

				break;

 			}

		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;

}

int getMethodCountByClassIndex( int classIndex ) {

	return __ClassMethodCount[ classIndex ];

}


char * * getMethodNamesByClassIndex( int classIndex ) {

	return __ClassMethodNames[ classIndex ];

}


int getMethodIndexByPropertyName( int classID, char * propertyName ) {

	int methodCount				= getMethodCountByClassIndex( classID );

	char * * methodNames		= getMethodNamesByClassIndex( classID );

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

		char * propertyNameCompare = methodNames[i];

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

			return i;

		}

	}

	return -1;

}