void EventArea_ConfigureEventArea()
{
	int iCount = pcli->events.count;

	g_CluiData.dwFlags &= ~(CLUI_FRAME_AUTOHIDENOTIFY|CLUI_FRAME_SHOWALWAYS);
	if ( db_get_b(NULL,"CLUI","EventArea",SETTING_EVENTAREAMODE_DEFAULT) == 1) g_CluiData.dwFlags |= CLUI_FRAME_AUTOHIDENOTIFY;
	if ( db_get_b(NULL,"CLUI","EventArea",SETTING_EVENTAREAMODE_DEFAULT) == 2) g_CluiData.dwFlags |= CLUI_FRAME_SHOWALWAYS;

	if (g_CluiData.dwFlags & CLUI_FRAME_SHOWALWAYS)
		g_CluiData.bNotifyActive = 1;
	else if (g_CluiData.dwFlags & CLUI_FRAME_AUTOHIDENOTIFY)
		g_CluiData.bNotifyActive = iCount > 0 ? 1 : 0;
	else
		g_CluiData.bNotifyActive = 0;

	EventArea_HideShowNotifyFrame();
}
int EventArea_Create(HWND hCluiWnd)
{

	CallService(MS_BACKGROUNDCONFIG_REGISTER,(WPARAM)(LPGEN("Event area background")"/EventArea"),0);
	HookEvent(ME_BACKGROUNDCONFIG_CHANGED,ehhEventAreaBackgroundSettingsChanged);
	ehhEventAreaBackgroundSettingsChanged(0, 0);

	WNDCLASS wndclass = {0};
	TCHAR pluginname[] = _T("EventArea");
	int h = GetSystemMetrics(SM_CYSMICON)+2;
	if (GetClassInfo(g_hInst,pluginname,&wndclass) == 0) {
		wndclass.style         = 0;
		wndclass.lpfnWndProc   = EventArea_WndProc;
		wndclass.cbClsExtra    = 0;
		wndclass.cbWndExtra    = 0;
		wndclass.hInstance     = g_hInst;
		wndclass.hIcon         = NULL;
		wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
		wndclass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
		wndclass.lpszMenuName  = NULL;
		wndclass.lpszClassName = pluginname;
		RegisterClass(&wndclass);
	}
	g_CluiData.hwndEventFrame = CreateWindow(pluginname,pluginname,WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN,
		0, 0, 0, h,hCluiWnd,NULL,g_hInst,NULL);

	// register frame
	CLISTFrame Frame = { sizeof(CLISTFrame) };
	Frame.hWnd = g_CluiData.hwndEventFrame;
	Frame.align = alBottom;
	Frame.hIcon = LoadSkinnedIcon(SKINICON_OTHER_FRAME);
	Frame.Flags = ( db_get_b(NULL,"CLUI","ShowEventArea",SETTING_SHOWEVENTAREAFRAME_DEFAULT)?F_VISIBLE:0)|F_LOCKED|F_NOBORDER|F_NO_SUBCONTAINER|F_TCHAR;
	Frame.height = h;
	Frame.tname = _T("EventArea"); //do not translate
	Frame.TBtname = TranslateT("Event Area");
	hNotifyFrame = (HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&Frame,0);
	CallService(MS_SKINENG_REGISTERPAINTSUB,(WPARAM)Frame.hWnd,(LPARAM)EventArea_PaintCallbackProc); //$$$$$ register sub for frame
	CallService(MS_CLIST_FRAMES_UPDATEFRAME,-1,0);
	EventArea_HideShowNotifyFrame();

	g_CluiData.szNoEvents = TranslateT("No Events");
	g_CluiData.hMenuNotify = CreatePopupMenu();
	g_CluiData.wNextMenuID = 1;
	EventArea_ConfigureEventArea();
	return 0;
}
void EventArea_ConfigureEventArea()
{
	int iCount = g_clistApi.events->getCount();

	g_CluiData.dwFlags &= ~(CLUI_FRAME_AUTOHIDENOTIFY | CLUI_FRAME_SHOWALWAYS);
	if (db_get_b(0, "CLUI", "EventArea", SETTING_EVENTAREAMODE_DEFAULT) == 1) g_CluiData.dwFlags |= CLUI_FRAME_AUTOHIDENOTIFY;
	if (db_get_b(0, "CLUI", "EventArea", SETTING_EVENTAREAMODE_DEFAULT) == 2) g_CluiData.dwFlags |= CLUI_FRAME_SHOWALWAYS;

	if (g_CluiData.dwFlags & CLUI_FRAME_SHOWALWAYS)
		g_CluiData.bNotifyActive = true;
	else if (g_CluiData.dwFlags & CLUI_FRAME_AUTOHIDENOTIFY)
		g_CluiData.bNotifyActive = iCount > 0;
	else
		g_CluiData.bNotifyActive = false;

	EventArea_HideShowNotifyFrame();
}
int cli_RemoveEvent(HANDLE hContact, HANDLE hDbEvent)
{
	int i;
	int res = 0;

	// Find the event that should be removed
	for (i=0; i < pcli->events.count; i++)
	{
		if ((pcli->events.items[i]->cle.hContact == hContact) && (pcli->events.items[i]->cle.hDbEvent == hDbEvent))
		{
			break;
		}
	}

	// Event was not found
	if (i == pcli->events.count)
		return 1;

	// remove event from the notify menu
	if (pcli->events.items[i]->menuId > 0) {
		MENUITEMINFO mii = {0};
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_DATA;
		if (GetMenuItemInfo(g_CluiData.hMenuNotify, pcli->events.items[i]->menuId, FALSE, &mii) != 0) {
			struct NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
			if (nmi && nmi->hContact == hContact && nmi->hDbEvent == hDbEvent) {
				free(nmi);
				DeleteMenu(g_CluiData.hMenuNotify, pcli->events.items[i]->menuId, MF_BYCOMMAND);
			}
		}
	}

	res = corecli.pfnRemoveEvent(hContact, hDbEvent);

	if (pcli->events.count == 0) {
		g_CluiData.bNotifyActive = FALSE;
		EventArea_HideShowNotifyFrame();
	}

	if (hContact == g_CluiData.hUpdateContact || (INT_PTR)hDbEvent == 1)
		g_CluiData.hUpdateContact = 0;
	CLUI__cliInvalidateRect(g_CluiData.hwndEventFrame, NULL, FALSE);
	return res;
}
int cli_RemoveEvent(MCONTACT hContact, MEVENT hDbEvent)
{
	// Find the event that should be removed
	CListEvent *pEvent = nullptr;
	for (auto &it : *g_clistApi.events)
		if (it->hContact == hContact && it->hDbEvent == hDbEvent) {
			pEvent = it;
			break;
		}

	// Event was not found
	if (pEvent == nullptr)
		return 1;

	// remove event from the notify menu
	int iMenuId = pEvent->menuId;
	if (iMenuId > 0) {
		MENUITEMINFO mii = { 0 };
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_DATA;
		if (GetMenuItemInfo(g_CluiData.hMenuNotify, iMenuId, FALSE, &mii) != 0) {
			struct NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
			if (nmi && nmi->hContact == hContact && nmi->hDbEvent == hDbEvent) {
				free(nmi);
				DeleteMenu(g_CluiData.hMenuNotify, iMenuId, MF_BYCOMMAND);
			}
		}
	}

	int res = corecli.pfnRemoveEvent(hContact, hDbEvent);

	if (g_clistApi.events->getCount() == 0) {
		g_CluiData.bNotifyActive = false;
		EventArea_HideShowNotifyFrame();
	}

	if (hContact == g_CluiData.hUpdateContact || (INT_PTR)hDbEvent == 1)
		g_CluiData.hUpdateContact = 0;
	cliInvalidateRect(g_CluiData.hwndEventFrame, nullptr, FALSE);
	return res;
}
struct CListEvent* cli_AddEvent(CLISTEVENT *cle)
{
	struct CListEvent* p = corecli.pfnAddEvent(cle);
		if ( p == NULL )
		return NULL;

	if (1) {
		if (p->cle.hContact != 0 && p->cle.hDbEvent != (HANDLE) 1 && !(p->cle.flags & CLEF_ONLYAFEW)) {
			int j;
			struct NotifyMenuItemExData *nmi = 0;
			char *szProto;
			TCHAR *szName;
			MENUITEMINFO mii = {0};
			mii.cbSize = sizeof(mii);
			mii.fMask = MIIM_DATA | MIIM_BITMAP | MIIM_ID;
			if (p->cle.pszService && (    !strncmp("SRMsg/ReadMessage", p->cle.pszService, SIZEOF("SRMsg/ReadMessage"))
								   	   || !strncmp("GChat/DblClickEvent", p->cle.pszService, SIZEOF("GChat/DblClickEvent"))))

			{
				// dup check only for msg events
				for (j = 0; j < GetMenuItemCount(g_CluiData.hMenuNotify); j++) {
					if (GetMenuItemInfo(g_CluiData.hMenuNotify, j, TRUE, &mii) != 0) {
						nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
						if (nmi != 0 && (HANDLE) nmi->hContact == (HANDLE) p->cle.hContact && nmi->iIcon == p->imlIconIndex)
							return p;
			}	}	}

			szProto = GetContactProto(p->cle.hContact);
			szName = pcli->pfnGetContactDisplayName(p->cle.hContact, 0);
			if (szProto && szName) {
				nmi = (struct NotifyMenuItemExData *) malloc(sizeof(struct NotifyMenuItemExData));
				if (nmi) {
					TCHAR szBuffer[128];
					TCHAR* szStatus = pcli->pfnGetStatusModeDescription(db_get_w(p->cle.hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
					TCHAR szwProto[64];
					MultiByteToWideChar(CP_ACP, 0, szProto, -1, szwProto, 64);
					szwProto[63] = 0;
					mir_sntprintf(szBuffer, SIZEOF(szBuffer), _T("%s: %s (%s)"), szwProto, szName, szStatus);
					szBuffer[127] = 0;
					AppendMenu(g_CluiData.hMenuNotify, MF_BYCOMMAND | MF_STRING, g_CluiData.wNextMenuID, szBuffer);
					mii.hbmpItem = HBMMENU_CALLBACK;
					nmi->hContact = p->cle.hContact;
					nmi->iIcon = p->imlIconIndex;
					nmi->hIcon = p->cle.hIcon;
					nmi->hDbEvent = p->cle.hDbEvent;
					mii.dwItemData = (ULONG_PTR) nmi;
					mii.wID = g_CluiData.wNextMenuID;
					SetMenuItemInfo(g_CluiData.hMenuNotify, g_CluiData.wNextMenuID, FALSE, &mii);
					p-> menuId = g_CluiData.wNextMenuID;
					g_CluiData.wNextMenuID++;
					if (g_CluiData.wNextMenuID > 0x7fff)
						g_CluiData.wNextMenuID = 1;
					g_CluiData.iIconNotify = p->imlIconIndex;
				}
			}
		}

		else if (p->cle.hContact != 0 && (p->cle.flags & CLEF_ONLYAFEW))
		{
			g_CluiData.iIconNotify = p->imlIconIndex;
			g_CluiData.hUpdateContact = p->cle.hContact;
		}
		if (pcli->events.count > 0) {
			g_CluiData.bEventAreaEnabled = TRUE;
			if (g_CluiData.bNotifyActive == FALSE) {
				g_CluiData.bNotifyActive = TRUE;
				EventArea_HideShowNotifyFrame();
			}
		}
		CLUI__cliInvalidateRect(g_CluiData.hwndEventFrame, NULL, FALSE);
	}

	return p;
}
CListEvent* cli_AddEvent(CLISTEVENT *cle)
{
	CListEvent *p = corecli.pfnAddEvent(cle);
	if (p == nullptr)
		return nullptr;

	if (p->hContact != 0 && p->hDbEvent != 1 && !(p->flags & CLEF_ONLYAFEW)) {
		MENUITEMINFO mii = { 0 };
		mii.cbSize = sizeof(mii);
		mii.fMask = MIIM_DATA | MIIM_BITMAP | MIIM_ID;
		if (p->pszService &&
			(!strncmp(MS_MSG_READMESSAGE, p->pszService, _countof(MS_MSG_READMESSAGE)) ||
			 !strncmp("GChat/DblClickEvent", p->pszService, _countof("GChat/DblClickEvent")))) {
			// dup check only for msg events
			for (int j = 0; j < GetMenuItemCount(g_CluiData.hMenuNotify); j++) {
				if (GetMenuItemInfo(g_CluiData.hMenuNotify, j, TRUE, &mii) != 0) {
					NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) mii.dwItemData;
					if (nmi != nullptr && (HANDLE)nmi->hContact == (HANDLE)p->hContact && nmi->iIcon == p->imlIconIndex)
						return p;
				}
			}
		}

		char *szProto = GetContactProto(p->hContact);
		wchar_t *szName = Clist_GetContactDisplayName(p->hContact);
		if (szProto && szName) {
			NotifyMenuItemExData *nmi = (struct NotifyMenuItemExData *) malloc(sizeof(struct NotifyMenuItemExData));
			if (nmi) {
				wchar_t szBuffer[128];
				wchar_t* szStatus = Clist_GetStatusModeDescription(db_get_w(p->hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
				wchar_t szwProto[64];
				MultiByteToWideChar(CP_ACP, 0, szProto, -1, szwProto, 64);
				szwProto[63] = 0;
				mir_snwprintf(szBuffer, L"%s: %s (%s)", szwProto, szName, szStatus);
				szBuffer[127] = 0;
				AppendMenu(g_CluiData.hMenuNotify, MF_BYCOMMAND | MF_STRING, g_CluiData.wNextMenuID, szBuffer);
				mii.hbmpItem = HBMMENU_CALLBACK;
				nmi->hContact = p->hContact;
				nmi->iIcon = p->imlIconIndex;
				nmi->hIcon = p->hIcon;
				nmi->hDbEvent = p->hDbEvent;
				mii.dwItemData = (ULONG_PTR)nmi;
				mii.wID = g_CluiData.wNextMenuID;
				SetMenuItemInfo(g_CluiData.hMenuNotify, g_CluiData.wNextMenuID, FALSE, &mii);
				p->menuId = g_CluiData.wNextMenuID;
				g_CluiData.wNextMenuID++;
				if (g_CluiData.wNextMenuID > 0x7fff)
					g_CluiData.wNextMenuID = 1;
				g_CluiData.iIconNotify = p->imlIconIndex;
			}
		}
	}
	else if (p->hContact != 0 && (p->flags & CLEF_ONLYAFEW)) {
		g_CluiData.iIconNotify = p->imlIconIndex;
		g_CluiData.hUpdateContact = p->hContact;
	}

	if (g_clistApi.events->getCount() > 0) {
		g_CluiData.bEventAreaEnabled = true;
		if (g_CluiData.bNotifyActive == false) {
			g_CluiData.bNotifyActive = true;
			EventArea_HideShowNotifyFrame();
		}
	}

	cliInvalidateRect(g_CluiData.hwndEventFrame, nullptr, FALSE);
	return p;
}