diff --git a/examples/dokk/config.py b/examples/dokk/config.py
index a1df410c2625253412a3e990141c6234a5328959..7fc526da344cdf241f437ab8e6f7d9c98be6a9a9 100644
--- a/examples/dokk/config.py
+++ b/examples/dokk/config.py
@@ -103,4 +103,4 @@ class TopTen():
       score = self._config.Get(str(rank))["SCORE"]
       return [name, score]
     except AttributeError:
-      return None
\ No newline at end of file
+      return None
diff --git a/examples/dokk/datafiles/thrombinNoH/top_ten.ini b/examples/dokk/datafiles/thrombinNoH/top_ten.ini
index f6b6564f8730f17c1c079a14af1eab729bdf344f..e268452c0bb2024d0c7cbae4f718a4c1ea517b44 100644
--- a/examples/dokk/datafiles/thrombinNoH/top_ten.ini
+++ b/examples/dokk/datafiles/thrombinNoH/top_ten.ini
@@ -1,8 +1,28 @@
 [1]
-score = 1.31137919426
+score = 1.25806855361
+name = 8AA
+
+[3]
+score = 1.86918596029
 name = AAA
 
 [2]
-score = 1.79155447086
+score = 1.38426769574
+name = EAA
+
+[5]
+score = 9.33016001383
+name = HAA
+
+[4]
+score = 1.92396162748
+name = GAA
+
+[7]
+score = 25.4150890907
 name = AAA
 
+[6]
+score = 10.5103771766
+name = AA5
+
diff --git a/examples/dokk/dokk b/examples/dokk/dokk
index c6f0c0249a9d967623d7440e0c4ef4981cce6397..66437f31d81c3a91808ebb78ff702aee3d0344d3 100644
--- a/examples/dokk/dokk
+++ b/examples/dokk/dokk
@@ -1,2 +1,2 @@
 #!/bin/sh
-cat start_dokk.py | gosty Dokk $@
\ No newline at end of file
+gosty start_dokk.py Dokk $@
\ No newline at end of file
diff --git a/examples/dokk/glwin.py b/examples/dokk/glwin.py
index 7b1de9ffd3f31f8c93178a8ea74a7f704ec5260c..8a1dda0651f0ee7deff605c49e7a2ab3c5f6ad68 100644
--- a/examples/dokk/glwin.py
+++ b/examples/dokk/glwin.py
@@ -25,6 +25,10 @@ class DokkGLCanvas(QGLWidget):
     self.spnav_input = SpnavInputDevice(self)
     self.update_timer = QTimer()
     self.update_timer.start(UPDATE_INTERVAL)
+    
+    self.hud = HUD()
+        
+    self._lock_input = False
     QObject.connect(self.update_timer, SIGNAL("timeout()"), self.update)
         
   def initializeGL(self):
@@ -38,8 +42,6 @@ class DokkGLCanvas(QGLWidget):
     ogl.glPopMatrix();
 
   def SetLevel(self, level):
-    self.level_=level
-    self.hud = HUD(level)
     self.spnav_input.SetLevel(level)
     
   def paintEvent(self, event):
@@ -56,7 +58,8 @@ class DokkGLCanvas(QGLWidget):
     painter.drawRect(QRect(QPoint(0, 0), QSize(self.width(), 25)))
     painter.setPen(QPen(QColor(255,255,255), Qt.SolidLine))
     painter.setFont(QFont("Verdana"))
-    painter.drawText(QPoint(10, 20), "You are %.1f away from the solution" % self.level_.GetRMSD())
+    painter.drawText(QPoint(10, 20), "You are %.1f away from the solution" % self.dokk.GetLevel().GetRMSD())
+    painter.drawText(QPoint(self.width()-100, 20), "%.0f seconds left" % self.dokk.GetLevel().GetRemainingTime())
     if self.hud is not None:
       self.hud.Paint(painter)
       
@@ -67,38 +70,41 @@ class DokkGLCanvas(QGLWidget):
     self.last_point_=QPoint(event.x(), event.y())
 
   def mouseMoveEvent(self, event):
-    delta=QPoint(event.x(), event.y())-self.last_point_
-    self.last_point_=QPoint(event.x(), event.y())
-    if event.buttons() & Qt.LeftButton:
-      tf=gfx.Scene().GetTransform()      
-      if event.modifiers() & Qt.ShiftModifier:
-        if event.modifiers() & Qt.AltModifier:
-          self.level_.Shift(tf.GetRot().GetRow(2)*delta.y()*0.1)          
+    if not self._lock_input:
+      delta=QPoint(event.x(), event.y())-self.last_point_
+      self.last_point_=QPoint(event.x(), event.y())
+      if event.buttons() & Qt.LeftButton:
+        tf=gfx.Scene().GetTransform()      
+        if event.modifiers() & Qt.ShiftModifier:
+          if event.modifiers() & Qt.AltModifier:
+            self.dokk.GetLevel().Shift(tf.GetRot().GetRow(2)*delta.y()*0.1)          
+          else:
+            self.dokk.GetLevel().Shift((tf.GetRot().GetRow(0)*delta.x()
+                             -tf.GetRot().GetRow(1)*delta.y())*0.1)
         else:
-          self.level_.Shift((tf.GetRot().GetRow(0)*delta.x()
-                           -tf.GetRot().GetRow(1)*delta.y())*0.1)
-      else:
+          if delta.y()!=0:
+            self.dokk.GetLevel().RotateAxis(tf.GetRot().GetRow(0), delta.y()*0.005)
+          if delta.x()!=0:
+            self.dokk.GetLevel().RotateAxis(tf.GetRot().GetRow(1), delta.x()*0.005)
+        self.dokk.GetLevel().UpdateScores()
+        self.update()
+      elif event.buttons() & Qt.RightButton:
         if delta.y()!=0:
-          self.level_.RotateAxis(tf.GetRot().GetRow(0), delta.y()*0.005)
+          gfx.Scene().Apply(gfx.InputEvent(gfx.INPUT_DEVICE_MOUSE,
+                                           gfx.INPUT_COMMAND_ROTX, delta.y()*0.5),
+                            False)
         if delta.x()!=0:
-          self.level_.RotateAxis(tf.GetRot().GetRow(1), delta.x()*0.005)
-      self.level_.UpdateScores()
-      self.update()
-    elif event.buttons() & Qt.RightButton:
-      if delta.y()!=0:
-        gfx.Scene().Apply(gfx.InputEvent(gfx.INPUT_DEVICE_MOUSE,
-                                         gfx.INPUT_COMMAND_ROTX, delta.y()*0.5),
-                          False)
-      if delta.x()!=0:
-        gfx.Scene().Apply(gfx.InputEvent(gfx.INPUT_DEVICE_MOUSE,
-                                         gfx.INPUT_COMMAND_ROTY, delta.x()*0.5),
-                          False)
-      self.update()
+          gfx.Scene().Apply(gfx.InputEvent(gfx.INPUT_DEVICE_MOUSE,
+                                           gfx.INPUT_COMMAND_ROTY, delta.x()*0.5),
+                            False)
+        self.update()
   def mouseDoubleClickEvent(self, event):
-    self.level_.SetPivot(event.x(), self.height()-event.y())
+    if not self._lock_input:
+      self.dokk.GetLevel().SetPivot(event.x(), self.height()-event.y())
   def wheelEvent(self, event):
-    self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0,gfx.TRANSFORM_VIEW,
-              0.1*(-event.delta()))
+    if not self._lock_input:
+      self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0,gfx.TRANSFORM_VIEW,
+                0.1*(-event.delta()))
 
 
   def OnTransform(self,com, indx, trg, val):
@@ -107,43 +113,65 @@ class DokkGLCanvas(QGLWidget):
     self.update()
     
   def keyReleaseEvent(self, event):
-    if event.key() == Qt.Key_Left or event.key() == Qt.Key_A:
-      self.OnTransform(gfx.INPUT_COMMAND_TRANSX,0, gfx.TRANSFORM_VIEW, -TRANS_VAL)
-      
-    if event.key() == Qt.Key_Right or event.key() == Qt.Key_D:
-      self.OnTransform(gfx.INPUT_COMMAND_TRANSX,0, gfx.TRANSFORM_VIEW, TRANS_VAL)
-      
-    if event.key() == Qt.Key_Down or event.key() == Qt.Key_S:
-      self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0, gfx.TRANSFORM_VIEW, TRANS_VAL)
-      
-    if event.key() == Qt.Key_Up or event.key() == Qt.Key_W:
-      self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0, gfx.TRANSFORM_VIEW, -TRANS_VAL)
-      
     if event.key() == Qt.Key_Escape:
       QApplication.exit()
     
+    if not self._lock_input:
+      if event.key() == Qt.Key_Left or event.key() == Qt.Key_A:
+        self.OnTransform(gfx.INPUT_COMMAND_TRANSX,0, gfx.TRANSFORM_VIEW, -TRANS_VAL)
+        
+      if event.key() == Qt.Key_Right or event.key() == Qt.Key_D:
+        self.OnTransform(gfx.INPUT_COMMAND_TRANSX,0, gfx.TRANSFORM_VIEW, TRANS_VAL)
+        
+      if event.key() == Qt.Key_Down or event.key() == Qt.Key_S:
+        self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0, gfx.TRANSFORM_VIEW, TRANS_VAL)
+        
+      if event.key() == Qt.Key_Up or event.key() == Qt.Key_W:
+        self.OnTransform(gfx.INPUT_COMMAND_TRANSZ,0, gfx.TRANSFORM_VIEW, -TRANS_VAL)
+    
+  def SetLockInput(self, lock):
+    self._lock_input = lock
+    self.spnav_input.SetLockInput(lock)
+
 class DokkGLWin(gfx.GLWinBase):
     def _CreateFormat(self):
       fmt=QGLFormat()
       fmt.setAlpha(True)
       return fmt
+    
     def __init__(self,dokk):
         gfx.GLWinBase.__init__(self)
         self.canvas_=DokkGLCanvas(self._CreateFormat(),dokk)
+        
     def DoRefresh(self):
       self.refresh_=True
+      
     def SetLevel(self, level):
       self.canvas_.SetLevel(level)
+      
     def Show(self, fullscreen):
       if fullscreen:
         self.canvas_.showFullScreen()
       else:
         self.canvas_.show()
+        
     def SetStereo():
       pass
     
+    def SetLockInput(self, lock):
+      self.canvas_.SetLockInput(lock)
+    
     def Width(self):
       return self.canvas_.width()
     
     def Height(self):
       return self.canvas_.height()
+    
+    def ClearHUDObjects(self):
+      self.canvas_.hud.Clear()
+    
+    def RemoveHUDObject(self, hud_object):
+      self.canvas_.hud.Remove(hud_object)
+      
+    def AddHUDObject(self, hud_object):
+      self.canvas_.hud.Add(hud_object)
diff --git a/examples/dokk/highscore.py b/examples/dokk/highscore.py
index a83ec5d14d9e9bf15a7ccaaec375ba49c8bfe68d..db5a01959274774ec198400ae237995de24257dc 100644
--- a/examples/dokk/highscore.py
+++ b/examples/dokk/highscore.py
@@ -14,18 +14,17 @@ class HighScore(QtCore.QObject):
     return self.ne.GetName()
   
   def Start(self):
-    rect = QtCore.QRect(QtCore.QPoint(60, 60), QtCore.QSize(dokk.Dokk().gl_win.Width()/3, dokk.Dokk().gl_win.Height()-120))
-    self.bg = RectHUDObject(-1,rect, bg_color=QtGui.QColor(128,128,128,200))
-    dokk.Dokk().gl_win.AddHUDObject(self.bg)
-
     topten=self.level.topten
-    text = "%4s %5s\n"%("Name","Score")
+    text = "%2s %4s %5s\n"%("#", "Name","Score")
     i=1
     while(topten.GetData(i)):
        data = topten.GetData(i)
-       text += "%4s %1.2f\n"%(data[0],float(data[1]))
+       text += "%2i %4s %1.2f\n"%(i, data[0],float(data[1]))
        i += 1
-    self.hud_text = RectTextHUDObject(text, rect=rect, time=-1,font = QtGui.QFont("Verdana",20))
+    rect = QtCore.QRect(QtCore.QPoint(60, 60), QtCore.QSize(dokk.Dokk().gl_win.Width()/5, (i+1)*30))
+    self.bg = RectHUDObject(-1,rect, bg_color=QtGui.QColor(128,128,128,200))
+    dokk.Dokk().gl_win.AddHUDObject(self.bg)
+    self.hud_text = RectTextHUDObject(text, rect=rect, time=-1, font=QtGui.QFont("Verdana",20))
     dokk.Dokk().gl_win.AddHUDObject(self.hud_text)
                   
   def Finish(self):
diff --git a/examples/dokk/hud.py b/examples/dokk/hud.py
index 31319fa6df2797cdf6dac0f28121365e5518dc7d..bc5aa3c1dca11a3d1b1cc7d4ec6a3fc9bf43951d 100644
--- a/examples/dokk/hud.py
+++ b/examples/dokk/hud.py
@@ -113,4 +113,4 @@ class RectHUDObject(HUDObject):
     painter.setPen(self.border_color)
     painter.setBrush(self.bg_color)
     painter.drawRect(self.rect)
-    painter.setPen(QPen(self.border_color, Qt.SolidLine))
\ No newline at end of file
+    painter.setPen(QPen(self.border_color, Qt.SolidLine))
diff --git a/examples/dokk/level.py b/examples/dokk/level.py
index f97f14a66e90863d80c7d1147f98e8edbf5c1a14..b177f70e2c43398acae3ee7d18730de5d2de1c38 100644
--- a/examples/dokk/level.py
+++ b/examples/dokk/level.py
@@ -1,24 +1,44 @@
 import os
+import time
+from PyQt4 import QtCore, QtGui
 from ost import io, gfx, qa, geom
 from ligand import Ligand
 from surface import Surface
 from protein import Protein
 from score_updater import ScoreUpdater
-from config import Config
+from config import *
 from dokk import Dokk
-from level_intro import LevelIntro
+from level_messages import LevelIntro
+from level_messages import LevelEnd
+from name_enter import HUDNameInput
+from highscore import HighScore
 
-class Level:
-  def __init__(self, name):
+class Level(QtCore.QObject):
+  def __init__(self, name, parent=None):
+    QtCore.QObject.__init__(self,parent)
     self.name_=name
     self.Load()
     self.hud = None
-    dokk = Dokk()
-    self.li = LevelIntro(self)
-        
+    
+    self.endtime = 0
+    self.stop_time = 0
+    
+    self.timer = QtCore.QTimer()
+    self.timer.setSingleShot(True)
+    self.connect(self.timer,QtCore.SIGNAL("timeout()"),self.Finished)
+    self.li = LevelIntro(self.config)
+    self.connect(self.li,QtCore.SIGNAL("Finished()"),self._IntroEnd)
+    self.le = None
+    self.hni = None
+    self.highscore = HighScore(self)
+    Dokk().gl_win.SetLockInput(True)
+    self._started = False
+    self.emit(QtCore.SIGNAL("Stopped()"))
+    
   def Load(self):
     level_dir=os.path.join('datafiles', self.name_)
     self.config = Config(os.path.join(level_dir, 'level.ini'))
+    self.topten = TopTen(os.path.join(level_dir, 'top_ten.ini'))
     print 'Loading %s' % self.config.Level["NAME"]
     ligand_ent=io.LoadSDF(os.path.join(level_dir, 'ligand.sdf'))
     self.ligand=Ligand(ligand_ent,self.config)
@@ -51,7 +71,44 @@ class Level:
   def GetRMSD(self):
     return self.ligand.RMSDToSolution()
 
+  def GetScore(self):
+    rmsd = self.GetRMSD()
+    return rmsd + self.GetTimeMalus()
+  
+  def GetRank(self):
+    return self.topten.GetRank(self.GetScore())
+  
+  def GetTTDiff(self):
+    return self.topten.GetDiff(self.GetScore())
+      
+  def GetStopTime(self):
+    time = (self.endtime-self.stop_time)
+    if time > 0:
+      return time
+    return 0
+    
+  def GetRemainingTime(self):
+    if self._started:
+      rem_time = self.endtime-time.time()
+      if rem_time > 0:
+        return rem_time
+    return 0
+  
+  def GetTimeMalus(self):
+    rem_time = self.GetStopTime()
+    if(rem_time>0):
+      return 1- (rem_time / (float(self.config.Level["TIME"])/1000.0))
+    return 1
+  
   def Reset(self):
+    self.endtime = 0
+    self.stop_time = 0
+    Dokk().gl_win.ClearHUDObjects()
+    if self.le is not None:
+      self.le.Stop()
+    self.li.Stop()
+    self.hni = None
+    
     self.ligand.Reset()
     gfx.Scene().SetTransform(self.transform_)
     gfx.Scene().SetCenter(self.surface.go.GetCenter())
@@ -64,14 +121,50 @@ class Level:
     gfx.Scene().SetCenter(self.surface.go.GetCenter())
     gfx.Scene().RequestRedraw()
     self.su.UpdateScores()
-    
-  def AddHUDObject(self, hud_object):
-    self.hud.Add(hud_object)
-    
+  
+  def Finished(self):
+    self._started = False
+    self.timer.stop()
+    self.stop_time = time.time()
+    Dokk().gl_win.SetLockInput(True)
+    if self.GetRank() > 0:
+      self.le = LevelEnd(self.config.TT)
+    else:
+      self.le = LevelEnd(self.config.NTT)
+    self.connect(self.le,QtCore.SIGNAL("Finished()"),self._FinishEnd)
+    self.le.Start()
+        
   def Begin(self):
+    self.Reset()
+    self.su.UpdateScores()
     self.li.Start()
+    self._started = True
+    self.emit(QtCore.SIGNAL("Started()"))
     
   def Close(self):
+    if self.le is not None:
+      self.le.Stop()
+    self.li.Stop()
+    self._started = False
     self.surface.Close()
     self.protein.Close()
     self.ligand.Close()
+
+  def _IntroEnd(self):
+    if self._started:
+      Dokk().gl_win.SetLockInput(False)
+      self.timer.start(int(self.config.Level["TIME"]))
+      self.endtime = float(time.time()+(int(self.config.Level["TIME"]))/1000.0)
+      
+  def _FinishEnd(self):
+    if bool(int(self.config.Level["SAVE"])) and self.GetRank()>0:
+      self.hni = HUDNameInput()
+      self.connect(self.hni,QtCore.SIGNAL("Finished()"),self._FinishEnterName)
+    else:
+      self.Reset()
+      self.emit(QtCore.SIGNAL("Stopped()"))
+      
+  def _FinishEnterName(self):
+    self.topten.SetValue(self.hni.GetName(),self.GetScore())
+    self.Reset()
+    self.emit(QtCore.SIGNAL("Stopped()"))
diff --git a/examples/dokk/ligand.py b/examples/dokk/ligand.py
index b10d0b138a3ad309f38239c621f1942402fd7c5e..1e4f5879850f57e1ac8c39f315d7540cbe065fbe 100644
--- a/examples/dokk/ligand.py
+++ b/examples/dokk/ligand.py
@@ -100,4 +100,4 @@ class Ligand:
      vec[1]< self.box_max[1] and vec[1]> self.box_min[1] and \
      vec[2]< self.box_max[2] and vec[2]> self.box_min[2] :
       return True
-    return False
+    return False
\ No newline at end of file
diff --git a/examples/dokk/start_dokk.py b/examples/dokk/start_dokk.py
index bd13f442133091a3ec126ea32fd6bf43b9d0e31f..e1850cddbf046e86f2ef80f0f5af484669b89caf 100644
--- a/examples/dokk/start_dokk.py
+++ b/examples/dokk/start_dokk.py
@@ -1,6 +1,6 @@
 from level import Level
 from dokk import Dokk
 dokk=Dokk()
-dokk.SetLevels(['thrombin','thrombinNoH'])
+dokk.SetLevels(['1bh5','thrombin','thrombinNoH'])
 dokk.Start(sys.argv)
 
diff --git a/examples/dokk/surface.py b/examples/dokk/surface.py
index 9f945372cf2477898d4aa62104a031c36dbf5c76..3de540af0a6a1cbc8c215c941ef087b5403d4448 100644
--- a/examples/dokk/surface.py
+++ b/examples/dokk/surface.py
@@ -14,4 +14,4 @@ class Surface:
 
   def Close(self):
     gfx.Scene().Remove(self.go)
-    del(self.go)
+    del(self.go)
\ No newline at end of file