//#ifndef CC_MTK_LOADER

//-----------------------------------------------------------------------------
// Static variables
//-----------------------------------------------------------------------------

#define NUM_SLOT 32
#define NUM_LENGTH   64
static UINT8 **_aIRHistogram = 0;  //[NUM_SLOT][NUM_LENGTH]
static UINT8 **_aOffOnHistogram = 0;  //[2][NUM_LENGTH];  //in order to record off+on0 and off+on1

static UINT8 _u1StartRecord = 0;
static UINT32 _u4TestKeyCode = 0xe0;
static UINT8 _u1TestBitCount = 8;

//error counters
static UINT16 _u2ErrorGuideC = 0;
static UINT16 _u2GoodGuideC = 0;
static UINT16 _u2BadGuidePulseC = 0;
static UINT16 _u2OnlyBadTimeOffC = 0;
static UINT16 _u2TimeOffStrictC = 0;
static UINT16 _u2OnlyBadTimeOn0C = 0;
static UINT16 _u2OnlyBadTimeOn1C = 0;
static UINT16 _u2ErrOthersC = 0;

//allocate memory for histogram
//if memory is not released, do nothing
//NOTE: data is not initialized to 0
static void initialize_histogram_memory(void)
{
    void *pBuffer = 0;
    UINT8 *pHistogramStart = 0;
    UINT32 i;

    if (_aIRHistogram != 0 || _aOffOnHistogram != 0)
    {
        Printf("IRDbg: memory of _aIRHistogram or _aOffOnHistogram is not released\n");
        return ;
    }

    pBuffer = x_mem_alloc(sizeof(UINT8*)*(NUM_SLOT+2) + sizeof(UINT8)*(NUM_SLOT+2)*NUM_LENGTH);
    if (0==pBuffer)
    {
        Printf("IRDbg: allocate memory for pBuffer fail\n");
        return ;
    }
    
    _aIRHistogram = (UINT8**)pBuffer;
    _aOffOnHistogram = (UINT8**)(pBuffer + sizeof(UINT8*)*NUM_SLOT);
    
    pHistogramStart = (UINT8*)(pBuffer + sizeof(UINT8*)*(NUM_SLOT+2));
    
    for (i=0; i<NUM_SLOT; ++i)
    {
        _aIRHistogram[i] = pHistogramStart + i*NUM_LENGTH;
    }
    _aOffOnHistogram[0] = pHistogramStart + NUM_SLOT*NUM_LENGTH;
    _aOffOnHistogram[1] = pHistogramStart + (NUM_SLOT+1)*NUM_LENGTH;
}
//release histogram memory
//reset _aIRHistogram and _aOffOnHistogram to 0
static void release_histogram_memory(void)
{
    if (_aIRHistogram)
    {
        x_mem_free(_aIRHistogram);
        _aIRHistogram = 0;
        _aOffOnHistogram = 0;
    }
}
//set data in histogram to 0
static void set_histogram_to_0(void)
{
    UINT8 i=0, j=0;
    for (i=0; i<NUM_SLOT; ++i)
    {
        for (j=0; j<NUM_LENGTH; ++j)
        {
            _aIRHistogram[i][j] = 0;
        }
    }
    for (j=0; j<NUM_LENGTH; ++j)
    {
        _aOffOnHistogram[0][j] = 0;
        _aOffOnHistogram[1][j] = 0;
    }
}
//add data to histogram
//only active if _u1StartRecord > 0
static void add_histogram(UINT32 *pu4TimeSlot, UINT32 u4SlotNum)
{
    UINT8 i=0, j=0;
    UINT32 keyCode = _u4TestKeyCode;
    if (_u1StartRecord)
    {
        if (pu4TimeSlot[0]*u4IrPulseTimeUnit < 1000)
        {
            ++_u2ErrorGuideC;
            return;
        }
        else
        {
            ++_u2GoodGuideC;
        }
        if (u4SlotNum > NUM_SLOT)
            u4SlotNum = NUM_SLOT;
        for (i=0; i<u4SlotNum; ++i)
        {
            j = pu4TimeSlot[i];
            if (j >= NUM_LENGTH)
                j = NUM_LENGTH - 1;
            _aIRHistogram[i][j] += 1;
        }
        //deal with off+on0 and off+on1
        for (i=1; i<u4SlotNum; i+=2)
        {
            j = pu4TimeSlot[i]+pu4TimeSlot[i+1];
            if (j >= NUM_LENGTH)
                j = NUM_LENGTH - 1;
                
            if(keyCode & 1)
            {
                _aOffOnHistogram[1][j] += 1;
            }
            else
            {
                _aOffOnHistogram[0][j] += 1;
            }
            keyCode >>= 1;
        }
    }
}
//set error counters to 0
static void clear_error_counters(void)
{
    _u2ErrorGuideC = 0;
    _u2GoodGuideC = 0;
    _u2BadGuidePulseC = 0;
    _u2OnlyBadTimeOffC = 0;
    _u2TimeOffStrictC = 0;
    _u2OnlyBadTimeOn0C = 0;
    _u2OnlyBadTimeOn1C = 0;
    _u2ErrOthersC = 0;
}
static void add_error_counters(UINT8 index)
{
    if (_u1StartRecord)
    {
        switch(index)
        {
            case 0: ++_u2ErrorGuideC;     break;
            case 1: ++_u2GoodGuideC;      break;
            case 2: ++_u2BadGuidePulseC;  break;
            case 3: ++_u2OnlyBadTimeOffC; break;
            case 4: ++_u2TimeOffStrictC;  break;
            case 5: ++_u2OnlyBadTimeOn0C; break;
            case 6: ++_u2OnlyBadTimeOn1C; break;
            case 7: ++_u2ErrOthersC;      break;
        }
    }
}
static void dump_error_counters(void)
{
    Printf("error/good guide: %d %d\n", _u2ErrorGuideC, _u2GoodGuideC);
    Printf("BadGuidePulse: %d\n", _u2BadGuidePulseC);
    Printf("OnlyBadTimeOff: %d\n", _u2OnlyBadTimeOffC);
    Printf("TimeOffStrict: %d\n", _u2TimeOffStrictC);
    Printf("OnlyBadTimeOn0: %d\n", _u2OnlyBadTimeOn0C);
    Printf("OnlyBadTimeOn1: %d\n", _u2OnlyBadTimeOn1C);
    Printf("ErrOthers: %d\n", _u2ErrOthersC);
}
//external functions
//initialize histogram
void initialized_histogram(void)
{
    release_histogram_memory();
    initialize_histogram_memory();
    set_histogram_to_0();
}
//release histogram
void destroy_histogram(void)
{
    release_histogram_memory();
}
//dump _aIRHistogram
void dump_histogram(void)
{
    UINT8 i=0, j=0;
    Printf("unit: %d\n", u4IrPulseTimeUnit);
    Printf("error/good guide: %d %d\n", _u2ErrorGuideC, _u2GoodGuideC);
    for (i=0; i<NUM_SLOT; ++i)
    {
        for (j=0; j<NUM_LENGTH; ++j)
        {
            Printf ("\t%d", _aIRHistogram[i][j]);
        }
        Printf("\n");
    }
}
//start to record
void start_record(UINT32 keyCode, UINT8 bitCount)
{
    _u1StartRecord = 1;
    _u4TestKeyCode = keyCode;
    _u1TestBitCount = bitCount;
}
//stop to record
void stop_record(void)
{
    _u1StartRecord = 0;
}
//clear histogram and error count
void clear_record(void)
{
    set_histogram_to_0();
    clear_error_counters();
}
//according to key code, shrink _aIRHistogram to off/on0/on1 histograms
void shrink_and_dump_record(void)
{
    //assume menu key
    UINT16 offHistogram[NUM_LENGTH];
    UINT16 on0Histogram[NUM_LENGTH];
    UINT16 on1Histogram[NUM_LENGTH];
    //define key code here
    UINT32 keyCode = _u4TestKeyCode;
    UINT8 bitCount=_u1TestBitCount;
    
    UINT8 i=0, j=0;
    //initialize
    for (j=0; j<NUM_LENGTH; ++j)
    {
        offHistogram[j] = 0;
        on0Histogram[j] = 0;
        on1Histogram[j] = 0;
    }
    //collect
    for (i=0; i<bitCount; ++i)
    {
        for (j=0; j<NUM_LENGTH; ++j)
            offHistogram[j] += _aIRHistogram[1+2*i][j];
    }
    for (i=0; i<bitCount; ++i)
    {
        if(keyCode & 1)
        {
            for (j=0; j<NUM_LENGTH; ++j)
                on1Histogram[j] += _aIRHistogram[2+2*i][j];
        }
        else
        {
            for (j=0; j<NUM_LENGTH; ++j)
                on0Histogram[j] += _aIRHistogram[2+2*i][j];
        }
        keyCode >>= 1;
    }
    //print
    Printf("guide");
    for (j=0; j<NUM_LENGTH; ++j)
        Printf("\t%d", _aIRHistogram[0][j]);
        
    Printf("\nOff");
    for (j=0; j<NUM_LENGTH; ++j)
        Printf("\t%d", offHistogram[j]);
    
    Printf("\nOn0");
    for (j=0; j<NUM_LENGTH; ++j)
        Printf("\t%d", on0Histogram[j]);

    Printf("\nOn1");
    for (j=0; j<NUM_LENGTH; ++j)
        Printf("\t%d", on1Histogram[j]);

    Printf("\nOff+On0");
    for (j=0; j<NUM_LENGTH; ++j)
    {
        Printf ("\t%d", _aOffOnHistogram[0][j]);
    }
    Printf("\nOff+On1");
    for (j=0; j<NUM_LENGTH; ++j)
    {
        Printf ("\t%d", _aOffOnHistogram[1][j]);
    }
    Printf("\n");
    dump_error_counters();
}
//#endif /* CC_MTK_LOADER */


