// Calc and store row height
int RowHeights_GetRowHeight(ClcData *dat, HWND hwnd, ClcContact *contact, int item)
{
	if (!dat->row_variable_height)
		return dat->rowHeight;

	DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
	//TODO replace futher code with new rowheight definition
	BOOL selected = ((item == dat->selection) && (dat->hwndRenameEdit != nullptr || dat->bShowSelAlways || (dat->exStyle & CLS_EX_SHOWSELALWAYS) || g_clcPainter.IsForegroundWindow(hwnd)) && contact->type != CLCIT_DIVIDER);
	BOOL minimalistic = (g_clcPainter.CheckMiniMode(dat, selected));

	if (!RowHeights_Alloc(dat, item + 1))
		return -1;

	int height = 0;
	ClcCacheEntry *pdnce = contact->pce;

	if (!dat->text_ignore_size_for_row_height) {
		int tmp = dat->fontModernInfo[g_clcPainter.GetBasicFontID(contact)].fontHeight;
		if (dat->text_replace_smileys && dat->first_line_draw_smileys && !dat->text_resize_smileys)
			tmp = max(tmp, contact->ssText.iMaxSmileyHeight);
		height += tmp;

		if (pdnce && !minimalistic) {
			if (dat->secondLine.show && pdnce->szSecondLineText && pdnce->szSecondLineText[0]) {
				tmp = dat->fontModernInfo[FONTID_SECONDLINE].fontHeight;
				if (dat->text_replace_smileys && dat->secondLine.draw_smileys && !dat->text_resize_smileys)
					tmp = max(tmp, pdnce->ssSecondLine.iMaxSmileyHeight);
				height += dat->secondLine.top_space + tmp;
			}

			if (dat->thirdLine.show && pdnce->szThirdLineText && pdnce->szThirdLineText[0]) {
				tmp = dat->fontModernInfo[FONTID_THIRDLINE].fontHeight;
				if (dat->text_replace_smileys && dat->thirdLine.draw_smileys && !dat->text_resize_smileys)
					tmp = max(tmp, pdnce->ssThirdLine.iMaxSmileyHeight);
				height += dat->thirdLine.top_space + tmp;
			}
		}
	}

	// Avatar size
	if (dat->avatars_show && !dat->avatars_ignore_size_for_row_height && contact->type == CLCIT_CONTACT && contact->avatar_data != nullptr && !minimalistic)
		height = max(height, dat->avatars_maxheight_size);

	// Checkbox size
	if (contact->isCheckBox(style))
		height = max(height, dat->checkboxSize);

	// Icon size
	if (!dat->icon_ignore_size_for_row_height) {
		if (contact->type == CLCIT_GROUP ||
			(contact->type == CLCIT_CONTACT && contact->iImage != -1 && !(dat->icon_hide_on_avatar && dat->avatars_show && contact->avatar_data != nullptr && !contact->bImageIsSpecial))) {
			height = max(height, ICON_HEIGHT);
		}
	}

	height += 2 * dat->row_border;

	// Min size
	return dat->row_heights[item] = max(height, dat->row_min_heigh);
}
int RowHeight_CalcRowHeight(ClcData *dat, ClcContact *contact, int item)
{
	if (!RowHeights_Alloc(dat, item + 1))
		return -1;

	if (!g_clistApi.hwndContactTree)
		return 0;

	ClcCacheEntry *pdnce = contact->pce;
	if (dat->hWnd != g_clistApi.hwndContactTree || !gl_RowRoot || contact->type == CLCIT_GROUP) {
		int tmp = dat->fontModernInfo[g_clcPainter.GetBasicFontID(contact)].fontHeight;
		if (dat->text_replace_smileys && dat->first_line_draw_smileys && !dat->text_resize_smileys)
			tmp = max(tmp, contact->ssText.iMaxSmileyHeight);
		if (contact->type == CLCIT_GROUP) {
			wchar_t *szCounts = Clist_GetGroupCountsText(dat, contact);
			// Has the count?
			if (szCounts && szCounts[0])
				tmp = max(tmp, dat->fontModernInfo[contact->group->expanded ? FONTID_OPENGROUPCOUNTS : FONTID_CLOSEDGROUPCOUNTS].fontHeight);
		}
		tmp = max(tmp, ICON_HEIGHT);
		tmp = max(tmp, dat->row_min_heigh);
		tmp += dat->row_border * 2;
		if (contact->type == CLCIT_GROUP && contact->group->parent->groupId == 0 && contact->group->parent->cl[0] != contact)
			tmp += dat->row_before_group_space;
		if (item != -1)
			dat->row_heights[item] = tmp;
		return tmp;
	}

	bool hasAvatar = contact->avatar_data != nullptr;
	for (int i = 0;; i++) {
		ROWCELL *pCell = gl_RowTabAccess[i];
		if (pCell == nullptr)
			break;

		if (pCell->type != TC_SPACE) {
			pCell->h = 0;
			pCell->w = 0;
			SetRect(&pCell->r, 0, 0, 0, 0);
			switch (pCell->type) {
			case TC_TEXT1:
				pCell->h = dat->fontModernInfo[g_clcPainter.GetBasicFontID(contact)].fontHeight;
				if (dat->text_replace_smileys && dat->first_line_draw_smileys && !dat->text_resize_smileys)
					pCell->h = max(pCell->h, contact->ssText.iMaxSmileyHeight);
				if (item == -1) {
					// calculate text width here
					SIZE size = { 0 };
					RECT dummyRect = { 0, 0, 1024, pCell->h };
					HDC hdc = CreateCompatibleDC(nullptr);
					g_clcPainter.ChangeToFont(hdc, dat, g_clcPainter.GetBasicFontID(contact), nullptr);
					g_clcPainter.GetTextSize(&size, hdc, dummyRect, contact->szText, contact->ssText.plText, 0, dat->text_resize_smileys ? 0 : contact->ssText.iMaxSmileyHeight);
					if (contact->type == CLCIT_GROUP) {
						wchar_t *szCounts = Clist_GetGroupCountsText(dat, contact);
						if (szCounts && mir_wstrlen(szCounts) > 0) {
							RECT count_rc = { 0 };
							// calc width and height
							g_clcPainter.ChangeToFont(hdc, dat, contact->group->expanded ? FONTID_OPENGROUPCOUNTS : FONTID_CLOSEDGROUPCOUNTS, nullptr);
							ske_DrawText(hdc, L" ", 1, &count_rc, DT_CALCRECT | DT_NOPREFIX);
							size.cx += count_rc.right - count_rc.left;
							count_rc.right = 0;
							count_rc.left = 0;
							ske_DrawText(hdc, szCounts, (int)mir_wstrlen(szCounts), &count_rc, DT_CALCRECT);
							size.cx += count_rc.right - count_rc.left;
							pCell->h = max(pCell->h, count_rc.bottom - count_rc.top);
						}
					}
					pCell->w = size.cx;
					SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
					ske_ResetTextEffect(hdc);
					DeleteDC(hdc);
				}
				break;

			case TC_TEXT2:
				if (dat->secondLine.show && pdnce->szSecondLineText && pdnce->szSecondLineText[0]) {
					pCell->h = dat->fontModernInfo[FONTID_SECONDLINE].fontHeight;
					if (dat->text_replace_smileys && dat->secondLine.draw_smileys && !dat->text_resize_smileys)
						pCell->h = max(pCell->h, pdnce->ssSecondLine.iMaxSmileyHeight);
					if (item == -1) {
						// calculate text width here
						SIZE size = { 0 };
						RECT dummyRect = { 0, 0, 1024, pCell->h };
						HDC hdc = CreateCompatibleDC(nullptr);
						g_clcPainter.ChangeToFont(hdc, dat, FONTID_SECONDLINE, nullptr);
						g_clcPainter.GetTextSize(&size, hdc, dummyRect, pdnce->szSecondLineText, pdnce->ssSecondLine.plText, 0, dat->text_resize_smileys ? 0 : pdnce->ssSecondLine.iMaxSmileyHeight);
						pCell->w = size.cx;
						SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
						ske_ResetTextEffect(hdc);
						DeleteDC(hdc);
					}
				}
				break;

			case TC_TEXT3:
				if (dat->thirdLine.show && pdnce->szThirdLineText && pdnce->szThirdLineText[0]) {
					pCell->h = dat->fontModernInfo[FONTID_THIRDLINE].fontHeight;
					if (dat->text_replace_smileys && dat->thirdLine.draw_smileys && !dat->text_resize_smileys)
						pCell->h = max(pCell->h, pdnce->ssThirdLine.iMaxSmileyHeight);
					if (item == -1) {
						//calculate text width here
						SIZE size = { 0 };
						RECT dummyRect = { 0, 0, 1024, pCell->h };
						HDC hdc = CreateCompatibleDC(nullptr);
						g_clcPainter.ChangeToFont(hdc, dat, FONTID_THIRDLINE, nullptr);
						g_clcPainter.GetTextSize(&size, hdc, dummyRect, pdnce->szThirdLineText, pdnce->ssThirdLine.plText, 0, dat->text_resize_smileys ? 0 : pdnce->ssThirdLine.iMaxSmileyHeight);
						pCell->w = size.cx;
						SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
						ske_ResetTextEffect(hdc);
						DeleteDC(hdc);
					}
				}
				break;

			case TC_STATUS:
				if ((contact->type == CLCIT_GROUP && !dat->row_hide_group_icon) ||
					(contact->type == CLCIT_CONTACT && contact->iImage != -1 &&
					!(dat->icon_hide_on_avatar && dat->avatars_show && (hasAvatar || (!hasAvatar && dat->icon_draw_on_avatar_space && contact->iImage != -1)) && !contact->bImageIsSpecial))) {
					pCell->h = ICON_HEIGHT;
					pCell->w = ICON_HEIGHT;
				}
				break;

			case TC_AVATAR:
				if (dat->avatars_show &&
					contact->type == CLCIT_CONTACT &&
					(hasAvatar || (dat->icon_hide_on_avatar && dat->icon_draw_on_avatar_space && contact->iImage != -1))) {
					int iW = 0, iH = 0;
					if (contact->avatar_data) {
						iH = contact->avatar_data->bmHeight;
						iW = contact->avatar_data->bmWidth;
					}

					SIZE sz = GetAvatarSize(iW, iH, dat->avatars_maxwidth_size, dat->avatars_maxheight_size);
					if ((sz.cx == 0 || sz.cy == 0) && dat->icon_hide_on_avatar && dat->icon_draw_on_avatar_space && contact->iImage != -1)
						sz.cx = ICON_HEIGHT, sz.cy = ICON_HEIGHT;

					pCell->h = sz.cy;
					pCell->w = sz.cx;
				}
				break;

			case TC_EXTRA: // Draw extra icons
				if (contact->type == CLCIT_CONTACT &&
					(!contact->iSubNumber || db_get_b(0, "CLC", "MetaHideExtra", SETTING_METAHIDEEXTRA_DEFAULT) == 0 && dat->extraColumnsCount > 0)) {
					bool hasExtra = false;
					int width = 0;
					for (int k = 0; k < dat->extraColumnsCount; k++)
						if (contact->iExtraImage[k] != EMPTY_EXTRA_ICON || !dat->bMetaIgnoreEmptyExtra) {
							hasExtra = true;
							if (item != -1) break;
							width += (width > 0) ? dat->extraColumnSpacing : (dat->extraColumnSpacing - 2);
						}
					if (hasExtra) {
						pCell->h = ICON_HEIGHT;
						pCell->w = width;
					}
				}
				break;

			case TC_EXTRA1:
			case TC_EXTRA2:
			case TC_EXTRA3:
			case TC_EXTRA4:
			case TC_EXTRA5:
			case TC_EXTRA6:
			case TC_EXTRA7:
			case TC_EXTRA8:
			case TC_EXTRA9:
				if (contact->type == CLCIT_CONTACT &&
					(!contact->iSubNumber || db_get_b(0, "CLC", "MetaHideExtra", SETTING_METAHIDEEXTRA_DEFAULT) == 0 && dat->extraColumnsCount > 0)) {
					int eNum = pCell->type - TC_EXTRA1;
					if (eNum < dat->extraColumnsCount)
						if (contact->iExtraImage[eNum] != EMPTY_EXTRA_ICON || !dat->bMetaIgnoreEmptyExtra) {
							pCell->h = ICON_HEIGHT;
							pCell->w = ICON_HEIGHT;
						}
				}
				break;

			case TC_TIME:
				if (contact->type == CLCIT_CONTACT && dat->contact_time_show && pdnce->hTimeZone) {
					pCell->h = dat->fontModernInfo[FONTID_CONTACT_TIME].fontHeight;
					if (item == -1) {
						wchar_t szResult[80];

						if (!TimeZone_PrintDateTime(pdnce->hTimeZone, L"t", szResult, _countof(szResult), 0)) {
							SIZE text_size = { 0 };
							RECT rc = { 0 };
							// Select font
							HDC hdc = CreateCompatibleDC(nullptr);
							g_clcPainter.ChangeToFont(hdc, dat, FONTID_CONTACT_TIME, nullptr);

							// Get text size
							text_size.cy = ske_DrawText(hdc, szResult, (int)mir_wstrlen(szResult), &rc, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
							SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
							ske_ResetTextEffect(hdc);
							DeleteDC(hdc);
							text_size.cx = rc.right - rc.left;
							pCell->w = text_size.cx;
						}
					}
				}
				break;
			}
		}
	}

	int height = cppCalculateRowHeight(gl_RowRoot);
	height += dat->row_border * 2;
	height = max(height, dat->row_min_heigh);
	if (item != -1)
		dat->row_heights[item] = height;
	return height;
}
// Calc and store row height
int RowHeights_GetRowHeight(struct ClcData *dat, HWND hwnd, struct ClcContact *contact, int item)
{
	int height = 0, tmp;
	DWORD style=GetWindowLong(hwnd,GWL_STYLE);

	if (!RowHeights_Alloc(dat, item + 1))
		return -1;

	if (dat->row_variable_height)
	{
		if (!dat->text_ignore_size_for_row_height)
		{
			tmp = dat->fontInfo[GetBasicFontID(contact)].fontHeight;
			if (dat->text_replace_smileys && dat->first_line_draw_smileys && !dat->text_resize_smileys)
			{
				tmp = max(tmp, contact->iTextMaxSmileyHeight);
			}
			height += tmp;

			if (dat->second_line_show && contact->szSecondLineText)
			{
				tmp = dat->fontInfo[FONTID_SECONDLINE].fontHeight;
				if (dat->text_replace_smileys && dat->second_line_draw_smileys && !dat->text_resize_smileys)
				{
					tmp = max(tmp, contact->iSecondLineMaxSmileyHeight);
				}
				height += dat->second_line_top_space + tmp;
			}

			if (dat->third_line_show && contact->szThirdLineText)
			{
				tmp = dat->fontInfo[FONTID_THIRDLINE].fontHeight;
				if (dat->text_replace_smileys && dat->third_line_draw_smileys && !dat->text_resize_smileys)
				{
					tmp = max(tmp, contact->iThirdLineMaxSmileyHeight);
				}
				height += dat->third_line_top_space + tmp;
			}
		}

		// Avatar size
		if (dat->avatars_show && !dat->avatars_ignore_size_for_row_height && 
				contact->type == CLCIT_CONTACT && 
				(
					(dat->use_avatar_service && contact->avatar_data != NULL) ||
      (!dat->use_avatar_service && contact->avatar_pos != AVATAR_POS_DONT_HAVE)
      )
      )
		{
			height = max(height, dat->avatars_size);
		}

		// Checkbox size
		if((style&CLS_CHECKBOXES && contact->type==CLCIT_CONTACT) ||
			(style&CLS_GROUPCHECKBOXES && contact->type==CLCIT_GROUP) ||
			(contact->type==CLCIT_INFO && contact->flags&CLCIIF_CHECKBOX))
		{
			height = max(height, dat->checkboxSize);
		}

		// Icon size
		if (!dat->icon_ignore_size_for_row_height)
		{
			if (contact->type == CLCIT_GROUP 
				|| (contact->type == CLCIT_CONTACT && contact->iImage != -1 
					&& !(dat->icon_hide_on_avatar && dat->avatars_show
						&& ( (dat->use_avatar_service && contact->avatar_data != NULL) ||
		  					 (!dat->use_avatar_service && contact->avatar_pos != AVATAR_POS_DONT_HAVE)
						   )
						&& !contact->image_is_special)))
			{
				height = max(height, ICON_HEIGHT);
			}
		}

		height += 2 * dat->row_border;

		// Min size
		height = max(height, dat->row_min_heigh);
	}
	else
	{
		height = dat->max_row_height;
	}

	dat->row_heights[item] = height;

	return height;
}