/**************************************************************
 * 
 * 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_svgio.hxx"

#include <svgio/svgreader/svgpatternnode.hxx>
#include <svgio/svgreader/svgdocument.hxx>

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

namespace svgio
{
    namespace svgreader
    {
        void SvgPatternNode::tryToFindLink()
        {
            if(!mpXLink && maXLink.getLength())
            {
                mpXLink = dynamic_cast< const SvgPatternNode* >(getDocument().findSvgNodeById(maXLink));
            }
        }

        SvgPatternNode::SvgPatternNode(
            SvgDocument& rDocument,
            SvgNode* pParent)
        :   SvgNode(SVGTokenPattern, rDocument, pParent),
            aPrimitives(),
            maSvgStyleAttributes(*this),
            mpViewBox(0),
            maSvgAspectRatio(),
            maX(),
            maY(),
            maWidth(),
            maHeight(),
            mpPatternUnits(0),
            mpPatternContentUnits(0),
            mpaPatternTransform(0),
            maXLink(),
            mpXLink(0)
        {
        }

        SvgPatternNode::~SvgPatternNode()
        {
            if(mpViewBox) delete mpViewBox;
            if(mpaPatternTransform) delete mpaPatternTransform;
            if(mpPatternUnits) delete mpPatternUnits;
            if(mpPatternContentUnits) delete mpPatternContentUnits;
        }

        const SvgStyleAttributes* SvgPatternNode::getSvgStyleAttributes() const
        {
            static rtl::OUString aClassStr(rtl::OUString::createFromAscii("pattern"));

            return checkForCssStyle(aClassStr, maSvgStyleAttributes);
        }

        void SvgPatternNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
        {
            // call parent
            SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);

            // read style attributes
            maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);

            // parse own
            switch(aSVGToken)
            {
                case SVGTokenStyle:
                {
                    maSvgStyleAttributes.readStyle(aContent);
                    break;
                }
                case SVGTokenViewBox:
                {
                    const basegfx::B2DRange aRange(readViewBox(aContent, *this));

                    if(!aRange.isEmpty())
                    {
                        setViewBox(&aRange);
                    }
                    break;
                }
                case SVGTokenPreserveAspectRatio:
                {
                    setSvgAspectRatio(readSvgAspectRatio(aContent));
                    break;
                }
                case SVGTokenX:
                {
                    SvgNumber aNum;

                    if(readSingleNumber(aContent, aNum))
                    {
                        setX(aNum);
                    }
                    break;
                }
                case SVGTokenY:
                {
                    SvgNumber aNum;

                    if(readSingleNumber(aContent, aNum))
                    {
                        setY(aNum);
                    }
                    break;
                }
                case SVGTokenWidth:
                {
                    SvgNumber aNum;

                    if(readSingleNumber(aContent, aNum))
                    {
                        if(aNum.isPositive())
                        {
                            setWidth(aNum);
                        }
                    }
                    break;
                }
                case SVGTokenHeight:
                {
                    SvgNumber aNum;

                    if(readSingleNumber(aContent, aNum))
                    {
                        if(aNum.isPositive())
                        {
                            setHeight(aNum);
                        }
                    }
                    break;
                }
                case SVGTokenPatternUnits:
                {
                    if(aContent.getLength())
                    {
                        if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
                        {
                            setPatternUnits(userSpaceOnUse);
                        }
                        else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
                        {
                            setPatternUnits(objectBoundingBox);
                        }
                    }
                    break;
                }
                case SVGTokenPatternContentUnits:
                {
                    if(aContent.getLength())
                    {
                        if(aContent.match(commonStrings::aStrUserSpaceOnUse, 0))
                        {
                            setPatternContentUnits(userSpaceOnUse);
                        }
                        else if(aContent.match(commonStrings::aStrObjectBoundingBox, 0))
                        {
                            setPatternContentUnits(objectBoundingBox);
                        }
                    }
                    break;
                }
                case SVGTokenPatternTransform:
                {
                    const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));

                    if(!aMatrix.isIdentity())
                    {
                        setPatternTransform(&aMatrix);
                    }
                    break;
                }
                case SVGTokenXlinkHref:
                {
                    const sal_Int32 nLen(aContent.getLength());

                    if(nLen && sal_Unicode('#') == aContent[0])
                    {
                        maXLink = aContent.copy(1);
                        tryToFindLink();
                    }
                    break;
                }
                default:
                {
                    break;
                }
            }
        }

        void SvgPatternNode::getValuesRelative(double& rfX, double& rfY, double& rfW, double& rfH, const basegfx::B2DRange& rGeoRange, SvgNode& rUser) const
        {
            double fTargetWidth(rGeoRange.getWidth());
            double fTargetHeight(rGeoRange.getHeight());

            if(fTargetWidth > 0.0 && fTargetHeight > 0.0)
            {
                const SvgUnits aPatternUnits(getPatternUnits() ? *getPatternUnits() : objectBoundingBox);

                if(objectBoundingBox == aPatternUnits)
                {
                    rfW = (getWidth().isSet()) ? getWidth().getNumber() : 0.0;
                    rfH = (getHeight().isSet()) ? getHeight().getNumber() : 0.0;

                    if(Unit_percent == getWidth().getUnit())
                    {
                        rfW *= 0.01;
                    }

                    if(Unit_percent == getHeight().getUnit())
                    {
                        rfH *= 0.01;
                    }
                }
                else
                {
                    rfW = (getWidth().isSet()) ? getWidth().solve(rUser, xcoordinate) : 0.0;
                    rfH = (getHeight().isSet()) ? getHeight().solve(rUser, ycoordinate) : 0.0;

                    // make relative to rGeoRange
                    rfW /= fTargetWidth;
                    rfH /= fTargetHeight;
                }

                if(rfW > 0.0 && rfH > 0.0)
                {
                    if(objectBoundingBox == aPatternUnits)
                    {
                        rfX = (getX().isSet()) ? getX().getNumber() : 0.0;
                        rfY = (getY().isSet()) ? getY().getNumber() : 0.0;

                        if(Unit_percent == getX().getUnit())
                        {
                            rfX *= 0.01;
                        }

                        if(Unit_percent == getY().getUnit())
                        {
                            rfY *= 0.01;
                        }
                    }
                    else
                    {
                        rfX = (getX().isSet()) ? getX().solve(rUser, xcoordinate) : 0.0;
                        rfY = (getY().isSet()) ? getY().solve(rUser, ycoordinate) : 0.0;

                        // make relative to rGeoRange
                        rfX = (rfX - rGeoRange.getMinX()) / fTargetWidth;
                        rfY = (rfY - rGeoRange.getMinY()) / fTargetHeight;
                    }
                }
            }
        }

        const drawinglayer::primitive2d::Primitive2DSequence& SvgPatternNode::getPatternPrimitives() const
        {
            if(!aPrimitives.hasElements() && Display_none != getDisplay())
            {
                decomposeSvgNode(const_cast< SvgPatternNode* >(this)->aPrimitives, true);
            }

            if(!aPrimitives.hasElements() && maXLink.getLength())
            {
                const_cast< SvgPatternNode* >(this)->tryToFindLink();

                if(mpXLink)
                {
                    return mpXLink->getPatternPrimitives();
                }
            }

            return aPrimitives;
        }

        const basegfx::B2DRange SvgPatternNode::getCurrentViewPort() const
        {
            if(getViewBox())
            {
                return *(getViewBox());
            }
            else
            {
                return SvgNode::getCurrentViewPort();
            }
        }

        const basegfx::B2DRange* SvgPatternNode::getViewBox() const 
        { 
            if(mpViewBox)
            {
                return mpViewBox; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getViewBox();
            }

            return 0;
        }

        const SvgAspectRatio& SvgPatternNode::getSvgAspectRatio() const 
        { 
            if(maSvgAspectRatio.isSet())
            {
                return maSvgAspectRatio; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getSvgAspectRatio();
            }

            return maSvgAspectRatio; 
        }

        const SvgNumber& SvgPatternNode::getX() const 
        { 
            if(maX.isSet())
            {
                return maX; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getX();
            }

            return maX; 
        }

        const SvgNumber& SvgPatternNode::getY() const 
        { 
            if(maY.isSet())
            {
                return maY; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getY();
            }

            return maY; 
        }

        const SvgNumber& SvgPatternNode::getWidth() const 
        { 
            if(maWidth.isSet())
            {
                return maWidth; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getWidth();
            }

            return maWidth; 
        }

        const SvgNumber& SvgPatternNode::getHeight() const 
        { 
            if(maHeight.isSet())
            {
                return maHeight; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getHeight();
            }

            return maHeight; 
        }

        const SvgUnits* SvgPatternNode::getPatternUnits() const 
        { 
            if(mpPatternUnits)
            {
                return mpPatternUnits; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getPatternUnits();
            }

            return 0; 
        }

        const SvgUnits* SvgPatternNode::getPatternContentUnits() const 
        { 
            if(mpPatternContentUnits)
            {
                return mpPatternContentUnits; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getPatternContentUnits();
            }

            return 0; 
        }

        const basegfx::B2DHomMatrix* SvgPatternNode::getPatternTransform() const 
        { 
            if(mpaPatternTransform)
            {
                return mpaPatternTransform; 
            }

            const_cast< SvgPatternNode* >(this)->tryToFindLink();

            if(mpXLink)
            {
                return mpXLink->getPatternTransform();
            }

            return 0; 
        }

    } // end of namespace svgreader
} // end of namespace svgio

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