#include "stdafx.h"
#include "grouppopuplist.h"

static int AppearancesLoaded = 0;
Appearance GroupPopupList::PublicEvent;
Appearance GroupPopupList::PrivateEvent;
Appearance GroupPopupList::DescriptionStyle;

GroupPopupList::GroupPopupList()
{

}

GroupPopupList::~GroupPopupList()
{

}

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

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

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

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

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

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

	return 1;
}

void GroupPopupList::DeepRefresh(int id, int showdescription)
{
	Vector<int> eventIds, userIds;
	groupId = id;
	list.DeleteAllItems();
	if(showdescription){
		GroupRecord record;
		db.GetCachedGroup(groupId,record);
		ListItem * item = list.CreateItem(record.Description,0);
		item->Set(DescriptionStyle);
		item->size.Height = MeasureTextHeight(item->fontname.data(),item->fontsize,
			record.Description,size.Width-item->textlocation.X-list.scrollbar.size.Width-1)+spacing;
		list.AddItem(item);	
	}
	db.GetGroupMembers(groupId,userIds);
	if(userIds.length>0){
		int i;
		users.allocate(userIds.length);
		for(i=0;i<userIds.length;i++){
			Buddy * buddy = &(users[i]);
			buddy->haspopup = 0; // no popup needed 
			buddy->DeepRefresh(userIds[i]);
			ListItem * item = list.CreateItem(buddy->record.UserLogin,buddy->record.UserId);
			buddy->item = item;
			buddy->editing = 0;
			buddy->ShallowRefresh();
			item->userdata = buddy;
			item->usertype = bcUser;
			list.AddItem(item);
		}
	}
	db.GetActiveGroupEvents(groupId,eventIds);
	if(eventIds.length>0){
		int i;
		events.allocate(eventIds.length);
		for(i=0;i<eventIds.length;i++){
			db.GetCachedEvent(eventIds[i],events[i]);
			ListItem * item = list.CreateItem(events[i].EventName,-(events[i].EventId+1));
			item->userdata = &(events[i]);
			item->usertype = bcEvent;
			// set the appearance style
			if(events[i].Private){
				item->Set(PrivateEvent);
			} else {
				item->Set(PublicEvent);
			}
			// calculate height required to show all the text at this width
			item->size.Height = MeasureTextHeight(item->fontname.data(),item->fontsize,
				events[i].EventName,size.Width-item->textlocation.X-list.scrollbar.size.Width-1)+spacing;
			list.AddItem(item);
		}
	}
}

void GroupPopupList::OnCustomNotify(int id, Notification& n)
{
	int i;
	switch(id){
	case bcUser: // give this notification to the Buddy object
		for(i=0;i<users.length;i++){
			if(users[i].record.UserId==n.param[0])
				users[i].OnCustomNotify(id,n);
		}
		break;
	case bcEvent:
		switch(n.reason){
		case bcActive:
		case bcIdle:
		case bcModified:
		case bcAdd:
			{
				// refresh if this event will be in this event 
				Vector<int> eventIds;
				db.GetActiveGroupEvents(groupId,eventIds);
				for(i=0;i<eventIds.length;i++){
					if(eventIds[i]==n.param[0]){
						DeepRefresh(groupId);
						break;
					}
				}
			}
			break;
		case bcRemove:
			{
				ListItem * item = list.GetItemByKey(-(n.param[0]+1));
				if(item) list.DeleteItem(item);
			}
			break;
		}
	case bcGroup:
		switch(n.reason){
		case bcSubscribe:
		case bcUnsubscribe:
		case bcModified:
			if(n.param[0]==groupId)
				DeepRefresh(groupId);
			break;
		}
	}
}

void GroupPopupList::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
				Event * event = (Event *)item->userdata;
				if(event){
					if(event->record.OwnerId==theApp.user.UserId){
						theApp.EditEvent(event->record.EventId);
					} else {
						theApp.ViewEvent(event->record.EventId);
					}
				}
			}
			break;
			case bcUser:
			{
				// its a user, show their profile
				Buddy * buddy = (Buddy *)item->userdata;
				if(buddy){
					theApp.ViewProfile(buddy->record.UserId);
				}
			}
			break;
		}
	}
}