int _cdecl CXTPCalendarEvents::CompareEvents_ByID(const CXTPCalendarEvent** ppEv1, const CXTPCalendarEvent** ppEv2)
{
	if (*ppEv1 == NULL || *ppEv2 == NULL)
	{
		ASSERT(FALSE);
		return XTPCompare(*ppEv1, *ppEv2);
	}

	//-----------------------------------------------------
	DWORD dwID1 = (*ppEv1)->GetEventID();
	DWORD dwID2 = (*ppEv2)->GetEventID();

	int nCmp = XTPCompare(dwID1, dwID2);

	return nCmp;
}
int CXTPCalendarTimeZones::CompareTZI(const CXTPCalendarTimeZone* pTZI1,
                                      const CXTPCalendarTimeZone* pTZI2, BOOL bUseIndex) const
{
    if (bUseIndex)
    {
        return XTPCompare(pTZI1->m_dwIndex, pTZI2->m_dwIndex);
    }

    int nOffset1, nOffset2;
    CString strPlace1, strPlace2;

    ParseDisplayStr(pTZI1->GetDisplayString(), nOffset1, strPlace1);
    ParseDisplayStr(pTZI2->GetDisplayString(), nOffset2, strPlace2);

    int nCmpRes = XTPCompare(nOffset1, nOffset2);
    if (nCmpRes)
    {
        return nCmpRes;
    }

    return XTPCompare(strPlace1, strPlace2);
}
int _cdecl CXTPCalendarEvents::CompareEvents_ForViewByStart(const CXTPCalendarEvent** ppEv1, const CXTPCalendarEvent** ppEv2)
{
	if (*ppEv1 == NULL || *ppEv2 == NULL)
	{
		ASSERT(FALSE);
		return XTPCompare(*ppEv1, *ppEv2);
	}

	int nPeriodDays1 = (*ppEv1)->GetEventPeriodDays();
	int nPeriodDays2 = (*ppEv2)->GetEventPeriodDays();

	int nAllDayEvent1 = (*ppEv1)->IsAllDayEvent() ? 1 : 0;
	int nAllDayEvent2 = (*ppEv2)->IsAllDayEvent() ? 1 : 0;

	int nCmp = 0;
	//---------------------------------------------------------------------------
	nCmp = XTPCompare((*ppEv1)->GetStartTime(), (*ppEv2)->GetStartTime());
	if (nCmp)
	{
		return nCmp;
	}
	//---------------------------------------------------------------------------
	nCmp = XTPCompare(nPeriodDays2, nPeriodDays1);
	if (nCmp)
	{
		return nCmp;
	}

	nCmp = XTPCompare(nAllDayEvent2, nAllDayEvent1);
	if (nCmp)
	{
		return nCmp;
	}

	nCmp = XTPCompare((*ppEv1)->GetDurationMinutes(), (*ppEv2)->GetDurationMinutes());
	if (nCmp)
	{
		return -nCmp;
	}

	//-----------------------------------------------------
	nCmp = XTPCompare((*ppEv1)->GetSubject(), (*ppEv2)->GetSubject());
	if (nCmp)
	{
		return nCmp;
	}

	//-----------------------------------------------------
	nCmp = CompareEvents_ByID(ppEv1, ppEv2);

	return nCmp;
}
int _cdecl CXTPCalendarEvents::CompareEvents_ForView(const CXTPCalendarEvent** ppEv1, const CXTPCalendarEvent** ppEv2)
{
	if (*ppEv1 == NULL || *ppEv2 == NULL)
	{
		ASSERT(FALSE);
		return XTPCompare(*ppEv1, *ppEv2);
	}

	int nPeriodDays1 = (*ppEv1)->GetEventPeriodDays();
	int nPeriodDays2 = (*ppEv2)->GetEventPeriodDays();

	int nAllDayEvent1 = (*ppEv1)->IsAllDayEvent() ? 1 : 0;
	int nAllDayEvent2 = (*ppEv2)->IsAllDayEvent() ? 1 : 0;

	BOOL bIsMultidayEvent = (nAllDayEvent1 && nAllDayEvent2 || nPeriodDays1 > 1 && nPeriodDays2 > 1);
	int nCmp = 0;
	//---------------------------------------------------------------------------
	if (bIsMultidayEvent)
	{
		nCmp = XTPCompare((*ppEv1)->GetStartTime(), (*ppEv2)->GetStartTime());
		if (nCmp)
		{
//extra criteria <<
			if (nCmp == 0)
				nCmp = XTPCompare((*ppEv1)->GetEndTime(), (*ppEv2)->GetEndTime());
//extra criteria >>
			return nCmp;
		}
	}
	//---------------------------------------------------------------------------
	nCmp = XTPCompare(nPeriodDays2, nPeriodDays1);
	if (nCmp)
	{
		return nCmp;
	}

	nCmp = XTPCompare(nAllDayEvent2, nAllDayEvent1);
	if (nCmp)
	{
		return nCmp;
	}

	if (!bIsMultidayEvent)
	{
		nCmp = XTPCompare((*ppEv1)->GetStartTime(), (*ppEv2)->GetStartTime());
		if (nCmp)
		{
			return nCmp;
		}
	}

	nCmp = XTPCompare((*ppEv1)->GetDurationMinutes(), (*ppEv2)->GetDurationMinutes());
	if (nCmp)
	{
		return -nCmp;
	}

	//-----------------------------------------------------
	nCmp = XTPCompare((*ppEv1)->GetSubject(), (*ppEv2)->GetSubject());
	if (nCmp)
	{
		return nCmp;
	}

	//-----------------------------------------------------
	nCmp = CompareEvents_ByID(ppEv1, ppEv2);

	return nCmp;
}