// Abstract base class for *all* UI controls, but not for visual style decorators!
class UIElement
{
protected:
	bool bVisible;

public:
	UIElement() {}
	UIElement(const UIElement &rhs):bVisible(rhs.bVisible) {}
	virtual ~UIElement() {}

	bool IsVisible() const { return bVisible; }
};

// An UI element that takes its appearance from a XML style file.
class StyleUIElement : public UIElement
{
protected:
	Style *style;

public:
	StyleUIElement():style(0) {}
	StyleUIElement(const StyleUIElement &rhs):UIElement(rhs), style(rhs.style) {}

	Style *GetStyle() { return style; }

	// Virtual so that subclasses can validate and configure the style to be set.
	// Note: We don't do anything here, as this is a class that'll be subclassed for the real functionality.
	virtual void SetStyle(Style *newStyle) {}
};

class UIButton : public StyleUIElement
{
public:
	void SetStyle(Style *newStyle)
	{
		if (newStyle && newStyle->IsScalable())
			style = newStyle;
		else
			style = 0; // Shouldn't use old and can't use new! Todo: Implement something like bool AcceptsStyle(Style *style);
	}
	
};

class UICanvas
{
private:
	// Contains all the UI elements on this canvas only. Note that the UI can consist of several canvases.
	std::vector<UIElement*> widgets;

public:
	// Changes the current style for all visible UI buttons.
	void SetStyleForVisibleButtons(Style *newStyle)
	{
		for(size_t = 0; i < widgets.size(); ++i)
			if (dynamic_cast<UIButton*>(widgets[i]) && widgets[i]->IsVisible())
			{
				// Hack: We can't know if an element accepts the given style until we set it, but we lose the old style config if we do, so
				//       make a copy of this control and set the style on it first to see if it works.

				StyleUIElement *copiedElement = new StyleUIElement(dynamic_cast<const StyleUIElement&>(*widgets[i]));
				copiedElement->SetStyle(newStyle);
				if (copiedElement->GetStyle() != 0) // Was the style accepted?
					widgets[i]->SetStyle(newStyle); // Alright, the new style is ok, so set it now for real.
				delete copiedElement;
			}
	}
};