void Cache_GetNthLineText(ClcData *dat, ClcCacheEntry *pdnce, int n)
{
	wchar_t Text[240 - EXTRA_ICON_COUNT]; Text[0] = 0;
	ClcLineInfo &line = (n == 2) ? dat->secondLine : dat->thirdLine;
	wchar_t* &szText = (n == 2) ? pdnce->szSecondLineText : pdnce->szThirdLineText;

	// in most cases replaceStrW does nothing
	if (!line.show) {
		replaceStrW(szText, nullptr);
		return;
	}
	
	int type = Cache_GetLineText(pdnce, line.type, Text, _countof(Text), line);
	if (Text[0] == 0) {
		replaceStrW(szText, nullptr);
		return;
	}
	
	Text[_countof(Text) - 1] = 0; //to be sure that it is null terminated string
	replaceStrW(szText, Text);

	CSmileyString &ss = (n == 2) ? pdnce->ssSecondLine : pdnce->ssThirdLine;
	if (type == TEXT_LISTENING_TO && szText[0] != '\0')
		ss.AddListeningToIcon(dat, szText);
	else
		ss.ReplaceSmileys(dat, pdnce, szText, line.draw_smileys);
}
/*
*	Get the text for Third Line
*/
void Cache_GetThirdLineText(struct SHORTDATA *dat, PDNCE pdnce)
{
    TCHAR Text[240-MAXEXTRACOLUMNS]={0};
    int type = TEXT_EMPTY;
    if (dat->third_line_show)
        type = Cache_GetLineText(pdnce, dat->third_line_type,(TCHAR*)Text, SIZEOF(Text), dat->third_line_text,
        dat->third_line_xstatus_has_priority,dat->third_line_show_status_if_no_away,dat->third_line_show_listening_if_no_away,
        dat->third_line_use_name_and_message_for_xstatus, dat->contact_time_show_only_if_different);

    // LockCacheItem(hContact, __FILE__,__LINE__);
    Text[SIZEOF(Text)-1]=_T('\0'); //to be sure that it is null terminated string
    
    if (pdnce->szThirdLineText) mir_free(pdnce->szThirdLineText);
    
    if (dat->third_line_show)//Text[0]!='\0')
        pdnce->szThirdLineText=mir_tstrdup((TCHAR*)Text);
    else
        pdnce->szThirdLineText=NULL;
    
    if (pdnce->szThirdLineText) 
    {
        if (type == TEXT_LISTENING_TO && pdnce->szThirdLineText[0] != _T('\0'))
        {
            pdnce->ssThirdLine.AddListeningToIcon(dat, pdnce, pdnce->szThirdLineText, dat->third_line_draw_smileys);
        }
        else
        {
			pdnce->ssThirdLine.ReplaceSmileys(dat, pdnce, pdnce->szThirdLineText, dat->third_line_draw_smileys);
        }
    }
    // UnlockCacheItem(hContact);
}
void Cache_GetThirdLineText(struct ClcData *dat, struct ClcContact *contact)
{
  TCHAR Text[120-MAXEXTRACOLUMNS]={0};
	Cache_GetLineText(contact, dat->third_line_type,(TCHAR*)Text, SIZEOF(Text), dat->third_line_text,
		dat->third_line_xstatus_has_priority,dat->third_line_show_status_if_no_away,
		dat->third_line_use_name_and_message_for_xstatus, dat->contact_time_show_only_if_different);
  if (contact->szThirdLineText) mir_free(contact->szThirdLineText);
  if (Text[0]!='\0')
    contact->szThirdLineText=mir_strdupT((TCHAR*)Text);
  else
    contact->szThirdLineText=NULL;
  Text[120-MAXEXTRACOLUMNS-1]='\0';
	Cache_ReplaceSmileys(dat, contact, contact->szThirdLineText, lstrlen(contact->szThirdLineText), &contact->plThirdLineText, 
		&contact->iThirdLineMaxSmileyHeight,dat->third_line_draw_smileys);
}
/*
*	Get the text for Third Line
*/
void Cache_GetThirdLineText(SHORTDATA *dat, ClcCacheEntry *pdnce)
{
	TCHAR Text[240 - EXTRA_ICON_COUNT] = { 0 };
	int type = TEXT_EMPTY;
	if (dat->third_line_show)
		type = Cache_GetLineText(pdnce, dat->third_line_type, Text, _countof(Text), dat->third_line_text,
		dat->third_line_xstatus_has_priority, dat->third_line_show_status_if_no_away, dat->third_line_show_listening_if_no_away,
		dat->third_line_use_name_and_message_for_xstatus, dat->contact_time_show_only_if_different);

	Text[_countof(Text) - 1] = 0; //to be sure that it is null terminated string

	replaceStrT(pdnce->szThirdLineText, (dat->third_line_show) ? Text : NULL);
	if (pdnce->szThirdLineText) {
		if (type == TEXT_LISTENING_TO && pdnce->szThirdLineText[0] != _T('\0'))
			pdnce->ssThirdLine.AddListeningToIcon(dat, pdnce->szThirdLineText);
		else
			pdnce->ssThirdLine.ReplaceSmileys(dat, pdnce, pdnce->szThirdLineText, dat->third_line_draw_smileys);
	}
}
// Get the text based on the settings for a especific line
void Cache_GetLineText(struct ClcContact *contact, int type, LPTSTR text, int text_size, TCHAR *variable_text, BOOL xstatus_has_priority, BOOL show_status_if_no_away, BOOL use_name_and_message_for_xstatus, BOOL contact_time_show_only_if_different)
{
	text[0] = '\0';
	switch(type)
	{
	case TEXT_STATUS:
		{
			if (GetStatusName(text, text_size, contact, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus)
			{
				DBVARIANT dbv;

				// Try to get XStatusMsg
				if (!DBGetContactSettingTString(contact->hContact, contact->proto, "XStatusMsg", &dbv)) 
				{
					if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
					{
						TCHAR *tmp = mir_strdupT(text);
						mir_sntprintf(text, text_size, TEXT("%s: %s"), tmp, dbv.pszVal);
						mir_free(tmp);
					}
					DBFreeVariant(&dbv);
				}
			}

			break;
		}
	case TEXT_NICKNAME:
		{
			if (contact->hContact && contact->proto)
			{
				DBVARIANT dbv;
				if (!DBGetContactSettingTString(contact->hContact, contact->proto, "Nick", &dbv)) 
				{
					lstrcpyn(text, dbv.ptszVal, text_size);
					DBFreeVariant(&dbv);
				}
			}
			break;
		}
	case TEXT_STATUS_MESSAGE:
		{
			if (GetStatusMessage(text, text_size, contact, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus)
			{
				DBVARIANT dbv;

				// Try to get XStatusName
				if (!DBGetContactSettingTString(contact->hContact, contact->proto, "XStatusName", &dbv)) 
				{
					if (dbv.pszVal != NULL && dbv.pszVal[0] != 0)
					{
						TCHAR *tmp = mir_strdupT(text);
						mir_sntprintf(text, text_size, TEXT("%s: %s"), dbv.pszVal, tmp);
						mir_free(tmp);
					}
					DBFreeVariant(&dbv);
				}
			}

			break;
		}
	case TEXT_TEXT:
		{
#ifndef UNICODE	
			if (!ServiceExists(MS_VARS_FORMATSTRING))
			{
				lstrcpyn(text, variable_text, text_size);
			}
			else
			{
				char *tmp = variables_parse(variable_text, contact->szText, contact->hContact);
				lstrcpyn(text, tmp, text_size);
				variables_free(tmp);
			}
#else
			lstrcpyn(text, variable_text, text_size);
#endif
			break;
		}
	case TEXT_CONTACT_TIME:
		{
			if (contact->timezone != -1 && (!contact_time_show_only_if_different || contact->timediff != 0))
			{
				// Get contact time
				DBTIMETOSTRINGT dbtts;
				time_t contact_time;

				contact_time = time(NULL) - contact->timediff;
				text[0] = '\0';

				dbtts.szDest = text;
				dbtts.cbDest = 70;
				dbtts.szFormat = TEXT("t");
				CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, contact_time, (LPARAM) & dbtts);
			}

			break;
		}
	}
	if (type==TEXT_STATUS_MESSAGE && show_status_if_no_away && text[0] == '\0')
	{
		//re-request status if no away
		Cache_GetLineText(contact, TEXT_STATUS, text, text_size, variable_text, xstatus_has_priority,0, use_name_and_message_for_xstatus, contact_time_show_only_if_different);		
	}

}
/*
*	Get the text for specified lines
*/
int Cache_GetLineText(
	ClcCacheEntry *pdnce, int type, LPTSTR text, int text_size, TCHAR *variable_text, BOOL xstatus_has_priority,
	BOOL show_status_if_no_away, BOOL show_listening_if_no_away, BOOL use_name_and_message_for_xstatus,
	BOOL pdnce_time_show_only_if_different)
{
	if (text == NULL)
		return TEXT_EMPTY;
	text[0] = '\0';

	switch (type) {
	case TEXT_STATUS:
		if (GetStatusName(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus) {
			DBVARIANT dbv = { 0 };

			// Try to get XStatusMsg
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) {
				if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0) {
					TCHAR *tmp = NEWTSTR_ALLOCA(text);
					mir_sntprintf(text, text_size, _T("%s: %s"), tmp, dbv.ptszVal);
					CopySkipUnprintableChars(text, text, text_size - 1);
				}
				db_free(&dbv);
			}
		}

		return TEXT_STATUS;

	case TEXT_NICKNAME:
		if (pdnce->hContact && pdnce->m_cache_cszProto) {
			DBVARIANT dbv = { 0 };
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "Nick", &dbv)) {
				mir_tstrncpy(text, dbv.ptszVal, text_size);
				db_free(&dbv);
				CopySkipUnprintableChars(text, text, text_size - 1);
			}
		}

		return TEXT_NICKNAME;

	case TEXT_STATUS_MESSAGE:
		if (GetStatusMessage(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus) {
			DBVARIANT dbv = { 0 };

			// Try to get XStatusName
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
				if (dbv.pszVal != NULL && dbv.pszVal[0] != 0) {
					TCHAR *tmp = NEWTSTR_ALLOCA(text);
					mir_sntprintf(text, text_size, _T("%s: %s"), dbv.pszVal, tmp);
				}
				CopySkipUnprintableChars(text, text, text_size - 1);
				db_free(&dbv);
			}
		}
		else if (use_name_and_message_for_xstatus && xstatus_has_priority) {
			DBVARIANT dbv = { 0 };
			// Try to get XStatusName
			if (!db_get_ts(pdnce->hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) {
				if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
					mir_tstrncpy(text, dbv.ptszVal, text_size);
				CopySkipUnprintableChars(text, text, text_size - 1);
				db_free(&dbv);
			}
		}

		if (text[0] == '\0') {
			if (show_listening_if_no_away) {
				Cache_GetLineText(pdnce, TEXT_LISTENING_TO, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);
				if (text[0] != '\0')
					return TEXT_LISTENING_TO;
			}

			if (show_status_if_no_away) {
				//re-request status if no away
				return Cache_GetLineText(pdnce, TEXT_STATUS, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);
			}
		}
		return TEXT_STATUS_MESSAGE;

	case TEXT_LISTENING_TO:
		GetListeningTo(text, text_size, pdnce);
		return TEXT_LISTENING_TO;

	case TEXT_TEXT:
	{
		TCHAR *tmp = variables_parsedup(variable_text, pdnce->tszName, pdnce->hContact);
		mir_tstrncpy(text, tmp, text_size);
		mir_free(tmp);
		CopySkipUnprintableChars(text, text, text_size - 1);
	}
	return TEXT_TEXT;

	case TEXT_CONTACT_TIME:
		if (pdnce->hTimeZone) {
			// Get pdnce time
			text[0] = 0;
			TimeZone_PrintDateTime(pdnce->hTimeZone, _T("t"), text, text_size, 0);
		}

		return TEXT_CONTACT_TIME;
	}

	return TEXT_EMPTY;
}
/*
*	Get the text for specified lines
*/
int Cache_GetLineText(PDNCE pdnce, int type, LPTSTR text, int text_size, TCHAR *variable_text, BOOL xstatus_has_priority, 
                      BOOL show_status_if_no_away, BOOL show_listening_if_no_away, BOOL use_name_and_message_for_xstatus, 
                      BOOL pdnce_time_show_only_if_different)
{
    text[0] = '\0';
    switch(type)
    {
    case TEXT_STATUS:
        {
            if (GetStatusName(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus)
            {
                DBVARIANT dbv={0};

                // Try to get XStatusMsg
                if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusMsg", &dbv)) 
                {
                    if (dbv.ptszVal != NULL && dbv.ptszVal[0] != 0)
                    {
                        TCHAR *tmp = mir_tstrdup(text);
                        mir_sntprintf(text, text_size, TEXT("%s: %s"), tmp, dbv.pszVal);
                        mir_free_and_nill(tmp);
                        CopySkipUnprintableChars(text, text, text_size-1);
                    }
                    ModernDBFreeVariant(&dbv);
                }
            }

            return TEXT_STATUS;
        }
    case TEXT_NICKNAME:
        {
            if (pdnce->m_cache_hContact && pdnce->m_cache_cszProto)
            {
                DBVARIANT dbv={0};
                if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "Nick", &dbv)) 
                {
                    lstrcpyn(text, dbv.ptszVal, text_size);
                    ModernDBFreeVariant(&dbv);
                    CopySkipUnprintableChars(text, text, text_size-1);
                }
            }

            return TEXT_NICKNAME;
        }
    case TEXT_STATUS_MESSAGE:
        {
            if (GetStatusMessage(text, text_size, pdnce, xstatus_has_priority) == -1 && use_name_and_message_for_xstatus)
            {
                DBVARIANT dbv={0};

                // Try to get XStatusName
                if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) 
                {
                    if (dbv.pszVal != NULL && dbv.pszVal[0] != 0)
                    {
                        TCHAR *tmp = mir_tstrdup(text);
                        
                        mir_sntprintf(text, text_size, TEXT("%s: %s"), dbv.pszVal, tmp);                        
                        mir_free_and_nill(tmp);
                    }
                    CopySkipUnprintableChars(text, text, text_size-1);
                    ModernDBFreeVariant(&dbv);
                }
            }
            else if (use_name_and_message_for_xstatus && xstatus_has_priority)
            {
                DBVARIANT dbv={0};
                // Try to get XStatusName
                if (!ModernGetSettingTString(pdnce->m_cache_hContact, pdnce->m_cache_cszProto, "XStatusName", &dbv)) 
                {
                    if (dbv.pszVal != NULL && dbv.pszVal[0] != 0)
                        mir_sntprintf(text, text_size, TEXT("%s"), dbv.pszVal);
                    CopySkipUnprintableChars(text, text, text_size-1);
                    ModernDBFreeVariant(&dbv);
                }
            }

            if (text[0] == '\0')
            {
                if (show_listening_if_no_away)
                {
                    Cache_GetLineText(pdnce, TEXT_LISTENING_TO, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);
                    if (text[0] != '\0')
                        return TEXT_LISTENING_TO;
                }

                if (show_status_if_no_away)
                {
                    //re-request status if no away
                    return Cache_GetLineText(pdnce, TEXT_STATUS, text, text_size, variable_text, xstatus_has_priority, 0, 0, use_name_and_message_for_xstatus, pdnce_time_show_only_if_different);		
                }
            }
            return TEXT_STATUS_MESSAGE;
        }
    case TEXT_LISTENING_TO:
        {
            GetListeningTo(text, text_size, pdnce);
            return TEXT_LISTENING_TO;
        }
    case TEXT_TEXT:
        {
            TCHAR *tmp = variables_parsedup(variable_text, pdnce->m_cache_tcsName, pdnce->m_cache_hContact);
            lstrcpyn(text, tmp, text_size);
            if (tmp) free(tmp);
            CopySkipUnprintableChars(text, text, text_size-1);

            return TEXT_TEXT;
        }
    case TEXT_CONTACT_TIME:
        {
            if (pdnce->hTimeZone)
            {
                // Get pdnce time
                text[0] = 0;
                tmi.printDateTime( pdnce->hTimeZone, _T("t"), text, text_size, 0);
            }

            return TEXT_CONTACT_TIME;
        }
    }

    return TEXT_EMPTY;
}