refactor and add more function