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