As per the tutorial by Michael Hart, with some tweaking to it