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

import dataobj,utils
from global_definitions import *
   

    
class GL2dScreen(dataobj.DataObj):
  names = []
  insts = []

#-----------------------------------------------------------------------
  def __init__(self,name='Legends&Images',filename='',dataparams={},restore_from_version=0,**kw):
#-----------------------------------------------------------------------
    dataobj.DataObj.__init__(self,'GL2dScreen',name=name,module='Legend', \
                     filename=filename,dataparams=dataparams)
    
    # This hack makes sure that there is always exactly one GL2dScreen and the last one
    # that was created (by restoring status, etc.)
    if len(GL2dScreen.insts)>0: 
       GL2dScreen.insts[0] = self
    else:
       GL2dScreen.insts.append(self)

    GL2dScreen.names.append('GL2dScreen')
    
#-----------------------------------------------------------------
  def add_object(self,object_type = 'Legend',params={},**keywords):
#-----------------------------------------------------------------
    if object_type == 'Legend':
      dobj = Legend(parent=self.name,visible=1,params=params)
    elif object_type == 'Image':
      import MGGLImage
      dobj = MGGLImage.Image(parent=self.name,visible=1,params=params)
    else:
      dobj = None
    return dobj


#------------------------------------------------------------------------
#------------------------------------------------------------------------
#------------------------------------------------------------------------
class Legend(dataobj.DispObj):
#------------------------------------------------------------------------
#------------------------------------------------------------------------
#------------------------------------------------------------------------

  class_dependents = {}


  def __init__(self,parent='',visible='1',name='', \
               type = 'Legend', params = {}, restore_from_legend=0,**keywords):

    #print "Legend params",params
    import graphicsmodel
    # Set default parameters
    font = FONTMANAGER().getHtmlFont('legend')
    self.selection = '<span '+font+'>Legend</span>'
    self.position =  [0.01,0.01]
    if params.has_key('colour') and  params.get('colour') and params.has_key('style') and  params.get('style'):
      params['position'] = [utils.safeFloat(params['colour'],0.01),utils.safeFloat(params['style'],0.01)]
      del params['colour'],params['style']
    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']

    if params.has_key('text_colour') and  params.has_key('font'):
      print "Can not restore Legend text_colour and font"
      del params['text_colour'], params['font']

    params.update(keywords)
    
    dataobj.DispObj.__init__(self,type,name,parent=parent,visible=visible,params=params)
    self.name_label='Legend'
 
    # Keep list of Text objects
    self.graph_objects = []
    self.label_graphmod = graphicsmodel.graphicsmodel( )
    BUILD().append(self.label_graphmod)
    self.moving = 0
      
    self.set_selection(text=self.selection,force=1)

    self.do_redraw=2

#-----------------------------------------------------------------------
  def set_position(self,x,y):
#-----------------------------------------------------------------------
    self.position = [float(x),float(y)]
    self.do_redraw = 1

#-----------------------------------------------------------------------
  def get_position(self):
#-----------------------------------------------------------------------
    return self.position

#----------------------------------------------------------------------
  def params(self,all=1):
#----------------------------------------------------------------------
    pars = dataobj.DispObj.params(self,all=all)

    for key in ['position','selection']:
      pars[key] = getattr(self,key,'')
    return pars

#----------------------------------------------------------------------
  def update_data_status(self,shadowdisp):
#----------------------------------------------------------------------
    import utils
    rv = 0
    diffs = utils.dict_diffs(self.params(),shadowdisp.params)[1]
    if diffs:
      rv = 1
      self.update_gui.append(['update'])
    for key in diffs.keys():
      if key == 'selection':
         self.set_text(diffs['selection'])
      elif key == 'position':
        self.set_position(diffs['position'][0],diffs['position'][1])
    
    rv = max(rv,dataobj.DispObj.update_data_status0(self,shadowdisp))
    return rv
  
  def get_position_label(self):
    return '%.2f %.2f'%(self.position[0],self.position[1])

  def get_text_label(self):
    import ParseHTMLTextString
    parser = ParseHTMLTextString.MyHTMLParser()
    parser.feed(self.selection)
    data = parser.getAllData().strip().replace('\n',' ')
    return data[:min(15,len(data))]

  def get_selection_label(self):
    return self.get_text_label()
  
#-----------------------------------------------------------------------
  def get_text(self):
#-----------------------------------------------------------------------
    return self.selection
  
#-----------------------------------------------------------------------
  def set_selection(self,text='',**args):
#-----------------------------------------------------------------------
    self.set_text(text)
    
#-----------------------------------------------------------------------
  def set_text(self,text='',**args):
#-----------------------------------------------------------------------
    self.selection = str(text)
    self.do_redraw = 2
    
#------------------------------------------------------------------
  def unthreadedDraw(self ):
#------------------------------------------------------------------
    if self.do_redraw<=0:
      return 0
    elif self.do_redraw > 1:
      Legend.delete(self,delete=0)
      self.create_annotation()
    elif self.do_redraw:
      if self.graph_objects:
        import pygl_coord
        self.graph_objects[0].SetVertices([pygl_coord.Cartesian(self.position[0],self.position[1],0.0)])
    self.do_redraw = 0
    self.do_rebuildGL.append('label_graphmod')
    return 1

#-----------------------------------------------------------------
  def create_annotation(self):
#------------------------------------------------------------------
    import cprim,pygl_coord
    import graphicsmodel

    text = self.selection
    #print 'Legend.create_annotation',text
    import TextLabel
    x,y= self.position
    label_ob = TextLabel.CreateBillBoardTextLabel(text,pygl_coord.Cartesian(x,y,0.0),pygl_coord.Cartesian(x,y,0.0))

    label_ob.thisown = 0

    self.label_graphmod.obj.add_text_primitive(label_ob)
    self.graph_objects.append(label_ob)
    self.label_graphmod.obj.rebuild()
    #self.update_font(label_ob)
    """
    # Cannot do this, we are not in thread bound to OpenGL context.
    # We can potentially bind to this context, but that's another story.
    if self.text_colour == 'complement':
      #print "call SetDefaultColour"
      label_ob.SetDefaultColour()
    """
    self.do_redraw = 0


#----------------------------------------------------------------------
  def delete(self,delete=1,**keywords) :
#-----------------------------------------------------------------------
    import cprim
    if delete:
      win = MAINWINDOW()
      win.removeGLDisplayObject(self.label_graphmod)
      if self.label_graphmod: BUILD().deletemod(self.label_graphmod)
      self.label_graphmod.obj.thisown = 0
      self.label_graphmod = ''
      dataobj.DispObj.delete(self)
    else:
      # Delete all of the text objects from label_graphmod
      if len(self.graph_objects)<=0 or not self.label_graphmod : return
      for graph_object in self.graph_objects:
        #print "deleting ",graph_object,'from',obj.graphmod
        cprim.DeleteTextLabel(self.label_graphmod.obj,graph_object.GetID())
      self.graph_objects = []
    

#-------------------------------------------------------------------
  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()
    
#------------------------------------------------------------------
  def movie_interpolation(self,initial_status=None,final_status=None, \
                          fraction=0.0,step=0,**keywords):
#------------------------------------------------------------------
    if initial_status and final_status:
      
      #print "Legend movie_interpolation",fraction
      #print "initial",initial_status.params
      #print "final",final_status.params
      final_x,final_y = final_status.params['position']
      initial_x,initial_y = initial_status.params['position']
      dx = float(final_x) - float(initial_x)
      dy = float(final_y) - float(initial_y)
      #print "dx,dy",dx,dy
      self.set_position ( initial_x + fraction*dx, initial_y+ fraction*dy)

    dataobj.DispObj.movie_interpolation(self,initial_status=initial_status, \
           final_status=final_status,fraction=fraction,step=step)

  def clone(self):
    pass
