"""
     qtgui/annotationGui.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2011 University of York

     This library is free software: you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public License
     version 3, modified in accordance with the provisions of the 
     license to address the requirements of UK law.
 
     You should have received a copy of the modified GNU Lesser General 
     Public License along with this library.  If not, copies may be 
     downloaded from http://www.ccp4.ac.uk/ccp4license.php
 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU Lesser General Public License for more details.
"""
from PyQt4 import QtCore, QtGui
import mgWidgets,MGSimpleDialog
from global_definitions import *

#------------------------------------------------------------------------
#------------------------------------------------------------------------
#------------------------------------------------------------------------
class autoAnnotate(QtCore.QObject):
#------------------------------------------------------------------------
#------------------------------------------------------------------------
#------------------------------------------------------------------------

  def __init__(self):
    QtCore.QObject.__init__(self)
    self.move_annotation = 1
    self.gui = None
    self.connect(MAINWINDOW(),QtCore.SIGNAL('atomContextMenu'),self.handleAtomPick)

#------------------------------------------------------------------------
  def handleAtomPick(self,pickevent=None):
#------------------------------------------------------------------------
    if not pickevent: return
    menu = pickevent.getContextMenu()
    if not menu: return
    import guiUtils
    guiUtils.populateMenu(self,menu,['add_annotation'],self.getActionDef,info = { 'pickevent' : pickevent } )

#------------------------------------------------------------------------
  def getActionDef(self,name='',pickevent=None,info={}):
#------------------------------------------------------------------------
    #pickevent=info.get('pickevent','')
    if not pickevent: return
    if name == 'add_annotation':
      obj = pickevent.getDataObj()
      if obj:
        return dict ( text = 'Add annotation',
                    tip = 'Add a text object by this atom',
                    slot = [self.drawGui,(obj.name,pickevent.getLabel(format='full'))],
                    deleteLater = 1
            )

#------------------------------------------------------------------------
  def drawGui(self,args):
#------------------------------------------------------------------------
    #print 'autoAnnotate.drawGui',args
    modelName,atomName = args
    if self.gui:
      try:
        self.gui.close()
      except:
        # This can happen if Escape has been used to close the gui
        pass
      self.gui = None

    self.gui = autoAnnotateGui(MAINWINDOW(),atomName=atomName,modelName=modelName)
    self.connect(self.gui.apply_button,QtCore.SIGNAL('clicked()'),self.add_annotation)
    
#------------------------------------------------------------------------
  def add_annotation(self):
#------------------------------------------------------------------------

    selection = self.gui.pickerWidget.modelNameAtomName()
    if not selection: return
    modelName,atomName = selection
    annotation = str(self.gui.labelWidget.text())
    
    import Annotation
    font = FONTMANAGER().getHtmlFont('annotation')
    annie = Annotation.Annotation(modelName,visible=1,
         params= {'text' :  '<span '+font+'>'+annotation+'</span>',
                 'atom_position' : atomName } )
    gobj = DISPLAYTABLE().addDispObj(parent_name=modelName,object_type='Annotation',name=annie.name)
    #print 'add_annotation gobj',gobj
    if gobj and self.move_annotation: gobj.toggleMoving(1)
    import rebuild
    rebuild.UpdateDisplay()
    self.gui.Close()
    self.gui = None
  
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
class autoAnnotateGui(MGSimpleDialog.MGSimpleDialog):
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

  def __init__(self,parent=None,modelName='',atomName=''):
    #print 'autoAnnotateGui',modelName,atomName
    MGSimpleDialog.MGSimpleDialog.__init__(self,parent)
    self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    self.setWindowTitle('Add annotation to '+modelName)
    layout = QtGui.QVBoxLayout()
    
    layout.addWidget(QtGui.QLabel('Place annotation by atom or residue..',self))
    self.pickerWidget = mgWidgets.mgAtomPicker(self)
    layout.addWidget(self.pickerWidget)
    self.pickerWidget.setSelection(modelName=modelName,atomName=atomName)

    layout.addWidget(QtGui.QLabel('Annotation format..',self))
    self.formatWidget = annotateFormatWidget(self)
    self.formatWidget.setFormat(PM('annotation_format').get('format'))
    layout.addWidget(self.formatWidget)
    for widget in self.formatWidget.widgets:
      self.connect(widget.label,QtCore.SIGNAL('currentIndexChanged(const QString&)'),self.updateLabel)
      self.connect(widget.spacer,QtCore.SIGNAL('currentIndexChanged(const QString&)'),self.updateLabel)
      self.connect(widget.spacer,QtCore.SIGNAL('editTextChanged(const QString&)'),self.updateLabel)

    import TextEdit
    self.labelWidget = TextEdit.TextEditWidget(self)
    layout.addWidget(self.labelWidget)
    self.labelWidget.setCurrentFont(definition=FONTMANAGER().getFont('annotation'),setGuiFont=True)
    self.labelWidget.setText(QtCore.QString(self.makeLabel()))

    dialog_buttons = QtGui.QDialogButtonBox()
    # 'Enter' or 'return' key anywhere in the dialog box seems to fire
    # the ok button and exit the dialog box. Remove ok button for now
    #ok_button = dialog_buttons.addButton(QtGui.QDialogButtonBox.Ok)
    self.apply_button = dialog_buttons.addButton(QtGui.QDialogButtonBox.Apply)
    cancel_button = dialog_buttons.addButton(QtGui.QDialogButtonBox.Cancel)
    self.connect(cancel_button,QtCore.SIGNAL('clicked()'),self.Close)
    layout.addWidget(dialog_buttons)

    self.setLayout(layout)
    self.show()

#-------------------------------------------------------------------------
  def updateLabel(self,string):
#-------------------------------------------------------------------------
    self.labelWidget.setText(QtCore.QString(self.makeLabel()))
    PM('annotation_format').setparams(do_rebuild=0,format=self.formatWidget.getFormat())

#-------------------------------------------------------------------------
  def makeLabel(self,force=0):
#-------------------------------------------------------------------------
    import string
    format = self.formatWidget.getFormat()
    # Does this label require an atom selected or will a residue do?
    # (Possible could just be chain but lets not bother with that)
    ifatom = 0
    for item in format:
      if annotateFormatWidget.label_menu[6:].count(item[1]):
        ifatom = 1
        break
    #print 'makeLabel',ifatom
    sele = self.pickerWidget.modelNameAtomName()
    pAtom = None
    if sele:
      molobj = data(sele[0])
      if molobj:
        if ifatom:
          pAtom = molobj.interpretAtomID(mol=molobj,atom_name=sele[1],force_one_atom=1)
        else:
          # This will really be a residue pointer
          nselres,pAtom = molobj.interpretResidueID(sele[1],'first')
    if not pAtom:
      return ''

    label = ''
    for spacer,item in format:
      label = label + spacer
      indx = annotateFormatWidget.label_menu.index(item)
      if indx == 1:
        label = label + str(pAtom.GetModelNum())
      elif indx == 2:
        label = label + pAtom.GetChainID()
      elif indx == 3:
        resn =  string.strip(pAtom.GetResName())
        label = label + resn[0] + string.lower(resn[1:]) 
      elif indx == 4:
        label = label + pAtom.GetResName()
      elif indx == 5:
        import selection_protocols
        label = label + selection_protocols.amino_acid_code.get(string.strip(str(pAtom.GetResName())),'X')
      elif indx == 6:
        label = label + str(pAtom.GetSeqNum())
        inscode = pAtom.GetInsCode()
        if inscode: label = label+','+inscode
      elif indx == 7:
        label = label + pAtom.name
        if pAtom.GetAltLoc():label = label +';'+ pAtom.GetAltLoc() 
      elif indx == 8:
        label = label + pAtom.GetElementName()
    return label



#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
class annotateFormatWidget0(QtGui.QWidget):
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

  
  def __init__(self,parent=None):
    QtGui.QWidget.__init__(self,parent)
    layout = QtGui.QHBoxLayout(self)
    layout.setSpacing(0)
    layout.setContentsMargins(0,0,0,0)
    self.spacer =  QtGui.QComboBox(self)
    self.spacer.setEditable(1)
    
    
    for item in annotateFormatWidget.spacer_menu:
      self.spacer.addItem(item)

    self.label = QtGui.QComboBox(self)
    self.label.setEditable(0)
    for item in annotateFormatWidget.label_menu:
      self.label.addItem(item)
    self.label.setFixedWidth(annotateFormatWidget.w1)
    self.spacer.setFixedWidth(annotateFormatWidget.w2)

    layout.addWidget(self.spacer)
    layout.addWidget(self.label)
    self.setLayout(layout)
    self.show()

  def setLabel(self,label=''):
    if annotateFormatWidget.label_menu.count(label):
      self.label.setCurrentIndex(annotateFormatWidget.label_menu.index(label))

  def setSpacer(self,spacer=999):
    if spacer != 999 and len(spacer)<=3:
      self.spacer.setEditText(spacer)

  def getLabel(self):
    return annotateFormatWidget.label_menu[self.label.currentIndex()]
    
  def getSpacer(self):
    return str(self.spacer.currentText())

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
class annotateFormatWidget(QtGui.QFrame):
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------

  #initial =  [['','Res name'],[' ','Chain id'],['','Seq #']]
  #                   1          2           3         4          5        6          7       8
  label_menu = ['','Model #','Chain id','Res name','RES name','R name','Seq #','Atom name','Element']
  spacer_menu = ['',' ','/','\\','-',',',';',':','.','(',')','[',']']
  w1 = 0
  w2 = 0

  def __init__(self,parent):
    QtGui.QFrame.__init__(self,parent)
    self.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Plain)
    layout = QtGui.QHBoxLayout()
    layout.setSpacing(0)
    layout.setContentsMargins(0,0,0,0)
    #print 'annotateFormatWidget',self.fontMetrics().width('Atom name'),self.fontMetrics().width('Atom')
    if not annotateFormatWidget.w1: annotateFormatWidget.w1=self.fontMetrics().width('Atom name')+30
    if not annotateFormatWidget.w2: annotateFormatWidget.w2=self.fontMetrics().width('ww')+30
    self.widgets = []

    for ii in range(0,6):
      self.widgets.append(annotateFormatWidget0())
      layout.addWidget(self.widgets[-1])

    self.setLayout(layout)


  def setFormat(self,format = []):
    for ww in range(min(len(self.widgets),len(format))):
      self.widgets[ww].setSpacer(format[ww][0])
      self.widgets[ww].setLabel(format[ww][1])

  def getFormat(self):
    output = []
    for ww in self.widgets:
      if ww.getLabel() or ww.getSpacer():
        output.append([ww.getSpacer(),ww.getLabel()])

    return output

