/**
* Copyright(c) 2011 Sunmedia Technologies - All Rights Reserved.
*
* @file
*
* @brief Gives the functionalities for quering as well as manipulating
* the events data related to certail service.
*
*/
#include <ctype.h>
#include "customize.h"
#include "al_event.h"
#include "ai_event.h"
#include "ai_time.h"
#include "mid_siutil_dvb.h"
#include "al_database.h"
#include "ai_debug_config.h"
#include "mid_playback.h"
#include "al_area_info.h"
#include "unicode.h"
#include "al_fw.h"

static AI_EventCallback pfuncallback;
static al_bool al_event_init = al_false;
#ifdef SUPPORT_CHNSCAN_COLLECT_EIT
MID_EPG_Handle_t EPGhdl;
#else
static MID_EPG_Handle_t EPGhdl;
#endif
static al_uint8 *langcode[2] = {NULL, NULL};
static al_int8 *country_code;
static al_uint8 al_epg_DTG_support = al_false;
static INT32 g_sdOrgGMTOffset = 0;
static MID_EPGInit_t stEpgInit;

/* debug and error print */
#if EPG_DEBUG_FLAG
	#define EPG_DEBUG_MESSAGE(fmt, arg...) \
	do { \
		UMFDBG(0,"[Debug]%s: %d Line ", __FUNCTION__, __LINE__); \
		UMFDBG(0,fmt, ##arg); \
	} while(0)
#else
	#define EPG_DEBUG_MESSAGE(fmt, arg...);
#endif

#if EPG_ERROR_FLAG
	#define EPG_ERROR_MESSAGE(fmt, arg...) \
	do { \
		UMFDBG(0,"[Error]%s: %d Line ", __FUNCTION__, __LINE__); \
		UMFDBG(0,fmt, ##arg); \
	} while(0)
#else
	#define EPG_ERROR_MESSAGE(fmt, arg...);
#endif

#if EPG_DEBUG_FLAG
void printevent(void);
#endif

static al_bool _AI_Event_IsContainLangCtrlCode(UINT8 *str)
{
	al_bool ret = al_false;

	if (str[0] <= 0x14)
	{
		ret = al_true;
	}

	return ret;
}
static UINT8 _AI_Event_GetLangCtrlCode(UINT8 *p_ISO639LangCode, UINT8 *langCode)
{
	UINT8 ret = 0;

	if (al_null == langCode || al_null == p_ISO639LangCode)
	{
		return 0;
	}
	if (strncasecmp((char *)p_ISO639LangCode, "chi", 3) == 0)
	{
		*langCode = 0x13;
		ret = 0x13;
	}

	return ret;
}
static void _AI_EventCallback(MID_EPGEvent_t enEvent, void* pParam)
{
	CDBIHandle_t hdl = 0;
	UINT16 ts_id = 0;
	UINT16 on_id = 0;
	UINT16 ser_id = 0;

	if (pParam == al_null)
	{
		EPG_DEBUG_MESSAGE("Error: %s(EPG_EVENT_ADDED) but no param!\n", __FUNCTION__);
		return;
	}

	if (enEvent == EPG_EVENT_ADDED
		|| enEvent == EPG_EVENT_NOW_ADDED
		|| enEvent == EPG_EVENT_NOW_MODIFIED
		|| enEvent == EPG_EVENT_MODIFIED
		|| enEvent == EPG_EVENT_NOW_DELETE
		|| enEvent == EPG_EVENT_DELETED
		|| enEvent == EPG_ALLEVENTS_DELETED)
	{
		MID_EPGEventCallback_t *param;
	 	param = (MID_EPGEventCallback_t* )pParam;
		if (param->event_type == EVENT_TYPE_NOW ||param->event_type == EVENT_TYPE_NEXT)
		{
			if (pfuncallback != al_null)
			{
				MID_PlaybackGetCurProgHandle(NULL, &hdl);

				CDBIGetRecBySymbol(hdl, &ts_id, (UINT8 *)"usTsId");
				CDBIGetRecBySymbol(hdl, &on_id, (UINT8 *)"usOrigNetId");
				CDBIGetRecBySymbol(hdl, &ser_id, (UINT8 *)"usServiceId");

				if (param->event_type == EVENT_TYPE_NOW
					&& ts_id == param->tranport_id
					&& on_id == param->original_network_id
					&& ser_id == param->service_id)
				{
					pfuncallback(AL_EVENT_NOWNEXT_EVNET_UPDATE, &param->epg_handle);
				}
				else
				{
					pfuncallback(AL_EVENT_NOWNEXT_EVNET_UPDATE, al_null);
				}
			}
		}
		else if(param->event_type == EVENT_TYPE_SCHEDULE || param->event_type == EVENT_TYPE_OTHER)
		{
			if (pfuncallback != al_null)
			{
				pfuncallback(AL_EVENT_SCHEDULE_EVNET_UPDATE, al_null);
			}
		}
	}
	else if (enEvent == EPG_GET_SYSTEMTIME)
	{
		al_uint32 CurrTime = 0;
		
		if (pParam != al_null)
		{
			AL_Time_GetRawTimeInSecs(&CurrTime);
			*((UINT32* )pParam) = CurrTime;
		}
	}
	else if (enEvent == EPG_CHECK_SRVEXIST)
	{
		MID_ServLocator_t* pSrvLoc = NULL;
		AL_Serv_SearchKey_t stSearchKey;
		AL_RecHandle_t hProgHdl = AL_DB_INVALIDHDL;
		AL_DB_EDBType_t eDBType = AL_DBTYPE_MAX;
		pSrvLoc = pParam;
		memset(&stSearchKey, 0, sizeof(stSearchKey));

		if ((MID_SUCCESS != MID_PlaybackGetCurProgHandle(al_null, &hProgHdl))
			|| (hProgHdl == AL_DB_INVALIDHDL))
		{
			return;
		}
		if (AL_SUCCESS != AL_DB_GetRecordType(hProgHdl, &eDBType, al_null))
		{
			return;
		}
		
		stSearchKey.eDBType = eDBType;
		stSearchKey.eRecType = AL_RECTYPE_DVBSERVICE;
		stSearchKey.eSearchField = AL_SRV_SEARCHFIELD_ORIGNETID
								| AL_SRV_SEARCHFIELD_TSID
								| AL_SRV_SEARCHFIELD_SRVID;
		stSearchKey.u16OrigNetId = pSrvLoc->original_network_id;
		stSearchKey.u16TsId = pSrvLoc->tranport_id;
		stSearchKey.u16ServId = pSrvLoc->service_id;
		hProgHdl = AL_DB_INVALIDHDL;
		if ((AL_SUCCESS == AL_DB_GetMatchedRecord((AL_DB_RecordMatchFunc)AL_Serv_MatchRecBySearchKey,
			(al_void *)&stSearchKey, eDBType, AL_RECTYPE_DVBSERVICE, AL_DB_REQ_GETFIRST, &hProgHdl))
			&& (hProgHdl != AL_DB_INVALIDHDL))
		{
			pSrvLoc->original_network_id = 0xffff;
			pSrvLoc->tranport_id = 0xffff;
			pSrvLoc->service_id = 0xffff;
		}
	}
}

static AL_Return_t _AI_Event_GetEventRating(MID_EPG_EventHandle_t eventhdl, al_uint8 *Rating)
{
	al_uint16 ratingdesc_offset = 0;
	bool parsing_status = al_false;
	al_uint8 desc[MAX_DES_LEN] = {0};
	al_uint8 tempPR = 0;
	al_uint8 desclen = 0;
	al_uint8 desc_offset = 0;

	if (MID_EPG_SUCCESS == MID_EPGGetDesc(EPGhdl,
		eventhdl, DESCR_PARENTAL_RATING, &ratingdesc_offset, &parsing_status, desc))
	{
		desclen = desc[1];
		if (desclen < 4)
		{
			return AL_FAILURE;
		}
		while (desclen)
		{
			tempPR = desc[desc_offset+5];
#ifndef CONFIG_ISDB_SYSTEM
			/* modify by qinhe , for SGP not need thranslate rating value */
			al_uint8 u8CountryId = MAX_AREA;
			frmwrk_pfOpConext_t pfPSIMonGetContext = al_null;
			AL_FW_GetContextCb( &pfPSIMonGetContext );

			pfPSIMonGetContext( FW_CONTEXT_TYPE_COUNTRY_ID , FW_CONTEXT_OP_TYPE_READ, (al_void *)&u8CountryId, 0 );
			#ifdef CONFIG_DVB_SYSTEM
			if( u8CountryId == AREA_SINGAPORE
#ifdef SUPPORT_THA_PARENT_LOCK
                || u8CountryId == AREA_THAILAND
#endif
                )
			{
				//*Rating = tempPR;
			}
			else
			#endif
			{
				if(tempPR > 0 && tempPR <= 0xf)	//Normal Case; follow EN 300 468
				{
					tempPR += 3;
				}
				else	//for specific countries & undefined PR, set MSB to 1
				{
					tempPR |= 0x80;
				}
			}
			if (toupper(desc[desc_offset+2]) == toupper(country_code[0])
				&& toupper(desc[desc_offset+3]) == toupper(country_code[1])
				&& toupper(desc[desc_offset+4]) == toupper(country_code[2]))
			{
				if( *Rating != tempPR )
				{
					*Rating = tempPR;
				}
				break;
			}
			else
			{
				if( *Rating != tempPR )
				{
					*Rating = tempPR;
				}
			}
#else
			*Rating = tempPR;
#endif
			desclen -=4;
			desc_offset += 4;
		}

		return AL_SUCCESS;
	}

	return AL_FAILURE;
}

static AL_Return_t _AI_Event_FillEventName(MID_SIDesc_EventDetail_t *pstMidEventDetails,
	al_uint8 *event_name)
{
	al_uint32 u32NameLen = 0;
	
	al_uint8 ctrlCode = 0;

	if (pstMidEventDetails == al_null ||event_name == NULL)
	{
		EPG_ERROR_MESSAGE("null ptr\n");
		return AL_INVALID_PARAM;
	}
	al_uint8 *pName = event_name;

	memset(pName, 0x0, MAX_DATA_SIZE);

	u32NameLen = pstMidEventDetails->event_name_length;

	if( u32NameLen > MAX_DATA_SIZE )
	{
		u32NameLen = MAX_DATA_SIZE;
	}

	MID_CmnTransStrWithEllipsis(pstMidEventDetails->event_name, (al_uint32*)&u32NameLen, MAX_DATA_SIZE);

	if (_AI_Event_IsContainLangCtrlCode(pstMidEventDetails->event_name))
	{
		memcpy(pName, pstMidEventDetails->event_name, u32NameLen);
	}
	else
	{
		if (_AI_Event_GetLangCtrlCode(pstMidEventDetails->iso_639_code, &ctrlCode))
		{
			pName[0] = ctrlCode;
			memcpy(&pName[1], pstMidEventDetails->event_name, u32NameLen);
			u32NameLen++;
		}
		else
		{
			memcpy(pName, pstMidEventDetails->event_name, u32NameLen);
		}
	}

//#ifdef CONFIG_SUPPORT_DTG_CERTIFICATION
	if( u32NameLen > 0 )
	{
		al_uint32 len = MID_CmnDecompressString(pName, u32NameLen);

		if(len > u32NameLen && len < MAX_DATA_SIZE)
		{
			u32NameLen = (al_uint32)len;
		}

		MID_CmnTransStrWithSpeciChar(pName, u32NameLen);
		MID_CmnTransStrWithoutControlChar(pName, u32NameLen);
	}
//#endif
#ifdef SUPPORT_SHOW_0X00_DRAW_STR
	if( al_epg_DTG_support && u32NameLen > 0 )
	{
		MID_CmnTransStrWith00(pName, u32NameLen);
	}
#endif

	if(u32NameLen > 0)
	{
		MID_CmnTransStrWithoutSpeciChar(pName, u32NameLen);
	}

	pName[u32NameLen] = 0;

#ifdef NEW_FONT
	al_uint32 u32CodePage = 0xff;
	al_uint8 *pExtText = al_null;
	al_int32 i32Len = 0;

	i32Len = u32NameLen;
	AL_Event_GetCodePage(&u32CodePage, pName, &i32Len);
	if (u32CodePage == 0xff)
	{
		AL_Event_GetDefaultCodePage(&u32CodePage);
	}
	pExtText = UNI_StringToUtf8(u32CodePage, pName, &i32Len, al_false);
	i32Len = i32Len <  MAX_DATA_SIZE ? i32Len : (MAX_DATA_SIZE -1);
	//memcpy(pName, pExtText, i32Len);//event name
	snprintf((char *)pName, MAX_DATA_SIZE, "%s", (char *)pExtText);
	//printf("[%s:%d] u32CodePage : %d, u32NameLen: %d\n",__FUNCTION__,__LINE__, u32CodePage, i32Len);
	free(pExtText);
	pExtText = al_null;
#endif

	return AL_SUCCESS;
}

static AL_Return_t _AI_Event_FillEventText(MID_SIDesc_EventDetail_t *pstMidEventDetails,
	al_uint8 *event_text)
{	
	al_uint16 ucTextLen = 0;
	al_uint8 ctrlCode = 0;

	if (pstMidEventDetails == al_null ||event_text == NULL)
	{
		EPG_ERROR_MESSAGE("null ptr\n");
		return AL_INVALID_PARAM;
	}
	al_uint8 *pText = event_text;

	memset(pText, 0x0, MAX_DATA_SIZE);
	ucTextLen = pstMidEventDetails->text_length;

	if (ucTextLen > MAX_DATA_SIZE-1)
	{
		ucTextLen = MAX_DATA_SIZE-1;
	}
	pText[0] = ucTextLen;
	if (_AI_Event_IsContainLangCtrlCode(&pstMidEventDetails->text[0]))
	{
		memcpy(pText + 1, pstMidEventDetails->text, ucTextLen);
	}
	else
	{
		if (_AI_Event_GetLangCtrlCode(pstMidEventDetails->iso_639_code, &ctrlCode))
		{
			pText[1] = ctrlCode;
			memcpy(&pText[2], pstMidEventDetails->text, ucTextLen);
			ucTextLen++;
		}
		else
		{
			memcpy(pText + 1, pstMidEventDetails->text, ucTextLen);
		}
	}
#ifdef CONFIG_SUPPORT_MALAYSIA_CERTIFICATION 
	if( ucTextLen > 0 )
	{
		int len = MID_CmnDecompressString(event_text + 1, ucTextLen);
		if (len > ucTextLen && len < MAX_DATA_SIZE)
		{
			ucTextLen=(al_uint32)len;
		}
	}
#endif

//#ifdef CONFIG_SUPPORT_DTG_CERTIFICATION
	if (ucTextLen> 0)
	{
		int len = MID_CmnDecompressString(pText+1, ucTextLen);

		if (len > ucTextLen && len < MAX_DATA_SIZE)
		{
			ucTextLen=(al_uint32)len;
		}
		MID_CmnTransStrWithSpeciChar(pText+1, ucTextLen);
		MID_CmnTransStrWithoutControlChar(pText+1, ucTextLen);
	}
//#endif
#ifdef SUPPORT_SHOW_0X00_DRAW_STR
	if (al_epg_DTG_support && ucTextLen > 0)
	{
		MID_CmnTransStrWith00(pText+1, ucTextLen);
	}
#endif

	if (ucTextLen > 0)
	{
		MID_CmnTransStrWithoutSpeciChar(pText+1, ucTextLen);
		if (strlen((const char *)(pText+1))==0)
		{
			pText[0]=0;
		}
	}

	pText[0] = MID_CmnGetDynamicStrLength(pText+1, (al_uint32)ucTextLen);

	pText[ucTextLen + 1] = 0;

	return AL_SUCCESS;
}

static AL_Return_t _AI_Event_FillExtendEventItem(MID_SIDesc_ExtEventDetail_t *pstMidExtEventDetails,
	al_uint8 *event_item)
{
	al_uint16 ucItemLen;

	ucItemLen = pstMidExtEventDetails->item_name_length;

	if (ucItemLen > MAX_DATA_SIZE-1)
	{
		ucItemLen = MAX_DATA_SIZE-1;
	}
#if 0	
	event_item[0] = ucItemLen;
	memcpy(event_item +1, pstMidExtEventDetails->item_name, ucItemLen);

#ifdef SUPPORT_SHOW_0X00_DRAW_STR
	if (al_epg_DTG_support && ucItemLen > 0)
	{
		MID_CmnTransStrWith00(event_item + 1, ucItemLen);
	}
#endif

	event_item[0] = MID_CmnGetDynamicStrLength(event_item + 1, (UINT32)ucItemLen);
#else
	al_uint16 ucTempLen = 0;
	al_uint16 ucLen = 0;
	al_uint8 item_description[AL_EVENT_EXTEND_LEN];

	memset(item_description, 0, AL_EVENT_EXTEND_LEN);
	event_item[0] = 0;
	for (; ucTempLen < ucItemLen; )
	{
		/* get len */
		item_description[ucLen] = pstMidExtEventDetails->item_name[ucTempLen];
		memcpy(&(item_description[ucLen+1]), &(pstMidExtEventDetails->item_name[ucTempLen+1]), pstMidExtEventDetails->item_name[ucTempLen]);
#ifdef SUPPORT_SHOW_0X00_DRAW_STR
		if (al_epg_DTG_support && pstMidExtEventDetails->item_name[ucTempLen] > 0)
		{
			MID_CmnTransStrWith00(&(item_description[ucLen+1]), pstMidExtEventDetails->item_name[ucTempLen]);
		}
#endif

		item_description[ucLen] = MID_CmnGetDynamicStrLength(&(item_description[ucLen+1]), (UINT32)(pstMidExtEventDetails->item_name[ucTempLen]));
		event_item[0] += item_description[ucLen]+1;
		ucLen += item_description[ucLen]+1;
		ucTempLen += pstMidExtEventDetails->item_name[ucTempLen]+1;
	}
	memcpy(event_item +1, item_description, event_item[0]);
#endif

	return AL_SUCCESS;

}

static AL_Return_t _AI_Event_FillExtendEventText(MID_SIDesc_ExtEventDetail_t *pstMidExtEventDetails,
	al_uint8 *event_text)
{
	al_uint16  ucTextLen;

#ifdef SUPPORT_SKIP_NEWLINE_IN_SERVICE_NAME
	al_uint8 ucItemLen = pstMidExtEventDetails->item_name_length;
#endif
	ucTextLen = pstMidExtEventDetails->text_length;

	if (ucTextLen > MAX_DATA_SIZE-1)
	{
		ucTextLen = MAX_DATA_SIZE-1;
	}

	memcpy(event_text + 1, pstMidExtEventDetails->text, ucTextLen + 1);

#ifdef CONFIG_SUPPORT_MALAYSIA_CERTIFICATION 
	if( ucTextLen > 0 )
	{
		int len = MID_CmnDecompressString(event_text + 1, ucTextLen);
		if (len > ucTextLen && len < MAX_DATA_SIZE)
		{
			ucTextLen=(al_uint32)len;
		}
	}
#endif

//#ifdef CONFIG_SUPPORT_DTG_CERTIFICATION
	if (al_epg_DTG_support && ucTextLen> 0)
	{
		MID_CmnTransStrWithSpeciChar(event_text + 1, ucTextLen);
		MID_CmnTransStrWithoutControlChar(event_text + 1, ucTextLen);
	}
//#endif

#ifdef SUPPORT_SHOW_0X00_DRAW_STR
	if (al_epg_DTG_support && ucTextLen > 0)
	{
		MID_CmnTransStrWith00(event_text + 1, ucTextLen);
	}
#endif

	if (ucTextLen > 0)
	{
		MID_CmnTransStrWithoutSpeciChar(event_text + 1, ucTextLen);
	}

#ifdef SUPPORT_SKIP_NEWLINE_IN_SERVICE_NAME
	if (al_epg_DTG_support && ucItemLen > 0)
	{
		MID_CmnTransStrWithoutNewline(event_text + 1, ucTextLen);
	}
#endif

	event_text[0] = MID_CmnGetDynamicStrLength(event_text + 1, (UINT32)ucTextLen);

	return AL_SUCCESS;

}

static AL_Return_t _AI_Event_FillEventTime(MID_EPGEventInfo_t *pstMidEventInfo,
	AL_Event_Time_Descript_t *event_time)
{
	al_bool	bTimeZoneChange = FALSE;
	al_uint32 start_in_sec = 0;
	al_uint32 end_in_sec = 0;
	al_uint32 start_timing = 0;

	AL_Time_Secs2Date(&pstMidEventInfo->start_time, &event_time->stStartTime);

	start_timing = event_time->stStartTime.Hour * 3600 + event_time->stStartTime.Min * 60
		+ event_time->stStartTime.Sec;

	if((AL_Time_GetRawMjd() <= AI_Time_GetNextRawMjd())
		&& (AL_Time_GetRawSecond() < AI_Time_GetNextTimeSec())
		&& (start_timing < AL_Time_GetRawSecond()))
	{
		g_sdOrgGMTOffset = AL_Time_GetGMTOffset();
		bTimeZoneChange = FALSE;
	}
	else
	{
		bTimeZoneChange = TRUE;
	}

	/* keep original start time in sec */
	start_in_sec = pstMidEventInfo->start_time;
	end_in_sec = start_in_sec + pstMidEventInfo->duration;

	al_uint32 eve_mjd = AL_Time_YmdToMjd(event_time->stStartTime.Year,
											event_time->stStartTime.Month,
											event_time->stStartTime.Day);
	if(AI_Time_GetNextRawMjd() > 0)
	{
		if(eve_mjd > AI_Time_GetNextRawMjd() ||
			(eve_mjd == AI_Time_GetNextRawMjd() &&
			start_timing >=  AI_Time_GetNextTimeSec()))
		{
			/* In this case apply the same change on start time and end time  */
			start_in_sec += AL_Time_GetNextGMTOffset();
			end_in_sec += AL_Time_GetNextGMTOffset();
		}
		else if(eve_mjd == AI_Time_GetNextRawMjd()
			&& (start_timing + pstMidEventInfo->duration >=  AI_Time_GetNextTimeSec()))
		{
			/* In this case only apply time change to event end time*/

			if(bTimeZoneChange && AI_Time_GetOldTimeOffset() == ~0)
			{
				start_in_sec += g_sdOrgGMTOffset;
				end_in_sec += AL_Time_GetNextGMTOffset();
			}
			else if(AI_Time_GetOldTimeOffset() != ~0)
			{
				start_in_sec += AI_Time_GetOldTimeOffset();
				end_in_sec += AL_Time_GetNextGMTOffset();
			}
			else
			{
				start_in_sec += AL_Time_GetGMTOffset();
				end_in_sec += AL_Time_GetNextGMTOffset();
			}
		}
		else
		{
			start_in_sec += AL_Time_GetGMTOffset();
			end_in_sec += AL_Time_GetGMTOffset();
		}
	}
	else
	{
		start_in_sec += AL_Time_GetGMTOffset();
		end_in_sec += AL_Time_GetGMTOffset();
	}

	AL_Time_Secs2Date(&start_in_sec, &event_time->stStartTime);
	AL_Time_Secs2Date(&end_in_sec, &event_time->stEndTime);

	return AL_SUCCESS;

}

static AL_Return_t _AI_Event_GetEventDetails(al_uint16 serv_id, al_uint16 trans_id, al_uint16 net_id,
	AL_Event_t eventhdl, AL_Event_Details_t *events_detail)
{
	al_uint32 event_end_time = 0;
	al_uint16 offset = 0;
	al_uint8 desc[MAX_DES_LEN] = {0};
	//al_uint8 u8count = 0;
	al_uint8 ucPos = 0;
	al_uint8 ucItemLen = 0;
	al_uint8 ucTextLen = 0;
	bool status = FALSE;
	MID_EPG_EventHandle_t First_handle = 0;
	MID_ServLocator_t ServLoc = {0};
	al_bool short_name_exist = al_true;

	if (events_detail == al_null)
	{
		EPG_ERROR_MESSAGE("null ptr\n");
		return AL_INVALID_PARAM;
	}

	memset(events_detail, 0, sizeof(AL_Event_Details_t));

	MID_EPGEventInfo_t mideventInfo;
	MID_SIDesc_EventDetail_t Midevendetails;

	memset(&mideventInfo, 0, sizeof(MID_EPGEventInfo_t));
	memset(&Midevendetails, 0, sizeof(MID_SIDesc_EventDetail_t));

	if (MID_EPG_SUCCESS != MID_EPGGetEventInfo(EPGhdl, eventhdl, &mideventInfo))
	{
		EPG_ERROR_MESSAGE("Get infor error\n");
		return AL_FAILURE;
	}

	events_detail->event_Id = mideventInfo.event_id;
	events_detail->event_hdl = eventhdl;

	event_end_time = mideventInfo.start_time + mideventInfo.duration;
	/* UTC time of the event which is not affected by TOT or TDT */
	AL_Time_Secs2Date(&mideventInfo.start_time, &events_detail->event_utc_time.stStartTime);

	AL_Time_Secs2Date(&event_end_time, &events_detail->event_utc_time.stEndTime);

	/* Local time of the event used by app */
	_AI_Event_FillEventTime(&mideventInfo, &events_detail->event_time);

	/* Get event short name and text */
	if (MID_EPG_SUCCESS != MID_EPGGetEventDetail(EPGhdl, eventhdl, langcode, 2, &Midevendetails))
	{
		//EPG_ERROR_MESSAGE("Get infor error\n");
		if (MID_EPG_SUCCESS != MID_EPGGetEventDetail(EPGhdl, eventhdl, NULL, 0, &Midevendetails))
		{
			EPG_ERROR_MESSAGE("Get infor error\n");
			short_name_exist = al_false;
			//return AL_FAILURE;
		}
	}
	/* If there's short event descriptor, fill the event details, or ignore these fields */
	if (short_name_exist != al_false)
	{
		/* event name */
		_AI_Event_FillEventName(&Midevendetails, events_detail->event_name);

		/* event name length */
		events_detail->event_name_length = Midevendetails.event_name_length;

		/* event text */
		_AI_Event_FillEventText(&Midevendetails, events_detail->event_text);
		/* event text length */
		events_detail->event_text_length = Midevendetails.text_length;

		memcpy(events_detail->event_langcode, Midevendetails.iso_639_code, MAX_ISO_LANG_CODE);
	}

	/* Get offset and extend num */
	ServLoc.original_network_id = net_id;
	ServLoc.tranport_id = trans_id;
	ServLoc.service_id = serv_id;

	/* Get content descriptor for event details
	* Note: There is the possibility to transmit more than one classification term.
	* HOWEVER, currently, only content_nibble_level_1 of the the first classification term is supported.
	*/
	if (MID_EPG_SUCCESS == MID_EPGGetDesc(EPGhdl,
		eventhdl, DESCR_CONTENT, &offset, &status, desc))
	{
		/* content_nibble_level_1 */
		events_detail->content_classify = desc[2] >> 4;
	}

	events_detail->event_offset = 0;
	events_detail->extend_num = 0;
	MID_EPGGetFirstEvent(EPGhdl, &ServLoc, &First_handle);

	do {
		if (First_handle == events_detail->event_hdl)
		{
			events_detail->event_offset = events_detail->extend_num;
			break;
		}
		events_detail->extend_num++;
	}while(MID_EPGGetNextEvent(EPGhdl, &ServLoc, &First_handle) == MID_EPG_SUCCESS);

	events_detail->extend_num = 0;

	memset(desc, 0, MAX_DES_LEN);

	offset = 0;
	while (MID_EPG_SUCCESS ==MID_EPGGetDesc(EPGhdl,
		events_detail->event_hdl, DESCR_EXTENDED_EVENT, &offset, &status, desc))
	{
		ucPos = 0;
		/* desc[1] is descriptor length and desc[2] is descriptor mun | last descriptor length*/
		ucPos += 2;			/* descriptor tag and length */
		ucPos += 1;			/* desc number and last desc number */
		ucPos += 3;			/* language code */

		ucItemLen = desc[ucPos];

		ucPos += 1 + ucItemLen;
		ucTextLen = desc[ucPos];
		if( ucItemLen != 0 || ucTextLen != 0 )
		{
			events_detail->extend_num++;
		}
		//++u8count;
	}

	/* Get rating information from start */
	_AI_Event_GetEventRating(eventhdl, &events_detail->event_rating);

	return AL_SUCCESS;

}

/***************************************************************************
** FUNCTION : AI_Event_Init
**
** DESCRIPTION :
**				Initializes the event component.
**
** PARAMETERS :
**				DBType: Specify database on which to build.
**				pstInit: pointer to initial parameters
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AI_Event_Init(AL_DB_EDBType_t DBType, AI_Event_Init_t *pstInit)
{
	if (pstInit == al_null)
	{
		EPG_ERROR_MESSAGE("null ptr\n");
		return AL_INVALID_PARAM;
	}

	if (al_event_init)
	{
		EPG_ERROR_MESSAGE("init twice\n");
		return AL_INITIALIZE_ALREADY;
	}

	if(pstInit->fpcallback != al_null)
	{
		pfuncallback = pstInit->fpcallback;
	}

	stEpgInit.db_type = DBType;
	stEpgInit.event_max = pstInit->TotalEvent + pstInit->TotalExtendEvent;
	stEpgInit.serv_max = pstInit->TotalChannel;
	stEpgInit.fCallback = _AI_EventCallback;
	//MID_EPGInit(&stEpgInit, &EPGhdl);

	al_event_init = al_true;

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AI_Event_Term
**
** DESCRIPTION :
**				Terminates the event component.
**
** PARAMETERS :
**				DBType: Specify database on which to terminate.
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AI_Event_Term(AL_DB_EDBType_t DBType)
{
	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_SUCCESS;
	}

	al_event_init = al_false;

	MID_EPGDeInit(&EPGhdl);

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_Stop
**
** DESCRIPTION :
**				Stop the event component, collecting of EIT stops.
**
** PARAMETERS :
**				DBType: Specify database on which to stop.
**				is_exit_task : al_true: exit EPG task, else no exit
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_Stop(AL_DB_EDBType_t DBType, al_bool is_exit_task)
{
	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (is_exit_task)
	{
		MID_EPGStop(EPGhdl);
		MID_EPGDeInit(&EPGhdl);
	}
	else
	{
		MID_EPGStop(EPGhdl);
	}

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_LockChannels
**
** DESCRIPTION :
**				start channels by given network id, ts id and serivce.
**
** PARAMETERS :
**				DBType: Specify database on which to stop.
**				net_id : network id
**				trans_id : ts id
**				serv_id : service id
**				chan_num : tells how many channels to open simultaneously
**				focus_index: tells which channel has higher priority. it's useful when cache
**					is not enough, events with lower priority will be replaced by higher ones.
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_LockChannels(AL_DB_EDBType_t DBType,  al_uint16 *net_id,
	al_uint16 *trans_id, al_uint16 *serv_id, al_uint8 chan_num, al_int32 focus_index)
{
	al_uint32 TotalTV = 0;
	al_uint32 TotalRadio = 0;
	al_uint8 i = 0;
	al_uint16	usTsId = 0xffff;	
	al_uint16	usOrigNetId = 0xffff;
	AL_RecHandle_t hCurrProgHdl = AL_DB_INVALIDHDL;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (net_id == al_null || trans_id == al_null ||serv_id == al_null ||chan_num == 0)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	if ((MID_SUCCESS != MID_PlaybackGetCurProgHandle(al_null, &hCurrProgHdl))
		|| (hCurrProgHdl == AL_DB_INVALIDHDL))
	{
		EPG_ERROR_MESSAGE("Get current program handle error.\n");
		return AL_FAILURE;
	}


	if ((AL_SUCCESS != AL_DB_QueryDetailFieldByName(hCurrProgHdl, (al_uint8 *)"usTsId", (al_void *)&usTsId))
		|| (AL_SUCCESS != AL_DB_QueryDetailFieldByName(hCurrProgHdl, (al_uint8 *)"usOrigNetId", (al_void *)&usOrigNetId)))
	{
		EPG_ERROR_MESSAGE("Get service info failed!!!\n");
		return AL_FAILURE;
	}


	AL_DB_GetRecordsTotalNum(DBType, AL_RECTYPE_DVBTV, &TotalTV);
	AL_DB_GetRecordsTotalNum(DBType, AL_RECTYPE_DVBRADIO, &TotalRadio);

	if (chan_num > TotalTV + TotalRadio)
	{
		chan_num = TotalTV + TotalRadio;
		EPG_DEBUG_MESSAGE("chan number is limited to total number of service: %d\n", chan_num);
	}

	MID_ServLocator_t *pstLocator = (MID_ServLocator_t *)GL_MemAlloc(chan_num * sizeof(MID_ServLocator_t));

	if (pstLocator == NULL)
	{
		EPG_ERROR_MESSAGE("Malloc memory failed\n");
		return AL_MEMORY_ALLOC_FAILED;
	}


	for (i = 0; i < chan_num; i++)
	{
		pstLocator[i].original_network_id = net_id[i];
		pstLocator[i].tranport_id = trans_id[i];
		pstLocator[i].service_id = serv_id[i];
	}

	if (EPGhdl == 0)
	{
		MID_EPGInit(&stEpgInit, &EPGhdl);
	}

	MID_EPGStart(EPGhdl);

	MID_EPGSetCurrTSIDORGID(usOrigNetId, usTsId);

	MID_EPGLockChannels(EPGhdl, pstLocator, chan_num);

	GL_MemFree(pstLocator);

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_UnLockChannels
**
** DESCRIPTION :
**				unlock channels by given network id, ts id and serivce. this API will
**				clear cache that pre-occupied by the channel. Note: Set both
**				net_id 0X00 and trans_id 0x00 for clear entire cache.
**
** PARAMETERS :
**				DBType -Specify database on which to stop.
**				net_id - network id. clear entire cache if set 0xFF
**				trans_id -ts id. clear entire cache if set 0xFF
**				serv_id - service id
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_UnLockChannels(AL_DB_EDBType_t DBType,  al_uint16 net_id,
	al_uint16 trans_id, al_uint16 serv_id)
{
	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	MID_ServLocator_t SerLocator;

	SerLocator.original_network_id = net_id;
	SerLocator.tranport_id = trans_id;
	SerLocator.service_id = serv_id;

	MID_EPGClearChannel(EPGhdl, SerLocator);

	return AL_SUCCESS;

}
/***************************************************************************
** FUNCTION : AL_Event_SetCountryCode
**
** DESCRIPTION :
**				Set country code.
**
** PARAMETERS :
**				countrycode: country code
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_SetCountryCode(al_int8 *countrycode)
{
	if (countrycode == al_null)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	country_code = countrycode;

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_SetPreferLanguageCode
**
** DESCRIPTION :
**				Set prefer language code for event module. this may be useful for event
**				to provide the event with prefer language code during parsing EIT process
** PARAMETERS :
**				langptr1 - prefer language code
**				langptr2 - prefer language code
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_SetPreferLanguageCode(void * langptr1, void * langptr2)
{

	langcode[0] = langptr1;
	langcode[1] = langptr2;

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_SetDTGSupport
**
** DESCRIPTION :
**				set DTG support flag. This flag may used during parsing EIT process
**
** PARAMETERS :
**				flag: al_true means set, al_false means unset.
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_SetDTGSupport(al_bool flag)
{
	al_epg_DTG_support = flag;

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_GetDTGSupport
**
** DESCRIPTION :
**				Get DTG support flag. This flag may used during parsing EIT process
**
** PARAMETERS :
**				flag: al_true means set, al_false means unset.
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
al_bool AL_Event_GetEDTGSupport(al_void)
{
	return al_epg_DTG_support;
}

/***************************************************************************
** FUNCTION : AL_Event_GetEventRatingByHdl
**
** DESCRIPTION :
**				API fills details of First 'n' events of given service.
**
** PARAMETERS :
**				eventhdl	- Events handle
**				Rating	- Event parental rating
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetEventRatingByHdl(AL_Event_t eventhdl, al_uint8 *pRating)
{
	if(pRating == NULL)
	{
		return AL_FAILURE;
	}

	return  _AI_Event_GetEventRating(eventhdl,pRating);
}

/***************************************************************************
** FUNCTION : AL_Event_GetEventHdlByStartTime
**
** DESCRIPTION :
**				API fills details of First 'n' events of given service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_start_time - the start time of the event
**				duration	- duration in minutes
**				events_req	- Events required
**				eventhdl_list	- Event handles to be filled into
**				events_fnd	- Events handle found
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetEventHdlByStartTime(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Time_t *event_start_time, al_uint32 duration,
	al_uint16 events_req, AL_Event_t *eventhdl_list, al_uint16 *events_fnd)
{
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;
	al_uint32 mid_start_time = 0;
	al_uint32 range_end;
	MID_EPG_Return_t ret_value = MID_EPG_FAILED;

	if (!al_event_init)
	{
		return AL_UNINITIALIZED;
	}

	if (eventhdl_list == al_null ||events_fnd == al_null ||events_req == 0)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;
	*events_fnd = 0;

	AL_Time_DateToSecs(event_start_time, &mid_start_time);

	mid_start_time -= AL_Time_GetGMTOffset();

	if (duration  > (0xFFFFFFFF - mid_start_time)/60)
	{
		range_end = 0xFFFFFFFF;
	}
	else
	{
		range_end = mid_start_time + duration*60;
	}
	
#ifdef CONFIG_DVB_SYSTEM
	al_uint8 u8CountryId = MAX_AREA;
	frmwrk_pfOpConext_t pfGetContext = al_null;
	AL_FW_GetContextCb( &pfGetContext );
	MID_EPGEventInfo_t stCurrEventInfo;
	MID_EPGEventInfo_t stNextEventInfo;
	MID_EPG_EventHandle_t Currepghandle = 0;
	MID_EPG_EventHandle_t Nextepghandle = 0;
	
	memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	pfGetContext( FW_CONTEXT_TYPE_COUNTRY_ID , FW_CONTEXT_OP_TYPE_READ, (al_void *)&u8CountryId, 0 );
	if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Currepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
			if (stCurrEventInfo.start_time > range_end
				|| stCurrEventInfo.start_time + stCurrEventInfo.duration <= mid_start_time)
			{
				Currepghandle = 0;
			}
		}

		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Nextepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
			if (stNextEventInfo.start_time > range_end
				|| stNextEventInfo.start_time + stNextEventInfo.duration <= mid_start_time)
			{
				Nextepghandle = 0;
			}
		}
	}
#endif

	MID_EPGEventInfo_t stEventInfo;

	/* get event from schedule event type */
	ret_value = MID_EPGGetEventAt(EPGhdl, &stLocator, mid_start_time, &epghandle);

	if ((MID_EPG_SUCCESS == ret_value) ||((MID_EPG_SUCCESS != ret_value) 
		&& (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))))
	{
		do
		{
			if (*events_fnd >= events_req)
			{
				break;
			}
			
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

			if (stEventInfo.start_time > range_end
				|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
			{
				continue;
			}

#ifdef CONFIG_DVB_SYSTEM
			if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
			{
				if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id)
				{
					eventhdl_list[*events_fnd] = Currepghandle;
				}
				else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id)
				{
					eventhdl_list[*events_fnd] = Nextepghandle;
				}
				else
				{
					eventhdl_list[*events_fnd] = epghandle;
				}
			}
			else
#endif
			{
				eventhdl_list[*events_fnd] = epghandle;
			}

			*events_fnd += 1;
		} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	}

	/* get event from p/f event type */
	if (*events_fnd == 0)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			if (stEventInfo.start_time > range_end
				|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
			{
				
			}
			else
			{
				eventhdl_list[*events_fnd] = epghandle;
				*events_fnd += 1;
			}
		}

		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			if (stEventInfo.start_time > range_end
				|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
			{
			
			}
			else
			{
				eventhdl_list[*events_fnd] = epghandle;
				*events_fnd += 1;
			}
		}		
	}

#ifdef NON_ORGID_GET_EVENT
	if (*events_fnd == 0)
	{
		stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
		
#ifdef CONFIG_DVB_SYSTEM
		Currepghandle = 0;
		Nextepghandle = 0;
		memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Currepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
			}

			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Nextepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
			}
		}
#endif

		ret_value = MID_EPGGetEventAt(EPGhdl, &stLocator, mid_start_time, &epghandle);
	
		if ((MID_EPG_SUCCESS == ret_value) ||((MID_EPG_SUCCESS != ret_value) 
			&& (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))))
		{
			do
			{
				if (*events_fnd >= events_req)
				{
					break;
				}

				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
	
				if (stEventInfo.start_time > range_end
					|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
				{
					continue;
				}

#ifdef CONFIG_DVB_SYSTEM
				if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
				{
					if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id)
					{
						eventhdl_list[*events_fnd] = Currepghandle;
					}
					else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id)
					{
						eventhdl_list[*events_fnd] = Nextepghandle;
					}
					else
					{
						eventhdl_list[*events_fnd] = epghandle;
					}
				}
				else
#endif
				{
					eventhdl_list[*events_fnd] = epghandle;
				}
	
				*events_fnd += 1;
			} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
		}
	
		/* get event from p/f event type */
		if (*events_fnd == 0)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				if (stEventInfo.start_time > range_end
					|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
				{
					
				}
				else
				{
					eventhdl_list[*events_fnd] = epghandle;
					*events_fnd += 1;
				}
			}
	
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				if (stEventInfo.start_time > range_end
					|| stEventInfo.start_time + stEventInfo.duration <= mid_start_time)
				{
				
				}
				else
				{
					eventhdl_list[*events_fnd] = epghandle;
					*events_fnd += 1;
				}
			}		
		}
	
	}
#endif

	

	return AL_SUCCESS;

}

/***************************************************************************
** FUNCTION : AL_Event_GetNextNumofEvents
**
** DESCRIPTION :
**				API fills details of Next 'n' events of given service, including current one
**				indicated by event_hdl
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_ref	- Ref Event
**				events_req	- Events required
**				events_detail	- Event data structure to be filled
**				events_fnd	- Events found
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetNextNumofEvents(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Event_t event_hdl, al_uint16 events_req,
	AL_Event_Details_t *events_detail, al_uint16 *events_fnd)
{
	MID_EPG_EventHandle_t epghandle = event_hdl;
	MID_ServLocator_t ServLoc;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (events_detail == al_null ||events_fnd == al_null ||events_req == 0 ||event_hdl == 0)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	
	ServLoc.original_network_id = net_id;
	ServLoc.tranport_id = trans_id;
	ServLoc.service_id = serv_id;

#ifdef CONFIG_DVB_SYSTEM
	al_uint8 u8CountryId = MAX_AREA;
	frmwrk_pfOpConext_t pfGetContext = al_null;
	AL_FW_GetContextCb( &pfGetContext );
	MID_EPGEventInfo_t stCurrEventInfo;
	MID_EPGEventInfo_t stNextEventInfo;
	MID_EPGEventInfo_t stEventInfo;
	MID_EPG_EventHandle_t Currepghandle = 0;
	MID_EPG_EventHandle_t Nextepghandle = 0;
	
	memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	pfGetContext( FW_CONTEXT_TYPE_COUNTRY_ID , FW_CONTEXT_OP_TYPE_READ, (al_void *)&u8CountryId, 0 );
	if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &Currepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
		}

		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &Nextepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
		}
	}
#endif

	*events_fnd = 0;
	/* get event from schedule event type */
	do
	{
		if (*events_fnd >= events_req)
		{
			break;
		}

#ifdef CONFIG_DVB_SYSTEM
		if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id)
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
					(AL_Event_t)Currepghandle, events_detail+*events_fnd) != AL_SUCCESS)
				{
					EPG_ERROR_MESSAGE("query event details error\n");
					return AL_FAILURE;
				}
			}
			else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id)
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
					(AL_Event_t)Nextepghandle, events_detail+*events_fnd) != AL_SUCCESS)
				{
					EPG_ERROR_MESSAGE("query event details error\n");
					return AL_FAILURE;
				}
			}
			else
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
					(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
				{
					EPG_ERROR_MESSAGE("query event details error\n");
					return AL_FAILURE;
				}
			}
		}
		else
#endif
		{
			if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
				(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
			{
				EPG_ERROR_MESSAGE("query event details error\n");
				return AL_FAILURE;
			}
		}

		*events_fnd += 1;
	} while (MID_EPGGetNextEvent(EPGhdl, &ServLoc, &epghandle) == MID_EPG_SUCCESS);
	/* get event from p/f event type */
	if (*events_fnd ==0)
	{
		if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &epghandle))
			&& (epghandle == event_hdl))
		{
			if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_false, &epghandle))
				&& (*events_fnd < events_req))
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
					(AL_Event_t)epghandle, events_detail+*events_fnd) == AL_SUCCESS)
				{
					*events_fnd += 1;
					return AL_SUCCESS;
				}
			}
		}

		return AL_FAILURE;
	}

	
#ifdef NON_ORGID_GET_EVENT
	if (*events_fnd == 0)
	{
		ServLoc.original_network_id = RESERVED_ORIGINAL_NET_ID;

#ifdef CONFIG_DVB_SYSTEM		
		Currepghandle = 0;
		Nextepghandle = 0;
		memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &Currepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
			}

			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &Nextepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
			}
		}
#endif

		do
		{
			if (*events_fnd >= events_req)
			{
				break;
			}

#ifdef CONFIG_DVB_SYSTEM
			if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id)
				{
					if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
						(AL_Event_t)Currepghandle, events_detail+*events_fnd) != AL_SUCCESS)
					{
						EPG_ERROR_MESSAGE("query event details error\n");
						return AL_FAILURE;
					}
				}
				else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id)
				{
					if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
						(AL_Event_t)Nextepghandle, events_detail+*events_fnd) != AL_SUCCESS)
					{
						EPG_ERROR_MESSAGE("query event details error\n");
						return AL_FAILURE;
					}
				}
				else
				{
					if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
						(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
					{
						EPG_ERROR_MESSAGE("query event details error\n");
						return AL_FAILURE;
					}
				}
			}
			else
#endif
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
					(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
				{
					EPG_ERROR_MESSAGE("query event details error\n");
					return AL_FAILURE;
				}
			}

			*events_fnd += 1;
		} while (MID_EPGGetNextEvent(EPGhdl, &ServLoc, &epghandle) == MID_EPG_SUCCESS);
		/* get event from p/f event type */
		if (*events_fnd ==0)
		{
			if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_true, &epghandle))
				&& (epghandle == event_hdl))
			{
				if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &ServLoc, al_false, &epghandle))
					&& (*events_fnd < events_req))
				{
					if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
						(AL_Event_t)epghandle, events_detail+*events_fnd) == AL_SUCCESS)
					{
						*events_fnd += 1;
						return AL_SUCCESS;
					}
				}
			}

			return AL_FAILURE;
		}
	
	}
#endif

	return AL_SUCCESS;

}

/***************************************************************************
** FUNCTION : AL_Event_GetPrevNumofEvents
**
** DESCRIPTION :
**				API fills details of previous 'n' events of given service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_ref	- Ref Event
**				events_req	- Events required
**				events_detail	- Event data structure to be filled
**				events_fnd	- Events found
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetPrevNumofEvents(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Event_t event_hdl, al_uint16 events_req,
	AL_Event_Details_t *events_detail, al_uint16 *events_fnd)
{
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle = event_hdl;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (events_detail == al_null ||events_fnd == al_null ||events_req == 0)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;
	*events_fnd = 0;

	if (event_hdl == 0)
	{
		EPG_ERROR_MESSAGE("Invalid event handle\n");
		return AL_FAILURE;
	}
	/* get event from schedule event type */
	do
	{
		if (*events_fnd >= events_req)
		{
			break;
		}

		if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
			(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
		{
			EPG_ERROR_MESSAGE("query event details error\n");
			return AL_FAILURE;
		}

		*events_fnd += 1;
	} while (MID_EPGPrevEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	/* get event from p/f event type */
	if (*events_fnd ==0)
	{
		if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
			&& (epghandle == event_hdl))
		{
			if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
				&& (*events_fnd < events_req))
			{
				if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
					(AL_Event_t)epghandle, events_detail+*events_fnd) == AL_SUCCESS)
				{
					*events_fnd += 1;
					return AL_SUCCESS;
				}
			}
		}

		return AL_FAILURE;
	}

#ifdef NON_ORGID_GET_EVENT
	if (*events_fnd == 0)
	{
		stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
	
		do
		{
			if (*events_fnd >= events_req)
			{
				break;
			}

			if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
				(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
			{
				EPG_ERROR_MESSAGE("query event details error\n");
				return AL_FAILURE;
			}

			*events_fnd += 1;
		} while (MID_EPGPrevEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	/* get event from p/f event type */
	if (*events_fnd ==0)
		{
			if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
				&& (epghandle == event_hdl))
			{
				if ((MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
					&& (*events_fnd < events_req))
				{
					if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
						(AL_Event_t)epghandle, events_detail+*events_fnd) == AL_SUCCESS)
					{
						*events_fnd += 1;
						return AL_SUCCESS;
					}
				}
			}

			return AL_FAILURE;
		}
	
	}
#endif


	return AL_SUCCESS;

}

/***************************************************************************
** FUNCTION : AL_Event_GetLastNumofEvents
**
** DESCRIPTION :
**				API fills details of last 'n' events of given service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_ref	- Ref Event
**				events_req	- Events required
**				events_detail	- Event data structure to be filled
**				events_fnd	- Events found
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetLastNumofEvents(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	al_uint16 events_req, AL_Event_Details_t *events_detail,
	al_uint16 *events_fnd)
{
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (events_detail == al_null ||events_fnd == al_null ||events_req == 0)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;

	*events_fnd = 0;

	if (MID_EPG_SUCCESS != MID_EPGGetLastEvent(EPGhdl, &stLocator, &epghandle))
	{
		return AL_FAILURE;
	}

	do
	{
		if (*events_fnd >= events_req)
		{
			break;
		}

		if (_AI_Event_GetEventDetails(serv_id, trans_id, net_id,
			(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
		{
			EPG_ERROR_MESSAGE("query event details error\n");
			return AL_FAILURE;
		}

		*events_fnd += 1;
	} while (MID_EPGPrevEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);

	
#ifdef NON_ORGID_GET_EVENT
	if (*events_fnd == 0)
	{
		stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
	
		if (MID_EPG_SUCCESS != MID_EPGGetLastEvent(EPGhdl, &stLocator, &epghandle))
		{
			return AL_FAILURE;
		}

		do
		{
			if (*events_fnd >= events_req)
			{
				break;
			}

			if (_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID,
				(AL_Event_t)epghandle, events_detail+*events_fnd) != AL_SUCCESS)
			{
				EPG_ERROR_MESSAGE("query event details error\n");
				return AL_FAILURE;
			}

			*events_fnd += 1;
		} while (MID_EPGPrevEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	
	}
#endif

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_GetCurrNextEvents
**
** DESCRIPTION :
**				API fill the details of current/next event of given Service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_cur	- event structure to hold current event info
**				event_next	- event structure to hold next event info
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetCurrNextEvents(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Event_Details_t *event_cur, AL_Event_Details_t *event_next)
{
	al_uint32 CurTimeInSec = 0;
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;
	MID_EPGEventInfo_t stEventInfo;
	AL_Return_t ret = AL_FAILURE;
#ifdef CUR_NEXT_EVENT_BY_TIME
	al_uint32 StartTimeInSec = 0;
	al_uint32 EndTimeInSec = 0;
#endif

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (event_cur == al_null && event_next == al_null)
	{
		EPG_ERROR_MESSAGE("invalid parameters\n");
		return AL_INVALID_PARAM;
	}

	if (event_cur != al_null)
	{
		memset(event_cur, 0x0, sizeof(AL_Event_Details_t));
	}

	if (event_next != al_null)
	{
		memset(event_next, 0x0, sizeof(AL_Event_Details_t));
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;
	AL_Time_GetCurTimeInSecs(&CurTimeInSec);

	CurTimeInSec -= AL_Time_GetGMTOffset();

	if (event_cur != NULL)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_cur);
#ifdef CUR_NEXT_EVENT_BY_TIME
			AL_Time_DateToSecs(&(event_cur->event_utc_time.stStartTime), &StartTimeInSec);
			AL_Time_DateToSecs(&(event_cur->event_utc_time.stEndTime), &EndTimeInSec);
			if ((CurTimeInSec < StartTimeInSec) ||(CurTimeInSec > EndTimeInSec))//current event is invalid
			{
				if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_cur);
					ret = AL_SUCCESS;
				}
				else
				{
					memset(event_cur, 0x0, sizeof(AL_Event_Details_t));
				}
			}
			else
#endif
			{
				ret = AL_SUCCESS;
			}
		}
		else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_cur);
			ret = AL_SUCCESS;
		}
#ifdef NON_ORGID_GET_EVENT
		else
		{
			stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_cur);
#ifdef CUR_NEXT_EVENT_BY_TIME
				AL_Time_DateToSecs(&(event_cur->event_utc_time.stStartTime), &StartTimeInSec);
				AL_Time_DateToSecs(&(event_cur->event_utc_time.stEndTime), &EndTimeInSec);
				if ((CurTimeInSec < StartTimeInSec) ||(CurTimeInSec > EndTimeInSec))//current event is invalid
				{
					if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
					{
						MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
						_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_cur);
						ret = AL_SUCCESS;
					}
					else
					{
						memset(event_cur, 0x0, sizeof(AL_Event_Details_t));
					}
				}
				else
#endif
				{
					ret = AL_SUCCESS;
				}
			}
			else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_cur);
				ret = AL_SUCCESS;
			}
		}
#endif
	}

	if (event_next != NULL)
	{		
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_next);
#ifdef CUR_NEXT_EVENT_BY_TIME	
			AL_Time_DateToSecs(&(event_next->event_utc_time.stStartTime), &StartTimeInSec);
			if (CurTimeInSec >= StartTimeInSec) //next event is invalid
			{
				if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
				{
					if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
					{
						MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
						_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_next);
						ret = AL_SUCCESS;
					}
					else
					{
						memset(event_next, 0x0, sizeof(AL_Event_Details_t));
					}
				}
				else
				{
					memset(event_next, 0x0, sizeof(AL_Event_Details_t));
				}
			}
			else
#endif
			{
				ret = AL_SUCCESS;
			}
		}
		else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
		{
			if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_next);
				ret = AL_SUCCESS;
			}
		}
#ifdef NON_ORGID_GET_EVENT
		else
		{
			stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_next);
#ifdef CUR_NEXT_EVENT_BY_TIME	
				AL_Time_DateToSecs(&(event_next->event_utc_time.stStartTime), &StartTimeInSec);
				if (CurTimeInSec >= StartTimeInSec) //next event is invalid
				{
					if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
					{
						if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
						{
							MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
							_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_next);
							ret = AL_SUCCESS;
						}
						else
						{
							memset(event_next, 0x0, sizeof(AL_Event_Details_t));
						}
					}
					else
					{
						memset(event_next, 0x0, sizeof(AL_Event_Details_t));
					}
				}
				else
#endif
				{
					ret = AL_SUCCESS;
				}
			}
			else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
			{
				if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_next);
					ret = AL_SUCCESS;
				}
			}
		}
#endif
	}

	return ret;
}

 
/***************************************************************************
** FUNCTION : AL_Event_GetCurrNextEventsForCurrRating
**
** DESCRIPTION :
**			  API fill the details of current/next event of given Service.
**
** PARAMETERS :
**			  DBType  - Database type(DVB_T/DVB_C etc)
**			  net_id  - Network ID
**			  trans_id- Transport Stream ID
**			  serv_id - Service ID
**			  event_cur   - event structure to hold current event info
**			  event_next  - event structure to hold next event info
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetCurrNextEventsForCurrRating(AL_DB_EDBType_t DBType,
  al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
  AL_Event_Details_t *event_cur, AL_Event_Details_t *event_next)
{
	if (AL_Time_GetSyncMode() == AL_TIME_SyncMode_Auto)
	{
		return AL_Event_GetCurrNextEvents(DBType, net_id, trans_id, serv_id, event_cur, event_next);
	}
	else
	{
		al_uint32 CurTimeInSec = 0;
		MID_ServLocator_t stLocator;
		MID_EPG_EventHandle_t epghandle;
		MID_EPGEventInfo_t stEventInfo;
		AL_Return_t ret = AL_FAILURE;
	  
		if (!al_event_init)
		{
			EPG_ERROR_MESSAGE("not initialised\n");
			return AL_UNINITIALIZED;
		}
	  
		if (event_cur == al_null && event_next == al_null)
		{
			EPG_ERROR_MESSAGE("invalid parameters\n");
			return AL_INVALID_PARAM;
		}
	  
		if (event_cur != al_null)
		{
			memset(event_cur, 0x0, sizeof(AL_Event_Details_t));
		}
	  
		if (event_next != al_null)
		{
			memset(event_next, 0x0, sizeof(AL_Event_Details_t));
		}
	  
		stLocator.original_network_id = net_id;
		stLocator.tranport_id = trans_id;
		stLocator.service_id = serv_id;
		AL_Time_GetCurTimeInSecs(&CurTimeInSec);
	  
		CurTimeInSec -= AL_Time_GetGMTOffset();
	  
		if (event_cur != NULL)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_cur);
				ret = AL_SUCCESS;
			}
			else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_cur);
				ret = AL_SUCCESS;
			}
#ifdef NON_ORGID_GET_EVENT
			else
			{
				stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
				if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_cur);
					ret = AL_SUCCESS;
				}
				else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_cur);
					ret = AL_SUCCESS;
				}
			}
#endif
		}
	  
		if (event_next != NULL)
		{		
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_next);
				ret = AL_SUCCESS;
			}
			else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
			{
				if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, net_id, (AL_Event_t)epghandle, event_next);
					ret = AL_SUCCESS;
				}
			}
#ifdef NON_ORGID_GET_EVENT
			else
			{
				stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
				if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
				{
					MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
					_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_next);
					ret = AL_SUCCESS;
				}
				else if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
				{
					if (MID_EPG_SUCCESS == MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle))
					{
						MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
						_AI_Event_GetEventDetails(serv_id, trans_id, RESERVED_ORIGINAL_NET_ID, (AL_Event_t)epghandle, event_next);
						ret = AL_SUCCESS;
					}
				}
			}
#endif
		}
		
		return ret;
	}

}

 #if EPG_DEBUG_FLAG
void printevent(void)
{
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;
	MID_EPGEventInfo_t stEventInfo;
	CDBIHandle_t hProg;
	al_uint32 pu32TvRadioType;


	MID_PlaybackGetCurProgHandle(&pu32TvRadioType, &hProg);

	CDBIGetRecBySymbol(hProg, &stLocator.original_network_id, (al_uint8 *)"usOrigNetId");
	CDBIGetRecBySymbol(hProg, &stLocator.tranport_id, (al_uint8 *)"usTsId");
	CDBIGetRecBySymbol(hProg, &stLocator.service_id, (al_uint8 *)"usServiceId");

	EPG_DEBUG_MESSAGE("net id ======= 0x%x\n", stLocator.original_network_id);
	EPG_DEBUG_MESSAGE("ts id ======= 0x%x\n", stLocator.tranport_id);
	EPG_DEBUG_MESSAGE("ser id ======= 0x%x\n", stLocator.service_id);

	al_uint32 CurTimeInSec;
	AL_Time_GetCurTimeInSecs(&CurTimeInSec);

	CurTimeInSec -= AL_Time_GetGMTOffset();


	if (MID_EPG_SUCCESS == MID_EPGGetEventAt(EPGhdl, &stLocator, CurTimeInSec, &epghandle))
	{
		EPG_DEBUG_MESSAGE("MID_EPGGetEventAt success################\n");
	}
	else
	{
		EPG_DEBUG_MESSAGE("MID_EPGGetEventAt failed#################\n");
	}

	MID_SIDesc_EventDetail_t stEventdetail;

	EPG_DEBUG_MESSAGE("AL_Time_GetGMTOffset = %d\n", AL_Time_GetGMTOffset());

	if (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))
	{
		AL_Time_t stTime;
		do
		{
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

			AL_Time_Secs2Date(&stEventInfo.start_time, &stTime);

			EPG_DEBUG_MESSAGE("start time[0x%x]: %d-%02d-%02d %02d:%02d:%02d, duration :%d\n",
						stEventInfo.event_id,
						stTime.Year,
						stTime.Month,
						stTime.Day,
						stTime.Hour,
						stTime.Min,
						stTime.Sec,
						stEventInfo.duration);
			memset(&stEventdetail, 0, sizeof(MID_SIDesc_EventDetail_t));
			if (MID_EPG_SUCCESS != MID_EPGGetEventDetail(EPGhdl,epghandle,langcode, 2, &stEventdetail))
			{
				if(MID_EPG_SUCCESS != MID_EPGGetEventDetail(EPGhdl,epghandle,NULL, 0, &stEventdetail))
				{
					EPG_DEBUG_MESSAGE("%s %d get event details failed\n", __FUNCTION__, __LINE__);
				}
				else
				{
					al_uint16 i = 0;
					EPG_DEBUG_MESSAGE("event_name_length ==== %d\n", stEventdetail.event_name_length);
					EPG_DEBUG_MESSAGE("event_name =========================\n");
					for (i = 0; i < stEventdetail.event_name_length; i++)
					{
						if (i % 32 == 0)
						{
							EPG_DEBUG_MESSAGE("\n");
						}
						EPG_DEBUG_MESSAGE("%c", stEventdetail.event_name[i]);
					}
					EPG_DEBUG_MESSAGE("\n=======================================\n");

				}
			}
			else
			{
				al_uint16 i = 0;
				EPG_DEBUG_MESSAGE("event_name_length == %d\n", stEventdetail.event_name_length);
				EPG_DEBUG_MESSAGE("event_name =========================\n");
				for (i = 0; i < stEventdetail.event_name_length; i++)
				{
					if (i % 32 == 0)
					{
						EPG_DEBUG_MESSAGE("\n");
					}
					EPG_DEBUG_MESSAGE("%c", stEventdetail.event_name[i]);
				}
				EPG_DEBUG_MESSAGE("\n=======================================\n");

			}
		} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	}

}
#endif
/***************************************************************************
** FUNCTION : AL_Event_GetEventsBetweenTime
**
** DESCRIPTION :
**				Provide events number between time for a service.
**				Notice: when event_start_time or event_start_time
**				is null, it means the user don't care about it. For example,
**				both event_start_time and event_end_time is set to null,
**				then, AL_Event_GetTotalEventsBetweentime returns the total
**				events number of certail service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_start_time- Event start time(Not include offset)
**				event_end_time	- Event end time(Not include offset)
**				offset	- offset to get result in event list
**				num_req	- number required to get
**				got_num - actual number has been got
**				EventDetaillist - pointer to event list that contain detail information as required
**				total_num - total number of the event that meet the requirment.
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetEventsBetweenTime(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Time_t *event_start_time, AL_Time_t *event_end_time,
	al_uint16 offset, al_uint16 num_req, al_uint16 *got_num,
	AL_Event_Details_t *EventDetaillist, al_uint16 *total_num)
{

	al_uint16 count = 0;
	//al_uint32 duration = 0;
	al_uint32 totalsec_start = 0;
	al_uint32 totalsec_end = 0;
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;

	MID_EPGEventInfo_t stEventInfo;
	al_uint32 got_count = 0;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (total_num == al_null)
	{
		EPG_ERROR_MESSAGE("total_num is null\n");
		return AL_INVALID_PARAM;
	}

	*total_num = 0;

	if (got_num != al_null)
	{
		*got_num = 0;
	}

	/* here we handle event start time */
	if (event_start_time == al_null)
	{
		AL_Time_t tmp;
	///	mjd = AL_Time_GetMjd();
		AL_Time_GetTime(&tmp.Hour, &tmp.Min, &tmp.Sec);
		//start_minute = tmp.Hour * 60 + tmp.Min;
		AL_Time_GetDate(&tmp.Year, &tmp.Month, &tmp.Day);
		AL_Time_DateToSecs(&tmp, &totalsec_start);
	}
	else
	{
	//	mjd = AL_Time_YmdToMjd(event_start_time->Year,	event_start_time->Month,event_start_time->Day);

		//start_minute = event_start_time->Hour * 60 + event_start_time->Min;
		AL_Time_DateToSecs(event_start_time, &totalsec_start);
	}

	/* here we handle event end time */
	if (event_end_time == al_null)
	{
		//duration = 0xFFFFFFFF;
		totalsec_end = 0xFFFFFFFF;
	}
	else
	{
		AL_Time_DateToSecs(event_end_time, &totalsec_end);
		//duration = totalsec_end - totalsec_start;
		//duration = duration/60;
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;

	if (got_num != NULL)
	{
		*got_num = 0;
	}

	totalsec_end -= AL_Time_GetGMTOffset();
	totalsec_start -= AL_Time_GetGMTOffset();

#ifdef CONFIG_DVB_SYSTEM
	al_uint8 u8CountryId = MAX_AREA;
	frmwrk_pfOpConext_t pfGetContext = al_null;
	AL_FW_GetContextCb( &pfGetContext );
	MID_EPGEventInfo_t stCurrEventInfo;
	MID_EPGEventInfo_t stNextEventInfo;
	MID_EPG_EventHandle_t Currepghandle = 0;
	MID_EPG_EventHandle_t Nextepghandle = 0;
	
	memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
	pfGetContext( FW_CONTEXT_TYPE_COUNTRY_ID , FW_CONTEXT_OP_TYPE_READ, (al_void *)&u8CountryId, 0 );
	if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Currepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
			if ((stCurrEventInfo.start_time > totalsec_end)
				|| (stCurrEventInfo.start_time + stCurrEventInfo.duration <=  totalsec_start))
			{
				Currepghandle = 0;
			}
		}

		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &Nextepghandle))
		{
			MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
			if ((stNextEventInfo.start_time > totalsec_end)
				|| (stNextEventInfo.start_time + stNextEventInfo.duration <=  totalsec_start))
			{
				Nextepghandle = 0;
			}
		}
	}
#endif

	/* get event from schedule event type */
	if (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))
	{
		do
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

			if ((stEventInfo.start_time > totalsec_end)
				|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
			{
				continue;
			}

			if (count >= offset && got_count < num_req)
			{
#ifdef CONFIG_DVB_SYSTEM
				if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id && (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA))
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, Currepghandle, EventDetaillist + got_count);
				}
				else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id && (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA))
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, Nextepghandle, EventDetaillist + got_count);
				}
				else
#endif
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, epghandle, EventDetaillist + got_count);
				}
				got_count += 1;
			}

			count += 1;
		} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	}

	*total_num = count;

	if (got_num != NULL)
	{
		*got_num = got_count;
	}

	/* get event from p/f event type */
	if (*total_num == 0)
	{
		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			
			if ((stEventInfo.start_time > totalsec_end)
				|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
			{
				
			}
			else
			{
				if (count >= offset && got_count < num_req)
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, epghandle, EventDetaillist + got_count);
					got_count += 1;
				}

				count += 1;
			}
		}

		if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
		{
			memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
			if ((stEventInfo.start_time > totalsec_end)
				|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
			{
				
			}
			else
			{
				if (count >= offset && got_count < num_req)
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, epghandle, EventDetaillist + got_count);
					got_count += 1;
				}

				count += 1;
			}
		}
	}

#ifdef NON_ORGID_GET_EVENT
	if (*total_num == 0)
	{
		stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
		
#ifdef CONFIG_DVB_SYSTEM
		Currepghandle = 0;
		Nextepghandle = 0;
		memset(&stCurrEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		memset(&stNextEventInfo, 0, sizeof(MID_EPGEventInfo_t));
		
		if (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Currepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Currepghandle, &stCurrEventInfo);
			}

			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &Nextepghandle))
			{
				MID_EPGGetEventInfo(EPGhdl, Nextepghandle, &stNextEventInfo);
			}
		}
#endif

		if (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))
		{
			do
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

				if ((stEventInfo.start_time > totalsec_end)
					|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
				{
					continue;
				}

				if (count >= offset && got_count < num_req)
				{
#ifdef CONFIG_DVB_SYSTEM
					if (Currepghandle != 0 && stCurrEventInfo.event_id == stEventInfo.event_id && (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA))
					{
						_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, Currepghandle, EventDetaillist + got_count);
					}
					else if (Nextepghandle != 0 && stNextEventInfo.event_id == stEventInfo.event_id && (u8CountryId == AREA_GHANA || u8CountryId == AREA_MALAYSIA))
					{
						_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, Nextepghandle, EventDetaillist + got_count);
					}
					else
#endif
					{
						_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, epghandle, EventDetaillist + got_count);
					}
					got_count += 1;
				}

				count += 1;
			} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
		}

		*total_num = count;

		if (got_num != NULL)
		{
			*got_num = got_count;
		}

		/* get event from p/f event type */
		if (*total_num == 0)
		{
			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_true, &epghandle))
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				
				if ((stEventInfo.start_time > totalsec_end)
					|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
				{
					
				}
				else
				{
					if (count >= offset && got_count < num_req)
					{
						_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, epghandle, EventDetaillist + got_count);
						got_count += 1;
					}

					count += 1;
				}
			}

			if (MID_EPG_SUCCESS == MID_EPGGetCurrNextEvent(EPGhdl, &stLocator, al_false, &epghandle))
			{
				memset(&stEventInfo, 0, sizeof(MID_EPGEventInfo_t));
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);
				if ((stEventInfo.start_time > totalsec_end)
					|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
				{
					
				}
				else
				{
					if (count >= offset && got_count < num_req)
					{
						_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, epghandle, EventDetaillist + got_count);
						got_count += 1;
					}

					count += 1;
				}
			}
		}
	}
#endif
	*total_num = count;

	if (got_num != NULL)
	{
		*got_num = got_count;
	}

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_GetEventsBetweenTime
**
** DESCRIPTION :
**				Provide events number between time for a service.
**				Notice: when event_start_time or event_start_time
**				is null, it means the user don't care about it. For example,
**				both event_start_time and event_end_time is set to null,
**				then, AL_Event_GetTotalEventsBetweentime returns the total
**				events number of certail service.
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_start_time- Event start time(Not include offset)
**				event_end_time	- Event end time(Not include offset)
**				offset	- offset to get result in event list
**				num_req	- number required to get
**				got_num - actual number has been got
**				EventDetaillist - pointer to event list that contain detail information as required
**				total_num - total number of the event that meet the requirment.
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetAllSchduleEventsBetweenTime(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id,
	AL_Time_t *event_start_time, AL_Time_t *event_end_time,
	al_uint16 offset, al_uint16 num_req, al_uint16 *got_num,
	AL_Event_Details_t *EventDetaillist, al_uint16 *total_num)
{

	al_uint16 count = 0;
	//al_uint32 duration = 0;
	al_uint32 totalsec_start = 0;
	al_uint32 totalsec_end = 0;
	MID_ServLocator_t stLocator;
	MID_EPG_EventHandle_t epghandle;

	MID_EPGEventInfo_t stEventInfo;
	al_uint32 got_count = 0;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (total_num == al_null)
	{
		EPG_ERROR_MESSAGE("total_num is null\n");
		return AL_INVALID_PARAM;
	}

	*total_num = 0;

	if (got_num != al_null)
	{
		*got_num = 0;
	}

	/* here we handle event start time */
	if (event_start_time == al_null)
	{
		AL_Time_t tmp;
	/// mjd = AL_Time_GetMjd();
		AL_Time_GetTime(&tmp.Hour, &tmp.Min, &tmp.Sec);
		//start_minute = tmp.Hour * 60 + tmp.Min;
		AL_Time_GetDate(&tmp.Year, &tmp.Month, &tmp.Day);
		AL_Time_DateToSecs(&tmp, &totalsec_start);
	}
	else
	{
	//	mjd = AL_Time_YmdToMjd(event_start_time->Year,	event_start_time->Month,event_start_time->Day);

		//start_minute = event_start_time->Hour * 60 + event_start_time->Min;
		AL_Time_DateToSecs(event_start_time, &totalsec_start);
	}

	/* here we handle event end time */
	if (event_end_time == al_null)
	{
		//duration = 0xFFFFFFFF;
		totalsec_end = 0xFFFFFFFF;
	}
	else
	{
		AL_Time_DateToSecs(event_end_time, &totalsec_end);
		//duration = totalsec_end - totalsec_start;
		//duration = duration/60;
	}

	stLocator.original_network_id = net_id;
	stLocator.tranport_id = trans_id;
	stLocator.service_id = serv_id;

	if (got_num != NULL)
	{
		*got_num = 0;
	}

	totalsec_end -= AL_Time_GetGMTOffset();
	totalsec_start -= AL_Time_GetGMTOffset();

	/* get event from schedule event type */
	if (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))
	{
		do
		{
			MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

			if ((stEventInfo.start_time > totalsec_end)
				|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
			{
				continue;
			}

			if (stEventInfo.event_type != EVENT_TYPE_SCHEDULE)
			{
				continue;
			}

			if (count >= offset && got_count < num_req)
			{
				_AI_Event_GetEventDetails(serv_id, trans_id,  net_id, epghandle, EventDetaillist + got_count);
				got_count += 1;
			}

			count += 1;
		} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
	}

	*total_num = count;

	if (got_num != NULL)
	{
		*got_num = got_count;
	}

#ifdef NON_ORGID_GET_EVENT
	if (*total_num == 0)
	{
		stLocator.original_network_id = RESERVED_ORIGINAL_NET_ID;
		if (MID_EPG_SUCCESS == MID_EPGGetFirstEvent(EPGhdl, &stLocator, &epghandle))
		{
			do
			{
				MID_EPGGetEventInfo(EPGhdl, epghandle, &stEventInfo);

				if ((stEventInfo.start_time > totalsec_end)
					|| (stEventInfo.start_time + stEventInfo.duration <=  totalsec_start))
				{
					continue;
				}

				if (stEventInfo.event_type != EVENT_TYPE_SCHEDULE)
				{
					continue;
				}

				if (count >= offset && got_count < num_req)
				{
					_AI_Event_GetEventDetails(serv_id, trans_id,  RESERVED_ORIGINAL_NET_ID, epghandle, EventDetaillist + got_count);
					got_count += 1;
				}

				count += 1;
			} while (MID_EPGGetNextEvent(EPGhdl, &stLocator, &epghandle) == MID_EPG_SUCCESS);
		}

		*total_num = count;

		if (got_num != NULL)
		{
			*got_num = got_count;
		}
	}
#endif
	*total_num = count;

	if (got_num != NULL)
	{
		*got_num = got_count;
	}

	return AL_SUCCESS;
}

/***************************************************************************
** FUNCTION : AL_Event_GetEventsBetweenTime
**
** DESCRIPTION :
**				Provide extend events details by given event.
**				Notice: when ExtendEvent_t is null, means user only cares
**				about total number of the extend event. For example,
**
** PARAMETERS :
**				DBType	- Database type(DVB_T/DVB_C etc)
**				net_id	- Network ID
**				trans_id- Transport Stream ID
**				serv_id	- Service ID
**				event_hdl - event handle
**				offset - tells the position to get the extend event
**				num_req	- number required to get
**				got_num - actual number has been got
**				ExtendDetail_list_t - pointer to list that contain extend detail information as required
**				total_num - total number of the event that meet the requirment.
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetEventsDescription(AL_DB_EDBType_t DBType,
	al_uint16 net_id, al_uint16 trans_id, al_uint16 serv_id, AL_Event_t event_hdl,
	al_uint16 offset, al_uint16 req_num, al_uint16 *got_num,
	AL_Event_Desciption_t *ExtendDetail_list_t, al_uint16 *total_num)
{
	MID_EPG_EventHandle_t epghandle = event_hdl;
	MID_SIDesc_ExtEventDetail_t stExtEventInfo;
	al_uint16 fetch_offset = 0;
	al_uint16 fetch_offset_nonlang = 0;
	al_uint16 find_count = 0;
	AL_Event_Desciption_t *pExtendInfor;
	al_uint8 i;
	al_uint8 findflag = 0;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (total_num == al_null || got_num == al_null)
	{
		EPG_ERROR_MESSAGE("total_num is null\n");
		return AL_INVALID_PARAM;
	}

	if (event_hdl == 0)
	{
		EPG_ERROR_MESSAGE("Invalid event handle\n");
		return AL_FAILURE;
	}

	*got_num = 0;

	for (i = 0; (offset + i < EPG_EXTEND_EVENT_DESC_NUM) && *got_num < req_num; i++)
	{
		findflag = 0;
		if (MID_EPG_SUCCESS == MID_EPGGetExtendEvent(EPGhdl,
			epghandle, langcode, 2, &fetch_offset, &stExtEventInfo))
		{
			find_count++;
			findflag = 1;
		}
		else
		{
			if (MID_EPG_SUCCESS == MID_EPGGetExtendEvent(EPGhdl,
				epghandle, NULL, 0, &fetch_offset_nonlang, &stExtEventInfo))
			{
				find_count++;
				findflag = 1;
			}
		}

		if (findflag == 0)
		{
			break;
		}

		if (find_count > offset)
		{
			pExtendInfor = ExtendDetail_list_t + *got_num;

			memcpy(pExtendInfor->event_langcode, stExtEventInfo.iso_639_code, MAX_ISO_LANG_CODE);

			if (stExtEventInfo.item_name_length != 0)
			{
				_AI_Event_FillExtendEventItem(&stExtEventInfo, pExtendInfor->item_description);

				pExtendInfor->item_description_exsit = al_true;
				pExtendInfor->item_description_length = stExtEventInfo.item_name_length;
			}
			if (stExtEventInfo.text_length != 0)
			{
				_AI_Event_FillExtendEventText(&stExtEventInfo, pExtendInfor->extend_text);

				pExtendInfor->extend_text_exsit = al_true;
				pExtendInfor->extend_text_length = stExtEventInfo.text_length;
			}
			*got_num += 1;
		}
	}

	*total_num = find_count;

	return AL_SUCCESS;

}

/***************************************************************************
** FUNCTION : AL_Event_GetDescriptor
**
** DESCRIPTION :
**				Get descriptor of the event by event id and tag
**
** PARAMETERS :
**				event_hdl - event handle
**				offset - tells the position to get  next descriptor
**				pDesc - pointer to the descriptor data
**
** RETURN VALUES : AL_Return_t
***************************************************************************/
AL_Return_t AL_Event_GetDescriptor(AL_Event_t event_hdl,
	al_uint8 tag, al_uint16 *offset, void *pDesc)
{
	bool parsed = FALSE;

	if (!al_event_init)
	{
		EPG_ERROR_MESSAGE("not initialised\n");
		return AL_UNINITIALIZED;
	}

	if (offset == al_null && pDesc == al_null)
	{
		EPG_ERROR_MESSAGE("Null ptrl\n");
		return AL_INVALID_PARAM;
	}

	return MID_EPGGetDesc(EPGhdl, event_hdl, tag, offset, &parsed, pDesc)
		== MID_EPG_SUCCESS?AL_SUCCESS:AL_FAILURE;

}

/**
* @brief if string not carry codepage, need to get defualt code page
*
* @param pCodePage, output defualt code page.
*
* @return AL_SUCCESS  is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_Event_GetDefaultCodePage(al_uint32 *pCodePage)
{
	AL_RecHandle_t hCurrProgHdl = AL_DB_INVALIDHDL;
	al_uint16	usOrigNetId = 0xffff;
	al_uint8 u8LocalRegionId = 0xff;
	frmwrk_pfOpConext_t pfPSIMonGetContext = al_null;
	
	if (pCodePage == NULL)
	{
		return AL_FAILURE;
	}

	if ((MID_SUCCESS != MID_PlaybackGetCurProgHandle(al_null, &hCurrProgHdl))
		|| (hCurrProgHdl == AL_DB_INVALIDHDL))
	{
		EPG_ERROR_MESSAGE("Get current program handle error.\n");
	}

	if (AL_SUCCESS != AL_DB_QueryDetailFieldByName(hCurrProgHdl, (al_uint8 *)"usOrigNetId", (al_void *)&usOrigNetId))
	{
		EPG_ERROR_MESSAGE("Get current program info error.\n");
	}

	*pCodePage = 0xff;
	AL_FW_GetContextCb(&pfPSIMonGetContext);
	if (pfPSIMonGetContext != al_null)
	{
		/* get user setting region id */
		pfPSIMonGetContext(FW_CONTEXT_TYPE_COUNTRY_ID , FW_CONTEXT_OP_TYPE_READ,
			(al_void *)&u8LocalRegionId, 0);
	}

	/* 0x20fa -> FRENCH orignal network id,  0x22d4 -> NETHERLANDS orignal network id, 0x2210 -> SPAIN orignal network id*/
	if ((usOrigNetId == 0x20fa) || (usOrigNetId == 0x22d4) || (usOrigNetId == 0x2210))
	{
		*pCodePage = ISO8859_9;
	}
	/* 0x013E -> GREECE orignal network id*/
	else if (usOrigNetId == 0x013E)
	{
		*pCodePage = ISO8859_7;
	}
	else if ((usOrigNetId == 0x0040) || (usOrigNetId == 0x0050) || (usOrigNetId == 0x20bf))
	{
		*pCodePage = ISO8859_2;
	}
	else
	{
		switch (u8LocalRegionId)
		{
		#if defined (CONFIG_DVB_SYSTEM)
			case AREA_HUNGARY:
				*pCodePage = ISO8859_2;
				break;
			case AREA_GERMANY:
			case AREA_FRANCE:
			case AREA_ITALY:
			case AREA_NETHERLANDS:
			case AREA_SPAIN:
				*pCodePage = ISO8859_9;
				break;
			case AREA_GREECE:
				*pCodePage = ISO8859_7;
				break;
			case AREA_THAILAND: 
				*pCodePage = ISO8859_11;
				break;
		#endif
		#if defined (CONFIG_DTMB_SYSTEM)
			case AREA_CHINA:
				*pCodePage = CP_936;
				break;
		#endif
			default:
				*pCodePage = ISO6937;
				break;
		}
	}

	return AL_SUCCESS;
}

/**
* for the case that iso 639 is Mongolia and the first byte is 0x11
*/
al_uint32 AL_Event_MonUtf16IsBEorLE(UINT8 *rawchr, INT32 *size)
{
	al_uint32 i=0;
	int BECharCount=0,LECharCount=0;
	UINT16 tempchar;
	al_uint32 codepage = UTF16_BE;
	al_uint8 HeaderSize = 0;
	al_uint32 Len = 0;
	al_uint32 iCount = 0;

	HeaderSize = 1;
	*size = *size - HeaderSize;;
	Len = *size;
	while (Len)
	{
		rawchr[iCount] = rawchr[iCount +HeaderSize];
		iCount++;
		Len--;
	}
	rawchr[iCount] = 0x00;

	for(i = 0; i < iCount; i = i+2)
	{
		//if BE
		tempchar = rawchr[i]<<8|rawchr[i+1];
		if(tempchar > 0x0000 &&tempchar < 0x00FF)
			BECharCount++;
		else if(tempchar > 0x0400 &&tempchar < 0x04FF)
			BECharCount++;
		else if(tempchar > 0x1800 &&tempchar < 0x18AF)
			BECharCount++;
		else if(tempchar > 0x2000 &&tempchar < 0x206F)
			BECharCount++;

		//if LE
		tempchar = rawchr[i+1]<<8|rawchr[i];
		if(tempchar > 0x0000 &&tempchar < 0x00FF)
			LECharCount++;
		else if(tempchar > 0x0400 &&tempchar < 0x04FF)
			LECharCount++;
		else if(tempchar > 0x1800 &&tempchar < 0x18AF)
			LECharCount++;
		else if(tempchar > 0x2000 &&tempchar < 0x206F)
			LECharCount++;
	}

	if(BECharCount < LECharCount)
		codepage = UTF16_LE;
	else
		codepage = UTF16_BE;

	return codepage;
}

/**
* @brief according raw data to get code page and remove codepage data from raw data
*
* @param pCodePage, output defualt code page.
*
* @param rawchr, point to raw data.
*
* @param size, raw data size.
*
* @return AL_SUCCESS  is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_Event_GetCodePage(al_uint32 *pCodePage, UINT8 *rawchr, INT32 *size)
{
	al_uint32 iCount = 0;
	al_uint8 HeaderSize = 0;
	al_uint32 Len = 0;
	
	if (pCodePage == NULL || rawchr == NULL || size == NULL || *size == 0)
	{
		return AL_FAILURE;
	}

	*pCodePage = 0xff;

	if (rawchr[0] >= 0x01 && rawchr[0] <= 0x0b)
	{
		*pCodePage = ISO8859_5+(rawchr[0]-1);
	}
	else if ((rawchr[0] == 0x11) || (rawchr[0] == 0x14)) //UTF 16
	{
		*pCodePage = UTF16_BE;
	}
	else if (rawchr[0] == 0x13) //GB2312
	{
		*pCodePage = GB2312;
	}
	else if (rawchr[0] == 0x15)
	{
		*pCodePage = UTF8;
	}
	else if (rawchr[0] == 0x10 && *size >= 3)
	{
		if (rawchr[1] == 0x00 && (rawchr[2] >= 0x01 && rawchr[2] <= 0x0f))
		{
			*pCodePage = ISO8859_1+(rawchr[2]-1);
		}
	}

	if (*pCodePage != 0xff)
	{
		if  (rawchr[0] == 0x10)
		{
			HeaderSize = 3;
		}
		else
		{
			HeaderSize = 1;
		}

		*size = *size - HeaderSize;;
		Len = *size;
		while (Len)
		{
			rawchr[iCount] = rawchr[iCount +HeaderSize];
			iCount++;
			Len--;
		}

		if (HeaderSize == 3)
		{
			rawchr[iCount] = 0x00;
			rawchr[iCount+1] = 0x00;
			rawchr[iCount+2] = 0x00;
		}
		else if (HeaderSize == 1)
		{
			rawchr[iCount] = 0x00;
		}	
	}

	return AL_SUCCESS;
}

/* For MHEG5 link error. this will be removed in future */
Boolean MID_EpgGetSupportDTG(void)
{
	return al_epg_DTG_support;
}

/*****************************************************************************
** $Rev: 1910 $
**
*****************************************************************************/

