#!/usr/bin/env python

from Tkinter import *
import os,regex,string,time,sys

class AppButton(Frame):
  def __init__(self,name,command,parent=None):
    Frame.__init__(self,parent)
    self.name=name
    self.command=command
    self.state="waiting";
    self.button=Button(parent,text=self.name,command=self.launch)
    self.button.pack(fill=X,expand=1)

  def launch(self):
    self.button.configure(state=DISABLED)
    self.childpid=os.fork()
    self.state="running";
    if self.childpid == 0:
      pid=os.getpid();
      cmd=["sh","-c","exec %s </dev/null" %(self.command)]
      os.execvp(cmd[0],cmd)
    else:
      self.check()

  def recover(self):
    self.button.configure(state=NORMAL)

  def isdone(self):
    if self.state == "running":
      self.piddone=os.waitpid(self.childpid,os.WNOHANG)
      # -1  no such process
      #  0  not done yet 
      # pid  child finished
      if self.piddone[0]>0:
        self.state="done";
        return 1 
      elif self.piddone[0]==0:
        return 0
      else:
        return -1
    else:
      return 1

  def kill(self):
    if self.state == "running":
      pid=self.childpid
      os.system("kill %(pid)s 2>/dev/null >/dev/null" % vars())
      self.state="killed";

  def check(self):
    if self.isdone()!=0:
      self.recover()
    else:
      self.after(500,self.check)


class Launcher(Frame):
  def __init__(self,appdict,parent=None):
    Frame.__init__(self,parent)
    self.appdict=appdict
    self.applist=self.appdict.keys()
    self.applist.sort()
    self.appbutton={}
    self.sourcebutton={}
    self.f=Frame(parent)
    self.f_left=Frame(self.f)
    self.f_right=Frame(self.f)
    for i in self.applist:
      self.appbutton[i]=AppButton(i,self.appdict[i],self.f_left)
      #self.appbutton[i].pack(fill=X,expand=1,side=LEFT)
      self.sourcebutton[i]=AppButton("source","viewer.tcl "+self.appdict[i],self.f_right)
      #self.sourcebutton[i].pack(fill=X,expand=1,side=RIGHT)

    self.f_left.pack(side=LEFT)
    self.f_right.pack(side=RIGHT)
    self.f.pack(expand=1,fill=X)
    self.f_button=Frame(parent)
    Label(self.f_button,text="-----------------").pack(fill=X,expand=1)
    Button(self.f_button,text="Quit",command=self.quit).pack(fill=X,expand=1)
    self.f_button.pack(expand=1,fill=X)

if __name__ == '__main__':
  appdict={ "Bind Example":"bind_example.tcl",
            "Button":"button_example.tcl",
            "Entry":"entry_example.tcl",
            "Frame":"frame_example.tcl",
            "Hello World":"intro_example.tcl",
            "Label":"label_example.tcl",
            "Listbox":"listbox_example.tcl",
            "Packer #1":"packer_example1.tcl",
            "Packer #2":"packer_example2.tcl",
            "Packer #3":"packer_example3.tcl",
            "Radiobutton":"radiobutton_example.tcl",
            "Srollbar":"scrollbar_example.tcl",
            "File Browser":"browser.tcl",
            "Spline":"spline.tcl" }

  main=Launcher(appdict)
  main.master.title("Tk demo launcher")

  try:
    main.mainloop()
  except KeyboardInterrupt:
    main.quit()



