class EM3DModule(EMImage3DGUIModule):
	
	def get_qt_widget(self):
		if self.qt_context_parent == None:	
			from emimageutil import EMParentWin
			from emimage3d import EMImage3DWidget
			self.under_qt_control = True
			self.gl_context_parent = EMImage3DWidget(self)
			self.qt_context_parent = EMParentWin(self.gl_context_parent)
			self.gl_widget = self.gl_context_parent			
			self.qt_context_parent.setWindowIcon(QtGui.QIcon(get_image_directory() +"single_image_3d.png"))
		
		return self.qt_context_parent
	
	def get_gl_widget(self,qt_context_parent,gl_context_parent):
		self.under_qt_control = False
		ret = EMImage3DGUIModule.get_gl_widget(self,qt_context_parent,gl_context_parent)
		self.gl_widget.setWindowTitle(remove_directories_from_name(self.file_name))
		self.__set_module_contexts()
		return ret
	
	def get_desktop_hint(self):
		return "image"

	def __init__(self,application=None,ensure_gl_context=True,application_control=True):
		EMImage3DGUIModule.__init__(self,application,ensure_gl_context=ensure_gl_context,application_control=application_control)
		#EMLightsDrawer.__init__(self)
		self.cam = Camera2(self)
		self.vdtools = EMViewportDepthTools(self)
		self.perspective = False
		self.colors = get_default_gl_colors()
		self.perspective = True
		
		# basic shapes will be stored in these lists
		self.gq = None # will be a glu quadric
		self.cylinderdl = 0 # will be a cylinder with no caps
		self.diskdl = 0 # this will be a flat disk
		self.spheredl = 0 # this will be a low resolution sphere
		self.highresspheredl = 0 # high resolution sphere
		self.cappedcylinderdl = 0 # a capped cylinder
		self.first_render_flag = True # this is used to catch the first call to the render function - so you can do an GL context sensitive initialization when you know there is a valid context
	
		self.inspector = None # will be the inspector, i.e. an instance of an EM3DInspector
		self.radius = 100
		
		self.font_renderer = None # will be a 3D fonts renderer
		
		
	def __del__(self):
		if self.under_qt_control and not self.dont_delete_parent:
			self.qt_context_parent.deleteLater()
		self.core_object.deleteLater()

	def width(self):
		try: return self.gl_widget.width()
		except: return 0
		
	def height(self):
		try: return self.gl_widget.height()
		except: return 0
	
	def initializeGL(self):
		# put your own initialization things in here
		glEnable(GL_LIGHTING)
		glEnable(GL_NORMALIZE)
		
	def load_gl_color(self,name):
		color = self.colors[name]
		glColor(color["ambient"])
		glMaterial(GL_FRONT,GL_AMBIENT,color["ambient"])
		glMaterial(GL_FRONT,GL_DIFFUSE,color["diffuse"])
		glMaterial(GL_FRONT,GL_SPECULAR,color["specular"])
		glMaterial(GL_FRONT,GL_EMISSION,color["emission"])
		glMaterial(GL_FRONT,GL_SHININESS,color["shininess"])
	
	
	def render(self):
		if self.first_render_flag:
#			self.initializeGL()
#			self.init_basic_shapes() # only does something the first time you call it
#			self.init_font_renderer()
			if not self.perspective:self.gl_context_parent.load_orthographic()
			else: self.gl_context_parent.load_perspective()
			self.first_render_flag = False
					
		#self.vdtools.set_update_P_inv()
		glPushMatrix()
		self.cam.position(True)
		# the ones are dummy variables atm... they don't do anything
		self.vdtools.update(1,1)
		glPopMatrix()
		
		glPushMatrix()
		self.cam.position()
	
		self.draw_objects()
		
		glPopMatrix()
		
#		glPushMatrix()
#		self.cam.translate_only()
#		EMLightsDrawer.draw(self)
#		glPopMatrix()
		
	
	def draw_objects(self):
#		glPushMatrix()
#		glScale(50,50,50)
#		self.load_gl_color("red")
#		glCallList(self.highresspheredl)
#		glPopMatrix()
		
		glPushMatrix()
		glTranslate(100,0,0)
		glScale(50,50,50)
		self.load_gl_color("blue")
		glCallList(self.spheredl)
		glPopMatrix()
		
		glPushMatrix()
		glTranslate(0,100,0)
		glScale(50,10,10)
		glTranslate(-0.5,0,0)
		glRotate(90,0,1,0)
		self.load_gl_color("emerald")
		glCallList(self.cylinderdl)
		glPopMatrix()
		
		glPushMatrix()
		glTranslate(-100,25,0)
		glScale(10,50,10)
		glTranslate(-0.5,0,0)
		glRotate(90,1,0,0)
		self.load_gl_color("gold")
		glCallList(self.cappedcylinderdl)
		glPopMatrix()
		
		glPushMatrix()
		glTranslate(0,-100,0)
		glScale(15,15,15)
		self.load_gl_color("copper")
		glCallList(self.diskdl)
		glPopMatrix()
		
		glPushMatrix()
		glTranslate(0,-100,-10)
		glScale(15,15,15)
		glRotate(180,0,1,0)
		self.load_gl_color("silver")
		glCallList(self.diskdl)
		glPopMatrix()
		
		glPushMatrix()
		glTranslate(0,0,50)
		s = "bdb:EMAN2"
		
		bbox = self.font_renderer.bounding_box(s)
		glTranslate(-(bbox[3]-bbox[0])/2, -(bbox[4]-bbox[1])/2,-(bbox[5]-bbox[02])/2)
		self.font_renderer.render_string(s)
		glPopMatrix()
		
		
		glPushMatrix()
		glTranslate(0,-50,-50)
		s = "=^_^="
		bbox = self.font_renderer.bounding_box(s)
		glTranslate(-(bbox[3]-bbox[0])/2, -(bbox[4]-bbox[1])/2,-(bbox[5]-bbox[02])/2)
		self.font_renderer.render_string(s)
		glPopMatrix()
	
	
	def init_font_renderer(self):
		if self.font_renderer == None:
			self.font_renderer = get_3d_font_renderer()
			self.font_renderer.set_face_size(20)
			self.font_renderer.set_depth(12)
			self.font_renderer.set_font_mode(FTGLFontMode.EXTRUDE)
		
		
	def init_basic_shapes(self):
		#self.gl_context_parent.makeCurrent()
		if self.gq == None:
			
			self.gq=gluNewQuadric() # a quadric for general use
			gluQuadricDrawStyle(self.gq,GLU_FILL)
			gluQuadricNormals(self.gq,GLU_SMOOTH)
			gluQuadricOrientation(self.gq,GLU_OUTSIDE)
			gluQuadricTexture(self.gq,GL_FALSE)
		
		if ( self.cylinderdl == 0 ):
			self.cylinderdl=glGenLists(1)
				
			glNewList(self.cylinderdl,GL_COMPILE)
			glPushMatrix()
			gluCylinder(self.gq,1.0,1.0,1.0,12,2)
			glPopMatrix()
				
			glEndList()
		
		if self.diskdl == 0:
			self.diskdl=glGenLists(1)
				
			glNewList(self.diskdl,GL_COMPILE)
			gluDisk(self.gq,0,1,12,2)
			glEndList()
		
		if self.spheredl == 0:
			self.spheredl=glGenLists(1)
				
			glNewList(self.spheredl,GL_COMPILE)
			gluSphere(self.gq,.5,4,2)
			glEndList()

		
		if self.highresspheredl == 0:
			self.highresspheredl=glGenLists(1)
				
			glNewList(self.highresspheredl,GL_COMPILE)
			gluSphere(self.gq,.5,16,16)
			glEndList()
			
		if ( self.cappedcylinderdl == 0 ):
			self.cappedcylinderdl=glGenLists(1)
			glNewList(self.cappedcylinderdl,GL_COMPILE)
			glCallList(self.cylinderdl)
			glPushMatrix()
			glTranslate(0,0,1)
			glCallList(self.diskdl)
			glPopMatrix()
			glPushMatrix()
			glRotate(180,0,1,0)
			glCallList(self.diskdl)
			glPopMatrix()
			glEndList()
			
	def eye_coords_dif(self,x1,y1,x2,y2,mdepth=True):
		return self.vdtools.eye_coords_dif(x1,y1,x2,y2,mdepth)
	
	def resizeEvent(self, width, height):
		for i in self.viewables:
			i.resizeEvent()
	
	def get_inspector(self):
		if self.inspector == None:
			self.inspector = EM3DInspector(self)
		return self.inspector

	def set_cam_z(self,z):
		self.cam.set_cam_z( z )
		self.updateGL()
		
	def set_cam_y(self,y):
		self.cam.set_cam_y( y )
		self.updateGL()
		
	def set_cam_x(self,x):
		self.cam.set_cam_x( x )
		self.updateGL()
	
	def set_scale(self,val):
		self.cam.scale = val
		self.updateGL()	

	def resizeEvent(self,width=0,height=0):
		self.vdtools.set_update_P_inv()
	
	def load_rotation(self,t3d):
		self.cam.load_rotation(t3d)
		self.updateGL()

	def get_start_z(self):
		return self.gl_context_parent.get_start_z()
	
	def get_near_plane_dims(self):
		return self.gl_context_parent.get_near_plane_dims()
	
	def set_perspective(self,bool):
		self.perspective = bool
		
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()
		if not self.perspective:self.gl_context_parent.load_orthographic()
		else: self.gl_context_parent.load_perspective()
		glMatrixMode(GL_MODELVIEW)
		
		self.updateGL()