#include "stdafx.h"
#include "buddypopuplist.h"


static int AppearancesLoaded = 0;
Appearance BuddyPopupList::PublicEvent;
Appearance BuddyPopupList::PrivateEvent;


BuddyPopupList::BuddyPopupList()
{

}

BuddyPopupList::~BuddyPopupList()
{

}

int BuddyPopupList::Create(HWND parent)
{
	Load("buddypopup");
	titlebar.Load("buddypopup::titlebar");
	subtitle.Load("buddypopup::subtitle");
	title = L"";
	titlebar.title = L"";
	subtitle.title = L"";

	list.Load("buddypopup::list");
	list.scrollbar.Load("buddypopup::scrollbar");

	if(!AppearancesLoaded){
		PublicEvent.Load("buddypopup::items::public");
		PrivateEvent.Load("buddypopup::items::private");
		AppearancesLoaded = 1;
	}

	spacing = env.GetInt("buddypopup::items","spacing",0);

	Hide();
	PopupList::Create(parent);

	AddCustomNotification(bcEvent);	
	// bcUser notifies are handled by the Buddy class

	return 1;
}

void BuddyPopupList::ClearList()
{
	std::list<ListItem*>::iterator it;
	for(it=list.items.begin();it!=list.items.end();it++){
		ListItem * item = *it;
		BuddyEvent * event = (BuddyEvent*)item->userdata;
		delete event;
	}
	list.DeleteAllItems();
}

void BuddyPopupList::Add(BuddyEvent * event)
{
	ListItem * item = list.CreateItem(event->record.EventName,event->record.EventId);
	event->item = item;
	event->ShallowRefresh();
	item->userdata = event;
	item->usertype = bcEvent;
	item->size.Height = MeasureTextHeight(item->fontname.data(),item->fontsize,
			event->record.EventName,list.size.Width-item->textlocation.X-1)+spacing;
	list.AddItem(item);
}

void BuddyPopupList::Delete(BuddyEvent * event)
{
	list.DeleteItem(event->item);
	delete event;
}

void BuddyPopupList::DeepRefresh(UserRecord& r)
{
	ClearList();

	record = r;
	std::list<int> tmplist;
	Vector<int> eventIds;

	// the popup list shows those events in the buddy's event list that are subscribable by this user
	Vector<int> subscribedIds;
	db.GetSubscribedEvents(record.UserId,subscribedIds);
	Vector<int> subscribableIds;
	db.GetSubscribableEvents(theApp.user.UserId,subscribableIds);
	// now take the intersection
	int i;
	for(i=0;i<subscribedIds.length;i++){
		if(subscribableIds.find(subscribedIds[i])!=-1){
			tmplist.push_back(subscribedIds[i]);
		}
	}

	if(tmplist.size()>0){
		std::list<int>::iterator j;
		eventIds.allocate(tmplist.size());
		for(i=0,j=tmplist.begin();j!=tmplist.end();i++,j++){
			eventIds[i] = *j;
		}
	}

	if(eventIds.length>0){
		Vector<int> current;

		list.GetKeys(current);
		
		// first delete the items that are no longer needed
		for(i=0;i<current.length;i++){
			if(eventIds.find(current[i])==-1){
				ListItem * item = list.GetItemByKey(current[i]);
				if(item){
					BuddyEvent * event = (BuddyEvent*)item->userdata;
					Delete(event);
				}
			}
		}

		// now add the new ones
		for(i=0;i<eventIds.length;i++){
			if(current.find(eventIds[i])==-1){
				BuddyEvent * event = new BuddyEvent;
				event->DeepRefresh(eventIds[i]);
				Add(event);
			}
		}
	} else {
		ClearList();
	}
	// now load the profile items: Interest
	if(0){
		std::wstring interests;
		interests = L"Interests: ";
		interests += record.Interest;
		ListItem * item = list.CreateItem(interests.data(),-2);
		item->userdata = &record;
		item->usertype = 0;
		// set the appearance style
		item->Set(PrivateEvent);
		// calculate height required to show all the text at this width
		item->size.Height = MeasureTextHeight(item->fontname.data(),item->fontsize,
			interests.data(),size.Width-item->textlocation.X-1)+spacing;
		list.AddItem(item);
	}
	// now load the profile items: Secret Weapon
	if(0){
		std::wstring secret;
		secret = L"Secret Weapon: ";
		secret += record.SecretWeapon;
		ListItem * item = list.CreateItem(secret.data(),-2);
		item->userdata = &record;
		item->usertype = 0;
		// set the appearance style
		item->Set(PrivateEvent);
		// calculate height required to show all the text at this width
		item->size.Height = MeasureTextHeight(item->fontname.data(),item->fontsize,
			secret.data(),size.Width-item->textlocation.X-1)+spacing;
		list.AddItem(item);
	}
}

void BuddyPopupList::OnCustomNotify(int id, Notification& n)
{
	ListItem * item;
	BuddyEvent * event;
	switch(id){
	case bcEvent:
		switch(n.reason){
		case bcAdd:
		case bcSubscribe:
			DeepRefresh(record);
			break;
		case bcUnsubscribe:
			if(n.param[1]==record.UserId){
				item = list.GetItemByKey(n.param[0]);
				if(item){
					Delete((BuddyEvent*)item->userdata);
				}
			}
			break;
		case bcRemove:
			item = list.GetItemByKey(n.param[0]);
			if(item){
				Delete((BuddyEvent*)item->userdata);
			}
			break;
		default:
			item = list.GetItemByKey(n.param[0]);
			if(item){
				event = (BuddyEvent*)item->userdata;
				if(event){
					// this notification applies to an event in the list
					event->OnCustomNotify(id,n);
				}
			}
			break;
		}

		break;
	}	
}

void BuddyPopupList::OnListSelect(HWND h, HWND hItem)
{
	ListItem * item = (ListItem*)GetWindowLongPtr(hItem,GWL_USERDATA);
	if(list.hWnd==h){
		switch(item->usertype){
			case bcEvent:
			{
				// Show the view or edit event windows depending on ownership
				BuddyEvent * event = (BuddyEvent *)item->userdata;
				if(event){
					if(event->record.OwnerId==theApp.user.UserId){
						theApp.EditEvent(event->record.EventId);
					} else {
						theApp.ViewEvent(event->record.EventId);
					}
				}
			}
			break;
		}
	}
}