import pygtk
pygtk.require('2.0')
import gtk

class VSlider(gtk.Fixed):
	
	def __init__(self, bg_path, fg_path, min_value=0, max_value=100, current_value=0, name=""):
		self._min_value = min_value
		self._max_value = max_value
		self._current_value = current_value
		self._name = name
		gtk.Fixed.__init__(self)
		self.setValueCallback(None)
		self.setEnterCallback(None)
		self.setLeaveCallback(None)
		self._bg_box = gtk.EventBox()
		background_img = gtk.Image()
		background_img.set_from_file(bg_path)
		background_img.show()
		self._bg_box.add(background_img)
		self._bg_box.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)
		self._bg_box.connect("button-press-event", self._onBackgroundPress)
		self._bg_box.connect("enter-notify-event", self._onEnterNotify)
		self._bg_box.connect("leave-notify-event", self._onLeaveNotify)
		self._fg_box = gtk.EventBox()
		self._nub_img = gtk.Image()
		self._nub_img.set_from_file(fg_path)
		self._nub_img.show()
		self._fg_box.add(self._nub_img)
		self._fg_box.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)
		self._fg_box.connect("expose-event", self._onAreaExpose)
		self._fg_box.connect("motion_notify_event", self._onIndicatorMotion)
		self._bg_box.connect("enter-notify-event", self._onEnterNotify)
		self._fg_box.connect("leave-notify-event", self._onLeaveNotify)
		self.put(self._bg_box, 0, 0)
		self.put(self._fg_box, 0, 0)
		self._bg_box.show()
		self._fg_box.show()
		
		
	def _onBackgroundPress(self, widget, event):
		x = int(self._fg_box.get_allocation()[0])
		height_difference = self._bg_box.get_allocation()[3] - self._fg_box.get_allocation()[3]
		height_difference = float(height_difference)
		if event.y > height_difference:
			y = int(self._bg_box.get_allocation()[1] + height_difference)
		else:
			y = int(self._bg_box.get_allocation()[1] + event.y)
		value_difference = self._min_value - self._max_value
		self._current_value = (value_difference/height_difference)*(y-self._bg_box.get_allocation()[1]) + self._max_value
		self._current_value = int(self._current_value)
		if self._current_value > self._max_value:
			self._current_value = self._max_value
		elif self._current_value < self._min_value:
			self._current_value = self._min_value
		self.value_callback(self._current_value)
		if self.enter_callback != None:
			self.enter_callback(self._name, self._current_value)
		self._fg_box.queue_draw_area(0, 0, self._fg_box.get_allocation()[2], self._fg_box.get_allocation()[3])
		
	def _onAreaExpose(self, widget, event):
		x = 0
		height_difference = self._bg_box.get_allocation()[3] - self._fg_box.get_allocation()[3]
		height_difference = float(height_difference)
		value_difference = self._min_value - self._max_value
		y = (height_difference/value_difference)*(self._current_value - self._max_value)
		y = int(y)
		self.move(self._fg_box, x, y)

	def _onIndicatorMotion(self, widget, event):
		if self.enter_callback != None:
			self.enter_callback(self._name, self._current_value)
		if event.is_hint:
			x, y, mask = event.window.get_pointer()
		else:
			x = event.x
			y = event.y
			mask = event.state
		if mask == gtk.gdk.BUTTON1_MASK:
			placement_difference = self._fg_box.get_allocation()[1] - self._bg_box.get_allocation()[1]
			height_difference = self._bg_box.get_allocation()[3] - self._fg_box.get_allocation()[3]
			height_difference = float(height_difference)
			if placement_difference + y > height_difference:
				y = height_difference - placement_difference
			elif placement_difference + y < 0:
				y = -(placement_difference)
			variable = int(self._fg_box.get_allocation()[1] + y)
			value_difference = self._min_value - self._max_value
			self._current_value = (value_difference/height_difference)*(variable-self._bg_box.get_allocation()[1]) + self._max_value
			self._current_value = int(self._current_value)
			if self._current_value > self._max_value:
				self._current_value = self._max_value
			elif self._current_value < self._min_value:
				self._current_value = self._min_value
			#print self._current_value
			self.value_callback(self._current_value)
			if self.enter_callback != None:
				self.enter_callback(self._name, self._current_value)
			self._fg_box.queue_draw_area(0, 0, self._fg_box.get_allocation()[2], self._fg_box.get_allocation()[3])

	def getCurrentValue(self):
		return self._current_value

	def setValueCallback(self, callback, data=None):
		self.value_callback = callback
		self.value_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_value)
		
	def _onLeaveNotify(self, widget, event):
		mask = event.state
		should_leave = False
		
		if event.x < 0.0:
			should_leave = True
		if event.x > self._fg_box.get_allocation()[2]:
			should_leave = True
		if (event.y < self._fg_box.get_allocation()[1] - self._bg_box.get_allocation()[1]):
			should_leave = True
		if (event.y > self._fg_box.get_allocation()[1] - self._bg_box.get_allocation()[1] + self._fg_box.get_allocation()[3]):
			should_leave = True
		if (mask != gtk.gdk.BUTTON1_MASK) and (should_leave == True):
			if self.leave_callback != None:
				self.leave_callback()


class HSlider(gtk.Fixed):
	
	def __init__(self, bg_path, fg_path, min_value=0, max_value=100, current_value=0, name=""):
		self._min_value = min_value
		self._max_value = max_value
		self._current_value = current_value
		self._name = name
		gtk.Fixed.__init__(self)
		self.setValueCallback(None)
		self.setEnterCallback(None)
		self.setLeaveCallback(None)
		self._bg_box = gtk.EventBox()
		background_img = gtk.Image()
		background_img.set_from_file(bg_path)
		background_img.show()
		self._bg_box.add(background_img)
		self._bg_box.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
		self._bg_box.connect("button-press-event", self._onBackgroundPress)
		self._bg_box.connect("enter-notify-event", self._onEnterNotify)
		self._bg_box.connect("leave-notify-event", self._onLeaveNotify)
		self._fg_box = gtk.EventBox()
		self._nub_img = gtk.Image()
		self._nub_img.set_from_file(fg_path)
		self._nub_img.show()
		self._fg_box.add(self._nub_img)
		self._fg_box.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
		self._fg_box.connect("expose-event", self._onAreaExpose)
		self._fg_box.connect("motion_notify_event", self._onIndicatorMotion)
		self._bg_box.connect("enter-notify-event", self._onEnterNotify)
		self._fg_box.connect("leave-notify-event", self._onLeaveNotify)
		self.put(self._bg_box, 0, 0)
		self.put(self._fg_box, 0, 0)
		self._bg_box.show()
		self._fg_box.show()
		
		
	def _onBackgroundPress(self, widget, event):
		x = int(self._fg_box.get_allocation()[0])
		width_difference = self._bg_box.get_allocation()[2] - self._fg_box.get_allocation()[2]
		width_difference = float(width_difference)
		if event.y > width_difference:
			x = int(self._bg_box.get_allocation()[0] + width_difference)
		else:
			x = int(self._bg_box.get_allocation()[0] + event.x)
		value_difference = self._max_value - self._min_value
		self._current_value = (value_difference/width_difference)*(x-self._bg_box.get_allocation()[0]) + self._min_value
		self._current_value = int(self._current_value)
		if self._current_value > self._max_value:
			self._current_value = self._max_value
		elif self._current_value < self._min_value:
			self._current_value = self._min_value
		#print self._current_value
		self.value_callback(self._current_value)
		if self.enter_callback != None:
			self.enter_callback(self._name, self._current_value)
		self._fg_box.queue_draw_area(0, 0, self._fg_box.get_allocation()[2], self._fg_box.get_allocation()[3])
		
	def _onAreaExpose(self, widget, event):
		y = 0
		width_difference = self._bg_box.get_allocation()[2] - self._fg_box.get_allocation()[2]
		width_difference = float(width_difference)
		value_difference = self._max_value - self._min_value
		x = (width_difference/value_difference)*(self._current_value - self._min_value)
		x = int(x)
		self.move(self._fg_box, x, y)

	def _onIndicatorMotion(self, widget, event):
		if self.enter_callback != None:
			self.enter_callback(self._name, self._current_value)
		if event.is_hint:
			x, y, mask = event.window.get_pointer()
		else:
			x = event.x
			y = event.y
			mask = event.state
		if mask == gtk.gdk.BUTTON1_MASK:
			placement_difference = self._fg_box.get_allocation()[0] - self._bg_box.get_allocation()[0]
			y = int(self.get_allocation()[1])
			width_difference = self._bg_box.get_allocation()[2] - self._fg_box.get_allocation()[2]
			width_difference = float(width_difference)
			if placement_difference + x > width_difference:
				x = width_difference - placement_difference
			elif placement_difference + y < 0:
				x = -(placement_difference)
			variable = int(self._fg_box.get_allocation()[0] + x)
			value_difference = self._max_value - self._min_value
			self._current_value = (value_difference/width_difference)*(variable-self._bg_box.get_allocation()[0]) + self._min_value
			self._current_value = int(self._current_value)
			if self._current_value > self._max_value:
				self._current_value = self._max_value
			elif self._current_value < self._min_value:
				self._current_value = self._min_value
			#print self._current_value
			self.value_callback(self._current_value)
			if self.enter_callback != None:
				self.enter_callback(self._name, self._current_value)
			self._fg_box.queue_draw_area(0, 0, self._fg_box.get_allocation()[2], self._fg_box.get_allocation()[3])

	def getCurrentValue(self):
		return self._current_value

	def setValueCallback(self, callback, data=None):
		self.value_callback = callback
		self.value_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_value)
		
	def _onLeaveNotify(self, widget, event):
		mask = event.state
		should_leave = False
		
		if (event.x < self._fg_box.get_allocation()[0] - self._bg_box.get_allocation()[0]):
			should_leave = True
		if (event.x > self._fg_box.get_allocation()[0] - self._bg_box.get_allocation()[0] + self._fg_box.get_allocation()[2]):
			should_leave = True
		if event.y < 0.0:
			should_leave = True
		if event.y > self._fg_box.get_allocation()[3]:
			should_leave = True

		if (mask != gtk.gdk.BUTTON1_MASK) and (should_leave == True):
			if self.leave_callback != None:
				self.leave_callback()