#!/usr/bin/python
import pygst
pygst.require("0.10")
import gst
import pygtk
import gtk
import gtk.glade
import time

class Instrument:
	def __init__(self, project, filename, insnum):

		self.project = project

		gst.debug("Adding an instrument gnlcomposition")
		self.comp = gst.element_factory_make("gnlcomposition", "mycomposition" + str(insnum))
		self.comp.connect("pad-added", self.project.OnPad, self)

		self.compconvert = gst.element_factory_make("audioconvert", "compconvert" + str(insnum))
		self.project.pipeline.add(self.compconvert)
		
		gst.debug("Adding a gnlfilesource")
		self.audio = gst.element_factory_make("gnlfilesource", "audio" + str(insnum))
		self.audio.set_property("location", filename)
		self.audio.set_property("start", long(0))
		self.audio.set_property("duration", long(60) * gst.SECOND)
		self.comp.add(self.audio)
		self.project.pipeline.add(self.comp)

		self.volume = gst.element_factory_make("volume", "volume" + str(insnum))
		self.project.pipeline.add(self.volume)

		self.level = gst.element_factory_make("level", "level" + str(insnum))
		self.project.pipeline.add(self.level)
		gst.debug("Adding an instrument audioconvert")
		self.convert = gst.element_factory_make("audioconvert", "convert" + str(insnum))
		self.project.pipeline.add(self.convert)
		self.resample = gst.element_factory_make("audioresample", "resample" + str(insnum))
		self.project.pipeline.add(self.resample)

		# effects stuff:

		self.effect_delay = gst.element_factory_make("ladspa-delay-5s", "effect" + str(insnum))
		self.project.pipeline.add(self.effect_delay)
		
		self.endconvert = gst.element_factory_make("audioconvert", "endconvert" + str(insnum))
		self.project.pipeline.add(self.endconvert)
			
		self.compconvert.link(self.effect_delay)
		self.effect_delay.link(self.endconvert)
		self.endconvert.link(self.volume)
		self.volume.link(self.level)
		self.level.link(self.convert)
		self.convert.link(self.resample)
		self.resample.link(self.project.masteradder)

class Project:
	def __init__(self):
		print "Running class"

		instruments = []

		self.pipeline = gst.Pipeline("mixer")

		self.bus = self.pipeline.get_bus()
		self.bus.add_signal_watch()
		self.bus.connect("message::error", self.BusMessage)

		gst.debug("Adding master adder")
		self.masteradder = gst.element_factory_make("adder", "masteradder")
		self.pipeline.add(self.masteradder)

		gst.debug("Adding alsasink")

		self.out = gst.element_factory_make("alsasink", "out")
		self.out.set_property("device", "default")
		self.pipeline.add(self.out)

		gst.debug("Linking masteradder to alsasink")

		# need to restrict the format on adder's output
		caps = gst.caps_from_string ("audio/x-raw-int,"
		    "rate=44100,channels=2,endianness=1234,width=16,depth=16,signed=(boolean)true")

		self.masteradder.link(self.out, caps)

		# change the file names to something on your computer
		
		self.ins1 = Instrument(self, "/home/jono/media/audioforjokosher/jonobacon-thelake.ogg", 1)
		##self.ins2 = Instrument(self, "/home/jono/media/audioforjokosher/spheres.mp3", 2)

		#self.ins8 = Instrument(self, "/home/jono/Desktop/testpipeline.ogg", 8)		

	def OnPad(self, comp, pad, instrument):
		print "pad added!"
		gst.debug("Pad added")
		convpad = instrument.compconvert.get_compatible_pad(pad, pad.get_caps())
		pad.link(convpad)

	def Play(self):
		self.pipeline.set_state(gst.STATE_PLAYING)
		print self.pipeline.get_state(0)

	def Stop(self):
		self.pipeline.set_state(gst.STATE_NULL)
		print self.pipeline.get_state(0)

	def BusMessage(self, bus, message):
		st = message.structure
		error, debug = message.parse_error()
		print "!!!! bus message error: " + str(error)
		print "!!!! bus message debug: " + str(debug)
class Main:
	def __init__(self):
		self.project = Project()

		self.wTree = gtk.glade.XML("buggui.glade", "mainwindow")
		
		signals = {
			"on_play_clicked" : self.OnPlay,
			"on_stop_clicked" : self.OnStop,
			"on_quit_clicked" : self.OnQuit,
		}

		self.wTree.signal_autoconnect(signals)

		self.window = self.wTree.get_widget("mainwindow")
		self.window.show_all()

	def OnPlay(self, widget):
		print "play"
		self.project.Play()

	def OnStop(self, widget):
		print "stop"
		self.project.Stop()

	def OnQuit(self, widget):
		gtk.main_quit()

start=Main()
gtk.main()
