import pygtk
pygtk.require('2.0')
import gtk
import cairo
from math import pi

class WaveformSelector(gtk.DrawingArea):
	def __init__(self, bg_color, fg_color, hl_color, press_color, width=50, height=50, selection=1, name="Waveform"):
		self._bg_color = bg_color	#background color
		self._fg_color = fg_color	#foreground color
		self._hl_color = hl_color	#highlight color
		self._press_color = press_color
		self._width = width
		self._width2 = int(1.*self._width*3/4)
		self._height = height
		self._name = name
		gtk.DrawingArea.__init__(self)
		self.set_size_request(self._width, self._height)
		self.setValueCallback(None)
		self.setEnterCallback(None)
		self.setLeaveCallback(None)
		self._current_selection = selection
		self._up_is_pressed = False
		self._down_is_pressed = False
		self.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)
		self.connect("button-press-event", self._onButtonPress)
		self.connect("button-release-event", self._onButtonRelease)
		self.connect("expose-event", self._onAreaExpose)
		self.connect("enter-notify-event", self._onEnterNotify)
		self.connect("leave-notify-event", self._onLeaveNotify)
	
	def _onAreaExpose(self, widget, event):
		context = widget.window.cairo_create()
		context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
		context.clip()
		context.set_source_rgb(self._bg_color[0], self._bg_color[1], self._bg_color[2])
		context.rectangle(0, 0, self._width2, self._height)
		context.fill()
		context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
		scale_width = int(1.*self._width/20)
		scale_width2 = int(1.*self._width2/10)
		scale_height = int(1.*self._height/10)
		if self._current_selection == 1:	#sine wave
			r = int(1.*self._width2/4)
			context.move_to(0+scale_width2, self._height/2)
			context.curve_to(0+scale_width2, 0+scale_height, r, 0+scale_height, r, 0+scale_height)
			context.stroke()
			context.move_to(r, 0+scale_height)
			context.curve_to(2*r, 0+scale_height, 2*r, self._height/2, 2*r, self._height/2)
			context.stroke()
			context.move_to(2*r, self._height/2)
			context.curve_to(2*r, self._height, 3*r, self._height-scale_height, 3*r, self._height-scale_height)
			context.stroke()
			context.move_to(3*r, self._height-scale_height)
			context.curve_to(4*r-scale_width2, self._height-scale_height, 4*r-scale_width2, self._height/2, 4*r-scale_width2, self._height/2)
			context.stroke()
		elif self._current_selection == 2:	#square wave
			context.move_to(0+scale_width2, self._height/2)
			context.line_to(0+scale_width2, 0+scale_height)
			context.line_to(self._width2/2, 0+scale_height)
			context.line_to(self._width2/2, self._height-scale_height)
			context.line_to(self._width2-scale_width2, self._height-scale_height)
			context.line_to(self._width2-scale_width2, self._height/2)
			context.stroke()
		elif self._current_selection == 3:	#saw wave
			context.move_to(0+scale_width2, self._height/2)
			context.line_to(0+scale_width2, 0+scale_height)
			context.line_to(self._width2-scale_width2, self._height-scale_height)
			context.line_to(self._width2-scale_width2, self._height/2)
			context.stroke()
		
		if (self._up_is_pressed == True):
			context.set_source_rgb(self._press_color[0], self._press_color[1], self._press_color[2])
			context.rectangle(self._width2, 0, self._width, self._height/2)
			context.fill()
			context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
			context.rectangle(self._width2, self._height/2, self._width, self._height)
			context.fill()
			context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
			context.move_to(self._width2+scale_width, self._height/4+scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), 0 )
			context.line_to(self._width-scale_width, self._height/4+scale_height)
			context.line_to(self._width2+scale_width, self._height/4+scale_height)
			context.set_source_rgb(self._bg_color[0], self._bg_color[1], self._bg_color[2])
			context.move_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), self._height )
			context.line_to(self._width-scale_width, int(self._height*(3./4))-scale_height)
			context.line_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.fill()
		elif (self._down_is_pressed == True):
			context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
			context.rectangle(self._width2, 0, self._width, self._height/2)
			context.fill()
			context.set_source_rgb(self._press_color[0], self._press_color[1], self._press_color[2])
			context.rectangle(self._width2, self._height/2, self._width, self._height)
			context.fill()
			context.set_source_rgb(self._bg_color[0], self._bg_color[1], self._bg_color[2])
			context.move_to(self._width2+scale_width, self._height/4+scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), 0 )
			context.line_to(self._width-scale_width, self._height/4+scale_height)
			context.line_to(self._width2+scale_width, self._height/4+scale_height)
			context.fill()
			context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
			context.move_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), self._height )
			context.line_to(self._width-scale_width, int(self._height*(3./4))-scale_height)
			context.line_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.fill()
		else:
			context.set_source_rgb(self._fg_color[0], self._fg_color[1], self._fg_color[2])
			context.rectangle(self._width2, 0, self._width, self._height/2)
			context.fill()
			context.rectangle(self._width2, self._height/2, self._width, self._height)
			context.fill()
			context.set_source_rgb(self._bg_color[0], self._bg_color[1], self._bg_color[2])
			context.move_to(self._width2+scale_width, self._height/4+scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), 0 )
			context.line_to(self._width-scale_width, self._height/4+scale_height)
			context.line_to(self._width2+scale_width, self._height/4+scale_height)
			context.fill()
			context.move_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.line_to( int(1.*(self._width+self._width2)/2), self._height )
			context.line_to(self._width-scale_width, int(self._height*(3./4))-scale_height)
			context.line_to(self._width2+scale_width, int(self._height*(3./4))-scale_height)
			context.fill()
		
		
		
		context.set_source_rgb(self._hl_color[0], self._hl_color[1], self._hl_color[2])
		context.move_to(0, 0)
		context.line_to(self._width2, 0)
		context.line_to(self._width2, self._height)
		context.line_to(0, self._height)
		context.line_to(0, 0)
		context.stroke()
		context.move_to(self._width2, 0)
		context.line_to(self._width, 0)
		context.line_to(self._width, self._height)
		context.line_to(self._width2, self._height)
		context.line_to(self._width2, 0)
		context.stroke()
		context.move_to(self._width2, self._height/2)
		context.line_to(self._width, self._height/2)
		context.stroke()

	def _onButtonPress(self, widget, event):
		if (event.x >= self._width2) and (event.x<= self._width):
			if (event.y >= 0) and (event.y <= self._height/2):
				self._up_is_pressed = True
				self._current_selection += 1
				if self._current_selection > 3:
					self._current_selection = 1
				self.queue_draw_area(0, 0, self._width, self._height)
				self.value_callback(self._current_selection)
				if self.enter_callback != None:
					self.enter_callback(self._name, self._current_selection)
			elif (event.y >= self._height/2) and (event.y <= self._height):
				self._down_is_pressed = True
				self._current_selection -= 1
				if self._current_selection < 1:
					self._current_selection = 3
				self.queue_draw_area(0, 0, self._width, self._height)
				self.value_callback(self._current_selection)
				if self.enter_callback != None:
					self.enter_callback(self._name, self._current_selection)

	def _onButtonRelease(self, widget, event):
		self._up_is_pressed = False
		self._down_is_pressed = False
		self.queue_draw_area(0, 0, self._width, self._height)
		
	def setValueCallback(self, callback, data=None):
		self.value_callback = callback
		self.waveform_data = data
	
	def setEnterCallback(self, callback, data=None):
		self.enter_callback = callback
		self.enter_data = data
		
	def setLeaveCallback(self, callback, data=None):
		self.leave_callback = callback
		self.leave_data = data

	def _onEnterNotify(self, widget, event):
		if self.enter_callback != None:
			self.enter_callback(self._name, self._current_selection)
		
	def _onLeaveNotify(self, widget, event):
		mask = event.state
		if mask != gtk.gdk.BUTTON1_MASK:
			if self.leave_callback != None:
				self.leave_callback()