// Filename : controller.h
//
// This file was initially generated by SpaceStudio but is meant to be modified
// by the user.
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include "spacecomp.h"
#include "abstract_module.h"
#include "application_definitions.h"
#include "matrix.h"

#include <stdint.h>

typedef enum {
	ADD,
	SUBTRACTION,
	MULTIPLY,
	DIVIDE,
	MATRIX_MULTIPLICATION
} operation_t;

class controller: public abstract_module {
	SPACECOMP_START(controller, INDEX, controller);

public:
	controller(SPACECOMP_CTOR_PARAMS(controller, INDEX));

	void thread(SPACECOMP_THREAD_PARAMS(controller, INDEX, thread));

private:

	uint32_t m_matrix_result[MATRIX_ROWS*MATRIX_COLUMNS];

	void send_result(int32_t data);
	void send_character(uint8_t character);
	uint8_t read_input();
	void read_data(int32_t* operand1, int32_t* operand2, operation_t* operation_t);
	int32_t get_first_operand(uint8_t* ptr);
	int32_t get_second_operand(uint8_t* ptr);
	int32_t character_to_number(uint8_t* ptr, uint32_t length);
	bool is_negative(uint8_t character);
	bool is_digit(uint8_t character);
	bool is_space(char character);
	bool is_operation_character(uint8_t character);
	uint32_t pow(int32_t base, int32_t exponent);
	int32_t get_operation_position(uint8_t* ptr);
	void read_input_stream(uint8_t* ptr);
	void sanitize(uint8_t* ptr, int* position);
	bool is_valid_command(uint8_t* ptr);
	bool is_division_by_zero(uint8_t* ptr);
	bool is_operation_detected(uint8_t* ptr);
	bool is_operand1_detected(uint8_t* ptr);
	bool is_operand2_detected(uint8_t* ptr);
	bool is_number(uint8_t* ptr, uint32_t length);
	bool is_lf_detected(uint8_t* ptr);
	int32_t get_lf_position(uint8_t* ptr);
	bool is_lf(uint8_t character);
	uint8_t* trim_spaces(uint8_t* ptr, uint32_t* length);
	operation_t get_operation(uint8_t* ptr);
	int32_t delegate_operation(operation_t operation, int32_t operand1, int32_t operand2);
	void send_addition_operand(int32_t data);
	void send_subtraction_operand(int32_t data);
	void send_multiplication_operand(int32_t data);
	void send_division_operand(int32_t data);
	int32_t read_addition_result();
	int32_t read_subtraction_result();
	int32_t read_multiplication_result();
	int32_t read_division_result();
	void init(uint8_t* ptr);
	int32_t atoi(uint8_t c);
	uint8_t itoa(uint32_t x);
	uint32_t get_order(uint32_t data);
	void display_message(const char* const message);
	void send_matrix(uint32_t index);
	void read_matrix_result();

	SPACECOMP_END(controller, INDEX, controller);
};

#endif
