#!/usr/bin/python
#*******************************************************************************
#                                                                              *
#                                   Viewmol                                    *
#                                                                              *
#                       S E T A T O M C O L O R S . P Y                        *
#                                                                              *
#                 Copyright (c) Joerg-R. Hill, October 2003                    *
#                                                                              *
#*******************************************************************************
#
# $Id: setAtomColors.py,v 1.1 2003/11/07 13:20:04 jrh Exp $
# $Log: setAtomColors.py,v $
# Revision 1.1  2003/11/07 13:20:04  jrh
# Initial revision
#
#
import sys
import os
import shutil
import string
import tempfile
import gettext
import viewmol
from molecule import getAtoms
from atom import name
import element
try:
  from Tkinter import *
  from tkCommonDialog import Dialog 
  import tkMessageBox
except ImportError:
  viewmol.write('setAtomColors.py: Tkinter or one of its components not found.\nPlease install it before running this script again.\n')
  raise ImportError

try:
  dir=os.environ['VIEWMOLPATH']
except KeyError:
  dir='/usr/local/viewmol'

#catalog=gettext.translation('Viewmol', localedir=dir + '/locale', languages=['en_US'])
catalog=gettext.translation('Viewmol', localedir=dir + '/locale')
_ = catalog.gettext
def N_(message): return message

class setAtomColors:
  "Set atom colors"

  moduleName=_('Set atom colors') 
  canvas=[]
  elementOldColors={}
  elementColors={}
  window=0
  transperancyScale=None
  shininessScale=None
  selected=0

  def run(self):
    colors=[N_('Color'),
            N_('Emission'),
            N_('Ambient'),
            N_('Specular')]

    elements=[]
    for molecule in viewmol.getMolecules():
      for atom in molecule.getAtoms():
        element=atom.getElement()
        name=element.getSymbol()
        if elements.count(name) == 0:
          elements.append(name)
          color1=element.darkColor()
          color2=element.lightColor()
          atomColor="#%02x%02x%02x" % (127.5*(color1[0]+color2[0]), 127.5*(color1[1]+color2[1]), 127.5*(color1[2]+color2[2]))
          color=element.emissionColor()
          emissionColor="#%02x%02x%02x" % (255.0*color[0], 255.0*color[1], 255.0*color[2])
          color=element.ambientColor()
          ambientColor="#%02x%02x%02x" % (255.0*color[0], 255.0*color[1], 255.0*color[2])
          color=element.specularColor()
          specularColor="#%02x%02x%02x" % (255.0*color[0], 255.0*color[1], 255.0*color[2])
          shininess=element.shininess()
          transperancy=element.transperancy()
          self.elementColors[name]=(element, atomColor, emissionColor, ambientColor, specularColor, shininess, transperancy)
          self.elementOldColors[name]=(element, atomColor, emissionColor, ambientColor, specularColor, shininess, transperancy)
    if elements == []:
      return None
  
    self.window=Tk()
    try:
      import Pmw
    except ImportError:
      tkMessageBox.showerror(_('Module Missing'), _('Module Pmw (Python Mega Widgets) not found. Please install it before running this script again. It can be found at http://pmw.sourceforge.net/.'))
      self.window.destroy()
    else:
      Pmw.initialise(self.window)
      row=Frame(self.window)
      selectElement=Pmw.OptionMenu(row, labelpos="w", label_text=_('Select element'),
                                   items=elements, command=self.displayElement)
      selectElement.pack(expand=1, fill=X)
      row.pack()
  
      self.canvas={}
      frame=Frame(self.window)
      i=0
      for t in colors:
        self.canvas[_(t) + " ..."]=Canvas(frame, height="32", width="64")
        self.canvas[_(t) + " ..."].grid(row=i, column=0, sticky=E+W+N+S)
        button=Button(frame, text=_(t) + " ...")
        button.bind("<Button>", self.setColor)
        button.grid(row=i, column=1, sticky=E+W+N+S)
        i=i+1
      label1=Label(frame, text=_('Transperancy')+" [%]")
      label1.grid(row=i, column=0, sticky=E+W+N+S)
      self.transperancyScale=Scale(frame, orient=HORIZONTAL, to=100, resolution=1, command=self.applyScale)
      self.transperancyScale.grid(row=i, column=1, sticky=E+W+N+S)
      i=i+1
      label2=Label(frame, text=_('Shininess')+" [%]")
      label2.grid(row=i, column=0, sticky=E+W+N+S)
      self.shininessScale=Scale(frame, orient=HORIZONTAL, to=100, command=self.applyScale)
      self.shininessScale.grid(row=i, column=1, sticky=E+W+N+S)
      i=i+1
      self.displayElement(elements[0])
 
      commandButtons=Frame(frame)
      button=Button(commandButtons)
      button["text"]=_('Confirm')
      button["command"]=self.confirm
      button.pack(side=LEFT, expand=1)
      button=Button(commandButtons)
      button["text"]=_('Confirm and Save')
      button["command"]=self.saveColors
      button.pack(side=LEFT, expand=1)
      button=Button(commandButtons)
      button["text"]=_('Cancel')
      button.bind("<Button>", self.cancel)
      button.pack(side=LEFT, expand=1)
      commandButtons.grid(row=i, column=0, columnspan=2)
      frame.pack(expand=1, fill=BOTH)
      self.window.after(200, self.redraw)
      self.window.title(_('Set Atom Colors'))
      self.window.mainloop()

  def displayElement(self, which):
    self.canvas[_('Color') + " ..."]["background"]=self.elementColors[which][1]
    self.canvas[_('Emission') + " ..."]["background"]=self.elementColors[which][2]
    self.canvas[_('Ambient') + " ..."]["background"]=self.elementColors[which][3]
    self.canvas[_('Specular') + " ..."]["background"]=self.elementColors[which][4]
    self.shininessScale.set(self.elementColors[which][5]/1.28)
    self.transperancyScale.set(100.0*(1.0-self.elementColors[which][6]))
    self.selected=which

  def setColor(self, event):
    color=self.canvas[event.widget["text"]]["background"]
    colorChooser=Chooser()
    self.canvas[event.widget["text"]]["background"]=colorChooser.askcolor(color)
    self.applyColor()

  def applyScale(self, event):
    self.applyColor()

  def applyColor(self):
    element=self.elementColors[self.selected][0]
    atomColor=self.canvas[_('Color') + " ..."]["background"]
    element.darkColor(eval("0x" + atomColor[1:3])/255., eval("0x" + atomColor[3:5])/255.,
                      eval("0x" + atomColor[5:7])/255.)
    element.lightColor(eval("0x" + atomColor[1:3])/255., eval("0x" + atomColor[3:5])/255.,
                       eval("0x" + atomColor[5:7])/255.)
    emissionColor=self.canvas[_('Emission') + " ..."]["background"]
    element.emissionColor(eval("0x" + emissionColor[1:3])/255., eval("0x" + emissionColor[3:5])/255.,
                          eval("0x" + emissionColor[5:7])/255.)
    ambientColor=self.canvas[_('Ambient') + " ..."]["background"]
    element.ambientColor(eval("0x" + ambientColor[1:3])/255., eval("0x" + ambientColor[3:5])/255.,
                         eval("0x" + ambientColor[5:7])/255.)
    specularColor=self.canvas[_('Specular') + " ..."]["background"]
    element.specularColor(eval("0x" + specularColor[1:3])/255., eval("0x" + specularColor[3:5])/255.,
                          eval("0x" + specularColor[5:7])/255.)
    shininess=1.28*self.shininessScale.get()
    transperancy=1.0-0.01*self.transperancyScale.get()
    self.elementColors[self.selected]=(element, atomColor, emissionColor, ambientColor, specularColor, shininess,
                                       transperancy)
    element.shininess(shininess)
    element.transperancy(transperancy)

  def confirm(self):
    self.window.quit()
    self.window.destroy()
  
  def saveColors(self):
    fileNames=self.findRcFile()
    if fileNames == None:
      tkMessageBox.showerror(_('Resource File Not Found'), _('The resource file, viewmolrc, cannot be found. Saving is not possible.'))
      return None
    infile=open(fileNames[0], "r")
    tmpFile=tempfile.mktemp()
    outfile=open(tmpFile, "w")
    for line in infile.readlines():
      element=None
      for i in self.elementColors.keys():
        name=string.lower(i) + ' '
        if name[0:2] == line[0:2]:
          element=self.elementColors[i][0]
          break
      if element != None:
        words=string.split(line)
        darkColor=element.darkColor()
        lightColor=element.lightColor()
        newline="%s  %s  %.2f %.2f %.2f   %.2f %.2f %.2f" % (words[0], words[1], darkColor[0], darkColor[1], darkColor[2],
                 lightColor[0], lightColor[1], lightColor[2])
        outfile.write(newline)
        emissionColor=element.emissionColor()
        if emissionColor[0] != 0.0 or emissionColor[1] != 0.0 or emissionColor[2] != 0.0:
          newline=" em %.2f %.2f %.2f" % (emissionColor[0], emissionColor[1], emissionColor[2])
          outfile.write(newline)
        ambientColor=element.ambientColor()
        if ambientColor[0] != darkColor[0] or ambientColor[1] != darkColor[1] or ambientColor[2] != darkColor[2]:
          newline=" am %.2f %.2f %.2f" % (ambientColor[0], ambientColor[1], ambientColor[2])
          outfile.write(newline)
        specularColor=element.specularColor()
        if specularColor[0] != 1.0 or specularColor[1] != 1.0 or specularColor[2] != 1.0:
          newline=" sp %.2f %.2f %.2f" % (specularColor[0], specularColor[1], specularColor[2])
          outfile.write(newline)
        shininess=element.shininess()
        if shininess != 128.0:
          newline=" sh %.2f" % shininess
          outfile.write(newline)
        transperancy=element.transperancy()
        if transperancy != 1.0:
          newline=" tr %.2f" % transperancy
          outfile.write(newline)
        outfile.write("\n")
      else:
        outfile.write(line)
    infile.close()
    outfile.close()
    if fileNames[1] == None:
      shutil.copyfile(tmpFile, fileNames[0])
    else:
      shutil.copyfile(tmpFile, fileNames[1])
    os.remove(tmpFile)
    self.window.quit()
    self.window.destroy()

  def findRcFile(self):
    file=os.getcwd() + os.sep + "viewmolrc"
    if os.path.isfile(file):
      return(file, None)
    file=os.environ['HOME'] + os.sep + ".viewmolrc"
    if os.path.isfile(file):
      return(file, None)
    file=os.environ['VIEWMOLPATH'] + os.sep + "viewmolrc"
    if os.path.isfile(file):
      return(file, os.environ['HOME'] + os.sep + ".viewmolrc")
    return(None)

  def cancel(self, event):
    for i in self.elementOldColors.keys():
      element=self.elementOldColors[i][0]
      element.darkColor(eval("0x" + self.elementOldColors[i][1][1:3])/255., eval("0x" + self.elementOldColors[i][1][3:5])/255.,
                        eval("0x" + self.elementOldColors[i][1][5:7])/255.)
      element.lightColor(eval("0x" + self.elementOldColors[i][1][1:3])/255., eval("0x" + self.elementOldColors[i][1][3:5])/255.,
                         eval("0x" + self.elementOldColors[i][1][5:7])/255.)
      element.emissionColor(eval("0x" + self.elementOldColors[i][2][1:3])/255., eval("0x" + self.elementOldColors[i][2][3:5])/255.,
                            eval("0x" + self.elementOldColors[i][2][5:7])/255.)
      element.ambientColor(eval("0x" + self.elementOldColors[i][3][1:3])/255., eval("0x" + self.elementOldColors[i][3][3:5])/255.,
                           eval("0x" + self.elementOldColors[i][3][5:7])/255.)
      element.specularColor(eval("0x" + self.elementOldColors[i][4][1:3])/255., eval("0x" + self.elementOldColors[i][4][3:5])/255.,
                            eval("0x" + self.elementOldColors[i][4][5:7])/255.)
      element.shininess(self.elementOldColors[i][5])
      element.transperancy(self.elementOldColors[i][6])
    self.window.quit()
    self.window.destroy()

  def redraw(self):
    viewmol.redraw()
    self.window.after(200, self.redraw)

  def register(self, language):
    viewmol.registerMenuItem(self.moduleName)
  
class Chooser(Dialog):
  "Ask for a color"
 
  command = "tk_chooseColor"

  def _fixoptions(self):
    try:
      # make sure initialcolor is a tk color string
      color = self.options["initialcolor"]
      if type(color) == type(()):
        # assume an RGB triplet
        self.options["initialcolor"] = "#%02x%02x%02x" % color
    except KeyError:
      pass

  def _fixresult(self, widget, result):
    if not result:
      return None # cancelled
    return result

  def askcolor(self, color = None, **options):
    "Ask for a color"
 
    if color:
      options = options.copy()
      options["initialcolor"] = color

    return apply(Chooser, (), options).show()

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