basically works. needs lots of refactoring