/**************************************************************
 *
 * 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, false);

            // parse own
            switch(aSVGToken)
            {
                case SVGTokenStyle:
                {
                    readLocalCssStyle(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
