#include "stdafx.h"
#include "locationpopuplist.h"

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

LocationPopupList::LocationPopupList()
{

}

LocationPopupList::~LocationPopupList()
{

}

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

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

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

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

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

	// finally request notifications for changes
	AddCustomNotification(bcEvent);

	return 1;
}

void LocationPopupList::DeepRefresh(int id)
{
	locationId = id;
	
	Vector<int> eventIds;
	db.GetActiveEventsByLocation(locationId,eventIds);
	if(eventIds.length>0){
		int i;
		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]);
				LocationEvent * event = (LocationEvent*)item->userdata;
				Delete(event);
			}
		}

		// now add the new ones
		for(i=0;i<eventIds.length;i++){
			if(current.find(eventIds[i])==-1){
				LocationEvent * event = new LocationEvent;
				event->DeepRefresh(eventIds[i]);
				Add(event);
			}
		}
	} else {
		ClearList();
	}
}

void LocationPopupList::Add(LocationEvent * 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,size.Width-item->textlocation.X-1)+spacing;
	list.AddItem(item);
}

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

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

void LocationPopupList::OnCustomNotify(int id, Notification& n)
{
	ListItem * item;
	LocationEvent * event;
	switch(id){
	case bcEvent:
		switch(n.reason){
		case bcActive:
		case bcIdle:
		case bcAdd:
		case bcModified:
			DeepRefresh(locationId);
			break;
		case bcRemove:
			item = list.GetItemByKey(n.param[0]);
			if(item){
				Delete((LocationEvent*)item->userdata);
			}
			break;
		default:
			item = list.GetItemByKey(n.param[0]);
			if(item){
				event = (LocationEvent*)item->userdata;
				if(event){
					// this notification applies to an event in the list
					event->OnCustomNotify(id,n);
				}
			}
			break;
		}

		break;
	}	
}

void LocationPopupList::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
				LocationEvent * event = (LocationEvent *)item->userdata;
				if(event){
					if(event->record.OwnerId==theApp.user.UserId){
						theApp.EditEvent(event->record.EventId);
					} else {
						theApp.ViewEvent(event->record.EventId);
					}
				}
			}
			break;
		}
	}
}