#include "mk.h"

extern MK_CLASS *mk_create_kernel_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_int_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_float_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_null_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_object_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_io_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_console_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_exception_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_vm_error_exception_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_compile_error_exception_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_container_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_array_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_array_outof_range_exception_class( MK_VM_STRUCT *vm );
extern MK_CLASS *mk_create_node_class( MK_VM_STRUCT *vm );

void mk_register_internal_classes( MK_VM_STRUCT *vm )
{
	MK_CLASS *target = NULL;
	MK_VARIABLE *entryPoint = NULL;

	// create Object class
	target = mk_create_object_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Kernel class
	target = mk_create_kernel_class( vm );
	mk_register_class( vm, target );

	// create entrypoint function
	entryPoint = 
		(MK_VARIABLE*)mk_create_object( MK_TYPE_VARIABLE );
	entryPoint->flags |= 
		MK_TYPE_ATTRIBUTE_VARIABLE_METHOD | 
		MK_TYPE_ATTRIBUTE_VARIABLE_METHOD_SCRIPT | 
		MK_TYPE_ATTRIBUTE_VARIABLE_STATIC | 
		MK_TYPE_ATTRIBUTE_VARIABLE_FINAL;

	entryPoint->name = 
		mk_get_symbol_name_ptr( vm, FUNCTIONNAME_ENTRYPOINT );
	mk_register_variable( vm, entryPoint, target );

	// create Null class
	target = mk_create_null_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Integer class
	target = mk_create_int_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );
	
	// create Float class
	target = mk_create_float_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create IO class
	target = mk_create_io_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Console class
	target = mk_create_console_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Container class
	target = mk_create_container_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );
	
	// create Array class
	target = mk_create_array_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Node class
	target = mk_create_node_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create Exception class
	target = mk_create_exception_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create CompileErrorException class
	target = mk_create_compile_error_exception_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create VMErrorException class
	target = mk_create_vm_error_exception_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );

	// create ArrayOutOfRangeException class
	target = mk_create_array_outof_range_exception_class( vm );
	mk_insert_item_hashtable( vm->code->classes, target->nameThis, target );
}
