/**************************************************************
 *
 * 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/sdrfillattribute.hxx>
#include <basegfx/color/bcolor.hxx>
#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
#include <drawinglayer/attribute/fillhatchattribute.hxx>
#include <drawinglayer/attribute/fillgradientattribute.hxx>

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

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

			// fill definitions
			double								mfTransparence;		// [0.0 .. 1.0], 0.0==no transp.
			basegfx::BColor						maColor;			// fill color
			FillGradientAttribute				maGradient;			// fill gradient (if used)
			FillHatchAttribute					maHatch;			// fill hatch (if used)
			SdrFillGraphicAttribute				maFillGraphic;		// fill graphic (if used)

		public:
			ImpSdrFillAttribute(
				double fTransparence,
                const basegfx::BColor& rColor,
                const FillGradientAttribute& rGradient,
				const FillHatchAttribute& rHatch,
                const SdrFillGraphicAttribute& rFillGraphic)
			:	mnRefCount(0),
			    mfTransparence(fTransparence),
			    maColor(rColor),
			    maGradient(rGradient),
			    maHatch(rHatch),
			    maFillGraphic(rFillGraphic)
            {
            }

			// data read access
			double getTransparence() const { return mfTransparence;	}
			const basegfx::BColor& getColor() const { return maColor; }
			const FillGradientAttribute& getGradient() const { return maGradient; }
			const FillHatchAttribute& getHatch() const { return maHatch; }
			const SdrFillGraphicAttribute& getFillGraphic() const { return maFillGraphic; }

            // compare operator
			bool operator==(const ImpSdrFillAttribute& rCandidate) const
            {
                return(getTransparence() == rCandidate.getTransparence()
                    && getColor() == rCandidate.getColor()
                    && getGradient() == rCandidate.getGradient()
                    && getHatch() == rCandidate.getHatch()
                    && getFillGraphic() == rCandidate.getFillGraphic());
            }

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

                if(!pDefault)
                {
                    pDefault = new ImpSdrFillAttribute(
				        0.0,
                        basegfx::BColor(),
                        FillGradientAttribute(),
				        FillHatchAttribute(),
                        SdrFillGraphicAttribute());

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

                return pDefault;
            }
		};

        SdrFillAttribute::SdrFillAttribute(
			double fTransparence,
            const basegfx::BColor& rColor,
            const FillGradientAttribute& rGradient,
			const FillHatchAttribute& rHatch,
            const SdrFillGraphicAttribute& rFillGraphic)
		:	mpSdrFillAttribute(
                new ImpSdrFillAttribute(
                    fTransparence, rColor, rGradient, rHatch, rFillGraphic))
		{
		}

		SdrFillAttribute::SdrFillAttribute()
        :	mpSdrFillAttribute(ImpSdrFillAttribute::get_global_default())
		{
			mpSdrFillAttribute->mnRefCount++;
		}

        SdrFillAttribute::SdrFillAttribute(const SdrFillAttribute& rCandidate)
		:	mpSdrFillAttribute(rCandidate.mpSdrFillAttribute)
		{
			mpSdrFillAttribute->mnRefCount++;
		}

		SdrFillAttribute::~SdrFillAttribute()
		{
			if(mpSdrFillAttribute->mnRefCount)
			{
				mpSdrFillAttribute->mnRefCount--;
			}
			else
			{
				delete mpSdrFillAttribute;
			}
		}

        bool SdrFillAttribute::isDefault() const
        {
            return mpSdrFillAttribute == ImpSdrFillAttribute::get_global_default();
        }

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

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

			return *this;
		}

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

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

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

		double SdrFillAttribute::getTransparence() const
        {
            return mpSdrFillAttribute->getTransparence();
        }

		const basegfx::BColor& SdrFillAttribute::getColor() const
        {
            return mpSdrFillAttribute->getColor();
        }

		const FillGradientAttribute& SdrFillAttribute::getGradient() const
        {
            return mpSdrFillAttribute->getGradient();
        }

		const FillHatchAttribute& SdrFillAttribute::getHatch() const
        {
            return mpSdrFillAttribute->getHatch();
        }

		const SdrFillGraphicAttribute& SdrFillAttribute::getFillGraphic() const
        {
            return mpSdrFillAttribute->getFillGraphic();
        }
    } // end of namespace attribute
} // end of namespace drawinglayer

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