fix some weird behavior, but still needs simplification & refactoring