Some major refactoring and rewrites based on actually reading the requirements for the assignment