
#include <classConfiguration.h>

#include <stdbool.h>

#include <stdio.h> 

#include <sys/ioctl.h>

#include <stdio.h>

#include <unistd.h>

#include <stdio.h>

#include <stdarg.h>

#include <vector2.h>

#define isCompatible(x, type) _Generic(x, type: true, default: false)


extern struct consoleManager * console;

class consoleManager{

	char * whiteSpace( int whiteSpaceCount ) {

		char * output = malloc( whiteSpaceCount + 1 );

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

			strcat( output, "	" );

		}

		output[whiteSpaceCount] = 0;

		return output;

	}

	logObject( void * voidPointer, int classIndex, int level ) {


		char * whiteSpace   = this->whiteSpace( level );

		level++;

		char * className	= getClassName( classIndex );

		printf( "\n\n" );

		printf( whiteSpace );

		printf("	%s : {\n", className );



		char * * propertyNames	= getPropertiesByClassIndex( classIndex );

		int propertyCount		= getPropertyCountByClassIndex( classIndex );

		int  * propertyOffsets	= getPropertyOffsetsByClassIndex( classIndex );

		int * datatypeIndices	= getPropertyDatatypeIndexesByClassIndex( classIndex );

		char * pointer			= voidPointer;


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

			char * propertyName 		= propertyNames[propertyIndex];

			printf( whiteSpace );

			printf("		%-20s : ", propertyName);

			int propertyDatatypeIndex	= getPropertyDatatypeIndex( datatypeIndices, propertyIndex );

			int propertyOffset			= getPropertyOffsetByPropertyIndex( propertyOffsets, propertyIndex );


			if( propertyDatatypeIndex == -5 ) {

				int value	= *( int * )(pointer + propertyOffset);

				printf( whiteSpace );

				printf("%-20i ", value );



			} else if( propertyDatatypeIndex == -3 ) {

				//char * columnValueCopy		= ( char * ) malloc( 8 );

				uintptr_t * value				= ( uintptr_t * ) ( pointer + propertyOffset );

				//strncpy( &columnValueCopy, value, 8 );

				printf( whiteSpace );

				printf( "%-20s", ( char * ) * value );

			} else if( propertyDatatypeIndex > 0 ) {

				char * memberClassName	= getClassName( propertyDatatypeIndex );

				if( strcmp( memberClassName, "array" ) == 0 ) {

					struct array * memberArray		= *(struct array ** )(pointer + propertyOffset) ;

					if( memberArray == NULL ) {

							printf("			this has to be fixed, array is not created.\n");

							continue;

					}

					int numberRows					= memberArray->length();

					int *  arrayPointer				= ( int * ) memberArray->items;

					for (int k = 0; k < numberRows; ++k)
					{
						
						void * pointer			= memberArray->get( k );

						short * row	= (short*)(pointer);

						this->logObject( pointer, (int) *row, level );

					}

				}

				//printf("This is another class:		%s\n\n", memberClassName);

			}

			
			printf("\n");
			

		}

		printf( whiteSpace );

		printf( "	}\n" );



	}
	
	void log( ...  ) {

		//int datatypes[], int count, 

		int level	= 0;

		va_list args;

		va_start( args, count );

		//printf("count: %i\n\n", count);

		for (int i = 0; i < count; ++i)
		{
			int datatype 		= datatypes[i]; // va_arg_type( argumentIndex )

			//printf("datatype %i\n", datatype);

			if( datatype == -2 ) {

				char * message = va_arg( args, char * );

				printf("%s", message);

			}

			if( datatype == -1 ) {

				int message = va_arg( args, int );

				printf("%i", message);
			}

			if( datatype > 0 ) {

				//int classIndex = va_arg( args, int );

				void * voidPointer		= va_arg( args,  void * );

				this->logObject( voidPointer, datatype, level++ );
				

			}

			printf(" ");

		}

		printf("\n");

		va_end( args);

	}

	void error( char * message ) {

		#define ANSI_COLOR_RED     "\x1b[31m"
		#define ANSI_COLOR_GREEN   "\x1b[32m"
		#define ANSI_COLOR_DIM_YELLOW  "\x1b[33m"
		#define ANSI_COLOR_BLUE    "\x1b[34m"
		#define ANSI_COLOR_MAGENTA "\x1b[35m"
		#define ANSI_COLOR_CYAN    "\x1b[36m"
		#define ANSI_COLOR_RESET   "\x1b[0m"

		#define ANSI_COLOR_BRIGHT_YELLOW  "\x1b[93m"

		printf( ANSI_COLOR_RED );

		printf( "\n\n		Error:		" );

		printf( "%s\n\n", message );

		printf( ANSI_COLOR_RESET );

		exit( 0 );

	}

	void createHorisontalLine() {

		struct winsize w;

		ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);

		for (int i = 0; i < w.ws_col; ++i)
		{

			printf("-");

		};

		printf("\n");

	}

}










