/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



#include "precompiled_sfx2.hxx"

#include "sfx2/sidebar/Theme.hxx"
#include "Paint.hxx"
#include "SidebarResource.hxx"
#include "sfx2/sidebar/Tools.hxx"

#include <tools/svborder.hxx>
#include <tools/rc.hxx>
#include <vcl/svapp.hxx>

using namespace css;
using namespace cssu;


namespace sfx2 { namespace sidebar {

::rtl::Reference<Theme> Theme::mpInstance;


Theme& Theme::GetCurrentTheme (void)
{
	if ( ! mpInstance.is())
	{
		mpInstance.set(new Theme());
		mpInstance->InitializeTheme();
	}
	return *mpInstance;
}


Theme::Theme (void)
	: ThemeInterfaceBase(m_aMutex),
	  maImages(),
	  maColors(),
	  maPaints(),
	  maIntegers(),
	  maBooleans(),
	  mbIsHighContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode()),
	  mbIsHighContrastModeSetManually(false),
	  maPropertyNameToIdMap(),
	  maPropertyIdToNameMap(),
	  maRawValues(),
	  maChangeListeners(),
	  maVetoableListeners()

{
	SetupPropertyMaps();
}


Theme::~Theme (void)
{
}


Image Theme::GetImage (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Image);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.maImages[nIndex];
}


Color Theme::GetColor (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Color || eType==PT_Paint);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	if (eType == PT_Color)
		return rTheme.maColors[nIndex];
	else if (eType == PT_Paint)
		return rTheme.maPaints[nIndex].GetColor();
	else
		return COL_WHITE;
}


const Paint& Theme::GetPaint (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Paint);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.maPaints[nIndex];
}


const Wallpaper Theme::GetWallpaper (const ThemeItem eItem)
{
	return GetPaint(eItem).GetWallpaper();
}


sal_Int32 Theme::GetInteger (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Integer);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.maIntegers[nIndex];
}


bool Theme::GetBoolean (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Boolean);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.maBooleans[nIndex];
}


Rectangle Theme::GetRectangle (const ThemeItem eItem)
{
	const PropertyType eType (GetPropertyType(eItem));
	OSL_ASSERT(eType==PT_Rectangle);
	const sal_Int32 nIndex (GetIndex(eItem, eType));
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.maRectangles[nIndex];
}


bool Theme::IsHighContrastMode (void)
{
	const Theme& rTheme (GetCurrentTheme());
	return rTheme.mbIsHighContrastMode;
}


void Theme::HandleDataChange (void)
{
	Theme& rTheme (GetCurrentTheme());

	if ( ! rTheme.mbIsHighContrastModeSetManually)
	{
		// Do not modify mbIsHighContrastMode when it was manually set.
		GetCurrentTheme().mbIsHighContrastMode = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
		rTheme.maRawValues[Bool_IsHighContrastModeActive] = Any(GetCurrentTheme().mbIsHighContrastMode);
	}

	GetCurrentTheme().UpdateTheme();
}


void Theme::InitializeTheme (void)
{
	setPropertyValue(
		maPropertyIdToNameMap[Bool_UseSymphonyIcons],
		Any(false));
	setPropertyValue(
		maPropertyIdToNameMap[Bool_UseSystemColors],
		Any(false));
}


void Theme::UpdateTheme (void)
{
	SidebarResource aLocalResource;

	try
	{
		const StyleSettings& rStyle (Application::GetSettings().GetStyleSettings());
		const bool bUseSystemColors (GetBoolean(Bool_UseSystemColors));

#define Alternatives(n,hc,sys) (mbIsHighContrastMode ? hc : (bUseSystemColors ? sys : n))

		Color aBaseBackgroundColor (rStyle.GetDialogColor());
		// UX says this should be a little brighter, but that looks off when compared to the other windows.
		//aBaseBackgroundColor.IncreaseLuminance(7);
		Color aBorderColor (aBaseBackgroundColor);
		aBorderColor.DecreaseLuminance(80);
		Color aSecondColor (aBaseBackgroundColor);
		aSecondColor.DecreaseLuminance(0);

		setPropertyValue(
			maPropertyIdToNameMap[Paint_DeckBackground],
			Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));

		setPropertyValue(
			maPropertyIdToNameMap[Paint_DeckTitleBarBackground],
			Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckLeftPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckTopPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckRightPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckBottomPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckBorderSize],
			Any(sal_Int32(1)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckSeparatorHeight],
			Any(sal_Int32(1)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_ButtonCornerRadius],
			Any(sal_Int32(3)));
		setPropertyValue(
			maPropertyIdToNameMap[Color_DeckTitleFont],
			Any(sal_Int32(mbIsHighContrastMode ? 0xffffff : 0x262626)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_DeckTitleBarHeight],
			Any(sal_Int32(Alternatives(
						26,
						26,
						rStyle.GetFloatTitleHeight()))));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_PanelBackground],
			Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));

		setPropertyValue(
			maPropertyIdToNameMap[Paint_PanelTitleBarBackground],
			Any(Tools::VclToAwtGradient(Gradient(
						GRADIENT_LINEAR,
						aSecondColor.GetRGBColor(),
						aBaseBackgroundColor.GetRGBColor()
						))));
		setPropertyValue(
			maPropertyIdToNameMap[Color_PanelTitleFont],
			Any(sal_Int32(mbIsHighContrastMode ? 0x00ff00 : 0x262626)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_PanelTitleBarHeight],
			Any(sal_Int32(Alternatives(
						26,
						26,
						rStyle.GetTitleHeight()))));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_TabBarBackground],
			Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabBarLeftPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabBarTopPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabBarRightPadding],
			Any(sal_Int32(2)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabBarBottomPadding],
			Any(sal_Int32(2)));

		setPropertyValue(
			maPropertyIdToNameMap[Int_TabMenuPadding],
			Any(sal_Int32(6)));
		setPropertyValue(
			maPropertyIdToNameMap[Color_TabMenuSeparator],
			Any(sal_Int32(aBorderColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabMenuSeparatorPadding],
			Any(sal_Int32(7)));

		setPropertyValue(
			maPropertyIdToNameMap[Int_TabItemWidth],
			Any(sal_Int32(32)));
		setPropertyValue(
			maPropertyIdToNameMap[Int_TabItemHeight],
			Any(sal_Int32(32)));
		setPropertyValue(
			maPropertyIdToNameMap[Color_TabItemBorder],
			Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor())));
		//					mbIsHighContrastMode ? 0x00ff00 : 0xbfbfbf)));

		setPropertyValue(
			maPropertyIdToNameMap[Paint_DropDownBackground],
			Any(sal_Int32(aBaseBackgroundColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Color_DropDownBorder],
			Any(sal_Int32(rStyle.GetActiveBorderColor().GetRGBColor())));

		setPropertyValue(
			maPropertyIdToNameMap[Color_Highlight],
			Any(sal_Int32(rStyle.GetHighlightColor().GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Color_HighlightText],
			Any(sal_Int32(rStyle.GetHighlightTextColor().GetRGBColor())));

		setPropertyValue(
			maPropertyIdToNameMap[Paint_TabItemBackgroundNormal],
			Any());
		setPropertyValue(
			maPropertyIdToNameMap[Paint_TabItemBackgroundHighlight],
			Any(sal_Int32(rStyle.GetActiveTabColor().GetRGBColor())));
		//					mbIsHighContrastMode ? 0x000000 : 0x00ffffff)));

		setPropertyValue(
			maPropertyIdToNameMap[Paint_HorizontalBorder],
			Any(sal_Int32(aBorderColor.GetRGBColor())));
		//					mbIsHighContrastMode ? 0x00ff00 : 0xe4e4e4)));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_VerticalBorder],
			Any(sal_Int32(aBorderColor.GetRGBColor())));
		//					mbIsHighContrastMode ? 0x00ff00 : 0xe4e4e4)));

		setPropertyValue(
			maPropertyIdToNameMap[Image_Grip],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/sfx2/res/grip_hc.png")
					: A2S("private:graphicrepository/sfx2/res/grip.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_Expand],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/res/plus_sch.png")
					: A2S("private:graphicrepository/res/plus.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_Collapse],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/res/minus_sch.png")
					: A2S("private:graphicrepository/res/minus.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_TabBarMenu],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/sfx2/res/symphony/open_more_hc.png")
					: A2S("private:graphicrepository/sfx2/res/symphony/open_more.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_PanelMenu],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/sfx2/res/symphony/morebutton_h.png")
					: A2S("private:graphicrepository/sfx2/res/symphony/morebutton.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_Closer],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/sfx2/res/closedochc.png")
					: A2S("private:graphicrepository/sfx2/res/closedoc.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_CloseIndicator],
			Any(
				mbIsHighContrastMode
					? A2S("private:graphicrepository/res/commandimagelist/lch_decrementlevel.png")
					: A2S("private:graphicrepository/res/commandimagelist/lc_decrementlevel.png")));
		setPropertyValue(
			maPropertyIdToNameMap[Image_ToolBoxItemSeparator],
			Any(
				A2S("private:graphicrepository/sfx2/res/separator.png")));

		// ToolBox

		/*
		// Separator style
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBackground],
			Any(sal_Int32(rStyle.GetMenuColor().GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft],
			Any());
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners],
			Any());
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight],
			Any());
		setPropertyValue(
			maPropertyIdToNameMap[Rect_ToolBoxPadding],
			Any(awt::Rectangle(2,2,2,2)));
		setPropertyValue(
			maPropertyIdToNameMap[Rect_ToolBoxBorder],
			Any(awt::Rectangle(0,0,0,0)));
		setPropertyValue(
			maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator],
			Any(true));

		*/

		// Gradient style
		Color aGradientStop2 (aBaseBackgroundColor);
		aGradientStop2.IncreaseLuminance(0);
		Color aToolBoxBorderColor (aBaseBackgroundColor);
		aToolBoxBorderColor.DecreaseLuminance(40);
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBackground],
			Any(Tools::VclToAwtGradient(Gradient(
						GRADIENT_LINEAR,
						aBaseBackgroundColor.GetRGBColor(),
						aGradientStop2.GetRGBColor()
						))));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderTopLeft],
			mbIsHighContrastMode
				? Any(util::Color(sal_uInt32(0x00ff00)))
				: Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderCenterCorners],
			mbIsHighContrastMode
				? Any(util::Color(sal_uInt32(0x00ff00)))
				: Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Paint_ToolBoxBorderBottomRight],
			mbIsHighContrastMode
				? Any(util::Color(sal_uInt32(0x00ff00)))
				: Any(util::Color(aToolBoxBorderColor.GetRGBColor())));
		setPropertyValue(
			maPropertyIdToNameMap[Rect_ToolBoxPadding],
			Any(awt::Rectangle(2,2,2,2)));
		setPropertyValue(
			maPropertyIdToNameMap[Rect_ToolBoxBorder],
			Any(awt::Rectangle(1,1,1,1)));
		setPropertyValue(
			maPropertyIdToNameMap[Bool_UseToolBoxItemSeparator],
			Any(false));
	}
	catch(beans::UnknownPropertyException& rException)
	{
		OSL_TRACE("unknown property: %s",
			OUStringToOString(
				rException.Message,
				RTL_TEXTENCODING_ASCII_US).getStr());
		OSL_ASSERT(false);
	}
}


void SAL_CALL Theme::disposing (void)
{
	ChangeListeners aListeners;
	maChangeListeners.swap(aListeners);

	const lang::EventObject aEvent (static_cast<XWeak*>(this));

	for (ChangeListeners::const_iterator
			 iContainer(maChangeListeners.begin()),
			 iContainerEnd(maChangeListeners.end());
		 iContainerEnd!=iContainerEnd;
		 ++iContainerEnd)
	{
		for (ChangeListenerContainer::const_iterator
				 iListener(iContainer->second.begin()),
				 iEnd(iContainer->second.end());
			 iListener!=iEnd;
			 ++iListener)
		{
			try
			{
				(*iListener)->disposing(aEvent);
			}
			catch(const Exception&)
			{
			}
		}
	}
}


Reference<beans::XPropertySet> Theme::GetPropertySet (void)
{
	return Reference<beans::XPropertySet>(static_cast<XWeak*>(&GetCurrentTheme()), UNO_QUERY);
}


Reference<beans::XPropertySetInfo> SAL_CALL Theme::getPropertySetInfo (void)
	throw(cssu::RuntimeException)
{
	return Reference<beans::XPropertySetInfo>(this);
}


void SAL_CALL Theme::setPropertyValue (
	const ::rtl::OUString& rsPropertyName,
	const cssu::Any& rValue)
	throw(cssu::RuntimeException)
{
	PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
	if (iId == maPropertyNameToIdMap.end())
		throw beans::UnknownPropertyException(rsPropertyName, NULL);

	const PropertyType eType (GetPropertyType(iId->second));
	if (eType == PT_Invalid)
		throw beans::UnknownPropertyException(rsPropertyName, NULL);

	const ThemeItem eItem (iId->second);

	if (rValue == maRawValues[eItem])
	{
		// Value is not different from the one in the property
		// set => nothing to do.
		return;
	}

	const Any aOldValue (maRawValues[eItem]);

	const beans::PropertyChangeEvent aEvent(
		static_cast<XWeak*>(this),
		rsPropertyName,
		sal_False,
		eItem,
		aOldValue,
		rValue);

	if (DoVetoableListenersVeto(GetVetoableListeners(__AnyItem, false), aEvent))
		return;
	if (DoVetoableListenersVeto(GetVetoableListeners(eItem, false), aEvent))
		return;

	maRawValues[eItem] = rValue;
	ProcessNewValue(rValue, eItem, eType);

	BroadcastPropertyChange(GetChangeListeners(__AnyItem, false), aEvent);
	BroadcastPropertyChange(GetChangeListeners(eItem, false), aEvent);
}


Any SAL_CALL Theme::getPropertyValue (
	const ::rtl::OUString& rsPropertyName)
	throw(css::beans::UnknownPropertyException,
		css::lang::WrappedTargetException,
		cssu::RuntimeException)
{
	PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
	if (iId == maPropertyNameToIdMap.end())
		throw beans::UnknownPropertyException();

	const PropertyType eType (GetPropertyType(iId->second));
	if (eType == PT_Invalid)
		throw beans::UnknownPropertyException();

	const ThemeItem eItem (iId->second);

	return maRawValues[eItem];
}


void SAL_CALL Theme::addPropertyChangeListener(
	const ::rtl::OUString& rsPropertyName,
	const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
	throw(css::beans::UnknownPropertyException,
		css::lang::WrappedTargetException,
		cssu::RuntimeException)
{
	ThemeItem eItem (__AnyItem);
	if (rsPropertyName.getLength() > 0)
	{
		PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
		if (iId == maPropertyNameToIdMap.end())
			throw beans::UnknownPropertyException();

		const PropertyType eType (GetPropertyType(iId->second));
		if (eType == PT_Invalid)
			throw beans::UnknownPropertyException();

		eItem = iId->second;
	}
	ChangeListenerContainer* pListeners = GetChangeListeners(eItem, true);
	if (pListeners != NULL)
		pListeners->push_back(rxListener);
}


void SAL_CALL Theme::removePropertyChangeListener(
	const ::rtl::OUString& rsPropertyName,
	const cssu::Reference<css::beans::XPropertyChangeListener>& rxListener)
	throw(css::beans::UnknownPropertyException,
		css::lang::WrappedTargetException,
		cssu::RuntimeException)
{
	ThemeItem eItem (__AnyItem);
	if (rsPropertyName.getLength() > 0)
	{
		PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
		if (iId == maPropertyNameToIdMap.end())
			throw beans::UnknownPropertyException();

		const PropertyType eType (GetPropertyType(iId->second));
		if (eType == PT_Invalid)
			throw beans::UnknownPropertyException();

		eItem = iId->second;
	}
	ChangeListenerContainer* pContainer = GetChangeListeners(eItem, false);
	if (pContainer != NULL)
	{
		ChangeListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
		if (iListener != pContainer->end())
		{
			pContainer->erase(iListener);

			// Remove the listener container when empty.
			if (pContainer->empty())
				maChangeListeners.erase(eItem);
		}
	}
}


void SAL_CALL Theme::addVetoableChangeListener(
	const ::rtl::OUString& rsPropertyName,
	const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
	throw(css::beans::UnknownPropertyException,
		css::lang::WrappedTargetException,
		cssu::RuntimeException)
{
	ThemeItem eItem (__AnyItem);
	if (rsPropertyName.getLength() > 0)
	{
		PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
		if (iId == maPropertyNameToIdMap.end())
			throw beans::UnknownPropertyException();

		const PropertyType eType (GetPropertyType(iId->second));
		if (eType == PT_Invalid)
			throw beans::UnknownPropertyException();

		eItem = iId->second;
	}
	VetoableListenerContainer* pListeners = GetVetoableListeners(eItem, true);
	if (pListeners != NULL)
		pListeners->push_back(rxListener);
}


void SAL_CALL Theme::removeVetoableChangeListener(
	const ::rtl::OUString& rsPropertyName,
	const cssu::Reference<css::beans::XVetoableChangeListener>& rxListener)
	throw(css::beans::UnknownPropertyException,
		css::lang::WrappedTargetException,
		cssu::RuntimeException)
{
	ThemeItem eItem (__AnyItem);
	if (rsPropertyName.getLength() > 0)
	{
		PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
		if (iId == maPropertyNameToIdMap.end())
			throw beans::UnknownPropertyException();

		const PropertyType eType (GetPropertyType(iId->second));
		if (eType == PT_Invalid)
			throw beans::UnknownPropertyException();

		eItem = iId->second;
	}
	VetoableListenerContainer* pContainer = GetVetoableListeners(eItem, false);
	if (pContainer != NULL)
	{
		VetoableListenerContainer::iterator iListener (::std::find(pContainer->begin(), pContainer->end(), rxListener));
		if (iListener != pContainer->end())
		{
			pContainer->erase(iListener);
			// Remove container when empty.
			if (pContainer->empty())
				maVetoableListeners.erase(eItem);
		}
	}
}


cssu::Sequence<css::beans::Property> SAL_CALL Theme::getProperties (void)
	throw(cssu::RuntimeException)
{
	::std::vector<beans::Property> aProperties;

	for (sal_Int32 nItem(__Begin),nEnd(__End); nItem!=nEnd; ++nItem)
	{
		const ThemeItem eItem (static_cast<ThemeItem>(nItem));
		const PropertyType eType (GetPropertyType(eItem));
		if (eType == PT_Invalid)
			continue;

		const beans::Property aProperty(
			maPropertyIdToNameMap[eItem],
			eItem,
			GetCppuType(eType),
			0);
		aProperties.push_back(aProperty);
	}

	return cssu::Sequence<css::beans::Property>(
		&aProperties.front(),
		aProperties.size());
}


beans::Property SAL_CALL Theme::getPropertyByName (const ::rtl::OUString& rsPropertyName)
	throw(css::beans::UnknownPropertyException,
		cssu::RuntimeException)
{
	PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
	if (iId == maPropertyNameToIdMap.end())
		throw beans::UnknownPropertyException();

	const PropertyType eType (GetPropertyType(iId->second));
	if (eType == PT_Invalid)
		throw beans::UnknownPropertyException();

	const ThemeItem eItem (iId->second);

	return beans::Property(
		rsPropertyName,
		eItem,
		GetCppuType(eType),
		0);
}


sal_Bool SAL_CALL Theme::hasPropertyByName (const ::rtl::OUString& rsPropertyName)
	throw(cssu::RuntimeException)
{
	PropertyNameToIdMap::const_iterator iId (maPropertyNameToIdMap.find(rsPropertyName));
	if (iId == maPropertyNameToIdMap.end())
		return sal_False;

	const PropertyType eType (GetPropertyType(iId->second));
	if (eType == PT_Invalid)
		return sal_False;

	return sal_True;
}


void Theme::SetupPropertyMaps (void)
{
	maPropertyIdToNameMap.resize(__Post_Rect);
	maImages.resize(__Image_Color - __Pre_Image - 1);
	maColors.resize(__Color_Paint - __Image_Color - 1);
	maPaints.resize(__Paint_Int - __Color_Paint - 1);
	maIntegers.resize(__Int_Bool - __Paint_Int - 1);
	maBooleans.resize(__Bool_Rect - __Int_Bool - 1);
	maRectangles.resize(__Post_Rect - __Bool_Rect - 1);

	#define AddEntry(e) maPropertyNameToIdMap[A2S(#e)]=e; maPropertyIdToNameMap[e]=A2S(#e)

	AddEntry(Image_Grip);
	AddEntry(Image_Expand);
	AddEntry(Image_Collapse);
	AddEntry(Image_TabBarMenu);
	AddEntry(Image_PanelMenu);
	AddEntry(Image_ToolBoxItemSeparator);
	AddEntry(Image_Closer);
	AddEntry(Image_CloseIndicator);

	AddEntry(Color_DeckTitleFont);
	AddEntry(Color_PanelTitleFont);
	AddEntry(Color_TabMenuSeparator);
	AddEntry(Color_TabItemBorder);
	AddEntry(Color_DropDownBorder);
	AddEntry(Color_Highlight);
	AddEntry(Color_HighlightText);

	AddEntry(Paint_DeckBackground);
	AddEntry(Paint_DeckTitleBarBackground);
	AddEntry(Paint_PanelBackground);
	AddEntry(Paint_PanelTitleBarBackground);
	AddEntry(Paint_TabBarBackground);
	AddEntry(Paint_TabItemBackgroundNormal);
	AddEntry(Paint_TabItemBackgroundHighlight);
	AddEntry(Paint_HorizontalBorder);
	AddEntry(Paint_VerticalBorder);
	AddEntry(Paint_ToolBoxBackground);
	AddEntry(Paint_ToolBoxBorderTopLeft);
	AddEntry(Paint_ToolBoxBorderCenterCorners);
	AddEntry(Paint_ToolBoxBorderBottomRight);
	AddEntry(Paint_DropDownBackground);

	AddEntry(Int_DeckTitleBarHeight);
	AddEntry(Int_DeckBorderSize);
	AddEntry(Int_DeckSeparatorHeight);
	AddEntry(Int_PanelTitleBarHeight);
	AddEntry(Int_TabMenuPadding);
	AddEntry(Int_TabMenuSeparatorPadding);
	AddEntry(Int_TabItemWidth);
	AddEntry(Int_TabItemHeight);
	AddEntry(Int_DeckLeftPadding);
	AddEntry(Int_DeckTopPadding);
	AddEntry(Int_DeckRightPadding);
	AddEntry(Int_DeckBottomPadding);
	AddEntry(Int_TabBarLeftPadding);
	AddEntry(Int_TabBarTopPadding);
	AddEntry(Int_TabBarRightPadding);
	AddEntry(Int_TabBarBottomPadding);
	AddEntry(Int_ButtonCornerRadius);

	AddEntry(Bool_UseSymphonyIcons);
	AddEntry(Bool_UseSystemColors);
	AddEntry(Bool_UseToolBoxItemSeparator);
	AddEntry(Bool_IsHighContrastModeActive);

	AddEntry(Rect_ToolBoxPadding);
	AddEntry(Rect_ToolBoxBorder);

	#undef AddEntry

	maRawValues.resize(maPropertyIdToNameMap.size());
}


Theme::PropertyType Theme::GetPropertyType (const ThemeItem eItem)
{
	switch(eItem)
	{
		case Image_Grip:
		case Image_Expand:
		case Image_Collapse:
		case Image_TabBarMenu:
		case Image_PanelMenu:
		case Image_ToolBoxItemSeparator:
		case Image_Closer:
		case Image_CloseIndicator:
			return PT_Image;

		case Color_DeckTitleFont:
		case Color_PanelTitleFont:
		case Color_TabMenuSeparator:
		case Color_TabItemBorder:
		case Color_DropDownBorder:
		case Color_Highlight:
		case Color_HighlightText:
			return PT_Color;

		case Paint_DeckBackground:
		case Paint_DeckTitleBarBackground:
		case Paint_PanelBackground:
		case Paint_PanelTitleBarBackground:
		case Paint_TabBarBackground:
		case Paint_TabItemBackgroundNormal:
		case Paint_TabItemBackgroundHighlight:
		case Paint_HorizontalBorder:
		case Paint_VerticalBorder:
		case Paint_ToolBoxBackground:
		case Paint_ToolBoxBorderTopLeft:
		case Paint_ToolBoxBorderCenterCorners:
		case Paint_ToolBoxBorderBottomRight:
		case Paint_DropDownBackground:
			return PT_Paint;

		case Int_DeckTitleBarHeight:
		case Int_DeckBorderSize:
		case Int_DeckSeparatorHeight:
		case Int_PanelTitleBarHeight:
		case Int_TabMenuPadding:
		case Int_TabMenuSeparatorPadding:
		case Int_TabItemWidth:
		case Int_TabItemHeight:
		case Int_DeckLeftPadding:
		case Int_DeckTopPadding:
		case Int_DeckRightPadding:
		case Int_DeckBottomPadding:
		case Int_TabBarLeftPadding:
		case Int_TabBarTopPadding:
		case Int_TabBarRightPadding:
		case Int_TabBarBottomPadding:
		case Int_ButtonCornerRadius:
			return PT_Integer;

		case Bool_UseSymphonyIcons:
		case Bool_UseSystemColors:
		case Bool_UseToolBoxItemSeparator:
		case Bool_IsHighContrastModeActive:
			return PT_Boolean;

		case Rect_ToolBoxBorder:
		case Rect_ToolBoxPadding:
			return PT_Rectangle;

		default:
			return PT_Invalid;
	}
}


cssu::Type Theme::GetCppuType (const PropertyType eType)
{
	switch(eType)
	{
		case PT_Image:
			return getCppuType((rtl::OUString*)NULL);

		case PT_Color:
			return getCppuType((sal_uInt32*)NULL);

		case PT_Paint:
			return getCppuVoidType();

		case PT_Integer:
			return getCppuType((sal_Int32*)NULL);

		case PT_Boolean:
			return getCppuType((sal_Bool*)NULL);

		case PT_Rectangle:
			return getCppuType((awt::Rectangle*)NULL);

		case PT_Invalid:
		default:
			return getCppuVoidType();
	}
}


sal_Int32 Theme::GetIndex (const ThemeItem eItem, const PropertyType eType)
{
	switch(eType)
	{
		case PT_Image:
			return eItem - __Pre_Image-1;
		case PT_Color:
			return eItem - __Image_Color-1;
		case PT_Paint:
			return eItem - __Color_Paint-1;
		case PT_Integer:
			return eItem - __Paint_Int-1;
		case PT_Boolean:
			return eItem - __Int_Bool-1;
		case PT_Rectangle:
			return eItem - __Bool_Rect-1;

		default:
			OSL_ASSERT(false);
			return 0;
	}
}


Theme::VetoableListenerContainer* Theme::GetVetoableListeners (
	const ThemeItem eItem,
	const bool bCreate)
{
	VetoableListeners::iterator iContainer (maVetoableListeners.find(eItem));
	if (iContainer != maVetoableListeners.end())
		return &iContainer->second;
	else if (bCreate)
	{
		maVetoableListeners[eItem] = VetoableListenerContainer();
		return &maVetoableListeners[eItem];
	}
	else
		return NULL;
}


Theme::ChangeListenerContainer* Theme::GetChangeListeners (
	const ThemeItem eItem,
	const bool bCreate)
{
	ChangeListeners::iterator iContainer (maChangeListeners.find(eItem));
	if (iContainer != maChangeListeners.end())
		return &iContainer->second;
	else if (bCreate)
	{
		maChangeListeners[eItem] = ChangeListenerContainer();
		return &maChangeListeners[eItem];
	}
	else
		return NULL;
}


bool Theme::DoVetoableListenersVeto (
	const VetoableListenerContainer* pListeners,
	const beans::PropertyChangeEvent& rEvent) const
{
	if (pListeners == NULL)
		return false;

	VetoableListenerContainer aListeners (*pListeners);
	try
	{
		for (VetoableListenerContainer::const_iterator
				 iListener(aListeners.begin()),
				 iEnd(aListeners.end());
			 iListener!=iEnd;
			 ++iListener)
		{
			(*iListener)->vetoableChange(rEvent);
		}
	}
	catch(const beans::PropertyVetoException&)
	{
		return true;
	}
	catch(const Exception&)
	{
		// Ignore any other errors (such as disposed listeners).
	}
	return false;
}


void Theme::BroadcastPropertyChange (
	const ChangeListenerContainer* pListeners,
	const beans::PropertyChangeEvent& rEvent) const
{
	if (pListeners == NULL)
		return;

	const ChangeListenerContainer aListeners (*pListeners);
	try
	{
		for (ChangeListenerContainer::const_iterator
				 iListener(aListeners.begin()),
				 iEnd(aListeners.end());
			 iListener!=iEnd;
			 ++iListener)
		{
			(*iListener)->propertyChange(rEvent);
		}
	}
	catch(const Exception&)
	{
		// Ignore any errors (such as disposed listeners).
	}
}


void Theme::ProcessNewValue (
	const Any& rValue,
	const ThemeItem eItem,
	const PropertyType eType)
{
	const sal_Int32 nIndex (GetIndex (eItem, eType));
	switch (eType)
	{
		case PT_Image:
		{
			::rtl::OUString sURL;
			if (rValue >>= sURL)
			{
				maImages[nIndex] = Tools::GetImage(sURL, NULL);
			}
			break;
		}
		case PT_Color:
		{
			sal_Int32 nColorValue (0);
			if (rValue >>= nColorValue)
			{
				maColors[nIndex] = Color(nColorValue);
			}
			break;
		}
		case PT_Paint:
		{
			maPaints[nIndex] = Paint::Create(rValue);
			break;
		}
		case PT_Integer:
		{
			sal_Int32 nValue (0);
			if (rValue >>= nValue)
			{
				maIntegers[nIndex] = nValue;
			}
			break;
		}
		case PT_Boolean:
		{
			sal_Bool nValue (0);
			if (rValue >>= nValue)
			{
				maBooleans[nIndex] = (nValue==sal_True);
				if (eItem == Bool_IsHighContrastModeActive)
				{
					mbIsHighContrastModeSetManually = true;
					mbIsHighContrastMode = maBooleans[nIndex];
					HandleDataChange();
				}
				else if (eItem == Bool_UseSystemColors)
				{
					HandleDataChange();
				}
			}
			break;
		}
		case PT_Rectangle:
		{
			awt::Rectangle aBox;
			if (rValue >>= aBox)
			{
				maRectangles[nIndex] = Rectangle(
					aBox.X,
					aBox.Y,
					aBox.Width,
					aBox.Height);
			}
			break;
		}
		case PT_Invalid:
			OSL_ASSERT(eType != PT_Invalid);
			throw RuntimeException();
	}
}

} } // end of namespace sfx2::sidebar

/* vim: set noet sw=4 ts=4: */
