A rough version with most function implemented, not tested
try to improve speed