/**************************************************************
 *
 * 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/sdrlightingattribute3d.hxx>
#include <basegfx/color/bcolor.hxx>
#include <basegfx/vector/b3dvector.hxx>
#include <drawinglayer/attribute/sdrlightattribute3d.hxx>

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

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

			// 3D light attribute definitions
			basegfx::BColor							maAmbientLight;
			::std::vector< Sdr3DLightAttribute >	maLightVector;

			ImpSdrLightingAttribute(
				const basegfx::BColor& rAmbientLight,
				const ::std::vector< Sdr3DLightAttribute >& rLightVector)
			:	mnRefCount(0),
		    	maAmbientLight(rAmbientLight),
			    maLightVector(rLightVector)
		    {
		    }

			// data read access
			const basegfx::BColor& getAmbientLight() const { return maAmbientLight; }
			const ::std::vector< Sdr3DLightAttribute >& getLightVector() const { return maLightVector; }

            bool operator==(const ImpSdrLightingAttribute& rCandidate) const
		    {
			    return (getAmbientLight() == rCandidate.getAmbientLight()
				    && getLightVector() == rCandidate.getLightVector());
		    }

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

                if(!pDefault)
                {
                    pDefault = new ImpSdrLightingAttribute(
			            basegfx::BColor(),
			            std::vector< Sdr3DLightAttribute >());

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

                return pDefault;
            }
		};

        SdrLightingAttribute::SdrLightingAttribute(
			const basegfx::BColor& rAmbientLight,
			const ::std::vector< Sdr3DLightAttribute >& rLightVector)
		:	mpSdrLightingAttribute(new ImpSdrLightingAttribute(
                rAmbientLight, rLightVector))
		{
		}

		SdrLightingAttribute::SdrLightingAttribute()
        :	mpSdrLightingAttribute(ImpSdrLightingAttribute::get_global_default())
		{
			mpSdrLightingAttribute->mnRefCount++;
		}

        SdrLightingAttribute::SdrLightingAttribute(const SdrLightingAttribute& rCandidate)
		:	mpSdrLightingAttribute(rCandidate.mpSdrLightingAttribute)
		{
			mpSdrLightingAttribute->mnRefCount++;
		}

		SdrLightingAttribute::~SdrLightingAttribute()
		{
			if(mpSdrLightingAttribute->mnRefCount)
			{
				mpSdrLightingAttribute->mnRefCount--;
			}
			else
			{
				delete mpSdrLightingAttribute;
			}
		}

        bool SdrLightingAttribute::isDefault() const
        {
            return mpSdrLightingAttribute == ImpSdrLightingAttribute::get_global_default();
        }

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

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

			return *this;
		}

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

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

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

		const basegfx::BColor& SdrLightingAttribute::getAmbientLight() const
        {
            return mpSdrLightingAttribute->getAmbientLight();
        }

        const ::std::vector< Sdr3DLightAttribute >& SdrLightingAttribute::getLightVector() const
        {
            return mpSdrLightingAttribute->getLightVector();
        }

        // color model solver
		basegfx::BColor SdrLightingAttribute::solveColorModel(
			const basegfx::B3DVector& rNormalInEyeCoordinates,
			const basegfx::BColor& rColor, const basegfx::BColor& rSpecular,
			const basegfx::BColor& rEmission, sal_uInt16 nSpecularIntensity) const
		{
			// initialize with emissive color
			basegfx::BColor aRetval(rEmission);

			// take care of global ambient light
			aRetval += mpSdrLightingAttribute->getAmbientLight() * rColor;

			// prepare light access. Is there a light?
			const sal_uInt32 nLightCount(mpSdrLightingAttribute->getLightVector().size());

			if(nLightCount && !rNormalInEyeCoordinates.equalZero())
			{
				// prepare normal
				basegfx::B3DVector aEyeNormal(rNormalInEyeCoordinates);
				aEyeNormal.normalize();

				for(sal_uInt32 a(0L); a < nLightCount; a++)
				{
					const Sdr3DLightAttribute& rLight(mpSdrLightingAttribute->getLightVector()[a]);
					const double fCosFac(rLight.getDirection().scalar(aEyeNormal));

					if(basegfx::fTools::more(fCosFac, 0.0))
					{
						aRetval += ((rLight.getColor() * rColor) * fCosFac);

						if(rLight.getSpecular())
						{
							// expand by (0.0, 0.0, 1.0) in Z
							basegfx::B3DVector aSpecularNormal(rLight.getDirection().getX(), rLight.getDirection().getY(), rLight.getDirection().getZ() + 1.0);
							aSpecularNormal.normalize();
							double fCosFac2(aSpecularNormal.scalar(aEyeNormal));

							if(basegfx::fTools::more(fCosFac2, 0.0))
							{
								fCosFac2 = pow(fCosFac2, (double)nSpecularIntensity);
								aRetval += (rSpecular * fCosFac2);
							}
						}
					}
				}
			}

			// clamp to color space before usage
			aRetval.clamp();

			return aRetval;
		}
	} // end of namespace attribute
} // end of namespace drawinglayer

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