final working product. code needs refractoring