"""
     python/ui/Image.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009 University of York
     Copyright (C) 2012 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.
"""

import dataobj
from global_definitions import *

def supportedReadFormats():
  # Workaround swig bug on Centos.
  from PyQt4 import QtGui
  return QtGui.QImageReader.supportedImageFormats()
  """
  import image_info
  image_formats_c = image_info.image_info.GetSupportedReadFormats()
  image_formats = []
  for im in image_formats_c: image_formats.append(str(im))
  return image_formats
  """

def supportedWriteFormats():
  # Workaround swig bug on Centos.
  from PyQt4 import QtGui
  return QtGui.QImageWriter.supportedImageFormats()
  """
  import image_info
  image_formats_c = image_info.image_info.GetSupportedWriteFormats()
  image_formats = []
  for im in image_formats_c: image_formats.append(str(im))
  return image_formats
  """


class Image(dataobj.DispObj):

  class_dependents = {}

  def __init__(self,parent='',visible='1',name='', \
               filename=[],params = {}, restore_from_version=0, **keywords):
      
    self.isValid = False
    import utils
    # Set default parameters
    if filename:
      self.filename = utils.check_filename(filename)
    elif params.has_key('filename'):
      self.filename = params['filename']
      
    defpars = { 'scale' : 1.0,
                'aspect' : 1.0,
                'position' : [0.0,0.0] }

    # update from pre 2.0
    if params.has_key('selection'):
      params['scale'] = utils.safeFloat(params['selection'],1.0)
      del params['selection']
    if params.has_key('colour') and  params.has_key('style'):
      params['position'] = [utils.safeFloat(params['colour'],0.01),utils.safeFloat(params['style'],0.01)]
      del params['colour'],params['style']
    #params['aspect'] = utils.safeFloat(params['aspect'],1.0)
    if params.has_key('x') and params.has_key('y'):
      params['position'] = [utils.safeFloat(params['x'],0.01),utils.safeFloat(params['y'],0.01)]
      del params['x'],params['y']
      
    defpars.update(params)
    defpars.update(keywords)
    
    #print "Image filename",self.filename
    if type(self.filename[2]) == unicode:
      name = 'IMG'+utils.fileRoot(self.filename[2].encode("utf-8"))
    else:
      name = 'IMG'+utils.fileRoot(self.filename[2])

    import image_info
    if type(self.filename[2]) == unicode:
      image = image_info.image_info(self.filename[2].encode("utf-8"))
    else:
      image = image_info.image_info(self.filename[2])
    if image.get_width() and image.get_height():
	self.isValid = True
    else:
        print "Error loading image file",self.filename[2]
	print 
	return

    dataobj.DispObj.__init__(self,'Image',name,parent=parent, \
                     visible=visible,params=defpars)
    
    # Find natural size of the image as fraction of current
    # display window size
    self.moving = 0
    
    # Create the graphics object
    self.graph_objects = []
    self.do_redraw = 1

  def get_selection_label(self):
    if self.name[0:3] == 'IMG':
      return self.name[3:]
    else:
      return self.name
    
#---------------------------------------------------------------------
  def set_scale(self,scale='',**keywords):
#---------------------------------------------------------------------
    self.scale=float(scale)
    self.do_redraw = 1

#---------------------------------------------------------------------
  def get_scale(self):
#---------------------------------------------------------------------
    return self.scale

#---------------------------------------------------------------------
  def set_position(self,x=None,y=None,dx=None,dy=None,**keywords):
#---------------------------------------------------------------------
    px,py = self.position
    if x != None : px = float(x)
    if y != None : py = float(y)
    # What is all this about?
    if dx != None :
      px = px+0.002*int(dx)
      if px<-1.0 or px > 2.0: px = self.position[0]
    if dy != None :
      py = py+0.002*int(dy)
      if py<-1.0 or py > 2.0: py = self.position[0]

    self.position = [px,py]
    self.do_redraw = 1

  def get_position(self):
    return self.position

#---------------------------------------------------------------------
  def get_position_label(self):
#---------------------------------------------------------------------
    return '%.2f %.2f'%(self.position[0],self.position[1])
       

#--------------------------------------------------------------------
  def set_aspect(self,aspect='',**keywords):
#--------------------------------------------------------------------
    if aspect:
      self.aspect = float(aspect)
      self.do_redraw = 1

#---------------------------------------------------------------------
  def get_aspect(self):
#---------------------------------------------------------------------
    return self.aspect
    
#------------------------------------------------------------------
  def params(self,all=1):
#------------------------------------------------------------------
    sel = dataobj.DispObj.params(self,all=all)
    for item in ['filename','aspect','position','scale']:
      sel[item]=getattr(self,item)
    return sel

#------------------------------------------------------------------
  def update_data_status(self,shadowdisp):
#------------------------------------------------------------------
    import utils
    rv = 0
    diffs = utils.dict_diffs(self.params(),shadowdisp.params)[1]
    if diffs:
      rv = 1
      if diffs.has_key('scale'):
        self.set_scale(scale= shadowdisp.params['scale'])
      if diffs.has_key('aspect'):
        self.set_aspect(aspect= shadowdisp.params['aspect'])
      if diffs.has_key('position'):
        self.set_position(diffs['position'][0],diffs['position'][1])
    rv = max(rv,dataobj.DispObj.update_data_status0(self,shadowdisp))
    if rv: self.update_gui.append(['update'])
    return rv
    
#----------------------------------------------------------------------
  def delete(self,**keywords) :
#-----------------------------------------------------------------------
    # If delete true then zap the whole graphical object
    BUILD().deletemod(self.graphmod)
    dataobj.DispObj.delete(self)  


#------------------------------------------------------------------
  def draw (self ):
#------------------------------------------------------------------
    '''
    Draw/update method called every cycle of event loop
    '''
    if not self.isValid: return 0
    if self.do_redraw == 0: return 0

    import cprim
    import graphicsmodel
    import pygl_coord

    # *****  Beware user resizing screen *********************
    #  Need to handle aspect ratio
    
    # Find vertices of the image
    # As I've sorted out BillBoard somewhat, cv[1] is now irrelavent.
    cv = pygl_coord.CartesianVector(2)
    cv[0] = pygl_coord.Cartesian(self.position[0],self.position[1],0)
    #cv[1] = pygl_coord.Cartesian(self.colour+(self.selection*self.size[0]*self.aspect), \
    #                  self.style+(self.selection*self.size[1]),0)

    
    if not  self.graph_objects:
      # Create the graphical object
      self.graphmod = graphicsmodel.graphicsmodel( )
      BUILD().append(self.graphmod)
      if type(self.filename[2]) == unicode:
        image_ob = cprim.BillBoard( cv, cv[0], self.filename[2].encode("utf-8"))
      else:
        image_ob = cprim.BillBoard( cv, cv[0], self.filename[2])
      if image_ob.GetImageWidth()>0 and image_ob.GetImageHeight()>0:
        #print "Image.draw",self.scale,self.aspect
        image_ob.SetScale(self.scale*self.aspect,self.scale)
        self.graph_objects.append(image_ob)
        #print "image_ob",image_ob,"graphmod", self.graphmod
        self.graphmod.obj.add_image_primitive(image_ob)
        self.graphmod.obj.rebuild()
        self.graphmod.obj.SetBuildDisplayList(0)
        self.do_rebuildGL.append('graphmod')
      else:
        return 0

    #else:
      # Update vertices of graphical object

    #print "Image.draw()",cv
    for obj in self.graph_objects:
      if self.do_redraw == 2 and hasattr(obj,"ClearTextureID"):
        obj.ClearTextureID()
      obj.SetVertices(cv)
      obj.SetScale(self.scale*self.aspect,self.scale)
    self.graphmod.rebuild()
    self.do_rebuildGL.append('graphmod')
    self.do_redraw = 0
    return 1
 
#------------------------------------------------------------------
  def movie_interpolation(self,initial_status=None,final_status=None, \
                          fraction=0.0,step=0,**keywords):
#------------------------------------------------------------------
    if initial_status and final_status:
      skey = 'scale'
      xkey = 'x'
      ykey = 'y'
      ini = initial_status.params
      fin = final_status.params
      
      self.set_scale(
        float(ini[skey])+fraction* (float(fin[skey])- float(ini[skey])))
      self.set_position(
        x = float(ini[xkey])+fraction* (float(fin[xkey])- float(ini[xkey])),
        y = float(ini[ykey])+fraction* (float(fin[ykey])- float(ini[ykey])))
      self.set_aspect(
        float(ini['aspect'])+fraction*(float(fin['aspect'])-float(ini['aspect'])))
       
      dataobj.DispObj.movie_interpolation(self,initial_status=initial_status, \
           final_status=final_status,fraction=fraction,step=step)
      
#-------------------------------------------------------------------
  def transform(self,glwidget):
#-------------------------------------------------------------------
    '''
    Handle mouse input to translate objects
    '''
    dx,dy,dz = glwidget.screenTransform()
    
    if dx: self.position[0] = self.position[0] + dx
    if dy: self.position[1] = self.position[1] + dy
    self.do_redraw = 1
    self.draw()
