again, super ugly code (half a day to make)