#include <stdlib.h>
#include <stdio.h>

typedef int BOOL;
#define TRUE 1
#define FALSE 0

typedef struct
{
	int length;
	int capacity;
	int* array;
} ArrayListState;

BOOL init_array_list(int capacity, ArrayListState* state)
{
	int* array_list = malloc(capacity * sizeof(int));
	if (array_list == NULL)
		return FALSE;

	state->capacity = capacity;
	state->length = 0;
	state->array = array_list;

	return TRUE;
}

BOOL append_to_array_list(int value, ArrayListState* state)
{
	if (state == NULL || state->array == NULL)
		return FALSE;
	
	if (state->length == state->capacity)
	{
		state->array = realloc(state->array, (state->capacity + 6) * sizeof(int));
		if (state->array == NULL)
			return FALSE;
		state->capacity = state->capacity + 6;
	}

	state->array[state->length] = value;
	++state->length;

	return TRUE;
}

BOOL get_from_array_list(int* value, int index, ArrayListState *state)
{
	if (state == NULL || state->array == NULL || index >= state->length)
		return FALSE;

	*value = state->array[index];

	return TRUE;
}

BOOL set_to_array_list(int value, int index, ArrayListState *state)
{
	if (state == NULL || state->array == NULL || index >= state->length)
		return FALSE;

	state->array[index] = value;

	return TRUE;
}

BOOL remove_from_array_list(int index, ArrayListState* state)
{
	if (state == NULL || state->array == NULL || index >= state->length)
		return FALSE;

	++index;
	while (index < state->length)
	{
		state->array[index-1] = state->array[index];
		++index;
	}

	--state->length;

	return TRUE;
}

BOOL insert_to_array_list(int value, int index, ArrayListState* state)
{
	if (state == NULL || state->array == NULL || index >= state->length)
		return FALSE;

	if (!append_to_array_list(0, state))
		return FALSE;

	int index_to_insert = index;
	while (index < state->length-1)
	{
		state->array[index+1] = state->array[index];
		++index;
	}
	
	state->array[index_to_insert] = value;

	return TRUE;
}

BOOL free_array_list(ArrayListState *state)
{
	if (state == NULL || state->array == NULL)
		return FALSE;

	free(state->array);
	state->array = NULL;
	state->capacity = 0;
	state->length = 0;

	return TRUE;
}

BOOL print_array_list(ArrayListState* state)
{
	if (state == NULL || state->array == NULL)
		return FALSE;

	printf("len: %d; cap: %d\n", state->length, state->capacity);
	printf("arr: ");
	for (int i = 0; i < state->length; ++i)
		printf("%d ", state->array[i]);
	printf("\n");

	return TRUE;
}

int main()
{
	ArrayListState state;
	init_array_list(2, &state);
	print_array_list(&state);
	append_to_array_list(25, &state);
	append_to_array_list(85, &state);
	append_to_array_list(45, &state);
	print_array_list(&state);
	set_to_array_list(99, 1, &state);
	print_array_list(&state);
	remove_from_array_list(1, &state);
	print_array_list(&state);
	
	printf("----\n");
	insert_to_array_list(67, 0, &state);
	print_array_list(&state);

	int value = 0;
	get_from_array_list(&value, 2, &state);
	printf("get: %d\n", value);
}