GUIStatusBar::GUIStatusBar(const PrivatelyConstruct& dummy,
		const String& style, const GUIDimensions& dimensions)
		:GUIElementContainer(dimensions, style)
	{
		mPanel = GUIPanel::create();
		mBgPanel = GUIPanel::create(1);
		_registerChildElement(mPanel);
		_registerChildElement(mBgPanel);

		mBackground = GUITexture::create(GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getGUIBackgroundTypeName()));
		mMessage = GUIButton::create(HString(L""), GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getGUIMessageTypeName()));
		mScene = GUILabel::create(HString(L"Scene: Unnamed"), GUIOptions(GUIOption::fixedWidth(150)));
		mProject = GUILabel::create(HString(L"Project: None"), GUIOptions(GUIOption::fixedWidth(200)));
		mCompiling = GUILabel::create(HString(L"Compiling..."), GUIOptions(GUIOption::fixedWidth(100)));

		GUILayoutY* vertLayout = mPanel->addNewElement<GUILayoutY>();
		vertLayout->addNewElement<GUIFixedSpace>(3);
		GUILayoutX* horzLayout = vertLayout->addNewElement<GUILayoutX>();

		horzLayout->addNewElement<GUIFixedSpace>(10);
		horzLayout->addElement(mMessage);
		horzLayout->addNewElement<GUIFlexibleSpace>();
		horzLayout->addElement(mScene);
		horzLayout->addNewElement<GUIFixedSpace>(10);
		horzLayout->addElement(mProject);
		horzLayout->addNewElement<GUIFixedSpace>(10);
		horzLayout->addElement(mCompiling);
		horzLayout->addNewElement<GUIFixedSpace>(10);

		mBgPanel->addElement(mBackground);
		mCompiling->setActive(false);

		mLogEntryAddedConn = gDebug().onLogModified.connect(std::bind(&GUIStatusBar::logModified, this));
		mMessageBtnPressedConn = mMessage->onClick.connect(std::bind(&GUIStatusBar::messageBtnClicked, this));
	}
	GUIFieldBase::GUIFieldBase(const PrivatelyConstruct& dummy, const GUIContent& labelContent, UINT32 labelWidth,
		const String& style, const GUIDimensions& dimensions, bool withLabel)
		:GUIElementContainer(dimensions, style), mLabel(nullptr)
	{
		mLayout = GUILayoutX::create();
		_registerChildElement(mLayout);

		if(withLabel)
		{
			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(getLabelStyleType()));
			mLayout->addElement(mLabel);
		}
	}
	GUIGameObjectField::GUIGameObjectField(const PrivatelyConstruct& dummy, const String& typeNamespace, const String& type, const GUIContent& labelContent, UINT32 labelWidth,
		const String& style, const GUIDimensions& dimensions, bool withLabel)
		: GUIElementContainer(dimensions, style), mLabel(nullptr), mDropButton(nullptr), mClearButton(nullptr), mType(type)
		, mNamespace(typeNamespace), mInstanceId(0)
	{
		mLayout = GUILayoutX::create();
		_registerChildElement(mLayout);

		if(withLabel)
		{
			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(BuiltinEditorResources::ObjectFieldLabelStyleName));
			mLayout->addElement(mLabel);
		}

		mDropButton = GUIDropButton::create((UINT32)DragAndDropType::SceneObject, GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(BuiltinEditorResources::ObjectFieldDropBtnStyleName));
		mClearButton = GUIButton::create(HString(L""), getSubStyleName(BuiltinEditorResources::ObjectFieldClearBtnStyleName));
		mClearButton->onClick.connect(std::bind(&GUIGameObjectField::onClearButtonClicked, this));

		mLayout->addElement(mDropButton);
		mLayout->addElement(mClearButton);

		mDropButton->onDataDropped.connect(std::bind(&GUIGameObjectField::dataDropped, this, _1));
		mDropButton->onClick.connect(std::bind(&GUIGameObjectField::onDropButtonClicked, this));
	}
	WindowFrameWidget::WindowFrameWidget(const HSceneObject& parent, bool allowResize, const SPtr<Camera>& camera, RenderWindow* parentWindow, const HGUISkin& skin)
		:CGUIWidget(parent, camera), mAllowResize(allowResize), mWindowFramePanel(nullptr), mParentWindow(parentWindow)
	{
		setSkin(skin);

		GUIPanel* backgroundPanel = getPanel()->addNewElement<GUIPanel>(500);
		backgroundPanel->addElement(GUITexture::create(TextureScaleMode::RepeatToFit,
			GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()), "WindowBackground"));

		mWindowFramePanel = getPanel()->addNewElement<GUIPanel>(499);

		mWindowFrame = GUIWindowFrame::create("WindowFrame");
		mWindowFramePanel->addElement(mWindowFrame);

		refreshNonClientAreas();
	}
	DropDownWindow::DropDownWindow(const SPtr<RenderWindow>& parent, const SPtr<Camera>& camera,
		const Vector2I& position, UINT32 width, UINT32 height)
		: mRenderWindow(parent), mFrontHitBox(nullptr), mBackHitBox(nullptr), mRootPanel(nullptr), mPosition(position)
		, mWidth(width), mHeight(height)
	{
		mSceneObject = SceneObject::create("EditorWindow", SOF_Internal | SOF_Persistent | SOF_DontSave);

		mGUI = mSceneObject->addComponent<CGUIWidget>(camera);

		mGUI->setDepth(0); // Needs to be in front of everything
		mGUI->setSkin(BuiltinEditorResources::instance().getSkin());

		mRootPanel = mGUI->getPanel()->addNewElement<GUIPanel>();
		
		GUIPanel* frontHitBoxPanel = mRootPanel->addNewElement<GUIPanel>(std::numeric_limits<INT16>::min());
		mFrontHitBox = GUIDropDownHitBox::create(false, false);
		mFrontHitBox->onFocusLost.connect(std::bind(&DropDownWindow::dropDownFocusLost, this));
		mFrontHitBox->setFocus(true);
		frontHitBoxPanel->addElement(mFrontHitBox);

		GUIPanel* backHitBoxPanel = mRootPanel->addNewElement<GUIPanel>(std::numeric_limits<INT16>::max());
		mBackHitBox = GUIDropDownHitBox::create(false, true);
		backHitBoxPanel->addElement(mBackHitBox);
		
		SPtr<Viewport> viewport = camera->getViewport();
		GUIPanel* captureHitBoxPanel = mGUI->getPanel()->addNewElement<GUIPanel>(std::numeric_limits<INT16>::max());
		GUIDropDownHitBox* captureHitBox = GUIDropDownHitBox::create(true, false);
		captureHitBox->setBounds(Rect2I(0, 0, viewport->getWidth(), viewport->getHeight()));
		captureHitBoxPanel->addElement(captureHitBox);

		setSize(width, height);

		GUIPanel* backgroundPanel = mRootPanel->addNewElement<GUIPanel>(500);
		backgroundPanel->addElement(GUITexture::create(TextureScaleMode::RepeatToFit,
			GUIOptions(GUIOption::flexibleWidth(), GUIOption::flexibleHeight()), "WindowBackground"));

		GUIPanel* windowFramePanel = mRootPanel->addNewElement<GUIPanel>(499);

		GUIWindowFrame* windowFrame = GUIWindowFrame::create("WindowFrame");
		windowFramePanel->addElement(windowFrame);

		mContents = mRootPanel->addNewElement<GUIPanel>();
		mContents->setPosition(1, 1);
		mContents->setWidth(width - 2);
		mContents->setHeight(height - 2);
	}
	GUIFloatField::GUIFloatField(const PrivatelyConstruct& dummy, const GUIContent& labelContent, UINT32 labelWidth, 
		const String& style, const GUIDimensions& dimensions, bool withLabel)
		: TGUIField(dummy, labelContent, labelWidth, style, dimensions, withLabel), mInputBox(nullptr), mValue(0.0f)
		, mLastDragPos(0), mMinValue(std::numeric_limits<float>::lowest()), mMaxValue(std::numeric_limits<float>::max())
		, mStep(0.0f), mIsDragging(false), mHasInputFocus(false)
	{
		mInputBox = GUIInputBox::create(false, GUIOptions(GUIOption::flexibleWidth()), getSubStyleName(getInputStyleType()));
		mInputBox->setFilter(&GUIFloatField::floatFilter);

		mInputBox->onValueChanged.connect(std::bind((void(GUIFloatField::*)(const String&))&GUIFloatField::valueChanging, this, _1));
		mInputBox->onFocusChanged.connect(std::bind(&GUIFloatField::focusChanged, this, _1));
		mInputBox->onConfirm.connect(std::bind(&GUIFloatField::inputConfirmed, this));

		mLayout->addElement(mInputBox);

		setValue(0);
		mInputBox->setText("0");
	}
	GUITextField::GUITextField(const PrivatelyConstruct& dummy, bool multiline, const GUIContent& labelContent, 
		UINT32 labelWidth, const String& style, const GUIDimensions& dimensions, bool withLabel)
		:GUIElementContainer(dimensions, style),
		mInputBox(nullptr), mLayout(nullptr), mLabel(nullptr), mHasInputFocus(false), mValue("")
	{
		mLayout = GUILayoutX::create();
		_registerChildElement(mLayout);

		if (withLabel)
		{
			mLabel = GUILabel::create(labelContent, GUIOptions(GUIOption::fixedWidth(labelWidth)), getSubStyleName(getLabelStyleType()));
			mLayout->addElement(mLabel);
		}

		mInputBox = GUIInputBox::create(multiline, getSubStyleName(getInputStyleType()));
		mLayout->addElement(mInputBox);

		mInputBox->onValueChanged.connect(std::bind(&GUITextField::valueChanged, this, _1));
		mInputBox->onFocusChanged.connect(std::bind(&GUITextField::focusChanged, this, _1));
		mInputBox->onConfirm.connect(std::bind(&GUITextField::inputConfirmed, this));
	}