Working prototype. It's awful in some places, but it's because of MySQL :(