/**************************************************************
 * 
 * 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/fillgradientattribute.hxx>
#include <basegfx/color/bcolor.hxx>

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

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

            // data definitions
		    GradientStyle							meStyle;
		    double									mfBorder;
		    double									mfOffsetX;
		    double									mfOffsetY;
		    double									mfAngle;
            basegfx::BColor							maStartColor;
		    basegfx::BColor							maEndColor;
		    sal_uInt16								mnSteps;

		    ImpFillGradientAttribute(
			    GradientStyle eStyle, 
                double fBorder, 
                double fOffsetX, 
                double fOffsetY, 
                double fAngle, 
			    const basegfx::BColor& rStartColor, 
                const basegfx::BColor& rEndColor, 
                sal_uInt16 nSteps)
		    :	mnRefCount(0),
		        meStyle(eStyle),
		        mfBorder(fBorder),
		        mfOffsetX(fOffsetX),
		        mfOffsetY(fOffsetY),
		        mfAngle(fAngle),
                maStartColor(rStartColor),
		        maEndColor(rEndColor),
		        mnSteps(nSteps)
            {
            }

		    // data read access
		    GradientStyle getStyle() const { return meStyle; }
		    double getBorder() const { return mfBorder; }
		    double getOffsetX() const { return mfOffsetX; }
		    double getOffsetY() const { return mfOffsetY; }
		    double getAngle() const { return mfAngle; }
		    const basegfx::BColor& getStartColor() const { return maStartColor; }
		    const basegfx::BColor& getEndColor() const { return maEndColor; }
		    sal_uInt16 getSteps() const { return mnSteps; }

		    bool operator==(const ImpFillGradientAttribute& rCandidate) const
            {
		        return (getStyle() == rCandidate.getStyle()
			        && getBorder() == rCandidate.getBorder()
			        && getOffsetX() == rCandidate.getOffsetX()
			        && getOffsetY() == rCandidate.getOffsetY()
			        && getAngle() == rCandidate.getAngle()
                    && getStartColor() == rCandidate.getStartColor()
			        && getEndColor() == rCandidate.getEndColor()
			        && getSteps() == rCandidate.getSteps());
            }

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

                if(!pDefault)
                {
                    pDefault = new ImpFillGradientAttribute(
                        GRADIENTSTYLE_LINEAR,
                        0.0, 0.0, 0.0, 0.0,
                        basegfx::BColor(),
                        basegfx::BColor(),
                        0);

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

                return pDefault;
            }
	    };

        FillGradientAttribute::FillGradientAttribute(
			GradientStyle eStyle, 
            double fBorder, 
            double fOffsetX, 
            double fOffsetY, 
            double fAngle, 
			const basegfx::BColor& rStartColor, 
            const basegfx::BColor& rEndColor, 
            sal_uInt16 nSteps)
        :	mpFillGradientAttribute(new ImpFillGradientAttribute(
                eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rStartColor, rEndColor, nSteps))
		{
		}

		FillGradientAttribute::FillGradientAttribute()
        :	mpFillGradientAttribute(ImpFillGradientAttribute::get_global_default())
		{
			mpFillGradientAttribute->mnRefCount++;
		}

		FillGradientAttribute::FillGradientAttribute(const FillGradientAttribute& rCandidate)
		:	mpFillGradientAttribute(rCandidate.mpFillGradientAttribute)
		{
			mpFillGradientAttribute->mnRefCount++;
		}

		FillGradientAttribute::~FillGradientAttribute()
		{
			if(mpFillGradientAttribute->mnRefCount)
			{
				mpFillGradientAttribute->mnRefCount--;
			}
			else
			{
				delete mpFillGradientAttribute;
			}
		}

        bool FillGradientAttribute::isDefault() const
        {
            return mpFillGradientAttribute == ImpFillGradientAttribute::get_global_default();
        }

        FillGradientAttribute& FillGradientAttribute::operator=(const FillGradientAttribute& rCandidate)
		{
			if(rCandidate.mpFillGradientAttribute != mpFillGradientAttribute)
			{
				if(mpFillGradientAttribute->mnRefCount)
				{
					mpFillGradientAttribute->mnRefCount--;
				}
				else
				{
					delete mpFillGradientAttribute;
				}
				
				mpFillGradientAttribute = rCandidate.mpFillGradientAttribute;
				mpFillGradientAttribute->mnRefCount++;
			}

			return *this;
		}

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

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

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

		const basegfx::BColor& FillGradientAttribute::getStartColor() const 
        {
            return mpFillGradientAttribute->getStartColor(); 
        }

		const basegfx::BColor& FillGradientAttribute::getEndColor() const 
        {
            return mpFillGradientAttribute->getEndColor(); 
        }

		double FillGradientAttribute::getBorder() const 
        {
            return mpFillGradientAttribute->getBorder(); 
        }

		double FillGradientAttribute::getOffsetX() const 
        {
            return mpFillGradientAttribute->getOffsetX(); 
        }

		double FillGradientAttribute::getOffsetY() const 
        {
            return mpFillGradientAttribute->getOffsetY(); 
        }

		double FillGradientAttribute::getAngle() const 
        {
            return mpFillGradientAttribute->getAngle(); 
        }

		GradientStyle FillGradientAttribute::getStyle() const 
        {
            return mpFillGradientAttribute->getStyle(); 
        }

		sal_uInt16 FillGradientAttribute::getSteps() const 
        {
            return mpFillGradientAttribute->getSteps(); 
        }

    } // end of namespace attribute
} // end of namespace drawinglayer

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