#!/usr/bin/python
#*******************************************************************************
#                                                                              *
#                                   Viewmol                                    *
#                                                                              *
#                                 D E M O . P Y                                *
#                                                                              *
#                 Copyright (c) Joerg-R. Hill, October 2003                    *
#                                                                              *
#*******************************************************************************
#
# $Id: demo.py,v 1.2 2003/11/07 13:19:53 jrh Exp $
# $Log: demo.py,v $
# Revision 1.2  2003/11/07 13:19:53  jrh
# Release 2.4
#
# Revision 1.1  2000/12/10 15:04:03  jrh
# Initial revision
#
#
import os
import viewmol
import molecule
import spectrum
import atom
import element
import energylevels
import history
import label
import light

ON=viewmol.__dict__['ON']
OFF=viewmol.__dict__['OFF']
WIREMODEL=viewmol.__dict__['WIREMODEL']
STICKMODEL=viewmol.__dict__['STICKMODEL']
BALLMODEL=viewmol.__dict__['BALLMODEL']
CPKMODEL=viewmol.__dict__['CPKMODEL']
PERSPECTIVE=viewmol.__dict__['PERSPECTIVE']
LINE=viewmol.__dict__['LINE']
SURFACE=viewmol.__dict__['SURFACE']
ORTHO=viewmol.__dict__['ORTHO']
MO=molecule.__dict__['MO']
DENSITY=molecule.__dict__['DENSITY']
IP_LOG=molecule.__dict__['IP_LOG']
REACTANT=molecule.__dict__['REACTANT']
PRODUCT=molecule.__dict__['PRODUCT']
REACTION=viewmol.__dict__['REACTION']
ANIMATE=spectrum.__dict__['ANIMATE']
ARROWS=spectrum.__dict__['ARROWS']
GAUSSIANS=spectrum.__dict__['GAUSSIANS']

class demo:
  def rotate(self, mol, axis, speed):
    n=0
    fps=viewmol.getFramesPerSecond()
    if fps>50.0:
      increment=2*speed
    else:
      increment=5*speed
    while n<180:
      mol.rotate(n*axis[0], n*axis[1], n*axis[2])
      viewmol.redraw()
      n=n+increment

  def translate(self, mol, direction):
    n=0.0
    while n<10.0:
      mol.translate(n*direction[0], n*direction[1], n*direction[2])
      viewmol.redraw()
      n=n+0.5

  def drawingModes(self, molecule):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-20, 0)
    label1.text('Viewmol supports different representations')
    label2=label.label()
    label2.translate(20, size[1]-40, 0)
    label2.text('such as wire frame models ...')
    viewmol.model(WIREMODEL)
    self.rotate(molecule, (1.0, 0.0, 0.0), 1.0)
    label2.text('... stick models ...')
    viewmol.model(STICKMODEL)
    self.rotate(molecule, (0.0, 1.0, 1.0), 1.0)
    label2.text('... ball-and-stick models ...')
    viewmol.model(BALLMODEL)
    self.rotate(molecule, (0.0, 0.0, 1.0), 1.0)
    label2.text('... or CPK models.')
    viewmol.model(CPKMODEL)
    self.rotate(molecule, (1.0, 1.0, 0.0), 1.0)
    label2.delete()
    label1.text('There is also a perspective mode.')
    viewmol.projection(PERSPECTIVE)
    self.rotate(molecule, (0.0, 1.0, 1.0), 10.0)
    label1.text('And you can turn lights on and off and move them.')
    lights=viewmol.getLights()
    lights[0].switch(OFF)
    self.rotate(lights[1], (0.0, 1.0, 0.0), 10.0)
    lights[1].rotate(0, 0, 0)
    lights[0].switch(ON)
    label1.text('You can also change drawing style and resolution.')
    viewmol.drawingMode(LINE)
    n=10
    while n<30:
      viewmol.sphereResolution(n)
      viewmol.redraw()
      n=n+4
    viewmol.drawingMode(SURFACE)
    viewmol.sphereResolution(20)
    label1.delete()
    viewmol.projection(ORTHO)
    viewmol.model(WIREMODEL)

  def vibrations(self, molecule):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-20, 0)
    label1.text('Viewmol can also show vibrational spectra.')
    viewmol.model(STICKMODEL)
    spectrum1=molecule.getSpectrum()
    spectrum1.show()
    spectrum1.mode(27)
    spectrum1.display(ANIMATE)
    self.rotate(molecule, (1.0, 0.0, 1.0), 1.0)
    label1.text('Of course, it doesn\'t have to be animated.')
    spectrum1.display(ARROWS)
    spectrum1.style(GAUSSIANS)
    self.rotate(molecule, (0.0, 1.0, 0.0), 1.0)
    spectrum1.deselect()
    del spectrum1
    label1.delete()

  def MOs(self, molecule):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-50, 0)
    label1.text('Viewmol can show energy levels and MOs ...')
    energylevel1=molecule.getEnergyLevels()
    energylevel1.show()
    energylevel1.selectMO(21)
    viewmol.isosurface(0.05)
    molecule.showElectrons(MO, 20, IP_LOG)
    self.rotate(molecule, (1.0, 1.0, 1.0), 1.0)
    label1.text('... or the electron density.')
    del energylevel1
    molecule.showElectrons(DENSITY, 20, IP_LOG)
    self.rotate(molecule, (0.0, 1.0, 1.0), 1.0)
    n=0.05
    while n>0.001:
      viewmol.isosurface(n)
      viewmol.redraw()
      n=n-0.001
    molecule.showElectrons(OFF)
    label1.delete()

  def history(self, molecule):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-20, 0)
    label1.text('Viewmol can show the history of an optimization.')
    history1=molecule.getHistory()
    history1.show()
    molecule.showForces(ON)
    n=1
    while n < 9:
      history1.iteration(n)
      viewmol.redraw()
      n=n+1
    molecule.showForces(OFF)
    del history1
    label1.delete()

  def buildMolecule(self, molecule1):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-20, 0)
    label1.text('Viewmol can also be used to build molecules.')
    viewmol.model(STICKMODEL)
    atoms=molecule1.getAtoms()
    atoms[11].replace('C')
    viewmol.redraw()
    molecule1.addAtom('H', atoms[11])
    molecule1.addAtom('C', atoms[11])
    viewmol.redraw()
    molecule1.addAtom('C', atoms[11])
    viewmol.redraw()
    del atoms
    atoms=molecule1.getAtoms()
    molecule1.addAtom('O', atoms[14])
    viewmol.redraw()
    molecule1.addAtom('N', atoms[14])
    viewmol.redraw()
    del atoms
    atoms=molecule1.getAtoms()
    molecule1.addAtom('H', atoms[16])
    molecule1.addAtom('H', atoms[16])
    viewmol.redraw()
    molecule1.addAtom('H', atoms[13])
    molecule1.addAtom('H', atoms[13])
    self.rotate(molecule1, (0.0, 1.0, 0.0), 1.0)
    del atoms
    label1.delete()

  def thermodynamics(self):
    size=viewmol.getWindowSize()
    label1=label.label()
    label1.translate(20, size[1]-20, 0)
    label1.text('Viewmol can handle reaction thermodynamics.')
    viewmol.showWarnings(OFF)
    viewmolpath=os.getenv("VIEWMOLPATH")
    molecule1=viewmol.load(viewmolpath + '/examples/reaction/hio3.outmol')
    molecule1.reaction(PRODUCT)
    text='Lets load a number of molecules: ' + molecule1.title()
    label2=label.label()
    label2.translate(20, 40, 0)
    label2.text(text)
    self.translate(molecule1, (-1.0, 1.0, 0.0))
    molecule2=viewmol.load(viewmolpath + '/examples/reaction/i2.outmol')
    molecule2.reaction(REACTANT)
    molecule2.rotate(90.0, 0.0, 0.0)
    text=text + ', ' + molecule2.title()
    label2.text(text)
    self.translate(molecule2, (1.0, 1.0, 0.0))
    molecule3=viewmol.load(viewmolpath + '/examples/reaction/hno3.outmol')
    molecule3.reaction(REACTANT)
    text=text + ', ' + molecule3.title()
    label2.text(text)
    self.translate(molecule3, (-1.0, -1.0, 0.0))
    molecule4=viewmol.load(viewmolpath + '/examples/reaction/no.outmol')
    molecule4.reaction(PRODUCT)
    text=text + ', ' + molecule4.title()
    label2.text(text)
    molecule4.rotate(90.0, 0.0, 0.0)
    self.translate(molecule4, (1.0, -1.0, 0.0))
    molecule5=viewmol.load(viewmolpath + '/examples/reaction/h2o.outmol')
    molecule5.reaction(PRODUCT)
    text=text + ', ' + molecule5.title()
    label2.text(text)
    viewmol.showThermodynamics(REACTION)

  def run(self):
    viewmolpath=os.getenv("VIEWMOLPATH")
    molecule1=viewmol.load(viewmolpath + '/examples/turbomole/control')
    self.drawingModes(molecule1)
    self.vibrations(molecule1)
    self.MOs(molecule1)
    self.history(molecule1)
    self.buildMolecule(molecule1)
    viewmol.delete(molecule1)
    self.thermodynamics()

  def register(self, language):
    viewmol.registerMenuItem("Demonstration")

#-------------------------
if __name__ == '__main__':
  demonstration=demo()
  demo.run(demonstration)
