Выкладываю первую версию.

 Надеюсь, найду время поправить и доделать :)