diff --git a/examples/dokk/config.py b/examples/dokk/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..0323a34613db55427c16022f672ce468c61f49f8
--- /dev/null
+++ b/examples/dokk/config.py
@@ -0,0 +1,20 @@
+import ConfigParser
+import string
+
+class Config:
+  def __init__(self, path):
+    config = ConfigParser.ConfigParser()
+    config.read(path)
+
+    self.values = dict()
+    for section in config.sections():
+      section_dict = dict()
+      for option in config.options(section):
+        section_dict[str(option).upper()]=config.get(section, option)
+      self.values[str(section).lower()]=section_dict
+      
+  def __getattr__(self, item):
+    item = str(item).lower()
+    if self.values.has_key(item):
+      return self.values[item]
+    raise AttributeError(item)
diff --git a/examples/dokk/dokk.py b/examples/dokk/dokk.py
index 60abd7d89d1484676507072b3e4f46013cd4a426..03603f942ee2193f96d963fb2c7086fbab5331ea 100644
--- a/examples/dokk/dokk.py
+++ b/examples/dokk/dokk.py
@@ -8,5 +8,6 @@ dokk_win=glwin.DokkGLWin()
 
 level=Level('thrombin')
 dokk_win.SetLevel(level)
+
 dokk_win.Show(fullscreen=('--fullscreen' in sys.argv))
 
diff --git a/examples/dokk/glwin.py b/examples/dokk/glwin.py
index 6124806ee4838d6fc1f1f26a05c335431cddefc3..29c9df1c0b8f7096163a2711e451a9b5a991ce63 100644
--- a/examples/dokk/glwin.py
+++ b/examples/dokk/glwin.py
@@ -57,7 +57,6 @@ class DokkGLCanvas(QGLWidget):
     self.last_point_=QPoint(event.x(), event.y())
 
   def mouseMoveEvent(self, event):
-    print "MOUSE MOVE"
     delta=QPoint(event.x(), event.y())-self.last_point_
     self.last_point_=QPoint(event.x(), event.y())
     if event.buttons() & Qt.LeftButton:
diff --git a/examples/dokk/level.py b/examples/dokk/level.py
index 1c9c51557c96f668548009593f1529bfe57748ea..d3c4f2bf2a991ca76ce5d730f5a798f1a9d71ad6 100644
--- a/examples/dokk/level.py
+++ b/examples/dokk/level.py
@@ -4,24 +4,27 @@ from ligand import Ligand
 from surface import Surface
 from protein import Protein
 from score_updater import ScoreUpdater
+from config import Config
 
 class Level:
   def __init__(self, name):
     self.name_=name
     self.Load()
   def Load(self):
-    print 'Loading %s' % self.name_
     level_dir=os.path.join('datafiles', self.name_)
+    self.config = Config(os.path.join(level_dir, 'level.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.ligand=Ligand(ligand_ent,self.config)
     protein_ent=io.LoadPDB(os.path.join(level_dir, 'protein.pdb'))
     self.protein=Protein(protein_ent)
     surface=io.LoadSurface(os.path.join(level_dir, 'surface'), 'msms')
     self.surface=Surface(surface)
     self.surface.handle.Attach(self.protein.handle, 5.0)
-    gfx.Scene().SetCenter(self.ligand.GetCenter())
+    gfx.Scene().SetCenter(self.surface.go.GetCenter())
     print 'Done Loading'
     self.su = ScoreUpdater(self)
+    self.transform_ = gfx.Scene().GetTransform()
     
   def RotateAxis(self, axis, angle):
     self.ligand.RotateAxis(axis, angle)
@@ -40,3 +43,17 @@ class Level:
     
   def GetRMSD(self):
     return self.ligand.RMSDToSolution()
+
+  def Reset(self):
+    self.ligand.Reset()
+    gfx.Scene().SetTransform(self.transform_)
+    gfx.Scene().SetCenter(self.surface.go.GetCenter())
+    gfx.Scene().RequestRedraw()
+    self.su.UpdateScores()
+    
+  def Solve(self):
+    self.ligand.Solve()
+    gfx.Scene().SetTransform(self.transform_)
+    gfx.Scene().SetCenter(self.surface.go.GetCenter())
+    gfx.Scene().RequestRedraw()
+    self.su.UpdateScores()
\ No newline at end of file
diff --git a/examples/dokk/ligand.py b/examples/dokk/ligand.py
index 960ab06ad9a54ed9fadaf20862603213504b91b8..c37bb8859fe68fd832a7e2069868e93dbdcc1959 100644
--- a/examples/dokk/ligand.py
+++ b/examples/dokk/ligand.py
@@ -2,7 +2,7 @@ from ost import gfx, geom
 from ost.mol import alg
 from ost import mol
 class Ligand:
-  def __init__(self, ligand):
+  def __init__(self, ligand, config=None):
     self.handle=ligand
     self.the_solution_=ligand.Copy().CreateFullView()
     self.go=gfx.Entity("Ligand", gfx.CUSTOM, self.handle)
@@ -12,7 +12,16 @@ class Ligand:
     bbox=self.go.GetBoundingBox()
     self.radius=geom.Length(bbox.GetMax()-bbox.GetMin())+3.0
     self.pivot_=mol.AtomHandle()
-
+    self.start_tf_=geom.Mat4()
+    self.config = config
+    self.box_max = geom.Vec3(float(self.config.Box["XMAX"]),
+                            float(self.config.Box["YMAX"]),
+                            float(self.config.Box["ZMAX"]))
+    self.box_min = geom.Vec3(float(self.config.Box["XMIN"]),
+                            float(self.config.Box["YMIN"]),
+                            float(self.config.Box["ZMIN"]))
+    self.Reset()
+    
   def SetPivot(self, pivot):
     self.pivot_=pivot
 
@@ -34,11 +43,12 @@ class Ligand:
     self.go.UpdatePositions()
 
   def Shift(self, vec):
-    trans=geom.Mat4()
-    trans.PasteTranslation(vec)
-    edi=self.handle.RequestXCSEditor()    
-    edi.ApplyTransform(trans)
-    self.go.UpdatePositions()
+    if self.__IsInside(self.GetCenter()+vec):
+      trans=geom.Mat4()
+      trans.PasteTranslation(vec)
+      edi=self.handle.RequestXCSEditor()    
+      edi.ApplyTransform(trans)
+      self.go.UpdatePositions()
   
   def SetTF(self, tf):
     edi=self.handle.RequestXCSEditor()
@@ -49,7 +59,11 @@ class Ligand:
       center=self.pivot_.GetPos()
     trans.PasteTranslation(-center)
     trans2=geom.Mat4()
-    trans2.PasteTranslation(center+tf.GetTrans())
+    trans2_vec = center+((tf.GetTrans())*gfx.Scene().GetTransform().GetRot())
+    if self.__IsInside(trans2_vec):
+      trans2.PasteTranslation(trans2_vec)
+    else:
+      trans2.PasteTranslation(center)
     full_tf = trans2*rot*trans
     edi.ApplyTransform(full_tf)
     self.go.UpdatePositions()
@@ -62,3 +76,29 @@ class Ligand:
   def RMSDToSolution(self):
     return alg.CalculateRMSD(self.handle.CreateFullView(), 
                              self.the_solution_)
+
+  def Solve(self):
+    edi=self.handle.RequestXCSEditor()
+    edi.SetTransform(self.start_tf_)
+    self.go.UpdatePositions()
+    
+  def Reset(self):
+    if self.config is not None:
+      edi=self.handle.RequestXCSEditor()
+      shift_vec = geom.Vec3(float(self.config.start["POSX"]),
+                            float(self.config.start["POSY"]),
+                            float(self.config.start["POSZ"]))
+      transf = mol.Transform()
+      transf.SetTrans(shift_vec)
+      edi.SetTransform(transf.GetMatrix())
+      self.RotateAxis(geom.Vec3(1,0,0), float(self.config.start["ROTX"]))
+      self.RotateAxis(geom.Vec3(0,1,0), float(self.config.start["ROTY"]))
+      self.RotateAxis(geom.Vec3(0,0,1), float(self.config.start["ROTZ"]))
+      self.go.UpdatePositions()
+    
+  def __IsInside(self, vec):
+    if vec[0]< self.box_max[0] and vec[0]> self.box_min[0] and \
+     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
\ No newline at end of file
diff --git a/examples/dokk/score_updater.py b/examples/dokk/score_updater.py
index d33bcfcafb3d185cfe8dd09389ac7f8966c8553a..b968d35b980f2cc68c1c1513d4b14a09c94bd46a 100644
--- a/examples/dokk/score_updater.py
+++ b/examples/dokk/score_updater.py
@@ -6,27 +6,8 @@ class ScoreUpdater(QtCore.QObject):
   def __init__(self, level, parent=None):
     QtCore.QObject.__init__(self, parent)
     self.level = level
-    self.ut = UpdateThread(level)
-    self.ut.start()
 
 
-  def UpdateScores(self):
-    self.ut.UpdateScores()
-
-
-class UpdateThread(QtCore.QProcess):
-  def __init__(self,level,parent=None):
-    QtCore.QProcess.__init__(self,parent)
-    self.level = level
-    
-  def run ( self ):
-    i=0
-    while(True):
-      i+=1
-      print "UPDATE",i
-      self.UpdateScores()
-      self.sleep(2)
-
   def UpdateScores(self):
     ligand = self.level.ligand
     prot_within=self.level.protein.handle.FindWithin(ligand.GetCenter(), 
@@ -35,4 +16,4 @@ class UpdateThread(QtCore.QProcess):
     for a in prot_within:
       score=qa.ClashScore(a, lig_view)
       a.SetGenericFloatProperty('clash', score)
-    self.level.surface.go.ReapplyColorOps()    
\ No newline at end of file
+    self.level.surface.go.ReapplyColorOps()
diff --git a/examples/dokk/spnav_input.py b/examples/dokk/spnav_input.py
index f7c742e8f68d06cbc770c968e8f8f0658bfe0eb8..b62c889eadda74f5d95fc65444e58015232425b5 100644
--- a/examples/dokk/spnav_input.py
+++ b/examples/dokk/spnav_input.py
@@ -2,9 +2,12 @@ from PyQt4 import QtCore, QtGui
 
 from ost import mol, geom, gfx, gui
 
+DEFAULT_REFRESHRATE = 30
+
 class SpnavInputDevice(QtCore.QObject):
   def __init__(self, gfx_win, parent=None):
     QtCore.QObject.__init__(self, parent)
+    self.refresh_rate_ = DEFAULT_REFRESHRATE
     self.spnav = gui.SpnavInput.GetQThread()
     self.spnav.start()
     self.gfx_win = gfx_win
@@ -15,29 +18,49 @@ class SpnavInputDevice(QtCore.QObject):
     self.trans = True
     self.rot = True
 
+    self.score_scip = 0
   def SetLevel(self, level):
     self.level=level
+    try:
+      self.refresh_rate_ = int(level.config.Score["FRAMESKIP"])
+    except:
+      pass
 
-  def InputChanged(self, tx,ty,tz,rx,ry,rz): 
-    ligand = self.level.ligand
-    transf = mol.Transform()
-    if(self.trans):
-      transf.ApplyXAxisTranslation(tx/480.0)
-      transf.ApplyYAxisTranslation(ty/480.0)
-      transf.ApplyZAxisTranslation(-tz/480.0)
-    if(self.rot):
-      transf.ApplyXAxisRotation(rx/480.0)
-      transf.ApplyYAxisRotation(ry/480.0)
-      transf.ApplyZAxisRotation(rz/480.0)
-    ligand.SetTF(transf)
-    gfx.Scene().RequestRedraw()
-    self.gfx_win.update()
+  def InputChanged(self, tx,ty,tz,rx,ry,rz):
+    if self.level is not None:
+      ligand = self.level.ligand
+      transf = mol.Transform()
+      if(self.trans):
+        scene_rot = geom.Mat4(gfx.Scene().GetTransform().GetRot())
+        center = gfx.Scene().GetCenter()
+        delta = geom.Vec3 (tx/480.0, ty/480.0, -tz/480.0)
+        transf.SetTrans(delta)
+      if(self.rot):
+        transf.ApplyXAxisRotation(rx/480.0)
+        transf.ApplyYAxisRotation(ry/480.0)
+        transf.ApplyZAxisRotation(rz/480.0)
+      ligand.SetTF(transf)
+      if self.score_scip >= self.refresh_rate_:
+        self.level.UpdateScores()
+        self.score_scip = 0
+      self.score_scip += 1
+      gfx.Scene().RequestRedraw()
+      self.gfx_win.update()
 
   def ToggleInputMode(self, button):
+    print button
     if button == 0:
       self.trans = not self.trans
       print "Translation Enabled:",self.trans
     elif button == 1:
       self.rot = not self.rot
       print "Rotation Enabled:",self.rot
-
+    elif button == 6:
+      QtGui.QApplication.exit()
+    elif button == 10:
+      self.level.Reset()
+      self.gfx_win.update()
+    elif button == 11:
+      self.level.Solve()
+      self.gfx_win.update()
+    
diff --git a/examples/dokk/surface.py b/examples/dokk/surface.py
index 8b5a58a73352ebdb449dcb762e153248ec3fd069..7fdcf1ff4786de81f2c41922bb3147aa7590333e 100644
--- a/examples/dokk/surface.py
+++ b/examples/dokk/surface.py
@@ -10,4 +10,4 @@ class Surface:
     grad.SetColorAt(0.0, gfx.Color(1.0, 1.0, 1.0))
     grad.SetColorAt(0.7, gfx.Color(1.0, 1.0, 0.0))
     grad.SetColorAt(1.0, gfx.Color(1.0, 0.0, 0.0))    
-    self.go.ColorBy('clash', grad, 0.0, 10.0, mol.Prop.Level.ATOM)        
\ No newline at end of file
+    self.go.ColorBy('clash', grad, 0.0, 10.0, mol.Prop.Level.ATOM)