#########################################################
# A generic Jam-O-Drum class to interface with the drum pads
# Author Jen Smith (jsmith2)
# Last Updated Aug 11, 2004
#########################################################

from globals import * #these are our global definey thigns
import midipy
from types import ListType
from direct.showbase import DirectObject

#this is the midi signal we get
PAD_2 = 60
PAD_3 = 65
PAD_0 = 64
PAD_1 = 62


#python doesn't make anythign private- so be nice and use the functions
#instead of accessing data directly
class DrumPads(DirectObject.DirectObject):

    #****************************************************************************
    #Constructor for a Drumpads object
    #****************************************************************************/
    def __init__( self ):
        self.midi=None
        self.mIsLoaded=False
        
    #****************************************************************************
    #Initialize the drum pads.
    #@param pDeviceID id of MIDI device controlling drum pads.
    #@return true on success, false on failure
    #@todo figure out how to print error messages
    #****************************************************************************/
    def Start(self): 
        
        #cheap jamodrum emulator
        self.accept('k', self.Handler, [PAD_0, 1])
        self.accept('d', self.Handler, [PAD_1, 1])
        self.accept('e', self.Handler, [PAD_2, 1])
        self.accept('i', self.Handler, [PAD_3, 1]) 
        try:
            midipy.closeInDevice()
            num_dev=midipy.getNumMidiInDevices()
            print num_dev , "midi device(s) found:"
            m_dev = midipy.getMidiInDevice()
            print m_dev
            if(num_dev<1):
                print "no midi devices found"
                self.mIsLoaded = False
            else:
                self.mIsLoaded = True
        except:
            print "no midi devices found"
            self.mIsLoaded = False
        
        if self.mIsLoaded and type(m_dev) is ListType:
                print midipy.openInDevice(m_dev[0]) 
                print midipy.startInDevice()
                midipy.setChannel('all')#without this you get segfaults *(

           
    #****************************************************************************
    #Clear out drumpad data
    #@todo add error messages and such
    #***************************************************************************/     
    def Clear(self):
        for p in self.mDrumPads:
            p=PAD_NOHIT

    #****************************************************************************/    
    #See if drumpads were loaded successfully- that is, if the midi device was found were found.
    #@return True is joysticks have been loaded
    #****************************************************************************/  
    def isLoaded(self):
        return self.mIsLoaded
    
    #****************************************************************************
    #Retrieve state of requested Drumpad.
    #@param pPad requested pad.
    #@return state of pPad.
    #****************************************************************************/
    def GetPadState(self,pPad):
        return self.mDrumPads[pPad]



    def Poll(self):
        if self.mIsLoaded:
            msg=midipy.returnMidiMsg()
            midipy.flush()
            if not msg == -1:
                print msg
                self.Handler(msg[2], msg[3])
        
    #****************************************************************************
    #Handle drumpad hits
    #@param pPad pad whose state we are updating
    #@param pValue velocity passed pad was hit at
    #****************************************************************************/
    def Handler(self, pPad, pValue): 
        station=-1
        if pPad == PAD_0:
            station=STATION_0
        elif pPad == PAD_1:
            station=STATION_1
        elif pPad == PAD_2:
            station=STATION_2
        elif pPad == PAD_3:
            station=STATION_3
        print "station ", station," hit:", pValue 
        s="HIT_"+str(station)
        messenger.send(s) 
        










