'''
Created on Jun 12, 2012

@author: manuel
'''
import wx.lib.newevent
import numpy

# this creates an UpdateCanvasEvent even class that will get created
# and sent from the worker thread to the main thread (which is the
# only place that updates to the GUI should happen...lest there be crashes)
(UpdateCanvasEvent, EVT_UPDATE_CANVAS) = wx.lib.newevent.NewEvent()

def enum(**enums):
    '''
    lets one dynamically define a new 'enum' type
    '''
    return type('Enum', (), enums)

def deinterleaveData(inData, nChan):
    '''
    takes a linear array with data points interleaved 
    [a1,b1,c1,a2,b2,c2,....aN-1,bN-1,cN-1,aN,bN]
    and return a (nChan,N) numpy.array with the data deinterleaved
    [[a1,a2,a3,...aN-1],
     [b1,b2,b3,...bN-1],
     [c1,c2,c3,...cN-1]]
    
    if the length of the input array was not a multiple of nChan, 
    the remaining points are returned in remainData.
    Otherwise, remainData is an empty array
    '''
    n = len(inData)
    nToKeep = n - (n % nChan)
    outData = numpy.array(inData[:nToKeep], dtype = int).reshape((-1, nChan)).transpose() #@UndefinedVariable
    remainData = inData[nToKeep:]
    return outData, remainData

def convertInVolts(inData, inMaxChanValues, inChanRanges):
    '''
    converts the int values obtained from comedi to a physical value
    arguments:
    inData: a (nChan,N) numpy array
    inMaxChanValues: a (nChan,1) array containing information about the ranges of each channel in comedi_range structure
    inChanRanges: a (nChan,1) array containing the id of the chanRange used for each channel.
    The actual chanRange will be obtained from comedi using comedi_get_range()
    '''
    nChan, _ = inData.shape
    out = numpy.array(inData, dtype = float) #@UndefinedVariable
    for i in range(nChan):
        out[i] = out[i] * (
                    float(inChanRanges[i].max-inChanRanges[i].min) / float(inMaxChanValues[i])) + \
                    float(inChanRanges[i].min)
    return out