"""
     CCP4ReportExternalManagerGui.py: CCP4 GUI Project
     Copyright (C) 2013 STFC

     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.
"""

"""
     Liz Potterton July 2013 - report jobs run external to ccp4i2
"""

import os, functools
from PyQt4 import QtGui,QtCore
import CCP4Data,CCP4Container,CCP4CustomisationGui,CCP4Widgets,CCP4ImportedJobManager
from CCP4ErrorHandling import *
from CCP4Modules import IMPORTEDJOBMANAGER,WEBBROWSER,PROJECTSMANAGER

def openGui():
  if CImportedJobManagerGui.insts is None:
    CImportedJobManagerGui.insts = CImportedJobManagerGui()
  CImportedJobManagerGui.insts.show()
  CImportedJobManagerGui.insts.raise_()


class CImportedJobManagerGui(CCP4CustomisationGui.CCustomisationGui):

  insts = None
  def __init__(self,parent=None):
    CCP4CustomisationGui.CCustomisationGui.__init__(self,parent=parent,mode='importedjobs',title='Import Job Manager')
    self.createWidget= None
    

  def manager(self):
    return IMPORTEDJOBMANAGER()

  def handleNew(self):
    if self.createWidget is None:
      self.createWidget = CCreateImportedJobDialog(self)
      self.connect(self.createWidget,QtCore.SIGNAL('importedJobCreated'),self.customListView.populate)
    else:
      self.createWidget.updateViewFromModel()
    self.createWidget.show()
    self.createWidget.raise_()


  def handleEdit(self,selected=None):
    if selected is None: selected = self.customListView.selectedItem()
    if selected is None: return
    editor = CCreateImportedJobDialog(self,name=selected)
    editor.show()

class CImportedJobDataView(CCP4Widgets.CComplexLineWidget):
  MODEL_CLASS = CCP4ImportedJobManager.CImportedJobData
  def __init__(self,parent=None,model=None,qualifiers={}):
    qualis = {'vboxLayout' : True }
    qualis.update(qualifiers)
    #print 'CListView qualis',qualis
    CCP4Widgets.CComplexLineWidget.__init__(self,parent=parent,qualifiers=qualis)
    self.setModel(model)
    line =  QtGui.QHBoxLayout()
    line.addWidget(self.layout().takeAt(0).widget())
    self.widgets['dataType'] = CCP4Widgets.CStringView(parent=self,model=self.model.dataType)
    self.connect(self.model.dataType,QtCore.SIGNAL('dataChanged'),self.handleDataTypeChanged)
    line.addWidget(self.widgets['dataType'] )
    self.widgets['label'] = CCP4Widgets.CStringView(parent=self,model=self.model.label)
    line.addWidget(self.widgets['label'] )
    line.setStretchFactor(self.widgets['label'],5)
    self.layout().addLayout(line)
    
    self.fileNameLayout =  QtGui.QHBoxLayout()
    qualis = { 'autoInfoOnFileImport' : False, 'jobCombo' : False, 'browseDb' : False , 'toolTip' :'Select imported job directory' }
    self.widgets['fileName'] = CCP4Widgets.CDataFileView(parent=self,model=self.model.fileName,qualifiers=qualis)
    self.fileNameLayout.addWidget(self.widgets['fileName'])
    self.layout().addLayout(self.fileNameLayout)
    
    self.layout().addStretch(5)
    self.handleDataTypeChanged()
    self.connect(self.model,QtCore.SIGNAL('dataChanged'),self.validate)


  def handleDataTypeChanged(self):
    import CCP4DataManager
    dataType = self.model.dataType.__str__()
    cls = CCP4DataManager.DATAMANAGER().getClass(dataType)
    if cls is None: return
    self.model.resetFileNameClass(cls)
    self.model.label.set(self.model.fileName.qualifiers('guiLabel'))
    
    widget = CCP4DataManager.DATAMANAGER().widget(model=self.model.fileName,parentWidget=self,qualifiers={'vboxLayout' : False }) 
    print 'CImportedJobDefinitionView.handleDataTypeChanged',dataType,widget
    if widget is not None:
      try:
        self.widgets['fileName'].deleteLater()
        self.fileNameLayout.takeAt(0)
      except:
        pass
      self.widgets['fileName'] = widget
      self.fileNameLayout.addWidget(widget)
    self.validate()  
    
class CImportedJobDataListView(CCP4Widgets.CListView):
  MODEL_CLASS = CCP4ImportedJobManager.CImportedJobDataList
  def __init__(self,parent=None,model=None,qualifiers={}):
    qualis = { 'mode' : 'table',
               'tableItems' : ['name','dataType','label'] ,
               'columnHeaders':['Name','Data type','Label on interface'],
               }
    qualis.update(qualifiers)
    CCP4Widgets.CListView.__init__(self,parent,model=model,qualifiers=qualis)
    
class CCreateImportedJobDialog(QtGui.QDialog):

  def __init__(self,parent=None,name=None):
    QtGui.QDialog.__init__(self,parent)

    self.setWindowTitle('Report an external job')
    self.setLayout(QtGui.QVBoxLayout())
    self.layout().setContentsMargins(2,2,2,2)
    self.layout().setSpacing(2)
    
    self.widgets = {}
    self.model = CCP4ImportedJobManager.CImportedJobDefinition(self,name=name)
    if name is not None:  
      self.model.loadDataFromXml(fileName=os.path.join(IMPORTEDJOBMANAGER().getDirectory(name),'task.xml'),loadHeader=True)

    line = QtGui.QHBoxLayout()
    line.addWidget(QtGui.QLabel('Name of imported job',self))
    self.widgets['name'] = CCP4Widgets.CStringView(parent=self,model=self.model.name)
    self.widgets['name'].setToolTip('Unique single-word identifier for task')
    line.addWidget(self.widgets['name'])
    line.addWidget(QtGui.QLabel('title',self))
    self.widgets['title'] = CCP4Widgets.CStringView(parent=self,model=self.model.title)
    self.widgets['title'].setToolTip('Task name that appears in the user interface')
    line.addWidget(self.widgets['title'])
    line.setStretchFactor(self.widgets['title'],5)
    self.widgets['title'].setMinimumWidth(300)
    line.addStretch(1)
    self.layout().addLayout(line)
    
    line = QtGui.QHBoxLayout()
    line.addWidget(CCP4Widgets.CItalicLabel('Directory to copy to CCP4i2 project directory (optional)'))
    self.layout().addLayout(line)   
    line = QtGui.QHBoxLayout()
    self.widgets['commandFile'] = CCP4Widgets.CDataFileView(parent=self,model=self.model.commandFile)
    line.addWidget(self.widgets['commandFile'])
    self.layout().addLayout(line)

    self.inputFrame = QtGui.QFrame()
    self.inputFrame.setFrameShape(QtGui.QFrame.Box)
    self.inputFrame.setLayout(QtGui.QVBoxLayout())
    self.inputFrame.layout().setSpacing(1)
    self.inputFrame.layout().setContentsMargins(1,1,1,1)
    line = QtGui.QHBoxLayout()
    line.addWidget(CCP4Widgets.CItalicLabel('Input files to job'))
    self.inputFrame.layout().addLayout(line)
    print 'CCreateImportedJobDialog.__init__',self.model,self.model.dataOrder()
    self.widgets['inputFileDefinitionList'] = CImportedJobDataListView(parent=self,model=self.model.inputFileDefinitionList)
    line = QtGui.QHBoxLayout()
    line.addWidget(self.widgets['inputFileDefinitionList'])
    self.inputFrame.layout().addLayout(line)
    line = QtGui.QHBoxLayout()
    line.addStretch(4)
    but = QtGui.QPushButton('Add input file',self)
    self.connect(but,QtCore.SIGNAL('released()'),functools.partial(self.addDataObject,'input'))
    line.addWidget(but)
    line.addStretch(1)
    self.inputFrame.layout().addLayout(line)
    self.layout().addWidget(self.inputFrame)

    self.outputFrame = QtGui.QFrame()
    self.outputFrame.setFrameShape(QtGui.QFrame.Box)
    self.outputFrame.setLayout(QtGui.QVBoxLayout())
    self.outputFrame.layout().setSpacing(1)
    self.outputFrame.layout().setContentsMargins(1,1,1,1)
    line = QtGui.QHBoxLayout()
    line.addWidget(CCP4Widgets.CItalicLabel('Output files'))
    self.outputFrame.layout().addLayout(line)
    line = QtGui.QHBoxLayout()
    self.widgets['outputFileDefinitionList'] = CImportedJobDataListView(parent=self,model=self.model.outputFileDefinitionList)
    line.addWidget(self.widgets['outputFileDefinitionList'])
    self.outputFrame.layout().addLayout(line)
    line = QtGui.QHBoxLayout()
    line.addStretch(4)
    but = QtGui.QPushButton('Add output file',self)
    self.connect(but,QtCore.SIGNAL('released()'),functools.partial(self.addDataObject,'output'))
    line.addWidget(but)
    line.addStretch(1)
    self.outputFrame.layout().addLayout(line)
    self.layout().addWidget(self.outputFrame)
    
    buttonBox = QtGui.QDialogButtonBox(self)
    but = buttonBox.addButton('Help',QtGui.QDialogButtonBox.HelpRole)
    but.setFocusPolicy(QtCore.Qt.NoFocus)
    self.connect(but,QtCore.SIGNAL('released()'),self.help)
    but = buttonBox.addButton('Cancel',QtGui.QDialogButtonBox.RejectRole)
    but.setFocusPolicy(QtCore.Qt.NoFocus)
    self.connect(but,QtCore.SIGNAL('released()'),self.cancel)
    but = buttonBox.addButton('Save custom task',QtGui.QDialogButtonBox.AcceptRole)
    but.setFocusPolicy(QtCore.Qt.NoFocus)
    self.connect(but,QtCore.SIGNAL('released()'),self.accept)
    self.layout().addWidget(buttonBox)

  def addDataObject(self,mode):
    if mode == 'input':
      defList = self.model.inputFileDefinitionList
      name = 'inputFileDefinitionList'
      frame = self.inputFrame
    else:
      defList = self.model.outputFileDefinitionList
      name = 'outputFileDefinitionList'
      frame = self.outputFrame
    print 'CCreateImportedJobDialog.addDataObject',mode,frame.layout().count(),defList.__len__()
    defList.addItem()
    indx = defList.__len__() - 1
    line = QtGui.QHBoxLayout()
    self.widgets[name+str(indx)] = CImportedJobDefinitionView(parent=self,model=defList[indx])
    line.addWidget(self.widgets[name+str(indx)])
    frame.layout().insertWidget(indx,self.widgets[name+str(indx)])

  def updateViewFromModel(self):
    for key in self.widgets.keys():
      self.widgets[key].updateViewFromModel()
    
  def help(self):
    WEBBROWSER().loadWebPage(helpFileName='customisation')

  def cancel(self):
    self.hide()

  def accept(self):
    if not self.model.isValid(): return
    name = self.model.name.__str__()
    if os.path.exists(os.path.join(IMPORTEDJOBMANAGER().getDirectory(name))):
      QtGui.QMessageBox.warning(self,self.windowTitle(),'There is already an imported job called: '+name+'.  Please enter alternative name')
      return
    self.model.saveDataToXml(fileName=os.path.join(IMPORTEDJOBMANAGER().getDirectory(name),'task.xml'))
    self.hide()
