"""
     pygl/build.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC

     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 pygl_coord import *
#from primitive import *
from  displayobject import *
from atom_util import *
from mmdb2 import *
from point_funcs import *
from eventdefs import *
from graphicsmodel import *
import util
import opts 
import time, threading
import math
import string
import Queue
import sys,os
import pickle
from texture import *
import cprim
import COLOUR
import UtilityThread

class build:
   """
   Class which turns some chemical data into ball/stick pictures, etc and
   sends off abstract primitive data to OpenGL thread. Also handles selection
   of primitives, though not perfectly yet.
   """
   insts = ""
   positions = []
   def animate(self,pos1,pos2,export=0,filename="screenshot",format=".ppm"):
       """
       Takes two instances of buildSaveData and animates between them.
       """
       numsteps = 50
       for j in range(numsteps+1):
         dx = float(j)/float(numsteps)
         for i in range(len(self.mods)):
           mod = self.mods[i]
           mod.obj.quat.dval = [ (1-dx)*pos1[i].quat.dval[0] + dx*pos2[i].quat.dval[0],\
                                 (1-dx)*pos1[i].quat.dval[1] + dx*pos2[i].quat.dval[1],\
                                 (1-dx)*pos1[i].quat.dval[2] + dx*pos2[i].quat.dval[2],\
                                 (1-dx)*pos1[i].quat.dval[3] + dx*pos2[i].quat.dval[3] ]
           mod.obj.origin    = ( (1-dx)*pos1[i].origin[0]    + dx*pos2[i].origin[0],\
                                 (1-dx)*pos1[i].origin[1]    + dx*pos2[i].origin[1],\
                                 (1-dx)*pos1[i].origin[2]    + dx*pos2[i].origin[2] )

         if export > 0:
           """
           The format bit is a bit kludgy, but we'll fix that.
           j needs to be replaced with some global counter ...
           """
           fname = filename + string.zfill(str(j),4) + format
           #print fname
           #self.glthread.screenshot(fname)
         else:
           time.sleep(0.1)


   def __init__(self,thread):
      """
      Initilaization. Set up some defaults.
      """
      build.insts = self
      self.mods = []
      self.jobtypeold = -1
      self.oldx = 0
      self.oldy = 0
      self.glthread = thread
      self.selected_model = -1 
      self.jq = Queue.Queue(0)
      self.animate_load = 1
      self.clicked_prims = []
      #self.glthread.glevent.registermods(self.mods)

   """
   def TestMovie(self):
      self.glthread.glevent.centre_on((0,0,0),self.mods[0].obj)
      self.glthread.quat = pygl_coord.Quat(0.0,0.0,0.0,0)
      for i in range(90):
         filename = "movie4%05d.pov" % i
         x = 10.0*math.sin(i*math.pi/1440.0)
         z = 10.0*math.sin(i*math.pi/1440.0)
         self.glthread.RADIUS = (90 - i/3.0)
         self.glthread.glevent.centre_on((0,0,0),self.mods[0].obj)
         self.glthread.move_camera(-x,5,z)
         self.glthread.rotate_camera((0,-0.2,0))
         print "Requesting", filename
         self.glthread.Flush()
         self.glthread.request_screenshot_pov(filename)
         #self.glthread.Flush()
      for j in range(30):
         i = i + 1
         filename = "movie4%05d.pov" % i
         self.glthread.RADIUS = (60 - j/2.0)
         print "Requesting", filename
         self.glthread.Flush()
         self.glthread.request_screenshot_pov(filename)
         #self.glthread.Flush()
      for j in range(90):
         i = i + 1
         filename = "movie4%05d.pov" % i
         self.glthread.rotate_camera((0,-0.2,0))
         print "Requesting", filename
         self.glthread.Flush()
         self.glthread.request_screenshot_pov(filename)
         #self.glthread.Flush()
   """

   def deletemod(self,graphmod):
      """
      Delete a model and all its objects and
      children, recursively hopefully. Instances
      should take care of themselves where possible.
      """
      if self.mods.count(graphmod):
	#print self.glthread
        modid = self.mods.index(graphmod)
        self.mods.pop(modid)
      if hasattr(graphmod,"obj") and hasattr(graphmod.obj,"clear_prims"):
        graphmod.obj.clear_prims()
      if hasattr(graphmod,"sinfo"):
        del graphmod.sinfo

   def registerqueue(self,jq):
        """
        A function which tells the thread
        which Python Queue it is meant to 
        push events to.
        """
        self.jq = jq

   def append(self,mod):
      self.append1(mod)
      self.append2(mod)

   def append1(self,mod):
      mod.build_primitives()

   def append2(self,mod):
      # At this point we need to add an object to GLWidgets somehow.
      #self.mods.append(mod)
      #self.glthread.addobj(mod.obj)
      import MGApplication
      win = MGApplication.GetMainWindow()
      win.addGLDisplayObject(mod)
      self.selected_model = self.selected_model + 1
      """
      dist = mod.GetMaxDimension()
      if(dist and dist>self.glthread.viewsize):
        self.glthread.setmaxviewsize(dist/2.0+5)
      """
      #win.setGLSize(dist/2.0+5)

   def newbillboard(self,mod,filename,coords_in=[0,0,1,1]):
      obj = cprim.Displayobject()
      mod.style = "BILLBOARD"
      mod.obj = obj
      coords = doublea(6)
      coords[0] = coords_in[0]
      coords[1] = coords_in[1]
      coords[2] = 0
      coords[3] = coords_in[2]
      coords[4] = coords_in[3]
      coords[5] = 0
      cprim.AddBillBoardImage(obj,filename,coords)
      self.append(mod)

   def newbillboardtextlabel(self,mod,label,coords_in=[0,0]):
      obj = cprim.Displayobject()
      mod.style = "BILLBOARD"
      mod.obj = obj
      cprim.AddBillBoardTextLabel(obj,coords_in[0],coords_in[1],label)
      self.append(mod)


