working code, took a while to write