#include "StdAfx.h"
#include "buddy.h"
#include "ATLComTime.h"

Buddy::Buddy()
{
	idletime = 0;
	onlinetime = 0;
	state = loggedoff;
	item = NULL;
	editing = 0;
	haspopup = 1;
}

Buddy::~Buddy(void)
{
}

// these things change due to time 
void Buddy::ShallowRefresh()
{
	if(haspopup && popup.hWnd==NULL){
		popup.Hide();
		popup.Create();
	}

	if(record.Idle && record.LoggedIn){
		state = State::idle;
	} else if(record.Away && record.LoggedIn){
		state = State::away;
	} else if(!record.LoggedIn){
		state = State::loggedoff;
	} else
		state = State::active;

	COleDateTime now = COleDateTime::GetCurrentTime();
	// adjust the local time to match the server time
	now += rpc.TimeAdjustment;
	COleDateTime idleSince(record.IdleSince);
	COleDateTime loggedOnSince(record.LoggedInSince);
	COleDateTimeSpan idlespan = (now-idleSince);
	COleDateTimeSpan onlinespan = (now-loggedOnSince);

	idletime = idlespan.GetTotalSeconds()/60.0;
	onlinetime = onlinespan.GetTotalSeconds()/60.0;

	if(haspopup){
		TCHAR buffer[1023];
		// update the associated popup list
		popup.titlebar.title = theApp.GetDisplayName(lrecord);
		popup.titlebar.title += L" : ";
		switch(state){
			case State::active:
				_stprintf(buffer,L"online %s",ConvertTimeSpanToCompactString(onlinespan));
				popup.titlebar.title += theApp.buddylist.Active.description;
				break;
			case State::away:
				_stprintf(buffer,L"away %s",ConvertTimeSpanToCompactString(onlinespan));
				popup.titlebar.title += theApp.buddylist.Away.description;
				break;
			case State::idle:
				_stprintf(buffer,L"idle %s",ConvertTimeSpanToCompactString(idlespan));
				popup.titlebar.title += theApp.buddylist.Idle.description;
				break;
			case State::loggedoff:
				_stprintf(buffer,
					env.GetWideString("buddypopup::subtitle::loggedoff",
					"formatstring",L"last logged on %s"),
					loggedOnSince.Format(theApp.DateFormat));
				popup.titlebar.title += theApp.buddylist.LoggedOff.description;
				break;
		}
		popup.subtitle.title = buffer;
		popup.Redraw();
	}

	// update the associated item's style
	if(item){
		if(editing){
			switch(state){
				case Buddy::active:
					item->Set(theApp.buddylist.eActive);
					break;
				case Buddy::idle:
					if(idletime<5){
						item->Set(theApp.buddylist.eIdle5min);
					} else if(idletime<15){
						item->Set(theApp.buddylist.eIdle15min);
					} else if(idletime<30){
						item->Set(theApp.buddylist.eIdle30min);
					} else {
						item->Set(theApp.buddylist.eIdle);
					}
					break;
				case Buddy::loggedoff:
						item->Set(theApp.buddylist.eLoggedOff);
					break;
				case Buddy::away:
					item->Set(theApp.buddylist.eAway);
					break;
			}
		} else {
			switch(state){
				case Buddy::active:
					item->Set(theApp.buddylist.Active);
					break;
				case Buddy::idle:
					if(idletime<5){
						item->Set(theApp.buddylist.Idle5min);
					} else if(idletime<15){
						item->Set(theApp.buddylist.Idle15min);
					} else if(idletime<30){
						item->Set(theApp.buddylist.Idle30min);
					} else {
						item->Set(theApp.buddylist.Idle);
					}
					break;
				case Buddy::loggedoff:
					// include this for the GroupPopupList
					item->Set(theApp.buddylist.LoggedOff);
					break;
				case Buddy::away:
					item->Set(theApp.buddylist.Away);
					break;
			}
		}

		item->Redraw();
	}
}

void Buddy::DeepRefresh(int buddyId)
{
	if(haspopup && popup.hWnd==NULL){
		popup.Create();
	}

	switch(db.GetCachedUser(buddyId,record)){
		case dbInvalidParam:
		case dbException:
			break;
		case dbSuccess:
			if(haspopup)
				popup.DeepRefresh(record);
			db.GetCachedLocation(record.LocationId,lrecord);
			
			ShallowRefresh();
			break;
	}
}

void Buddy::OnCustomNotify(int id, Notification& n)
{
	switch(id){
	case bcUser:
		if(n.param[0]==record.UserId){
			switch(n.reason){
			case bcLogOn:
				db.GetCachedUserState(record.UserId,record);
				if(record.LocationId!=lrecord.LocationId)
					db.GetCachedLocation(record.LocationId,lrecord);
				ShallowRefresh();
				break;
			case bcLogOff:
				db.GetCachedUserState(record.UserId,record);
				if(record.LocationId!=lrecord.LocationId)
					db.GetCachedLocation(record.LocationId,lrecord);
				ShallowRefresh();
				break;
			case bcAway:
				db.GetCachedUserState(record.UserId,record);
				ShallowRefresh();
				break;
			case bcIdle:
				db.GetCachedUserState(record.UserId,record);
				ShallowRefresh();
				break;
			case bcBack:
				db.GetCachedUserState(record.UserId,record);
				ShallowRefresh();
				break;
			case bcActive:
				db.GetCachedUserState(record.UserId,record);
				ShallowRefresh();
				break;
			case bcMove:
				db.GetCachedUserState(record.UserId,record);
				if(record.LocationId!=lrecord.LocationId)
					db.GetCachedLocation(record.LocationId,lrecord);
				ShallowRefresh();
				break;
			case bcModified:
				db.GetCachedUser(record.UserId,record);
				if(record.LocationId!=lrecord.LocationId)
					db.GetCachedLocation(record.LocationId,lrecord);
				ShallowRefresh();
				break;
			} // switch(reason)
		} // if...
		break;
	} // switch(id)

}
