from PyQt4 import QtGui,QtCore

from CCP4TaskWidget import CTaskWidget
from CCP4ErrorHandling import *
import functools

#-------------------------------------------------------------------
class matthews_gui(CTaskWidget):
#-------------------------------------------------------------------
    
    # Subclass CTaskWidget to give specific task window
    TASKNAME = 'matthews'
    TASKVERSION = 0.1
    TASKMODULE=[ 'data_reduction', 'expt_data_utility' ]
    TASKTITLE='Estimate cell content'
    EDITOR = True  
    DESCRIPTION='''Estimate number of molecules in the asymmetric unit and solvent content (Matthews_coeff)'''
    RANK = 2
    MAINTAINER = 'liz.potterton@york.ac.uk'
    
    def drawContents(self):
        
        self.openFolder(folderFunction='inputData',followFrom=False)
        self.createLine( ['subtitle' , 'Cell parameters taken from reflection data', 'Select a reflection file containing the cell parameters' ] )
        self.openSubFrame(frame=[True])
        self.createLine( [ 'widget', 'HKLIN' ] )
        self.closeSubFrame()

        self.createLine( ['subtitle' , 'Calculate molecular weight from..','Define the contents of the crystal cell'] )
        self.openSubFrame(frame=[True])
        self.group = QtGui.QButtonGroup(self)
        
        widget = QtGui.QRadioButton('.. the sequence composition',self)
        widget.setToolTip('Enter sequence to define cell content')
        widget.setChecked(True)
        self.group.addButton(widget,1)
        line = self.createLine()
        line.layout().addWidget(widget)
        self.createLine ( [ 'widget', '-title','Contents of biological unit  - click "Show list" if more than one type of chain is present', 'ASU_COMPONENTS' ] )
        #self.createLine( [ 'widget', 'SEQIN' ] )
        self.connect(self.container.inputData.ASU_COMPONENTS,QtCore.SIGNAL('dataChanged'),functools.partial(self.updateMode,'asu_components'))
        self.connect(widget,QtCore.SIGNAL('released()'),self.runAnalysis)
        
        widget = QtGui.QRadioButton('.. number of residues',self)
        widget.setToolTip('Enter number of residues to define cell content')
        self.group.addButton(widget,2)
        line = self.createLine( ['tip','Number of residues','widget', 'NRES' ] )
        line.layout().insertWidget(0,widget)
        self.connect(self.container.inputData.NRES,QtCore.SIGNAL('dataChanged'),functools.partial(self.updateMode,'nres'))
        self.connect(widget,QtCore.SIGNAL('released()'),self.runAnalysis)
        
        widget = QtGui.QRadioButton('.. molecular weight',self)
        widget.setToolTip('Enter molecular weight to define cell content')
        line = self.createLine( ['tip','Molecular weight','widget', 'MOLWT' ] )
        self.group.addButton(widget,3)
        line.layout().insertWidget(0,widget)
        self.connect(self.container.inputData.MOLWT,QtCore.SIGNAL('dataChanged'),functools.partial(self.updateMode,'molwt'))
        self.connect(widget,QtCore.SIGNAL('released()'),self.runAnalysis)
        self.closeSubFrame()

        self.createLine( ['Results will be shown here','subtitle' , 'The expected number of molecules in cell','Result will be shown here after data entered above'] )
        self.openSubFrame(frame=[True])
        self.resultWidget = QtGui.QTextEdit(self)
        self.resultWidget.setReadOnly(True)
        self.resultWidget.setToolTip('Results will be shown here')
        self.widget.currentFolderLayout.addWidget(self.resultWidget)
        self.closeSubFrame()
        
        self.connect(self.container.inputData.HKLIN,QtCore.SIGNAL('dataChanged'),self.runAnalysis)
        self.connect(self.container.inputData.ASU_COMPONENTS,QtCore.SIGNAL('dataChanged'),self.runAnalysis)
        self.connect(self.group,QtCore.SIGNAL('buttonClicked(int)'),self.handleModeChange)

        self.runAnalysis()

    def handleModeChange(self,mode):
      if mode == 1:
        listMinLength = 1
        allowUndefined = False
      else:
        listMinLength = 0
        allowUndefined = True
      self.container.inputData.ASU_COMPONENTS.setQualifiers({'listMinLength':listMinLength})
      for n in range(len(self.container.inputData.ASU_COMPONENTS)):
        self.container.inputData.ASU_COMPONENTS[n].seqFile.setQualifiers({'allowUndefined':allowUndefined })
      self.getWidget('ASU_COMPONENTS').validate()
        
    def updateMode(self,mode):
      #print 'matthews_gui.updateMode',mode
      if self.container.inputData.get(mode.upper()).isSet():
         self.container.inputData.MODE = mode
         self.group.button(self.container.inputData.MODE.qualifiers('enumerators').index(mode)+1).setChecked(True)
         self.runAnalysis()
         
    def runAnalysis(self):
       if not self.isEditable(): return
       self.container.inputData.MODE = self.container.inputData.MODE.qualifiers('enumerators')[self.group.checkedId()-1]
       #print 'runAnalysis',self.container.inputData.MODE,self.container.inputData.ASU_COMPONENTS.isSet()
       if self.container.inputData.MODE == 'asu_components' and not self.container.inputData.ASU_COMPONENTS.isSet():
          self.resultWidget.clear()
          return
       elif self.container.inputData.MODE == 'molwt' and not self.container.inputData.MOLWT.isSet():
          self.resultWidget.clear()
          return
       elif self.container.inputData.MODE == 'nres' and not self.container.inputData.NRES.isSet():
          self.resultWidget.clear()
          return

       if not  self.container.inputData.HKLIN.isSet():
        self.resultWidget.clear()
        return
       #print 'matthews.runAnalysis mode',self.container.inputData.MODE
       
       text = '<html><body>'
       if self.container.inputData.MODE == 'asu_components':
         text = text + '<p>Calculating molecular weight for composition\n'
         for obj in self.container.inputData.ASU_COMPONENTS:
           text = text + '<br>'+str(obj.numberOfCopies) + ' * '+ str(obj.seqFile.annotation) + ' ('+ str(obj.seqFile) + ')'
           text = text + '<br>'+ 'Which has molecular weight: '+ str(self.container.inputData.ASU_COMPONENTS.molecularWeight())
       elif self.container.inputData.MODE == 'nres':
         text = text + '<p>Estimated molecular weight for ' + str(self.container.inputData.NRES) + ' residues: '+str(self.container.inputData.NRES*110)
       else:
         text = text + '<p>Using given molecular weight: ' + str(self.container.inputData.MOLWT)
          
       print 'Sequence weight',self.container.inputData.SEQIN.fileContent.getAnalysis()
       try:
         self.container.inputData.HKLIN.loadFile()
         if self.container.inputData.MODE == 'asu_components':
           molWt = self.container.inputData.ASU_COMPONENTS.molecularWeight()
           rv = self.container.inputData.HKLIN.fileContent.matthewsCoeff(molWt=molWt)
         elif self.container.inputData.MODE == 'nres':          
           rv = self.container.inputData.HKLIN.fileContent.matthewsCoeff(nRes=self.container.inputData.NRES)
         else:
           rv = self.container.inputData.HKLIN.fileContent.matthewsCoeff(molWt=self.container.inputData.MOLWT)
       except:
         rv = {}

       #print 'runAnalysis',rv

       vol = rv.get('cell_volume','Unkown')
       nmol=[]
       solv = []
       matt=[]
       prob=[]
       if vol == 'Unkown':
           text = text + '<p>Cell volume = Unknown</p>'
       else:
           text = text + '<p>Cell volume = {0:.1f}<p>\n'.format(float(vol)) 
       text =      text +    '<table><tr><th>  Nmol  </th><th>  %solvent  </th><th>  Matthews  </th><th>  prob(Matthews)  </th></tr>\n'
       for result in rv.get('results',[]):
           text = text + '<tr><td>  {0}  </td><td>  {1:.2f}  </td><td>  {2:.2f}  </td><td>  {3:.2f}  </td></tr>'.format(result.get('nmol_in_asu'),result.get('percent_solvent'),result.get('matth_coef'),result.get('prob_matth')) + '\n'
           nmol.append(result.get('nmol_in_asu'))
           solv.append(result.get('percent_solvent'))
           matt.append(result.get('matth_coef'))
           prob.append(result.get('prob_matth'))
       text =      text + '</table></body></html>'
       self.resultWidget.setReadOnly(False)
       self.resultWidget.setHtml(text)
       self.resultWidget.setReadOnly(True)


       import CCP4ReportParser
       import CCP4Modules
       report = CCP4ReportParser.Report()
       if vol == 'Unkown':
         report.addText(text='Cell volume = Unknown')
       else:
         report.addText(text='Cell volume = {0:.1f}\n'.format(float(vol)))
       tab = report.addTable()
       tab.addData(title='Nmol',data=nmol)
       tab.addData(title='%solvent',data=solv)
       tab.addData(title='Matthews',data=matt)
       tab.addData(title='prob(Matthews)',data=prob)
       report.as_html_file(fileName=CCP4Modules.PROJECTSMANAGER().makeFileName(jobId=self.jobId(),mode='REPORT'))


