EditorWidgetBase* EditorWidgetManager::create(const String& name, EditorWidgetContainer& parentContainer)
	{
		auto iterFind = mActiveWidgets.find(name);

		if(iterFind != mActiveWidgets.end())
		{
			EditorWidgetBase* existingWidget = iterFind->second;
			if(existingWidget->_getParent() != nullptr && existingWidget->_getParent() != &parentContainer)
				existingWidget->_getParent()->remove(*existingWidget);

			if(existingWidget->_getParent() != &parentContainer)
				parentContainer.add(*iterFind->second);

			return iterFind->second;
		}

		auto iterFindCreate = mCreateCallbacks.find(name);
		if(iterFindCreate == mCreateCallbacks.end())
			return nullptr;

		EditorWidgetBase* newWidget = mCreateCallbacks[name](parentContainer);
		parentContainer.add(*newWidget);

		if(newWidget != nullptr)
			mActiveWidgets[name] = newWidget;

		return newWidget;
	}
	MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName, 
		ScriptEditorWindow* parentWindow, Vector2I* position)
	{
		String strTypeName = MonoUtil::monoToString(typeName);
		String strNamespace = MonoUtil::monoToString(ns);
		String fullName = strNamespace + "." + strTypeName;

		MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName);
		if (windowClass == nullptr)
			return nullptr;

		MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY);

		MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize");
		if (defaultSizeAttrib == nullptr)
			BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class.");

		MonoField* defaultWidthField = defaultSizeAttrib->getField("width");
		MonoField* defaultHeightField = defaultSizeAttrib->getField("height");

		int width = 200;
		int height = 200;

		MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib);
		if (defaultSizeObj != nullptr)
		{
			defaultWidthField->get(defaultSizeObj, &width);
			defaultHeightField->get(defaultSizeObj, &height);
		}

		MonoObject* instance = windowClass->createInstance(false);

		ManagedDropDownWindow* dropDownWindow = nullptr;
		if (parentWindow != nullptr && !parentWindow->isDestroyed())
		{
			EditorWidgetBase* editorWidget = parentWindow->getEditorWidget();
			EditorWidgetContainer* parentContainer = editorWidget->_getParent();
			if (parentContainer != nullptr)
			{
				SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow();
				SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera();

				position->x += editorWidget->getX();
				position->y += editorWidget->getY();

				dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>(
					parentRenderWindow, parentCamera, *position, instance, width, height);
			}
		}

		ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow);

		if (dropDownWindow != nullptr)
			dropDownWindow->initialize(nativeInstance);

		windowClass->construct(instance);
		return instance;
	}
	void EditorWidgetManager::onFocusLost(const RenderWindow& window)
	{
		for (auto& widgetData : mActiveWidgets)
		{
			EditorWidgetBase* widget = widgetData.second;
			EditorWidgetContainer* parentContainer = widget->_getParent();
			if (parentContainer == nullptr)
				continue;

			EditorWindowBase* parentWindow = parentContainer->getParentWindow();
			SPtr<RenderWindow> parentRenderWindow = parentWindow->getRenderWindow();

			if (parentRenderWindow.get() != &window)
				continue;

			widget->_setHasFocus(false);
		}
	}
	void EditorWidgetManager::update()
	{
		if (gInput().isPointerButtonDown(PointerEventButton::Left) || gInput().isPointerButtonDown(PointerEventButton::Right))
		{
			for (auto& widgetData : mActiveWidgets)
			{
				EditorWidgetBase* widget = widgetData.second;
				EditorWidgetContainer* parentContainer = widget->_getParent();
				if (parentContainer == nullptr)
				{
					widget->_setHasFocus(false);
					continue;
				}

				EditorWindowBase* parentWindow = parentContainer->getParentWindow();
				SPtr<RenderWindow> parentRenderWindow = parentWindow->getRenderWindow();
				const RenderWindowProperties& props = parentRenderWindow->getProperties();

				if (!props.hasFocus())
				{
					widget->_setHasFocus(false);
					continue;
				}

				if (parentContainer->getActiveWidget() != widget)
				{
					widget->_setHasFocus(false);
					continue;
				}

				Vector2I widgetPos = widget->screenToWidgetPos(gInput().getPointerPosition());
				if (widgetPos.x >= 0 && widgetPos.y >= 0
					&& widgetPos.x < (INT32)widget->getWidth()
					&& widgetPos.y < (INT32)widget->getHeight())
				{
					widget->_setHasFocus(true);
				}
				else
					widget->_setHasFocus(false);
			}
		}
	}