#pragma once

#include "geometric_objects.h"
#include<set>

class maze : public wall_block {
public:
	glm::vec3 start_location;
	maze() : wall_block("cube.obj", "brick_2.png", glm::vec3(4, 4, 4)) {
		scale = 4.0f;
	}
	
	bool load_from_file(const char* filename);
};

class maze_solver : public rollsphere {
	struct intpoint {
		int x, y, z;
		intpoint(glm::vec3 p) {
			x = roundf(p.x);
			y = roundf(p.y);
			z = roundf(p.z);
		}
		intpoint(int nx, int ny, int nz) : x(nx), y(ny), z(nz) {}
		bool operator== (const intpoint &other) const {
			return other.x == x && other.y == y && other.z == z;
		}
		bool operator<(const intpoint &other) const { 
			return (x << 20) + (y << 10) + z < (other.x << 20) + (other.y << 10) + other.z;
		}
		std::vector<intpoint> neighbors(){
			std::vector<intpoint> retval;
			retval.push_back(intpoint(x, y, z - 8));
			retval.push_back(intpoint(x - 8, y, z));
			retval.push_back(intpoint(x + 8, y, z));
			retval.push_back(intpoint(x, y, z + 8));
			return retval;
		}
		glm::vec3 vec3(){
			return glm::vec3(x, y, z);
		}
	};
public:
	float solve_speed = 0.1f;
	std::vector<std::set<intpoint>> visiteds;
	std::vector<std::vector<intpoint>> stacks;
	void launch(float maze_height);
	void move(int elapsed_time) override;
	void remove(size_t idx);
};
