Fully functional, but need refactoring, maybe later