#!/usr/bin/python
from Tkinter import *

class Panel(Frame):

    def example1(self,event):
     if self.firsttime:
       try:
        import sndobj
        tab = sndobj.HarmTable(10000, 40, sndobj.SAW)
        env = sndobj.Interp(0, 20000, 0.02)
        osc = sndobj.Oscili(tab, 440, 0, None, env)
        fil = sndobj.Reson(1000, 10, osc)
        outp = sndobj.SndRTIO(fil)

        process_period = osc.GetVectorSize()/osc.GetSr()
        count = 0.0
        dur = 1.0
        while count < dur:
            env.DoProcess()
            osc.DoProcess()
            fil.DoProcess()
            outp.Write()
            count += process_period
       except:
          print "no PySndObj module available"  
        
    def example2_procon(self,event):
     try:
      if self.firsttime:
        import sndobj
        self.tab = sndobj.HarmTable(10000, 40, sndobj.SAW)
        self.env = sndobj.Interp(0, 20000, 0.02)
        self.osc = sndobj.Oscili(self.tab, 440, 0, None, self.env)
        self.fil = sndobj.Reson(1000, 10, self.osc)
        self.metered = self.fil
        self.outp = sndobj.SndRTIO(self.fil)
        self.thread = sndobj.SndThread()
        self.thread.AddObj(self.env) 
        self.thread.AddObj(self.osc)
        self.thread.AddObj(self.fil) 
        self.thread.AddObj(self.outp, sndobj.SNDIO_OUT)
        self.firsttime = 0
       
      if not self.thread.GetStatus(): 
       self.thread.ProcOn()
      else:
       print "processing already on"
       
     except:
        print "no PySndObj module available"
             
    def example2_procoff(self,event):
      try:
        if not self.firsttime:
          self.thread.ProcOff()
      except:
        print "no PySndObj module available"

    def example2_slider1(self,event):
        canvas = event.widget
        x = canvas.canvasx(event.x)
        if not self.line1:
         self.line1 =canvas.create_line(x,520,x,540, fill="red")
        item = canvas.find_withtag("current")[0]
        if x  > 700 and x < 900:
          canvas.coords(self.line1, x, 520, x, 540)
          try:
           self.fil.SetFreq(300.0+3000.0*(x-700)/200.0)
          except:
           print "no PySndObj module available"
        
    def example2_slider2(self,event):
        canvas = event.widget
        x = canvas.canvasx(event.x)
        if not self.line2:
         self.line2 =canvas.create_line(x,580,x,600, fill="blue")
        item = canvas.find_withtag("current")[0]
        if x  > 700 and x < 900:
          canvas.coords(self.line2, x, 580, x, 600)
          try:
           self.osc.SetFreq(100.0+300.0*(x-700)/200.0)
          except:
           print "no PySndObj module available"

    def example2_button(self,event):
        canvas = event.widget
        item = canvas.find_withtag("current")[0]
        try:
         self.env.SetDur(0.8)
         self.env.Restart()
        except:
         print "no PySndObj module available"

    def ProcessCallback(self,ignored):
       try: 
        x = abs(self.metered.Output(0)/10)
        self.canvas.coords(self.rect, 620, 650-x, 640, 650)
       except:
        print "no PySndObj module available"

    def setproccb(self,event):
        self.rect = self.canvas.create_rectangle(620, 640, 640, 650, fill="violet")
        try:
         self.thread.SetProcessCallback(self.ProcessCallback, self)
        except:
         print "no PySndObj module available"
         
    def example3(self,event):
        try:
         import sndobj
         self.thread.DeleteObj(self.env)
         self.thread.DeleteObj(self.osc)
         self.thread.DeleteObj(self.fil)
         self.inp = sndobj.SndRTIO(1, sndobj.SND_INPUT)
         self.snd = sndobj.SndIn(self.inp, 1)
         self.cmb = sndobj.Comb(0.5, 0.6, self.snd) 
         self.thread.AddObj(self.snd)
         self.thread.AddObj(self.cmb)
         self.thread.AddObj(self.inp, sndobj.SNDIO_IN)
         self.outp.SetOutput(1, self.cmb)
         self.metered = self.cmb
        except:
          print "no PySndObj module available"

    def splash(self):
      self.screen = Toplevel(self.master)
      self.screen.title("More info & Acknowledgments")
      self.canvas2 = Canvas(self.screen, width=1000, height=750, bg="white")
      self.canvas2.pack()
      self.image = PhotoImage(file="slide.gif")
      self.canvas2.create_image(500,375, image=self.image)

    def translate(self, event):
      self.canvas3.delete(self.zenitem)
      fnt = ("times", 36, "italic")
      self.zenitem = self.canvas3.create_text(500,375,text=zen.zen, fill="blue", font=fnt)
      
    def zensal(self):
      self.screen = Toplevel(self.master)
      self.screen.title("The Zen of ...")
      self.canvas3 = Canvas(self.screen, width=1000, height=750, bg="white")
      self.canvas3.pack()
      fnt = ("times", 36, "italic")
      self.zenitem = self.canvas3.create_text(500,375,text=zen.s, fill="red", font=fnt)
      self.screen.bind("<Return>", self.translate)

    def gens(self):

      # explaining sound objects
      self.itemgens.append(lambda x: self.canvas.create_text(140,30, text="A Sound Object..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(100,100,180,140))
      self.itemgens.append(lambda x: self.canvas.create_text(140,115, text="--SndObj--"))
      self.itemgens.append(lambda x: self.canvas.create_text(140,70, text="input"))
      self.itemgens.append(lambda x: self.canvas.create_line(80,110,100,110))
      self.itemgens.append(lambda x: self.canvas.create_text(70,110, text="sr"))
      self.itemgens.append(lambda x: self.canvas.create_line(80,130,100,130))
      self.itemgens.append(lambda x: self.canvas.create_text(45,130, text="vector size"))
      self.itemgens.append(lambda x: self.canvas.create_line(140,80,140,100))
      self.itemgens.append(lambda x: self.canvas.create_text(245,120, text="enable/disable"))
      self.itemgens.append(lambda x: self.canvas.create_line(180,120,200,120))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(120,125,160,140))
      self.itemgens.append(lambda x: self.canvas.create_text(140,132, text="output"))
      self.itemgens.append(None)

      # connecting sound objects
      self.itemgens.append(lambda x: self.canvas.create_text(410,80, text="Connecting SndObjs..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(400,100,480,125))
      self.itemgens.append(lambda x: self.canvas.create_text(440,115, text=" SndObj1 "))
      self.itemgens.append(lambda x: self.canvas.create_line(440,125,440,140))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(400,140,480,165))
      self.itemgens.append(lambda x: self.canvas.create_text(440,155, text=" SndObj2 "))
      self.itemgens.append(lambda x: self.canvas.create_line(440,165,440,180))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(400,180,480,205))
      self.itemgens.append(lambda x: self.canvas.create_text(440,195, text=" SndObj3 "))
      self.itemgens.append(None)
      
      # doprocess...
      self.itemgens.append(lambda x: self.canvas.create_text(550,80, text="...and processing."))
      self.itemgens.append(lambda x: self.canvas.create_line(490,110,480,110))
      self.itemgens.append(lambda x: self.canvas.create_line(490,150,480,150))
      self.itemgens.append(lambda x: self.canvas.create_line(490,190,480,190))
      self.itemgens.append(lambda x: self.canvas.create_line(490,100,490,190))
      self.itemgens.append(lambda x: self.canvas.create_line(490,100,500,100))
      self.itemgens.append(lambda x: self.canvas.create_line(500,100,505,95))
      self.itemgens.append(lambda x: self.canvas.create_line(500,100,505,105))
      self.itemgens.append(lambda x: self.canvas.create_text(545,100, text="DoProcess()"))
      self.itemgens.append(None)
      
       # explaining sound ios
      self.itemgens.append(lambda x: self.canvas.create_text(740,30, text="A Sound IO..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(700,100,780,140))
      self.itemgens.append(lambda x: self.canvas.create_text(740,115, text="--SndIO--"))
      self.itemgens.append(lambda x: self.canvas.create_text(740,70, text="input"))
      self.itemgens.append(lambda x: self.canvas.create_line(680,110,700,110))
      self.itemgens.append(lambda x: self.canvas.create_text(670,110, text="sr"))
      self.itemgens.append(lambda x: self.canvas.create_line(680,130,700,130))
      self.itemgens.append(lambda x: self.canvas.create_text(650,130, text="channels"))
      self.itemgens.append(lambda x: self.canvas.create_text(860,120, text="vector size (frames)"))
      self.itemgens.append(lambda x: self.canvas.create_line(740,80,740,100))
      self.itemgens.append(lambda x: self.canvas.create_line(780,120,800,120))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(720,125,760,140))
      self.itemgens.append(lambda x: self.canvas.create_text(740,132, text="output"))
      self.itemgens.append(None)
      
      # adding output
      self.itemgens.append(lambda x: self.canvas.create_text(540,215, text="connecting to an output"))
      self.itemgens.append(lambda x: self.canvas.create_line(440,205,440,225))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(400,225,480,250)) 
      self.itemgens.append(lambda x: self.canvas.create_text(440,240, text=" SndIO "))
      self.itemgens.append(lambda x: self.canvas.create_line(480,240,500,240))
      self.itemgens.append(lambda x: self.canvas.create_line(500,240,505,235))
      self.itemgens.append(lambda x: self.canvas.create_line(500,240,505,245))
      self.itemgens.append(lambda x: self.canvas.create_text(530,240, text="Write()"))
      self.itemgens.append(None)

      # tables 
      self.itemgens.append(lambda x: self.canvas.create_text(740,180, text="Tables..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(700,200,780,240))
      self.itemgens.append(lambda x: self.canvas.create_text(740,215, text="--Table--"))
      self.itemgens.append(lambda x: self.canvas.create_text(860,220, text="table size"))
      self.itemgens.append(lambda x: self.canvas.create_line(780,220,800,220))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(720,225,760,240))
      self.itemgens.append(lambda x: self.canvas.create_text(740,232, text="table"))
      self.itemgens.append(None)
      
      # now some code
      code = '''
tab = sndobj.HarmTable(10000, 40, sndobj.SAW)
env = sndobj.Interp(0, 20000, 0.02)
osc = sndobj.Oscili(tab, 440, 0, None, env)
fil = sndobj.Reson(1000, 10, osc)
outp = sndobj.SndRTIO(fil)

count = 0.0
while count < dur:
    env.DoProcess()
    osc.DoProcess()
    fil.DoProcess()
    outp.Write()
    count += process_period
'''
      self.itemgens.append(lambda x: self.canvas.create_rectangle(300,280,580,500, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example1))
      self.itemgens.append(lambda x: self.canvas.create_text(440,375, text=code, fill="blue"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example1))
      self.itemgens.append(None)

      # threads
      self.itemgens.append(lambda x: self.canvas.create_text(800,280, text="Sound Threads..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(720,300,870,340))
      self.itemgens.append(lambda x: self.canvas.create_text(800,315, text="--SndThread--"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(730,325,770,340))
      self.itemgens.append(lambda x: self.canvas.create_text(750,332, text="inlist"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(772,325,817,340))
      self.itemgens.append(lambda x: self.canvas.create_text(795,332, text="proclist"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(820,325,860,340))
      self.itemgens.append(lambda x: self.canvas.create_text(840,332, text="outlist"))
      self.itemgens.append(None)

      # using them
      self.itemgens.append(lambda x: self.canvas.create_text(620,310, text="AddObj()"))
      self.itemgens.append(lambda x: self.canvas.create_line(550,320,710,320))
      self.itemgens.append(lambda x: self.canvas.create_line(710,315,720,320))
      self.itemgens.append(lambda x: self.canvas.create_line(710,325,720,320))
      
      code2 = '''
thread = sndobj.SndThread()
thread.AddObj(env) 
thread.AddObj(osc)
thread.AddObj(fil) 
thread.AddObj(outp, sndobj.SNDIO_OUT)
'''
      self.itemgens.append(lambda x: self.canvas.create_text(800,400, text=code2, fill="purple"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(700,450,780,470, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_procon))
      self.itemgens.append(lambda x: self.canvas.create_text(740,460, text="ProcOn()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_procon))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(800,450,880,470, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_procoff))
      self.itemgens.append(lambda x: self.canvas.create_text(840,460, text="ProcOff()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_procoff))
      self.itemgens.append(None)

      # sliders
      self.itemgens.append(lambda x: self.canvas.create_text(800,510, text="fil.SetFreq()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(700,520,900,540, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<B1-Motion>",self.example2_slider1))
      self.itemgens.append(lambda x: self.canvas.create_text(800,570, text="osc.SetFreq()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(700,580,900,600, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<B1-Motion>",self.example2_slider2))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(760,610,840,630, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_button))
      self.itemgens.append(lambda x: self.canvas.create_text(800,620, text="env.Restart()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example2_button))
      self.itemgens.append(None)

      # callback
      self.itemgens.append(lambda x: self.canvas.create_text(800,640, text="Add a graphic meter", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(730,650,870,670, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.setproccb))
      self.itemgens.append(lambda x: self.canvas.create_text(800,660, text="SetProcessCallback()", fill="purple"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.setproccb))
      self.itemgens.append(None)

      code3 = '''
inp = sndobj.SndRTIO(1, sndobj.SND_INPUT)
snd = sndobj.SndIn(inp, 1)
cmb = sndobj.Comb(0.5, 0.6, snd) 
thread.AddObj(snd)
thread.AddObj(cmb)
thread.AddObj(inp, sndobj.SNDIO_IN)
outp.SetOutput(1, cmb)
'''
      self.itemgens.append(lambda x: self.canvas.create_text(440,530, text="Using inputs..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(300,540,580,660, fill="white"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example3))
      self.itemgens.append(lambda x: self.canvas.create_text(440,600, text=code3, fill="red"))
      self.itemgens.append(lambda x: self.canvas.tag_bind(x, "<ButtonPress>",self.example3))
      self.itemgens.append(None)

      # the future
      self.itemgens.append(lambda x: self.canvas.create_text(130,280, text="The future(?) ..."))
      self.itemgens.append(lambda x: self.canvas.create_rectangle(60,380,200,405))
      self.itemgens.append(lambda x: self.canvas.create_text(130,395, text="Synthesis Engine"))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_line(200,400,210,400))
      self.itemgens.append(lambda x: self.canvas.create_text(225,400, text="C++"))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_line(200,385,220,385))
      self.itemgens.append(lambda x: self.canvas.create_text(255,385, text="other langs"))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_rectangle(60,340,200,365))
      self.itemgens.append(lambda x: self.canvas.create_text(130,355, text="Music Proc Lang"))
      self.itemgens.append(lambda x: self.canvas.create_line(130,365,130,380))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_line(200,352,220,352))
      self.itemgens.append(lambda x: self.canvas.create_text(255,352, text="Python"))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_rectangle(60,300,200,325))
      self.itemgens.append(lambda x: self.canvas.create_text(130,315, text="Patching App"))
      self.itemgens.append(lambda x: self.canvas.create_line(130,325,130,340))
      self.itemgens.append(None)
      self.itemgens.append(lambda x: self.canvas.create_line(200,312,220,312))
      self.itemgens.append(lambda x: self.canvas.create_text(255,312, text="graphic lang"))
      self.itemgens.append(None)
      #self.itemgens.append(lambda x: self.splash())
      #self.itemgens.append(None) 

    def advance(self,event):
        start = self.cnt
        x = 0
        for i in self.itemgens[start:]:
          if i != None:
            x = i(x)
            self.items.append(x)
            self.cnt += 1
          else:
            self.cnt += 1
            break

    def clear(self,event):
        for i in self.items:
         self.canvas.delete(i)
        self.items = []
        self.cnt = 0
        self.canvas.delete(self.line1)
        self.line1 = 0
        self.canvas.delete(self.line2)
        self.line2 = 0
        

    def destroy_last(self):
        for i in self.items:
            self.canvas.delete(i)
      
    def __init__(self, master=None):
      Frame.__init__(self, master)
      self.master = master
      self.master.title("Musical Signal Scripting with PySndObj")
      self.pack()
      self.canvas = Canvas(self, height=700, width=1000)
      self.canvas.pack()
      self.bt1 = self.canvas.create_rectangle(10,10,60,30, fill="red")
      txt = self.canvas.create_text(35,20,text="advance")
      self.bt2 = self.canvas.create_rectangle(10,35,60,55, fill="blue")
      txt2 = self.canvas.create_text(35,45,text="clear")
      self.master.bind("<Return>", self.advance)
      self.canvas.tag_bind(self.bt1,"<ButtonPress>", self.advance)
      self.canvas.tag_bind(txt,"<ButtonPress>", self.advance)
      self.canvas.tag_bind(txt2,"<ButtonPress>", self.clear)
      self.canvas.tag_bind(self.bt2,"<ButtonPress>", self.clear)
      self.items = []
      self.itemgens = []
      self.cnt =0
      self.firsttime = 1
      self.line1 =0
      self.line2 =0
      self.gens()
    


pane = Panel(Tk())

pane.mainloop()

