/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_drawinglayer.hxx"

#include <drawinglayer/attribute/materialattribute3d.hxx>
#include <basegfx/color/bcolor.hxx>

//////////////////////////////////////////////////////////////////////////////

namespace drawinglayer
{
	namespace attribute
	{
		class ImpMaterialAttribute3D
		{
		public:
			// refcounter
			sal_uInt32								mnRefCount;

			// materialAttribute3D definitions
			basegfx::BColor							maColor;				// object color
			basegfx::BColor							maSpecular;				// material specular color
			basegfx::BColor							maEmission;				// material emissive color
			sal_uInt16								mnSpecularIntensity;	// material specular intensity [0..128]

			ImpMaterialAttribute3D(const basegfx::BColor& rColor, const basegfx::BColor& rSpecular, const basegfx::BColor& rEmission, sal_uInt16 nSpecularIntensity)
			:	mnRefCount(0),
                maColor(rColor),
				maSpecular(rSpecular),
				maEmission(rEmission),
				mnSpecularIntensity(nSpecularIntensity)
			{
			}

			ImpMaterialAttribute3D(const basegfx::BColor& rColor)
			:	mnRefCount(0),
                maColor(rColor),
				maSpecular(1.0, 1.0, 1.0),
				maEmission(),
				mnSpecularIntensity(15)
			{
			}

			// data read access
			const basegfx::BColor& getColor() const { return maColor; }
			const basegfx::BColor& getSpecular() const { return maSpecular; }
			const basegfx::BColor& getEmission() const { return maEmission; }
			sal_uInt16 getSpecularIntensity() const { return mnSpecularIntensity; }

			bool operator==(const ImpMaterialAttribute3D& rCandidate) const
			{
				return (getColor() == rCandidate.getColor()
					&& getSpecular() == rCandidate.getSpecular()
					&& getEmission() == rCandidate.getEmission()
					&& getSpecularIntensity() == rCandidate.getSpecularIntensity());
			}

            static ImpMaterialAttribute3D* get_global_default()
            {
                static ImpMaterialAttribute3D* pDefault = 0;

                if(!pDefault)
                {
                    pDefault = new ImpMaterialAttribute3D(
                        basegfx::BColor(),
                        basegfx::BColor(),
                        basegfx::BColor(),
                        0);

                    // never delete; start with RefCount 1, not 0
    			    pDefault->mnRefCount++;
                }

                return pDefault;
            }
		};

        MaterialAttribute3D::MaterialAttribute3D(
            const basegfx::BColor& rColor,
            const basegfx::BColor& rSpecular,
            const basegfx::BColor& rEmission,
            sal_uInt16 nSpecularIntensity)
		:	mpMaterialAttribute3D(new ImpMaterialAttribute3D(
                rColor, rSpecular, rEmission, nSpecularIntensity))
		{
		}

		MaterialAttribute3D::MaterialAttribute3D(
            const basegfx::BColor& rColor)
		:	mpMaterialAttribute3D(new ImpMaterialAttribute3D(rColor))
		{
		}

		MaterialAttribute3D::MaterialAttribute3D()
        :	mpMaterialAttribute3D(ImpMaterialAttribute3D::get_global_default())
		{
			mpMaterialAttribute3D->mnRefCount++;
		}

		MaterialAttribute3D::MaterialAttribute3D(const MaterialAttribute3D& rCandidate)
		:	mpMaterialAttribute3D(rCandidate.mpMaterialAttribute3D)
		{
			mpMaterialAttribute3D->mnRefCount++;
		}

		MaterialAttribute3D::~MaterialAttribute3D()
		{
			if(mpMaterialAttribute3D->mnRefCount)
			{
				mpMaterialAttribute3D->mnRefCount--;
			}
			else
			{
				delete mpMaterialAttribute3D;
			}
		}

        bool MaterialAttribute3D::isDefault() const
        {
            return mpMaterialAttribute3D == ImpMaterialAttribute3D::get_global_default();
        }

        MaterialAttribute3D& MaterialAttribute3D::operator=(const MaterialAttribute3D& rCandidate)
		{
			if(rCandidate.mpMaterialAttribute3D != mpMaterialAttribute3D)
			{
				if(mpMaterialAttribute3D->mnRefCount)
				{
					mpMaterialAttribute3D->mnRefCount--;
				}
				else
				{
					delete mpMaterialAttribute3D;
				}

				mpMaterialAttribute3D = rCandidate.mpMaterialAttribute3D;
				mpMaterialAttribute3D->mnRefCount++;
			}

			return *this;
		}

		bool MaterialAttribute3D::operator==(const MaterialAttribute3D& rCandidate) const
		{
			if(rCandidate.mpMaterialAttribute3D == mpMaterialAttribute3D)
			{
				return true;
			}

			if(rCandidate.isDefault() != isDefault())
			{
				return false;
			}

			return (*rCandidate.mpMaterialAttribute3D == *mpMaterialAttribute3D);
		}

		const basegfx::BColor& MaterialAttribute3D::getColor() const
		{
			return mpMaterialAttribute3D->getColor();
		}

		const basegfx::BColor& MaterialAttribute3D::getSpecular() const
		{
			return mpMaterialAttribute3D->getSpecular();
		}

		const basegfx::BColor& MaterialAttribute3D::getEmission() const
		{
			return mpMaterialAttribute3D->getEmission();
		}

		sal_uInt16 MaterialAttribute3D::getSpecularIntensity() const
		{
			return mpMaterialAttribute3D->getSpecularIntensity();
		}
	} // end of namespace attribute
} // end of namespace drawinglayer

//////////////////////////////////////////////////////////////////////////////
// eof
