from sugar.activity import activity
import logging

from CsoundServer import *
from CsoundEventSequencer import *

import random
import sys, os
import gtk

import gobject

class CSSimpleStepActivity(activity.Activity):
    orchestra = """
    nchnls = 2

gisin	ftgen	1, 0, 4096, 10, 1

    instr	10

iPitchHigh	= 	8.17579891564 * exp(0.0577622650 * (p4+36))
iPitchLow	= 	8.17579891564 * exp(0.0577622650 * p4)

kPitch    expon    iPitchHigh, p3 * 0.5, iPitchLow

aAmp      line    ampdbfs(-12), p3, 0

a1         oscil	aAmp, kPitch, gisin

    outs	a1, a1
    endin
    """


    def destroy(self, data=None):
        print "Destroy"
        self.sequencer.shutdownServer()
        return True

    def launchServer(self):
        print "Launching Local Server"                
        logging.debug("test")
        server = CsoundServer()
        fd = server.launch()
        
        if fd != None:
            gobject.io_add_watch(fd.fileno(), gobject.IO_IN, self.serverMessages, fd)                 
            print "Successfully Launched Server"
        else:
            print "Problem launching..."

    def __init__(self, handle):
        
        activity.Activity.__init__(self, handle)
        self.connect('destroy', self.destroy)
        
        self.launchServer()
        
        self.set_title('Hello World')
        self.initializeParameters()
                
        # Creates the Toolbox. It contains the Activity Toolbar, which is the
        # bar that appears on every Sugar window and contains essential
        # functionalities, such as the 'Collaborate' and 'Close' buttons.
        toolbox = activity.ActivityToolbox(self)
        self.set_toolbox(toolbox)
        toolbox.show()
        
        
        widgets = self.setupWidgets()
        widgets.show()


        # create the sequencer
        self.sequencer = CsoundEventSequencer("StepSequencer", self.orchestra)        
        # connect to at least one server
        self.sequencer.addConnection("localhost")

        # NOW ITS OKAY TO ISSUE COMMANDS TO THE SEQUENCER (we're connected)
        
        # add a sequencer track
        self.sequencer.requestNewTrack()

        # we want to loop around
        self.sequencer.setLoopEnabled(True)
        self.sequencer.setLoopPoints(0, 4) # start, duration
                        
        # begin playing
        self.sequencer.play()
                
        # Set the button to be our canvas. The canvas is the main section of
        # every Sugar Window. It fills all the area below the toolbox.
        self.set_canvas(widgets)
        

    def tempoSliderChanged(self, widget, data=None):                
        self.sequencer.setTempo(widget.get_value())
        
    def toggle(self, widget, data=None):        
        start = data * 0.25

        if widget.get_active():
            start = data * 0.25
            duration = 0.25
            notenum = 48
            self.sequencer.track(0).requestNewEvent(start, duration, notenum)
        
        else:
            event = self.sequencer.track(0).timeIntersectsEvent(start)
            if event != None:
                self.sequencer.track(0).requestRemoveEvent(event)                
                                                            


    def initializeParameters(self):
        """
        Initialize performance parameters
        """
        self.tempo = 120
        self.maxTempo = 240
        self.minTempo = 30

    def setupWidgets(self):
        """
        Construct the gtk interface - layout of buttons and sliders
        """        
        self.layout = gtk.Layout()
	self.layout.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#C0C0C0"))
        
        self.tempo = 120
        self.maxTempo = 240
        self.minTempo = 30
                
        # value, lower, upper, step_increment, page_increment, page_size
        self.tempoSlider = gtk.HScale(gtk.Adjustment(self.tempo, self.minTempo, self.maxTempo, 1.0, 1.0, 1.0))
        self.tempoSlider.connect("value_changed", self.tempoSliderChanged, self.tempoSlider)
        self.tempoSlider.set_update_policy(gtk.UPDATE_CONTINUOUS)
        self.tempoSlider.set_size_request(400, 30)
        self.tempoSlider.show()
        
        tempoLabel = gtk.Label('tempo')
        tempoLabel.show()
        patternLabel = gtk.Label('pattern')
        patternLabel.show()
                
        self.layout.put(tempoLabel, 25, 50)        
        self.layout.put(self.tempoSlider, 25, 85)
        self.layout.put(patternLabel, 25, 150)
        
        self.buttons = []
        
        for i in range(16):
            button = gtk.ToggleButton(" ")
            button.connect("clicked", self.toggle, i)
            button.show()
            self.layout.put(button, 35 * i + 25, 185)
            
            # keep track of the button
            self.buttons.append(button)

        return self.layout



    def serverMessages(self, source, condition, userData = None):
        print userData.readline(),
        return True

    def csoundMessages(self, message):
        message.display("Csound")
        pass
