void
MainWindow::MakeEmpty(void)
{
	while (fListView->CountItems())
	{
		ObjectItem *item = (ObjectItem*)fListView->RemoveItem(0L);
		if (item)
		{
			delete item->GetObject();
			delete item;
		}
	}
}
void
MainWindow::UpdateFloaters(void)
{
	ObjectItem *item = dynamic_cast<ObjectItem*>(fListView->FullListItemAt(
											fListView->FullListCurrentSelection()));
	
	FloaterBroker *broker = FloaterBroker::GetInstance();
	broker->DetachAllFloaters();
	
	if (item)
	{
		PView *view = dynamic_cast<PView*>(item->GetObject());
		broker->AttachAllFloaters(view);
	}
}
void
MainWindow::UpdateProperties(void)
{
	int32 selection = fListView->FullListCurrentSelection();

	BMessenger msgr(fPropertyWin);
	BMessage msg(M_SET_OBJECT);
	
	if (selection < 0)
	{
		// If there is no selection, we empty the property window. 0 is a built-in invalid
		// object handle, just like NULL is an invalid pointer.
		msg.AddInt64("id",0);
	}
	else
	{
		ObjectItem *item = dynamic_cast<ObjectItem*>(fListView->FullListItemAt(selection));
		PObject *obj = item->GetObject();
		msg.AddInt64("id",obj->GetID());
	}
	
	msgr.SendMessage(&msg);
}
void
MainWindow::AddControl(const BString &type)
{
	if (type.CountChars() < 1)
		return;
	
	PObjectBroker *broker = PObjectBroker::GetBrokerInstance();
	PObject *pobj = broker->MakeObject(type.String());
	
	if (!pobj || !pobj->UsesInterface("PView"))
		return;
		
	PView *pview = dynamic_cast<PView*>(pobj);
	if (!pview)
		return;
	
	BString name(pview->GetType());
	name << pview->GetID();
	pview->AddProperty(new StringProperty("Name",name.String(),"The name for this view"),0,0);
	
	if (pview->GetType().Compare("PTextControl") == 0)
	{
		// Create each text control with some more useful defaults for the GUI
		pview->SetStringProperty("Text", "Text");
		pview->SetStringProperty("Label", "Label");
		
		PArgs in, out;
		pview->RunMethod("SetPreferredDivider", in.ListRef(), out.ListRef());
	}
	
	FloatValue pw, ph;
	pview->GetProperty("PreferredWidth", &pw);
	pview->GetProperty("PreferredHeight", &ph);
	
	if (*pw.value > 0.0)
		pview->SetFloatProperty("Width",*pw.value);
	else
		pview->SetFloatProperty("Width",100);
	
	if (*ph.value > 0.0)
		pview->SetFloatProperty("Height",*ph.value);
	else
		pview->SetFloatProperty("Height",100);
	
	// If we have a PWindow selected in the window, we will add the view as a child of the
	// selected window. If there is no selection, we will add the item at the end with no
	// parent
	
	ObjectItem *item = new ObjectItem(pview);
	int32 selection = fListView->FullListCurrentSelection();
	if (selection < 0)
		fListView->AddItem(item);
	
	ObjectItem *oitem = dynamic_cast<ObjectItem*>(fListView->FullListItemAt(selection));
	if (!oitem)
		return;
	
	PWindow *pwin = dynamic_cast<PWindow*>(oitem->GetObject());
	if (pwin)
	{
		PArgs args,out;
		
		if (pview->GetType().Compare("PView") == 0 && 
			pwin->RunMethod("CountChildren",args.ListRef(),out.ListRef()) == B_OK)
		{
			int32 count;
			if (out.FindInt32("count",&count) == B_OK && count == 0)
			{
				float winWidth, winHeight;
				pwin->GetFloatProperty("Width",winWidth);
				pwin->GetFloatProperty("Height",winHeight);
				pview->SetFloatProperty("Width",winWidth);
				pview->SetFloatProperty("Height",winHeight);
				pview->SetIntProperty("HResizingMode",RESIZE_BOTH);
				pview->SetIntProperty("VResizingMode",RESIZE_BOTH);
			}
			pview->SetColorProperty("BackColor",ui_color(B_PANEL_BACKGROUND_COLOR));
		}
		
		args.AddInt64("id",item->GetObject()->GetID());
		if (pwin->RunMethod("AddChild", args.ListRef(), out.ListRef()) == B_OK)
			fListView->AddUnder(item,oitem);
		else
			fListView->AddItem(item);
	}
	else
	{
		if (oitem->GetObject()->UsesInterface("PView"))
		{
			PView *parent = dynamic_cast<PView*>(oitem->GetObject());
			PArgs args,out;
			args.AddInt64("id",item->GetObject()->GetID());
			if(parent->RunMethod("AddChild", args.ListRef(), out.ListRef()) == B_OK)
				fListView->AddUnder(item,oitem);
			else
				fListView->AddItem(item);
		}
		else
		{
			// Not a view or window, so just add it on at the end
			fListView->AddItem(item);
		}
	}
	
	pview->ConnectEvent("FocusChanged", PViewFocusChanged);
	pview->ConnectEvent("MouseDown", PViewMouseDown);
	pview->SetMsgHandler(M_FLOATER_ACTION, PViewHandleFloaterMsg);
	
	pview->SetBoolProperty("Focus", true);
	
	fListView->Select(fListView->FullListIndexOf(item));
}
void
MainWindow::MessageReceived(BMessage *msg)
{
	switch (msg->what)
	{
		case M_ADD_WINDOW:
		{
			AddWindow();
			break;
		}
		case M_ADD_CONTROL:
		{
			BString type;
			msg->FindString("type",&type);
			if (type.ICompare("PWindow") == 0)
				AddWindow();
			else
				AddControl(type);
			break;
		}
		case M_REMOVE_SELECTED:
		{
			int32 index = fListView->CurrentSelection();
			fListView->Deselect(index);
			UpdateProperties();
			
			ObjectItem *item = (ObjectItem*)fListView->RemoveItem(index);
			if (item)
			{
				PObject *obj = item->GetObject();
				delete item;
				delete obj;
			}
			break;
		}
		case M_TOGGLE_PROPERTY_WIN:
		{
			if (fPropertyWin->IsHidden())
				fPropertyWin->Show();
			else
				fPropertyWin->Hide();
			break;
		}
		case M_OBJECT_SELECTED:
		{
			UpdateFloaters();
			UpdateProperties();
			break;
		}
		case M_ACTIVATE_OBJECT:
		{
			uint64 id;
			if (msg->FindInt64("id",(int64*)&id) != B_OK)
				break;
			
			for (int32 i = 0; i < fListView->CountItems(); i++)
			{
				ObjectItem *item = (ObjectItem*) fListView->ItemAt(i);
				if (item->GetObject()->GetID() == id)
				{
					fListView->Select(i);
					break;
				}
			}
			break;
		}
		case M_UPDATE_PROPERTY_EDITOR:
		{
			fPropertyWin->PostMessage(msg);
			break;
		}
		default:
		{
			BWindow::MessageReceived(msg);
			break;
		}
	}
}