    /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    /*
     * This file is part of the LibreOffice project.
     *
     * This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     *
     * This file incorporates work covered by the following license notice:
     *
     *   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 .
     */

    #include <sal/config.h>

    #include <o3tl/any.hxx>
    #include <osl/diagnose.h>
    #include <sal/log.hxx>
    #include <set>
    #include <xmloff/xmlnmspe.hxx>
    #include <xmloff/xmltoken.hxx>
    #include <xmloff/xmlprcon.hxx>
    #include <com/sun/star/style/XStyle.hpp>
    #include <com/sun/star/style/XAutoStyleFamily.hpp>
    #include <com/sun/star/container/XNameContainer.hpp>
    #include <com/sun/star/beans/XPropertySet.hpp>
    #include <com/sun/star/beans/XPropertyState.hpp>
    #include <com/sun/star/beans/XMultiPropertyStates.hpp>
    #include <com/sun/star/lang/XMultiServiceFactory.hpp>
    #include <xmloff/xmlimp.hxx>
    #include <xmloff/prstylei.hxx>
    #include <xmloff/attrlist.hxx>
    #include <xmloff/xmlerror.hxx>
    #include <xmloff/xmltypes.hxx>
    #include <xmloff/maptype.hxx>
    #include <comphelper/sequence.hxx>
    #include <com/sun/star/drawing/FillStyle.hpp>

    using namespace ::com::sun::star;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::xml::sax;
    using namespace ::com::sun::star::style;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::lang;
    using namespace ::xmloff::token;
    using namespace com::sun::star::drawing;

    void XMLPropStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
                                            const OUString& rLocalName,
                                            const OUString& rValue )
    {
        if( XML_NAMESPACE_STYLE == nPrefixKey && IsXMLToken( rLocalName, XML_FAMILY ) )
        {
            SAL_WARN_IF( GetFamily() != static_cast<SvXMLStylesContext *>(mxStyles.get())->GetFamily( rValue ), "xmloff", "unexpected style family" );
        }
        else
        {
            SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
        }
    }

    namespace
    {
        struct theStandardSet :
            public rtl::StaticWithInit<OldFillStyleDefinitionSet, theStandardSet>
        {
            OldFillStyleDefinitionSet operator () ()
            {
                OldFillStyleDefinitionSet aSet;
                aSet.insert("BackColorRGB");
                aSet.insert("BackTransparent");
                aSet.insert("BackColorTransparency");
                aSet.insert("BackGraphic");
                aSet.insert("BackGraphicFilter");
                aSet.insert("BackGraphicLocation");
                aSet.insert("BackGraphicTransparency");
                return aSet;
            }
        };
        struct theHeaderSet :
            public rtl::StaticWithInit<OldFillStyleDefinitionSet, theHeaderSet>
        {
            OldFillStyleDefinitionSet operator () ()
            {
                OldFillStyleDefinitionSet aSet;
                aSet.insert("HeaderBackColorRGB");
                aSet.insert("HeaderBackTransparent");
                aSet.insert("HeaderBackColorTransparency");
                aSet.insert("HeaderBackGraphic");
                aSet.insert("HeaderBackGraphicFilter");
                aSet.insert("HeaderBackGraphicLocation");
                aSet.insert("HeaderBackGraphicTransparency");
                return aSet;
            }
        };
        struct theFooterSet :
            public rtl::StaticWithInit<OldFillStyleDefinitionSet, theFooterSet>
        {
            OldFillStyleDefinitionSet operator () ()
            {
                OldFillStyleDefinitionSet aSet;
                aSet.insert("FooterBackColorRGB");
                aSet.insert("FooterBackTransparent");
                aSet.insert("FooterBackColorTransparency");
                aSet.insert("FooterBackGraphic");
                aSet.insert("FooterBackGraphicFilter");
                aSet.insert("FooterBackGraphicLocation");
                aSet.insert("FooterBackGraphicTransparency");
                return aSet;
            }
        };
        struct theParaSet :
            public rtl::StaticWithInit<OldFillStyleDefinitionSet, theParaSet>
        {
            OldFillStyleDefinitionSet operator () ()
            {
                OldFillStyleDefinitionSet aSet;
                // Caution: here it is *not* 'ParaBackColorRGB' as it should be, but indeed
                // 'ParaBackColor' is used, see aXMLParaPropMap definition (line 313)
                aSet.insert("ParaBackColor");
                aSet.insert("ParaBackTransparent");
                aSet.insert("ParaBackGraphicLocation");
                aSet.insert("ParaBackGraphicFilter");
                aSet.insert("ParaBackGraphic");

                // These are not used in aXMLParaPropMap definition, thus not needed here
                // aSet.insert("ParaBackColorTransparency");
                // aSet.insert("ParaBackGraphicTransparency");
                return aSet;
            }
        };
    }

    static const OUStringLiteral gsIsPhysical(  "IsPhysical"  );
    static const OUStringLiteral gsFollowStyle(  "FollowStyle"  );

    XMLPropStyleContext::XMLPropStyleContext( SvXMLImport& rImport,
            sal_uInt16 nPrfx, const OUString& rLName,
            const Reference< XAttributeList > & xAttrList,
            SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
            bool bDefault )
    :   SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, nFamily, bDefault )
    ,   mxStyles( &rStyles )
    {
    }

    XMLPropStyleContext::~XMLPropStyleContext()
    {
    }

    const OldFillStyleDefinitionSet& XMLPropStyleContext::getStandardSet()
    {
        return theStandardSet::get();
    }

    const OldFillStyleDefinitionSet& XMLPropStyleContext::getHeaderSet()
    {
        return theHeaderSet::get();
    }

    const OldFillStyleDefinitionSet& XMLPropStyleContext::getFooterSet()
    {
        return theFooterSet::get();
    }

    SvXMLImportContextRef XMLPropStyleContext::CreateChildContext(
            sal_uInt16 nPrefix,
            const OUString& rLocalName,
            const Reference< XAttributeList > & xAttrList )
    {
        SvXMLImportContextRef xContext;

        sal_uInt32 nFamily = 0;
        if( XML_NAMESPACE_STYLE == nPrefix || XML_NAMESPACE_LO_EXT == nPrefix )
        {
            if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
                nFamily = XML_TYPE_PROP_GRAPHIC;
            else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_DRAWING_PAGE;
            else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_TEXT;
            else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_PARAGRAPH;
            else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_RUBY;
            else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_SECTION;
            else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_TABLE;
            else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_TABLE_COLUMN;
            else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_TABLE_ROW;
            else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES )  )
                nFamily = XML_TYPE_PROP_TABLE_CELL;
            else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
                nFamily = XML_TYPE_PROP_CHART;
        }
        if( nFamily )
        {
            rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
                static_cast<SvXMLStylesContext *>(mxStyles.get())->GetImportPropertyMapper(
                                                            GetFamily() );
            if( xImpPrMap.is() )
                xContext = new SvXMLPropertySetContext( GetImport(), nPrefix,
                                                        rLocalName, xAttrList,
                                                        nFamily,
                                                        maProperties,
                                                        xImpPrMap );
        }

        if (!xContext)
            xContext = SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName,
                                                              xAttrList );

        return xContext;
    }

    void XMLPropStyleContext::FillPropertySet(
                const Reference< XPropertySet > & rPropSet )
    {
        rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
            static_cast<SvXMLStylesContext *>(mxStyles.get())->GetImportPropertyMapper(
                                                                    GetFamily() );
        SAL_WARN_IF( !xImpPrMap.is(), "xmloff", "There is the import prop mapper" );
        if( xImpPrMap.is() )
            xImpPrMap->FillPropertySet( maProperties, rPropSet );
    }

    void XMLPropStyleContext::SetDefaults()
    {
    }

    Reference < XStyle > XMLPropStyleContext::Create()
    {
        Reference < XStyle > xNewStyle;

        OUString sServiceName(
            static_cast<SvXMLStylesContext *>(mxStyles.get())->GetServiceName( GetFamily() ) );
        if( !sServiceName.isEmpty() )
        {
            Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
                                                        UNO_QUERY );
            if( xFactory.is() )
            {
                Reference < XInterface > xIfc =
                    xFactory->createInstance( sServiceName );
                if( xIfc.is() )
                    xNewStyle.set( xIfc, UNO_QUERY );
            }
        }

        return xNewStyle;
    }

    void XMLPropStyleContext::CreateAndInsert( bool bOverwrite )
    {
        SvXMLStylesContext* pSvXMLStylesContext = static_cast< SvXMLStylesContext* >(mxStyles.get());
        rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap = pSvXMLStylesContext->GetImportPropertyMapper(GetFamily());
        OSL_ENSURE(xImpPrMap.is(), "There is no import prop mapper");

        // need to filter out old fill definitions when the new ones are used. The new
        // ones are used when a FillStyle is defined
        const bool bTakeCareOfDrawingLayerFillStyle(xImpPrMap.is() && GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH);
        bool bDrawingLayerFillStylesUsed(false);

        if(bTakeCareOfDrawingLayerFillStyle)
        {
            // check if new FillStyles are used and if so mark old ones with -1
            static ::rtl::OUString s_FillStyle("FillStyle");

            if(doNewDrawingLayerFillStyleDefinitionsExist(s_FillStyle))
            {
                deactivateOldFillStyleDefinitions(theParaSet::get());
                bDrawingLayerFillStylesUsed = true;
            }
        }

        if( pSvXMLStylesContext->IsAutomaticStyle()
            && ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT || GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) )
        {
            // Need to translate StyleName from temp MapNames to names
            // used in already imported items (already exist in the pool). This
            // is required for AutomaticStyles since these do *not* use FillPropertySet
            // and thus just trigger CheckSpecialContext in XMLTextStyleContext::FillPropertySet
            // (which may be double action anyways). The mechanism there to use _ContextID_Index_Pair
            // is not working for AutomaticStyles and is already too late, too (this
            // method is already called before XMLTextStyleContext::FillPropertySet gets called)
            if(bDrawingLayerFillStylesUsed)
            {
                translateNameBasedDrawingLayerFillStyleDefinitionsToStyleDisplayNames();
            }

            Reference < XAutoStyleFamily > xAutoFamily = pSvXMLStylesContext->GetAutoStyles( GetFamily() );
            if( !xAutoFamily.is() )
                return;
            if( xImpPrMap.is() )
            {
                Sequence< PropertyValue > aValues;
                xImpPrMap->FillPropertySequence( maProperties, aValues );

                sal_Int32 nLen = aValues.getLength();
                if( nLen )
                {
                    if( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
                    {
                        aValues.realloc( nLen + 2 );
                        PropertyValue *pProps = aValues.getArray() + nLen;
                        pProps->Name = "ParaStyleName";
                        OUString sParent( GetParentName() );
                        if( !sParent.isEmpty() )
                        {
                            sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent );
                            Reference < XNameContainer > xFamilies = pSvXMLStylesContext->GetStylesContainer( GetFamily() );
                            if(xFamilies.is() && xFamilies->hasByName( sParent ) )
                            {
                                css::uno::Reference< css::style::XStyle > xStyle;
                                Any aAny = xFamilies->getByName( sParent );
                                aAny >>= xStyle;
                                sParent = xStyle->getName() ;
                            }
                        }
                        else
                            sParent = "Standard";
                        pProps->Value <<= sParent;
                        ++pProps;
                        pProps->Name = "ParaConditionalStyleName";
                        pProps->Value <<= sParent;
                    }

                    Reference < XAutoStyle > xAutoStyle = xAutoFamily->insertStyle( aValues );
                    if( xAutoStyle.is() )
                    {
                        Sequence< OUString > aPropNames(1);
                        aPropNames[0] = GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ?
                            OUString("ParaAutoStyleName") :
                            OUString("CharAutoStyleName");
                        Sequence< Any > aAny = xAutoStyle->getPropertyValues( aPropNames );
                        if( aAny.hasElements() )
                        {
                            OUString aName;
                            aAny[0] >>= aName;
                            SetAutoName( aName );
                        }
                    }
                }
            }
        }
        else
        {
            const OUString& rName = GetDisplayName();
            if( rName.isEmpty() || IsDefaultStyle() )
                return;

            Reference < XNameContainer > xFamilies = pSvXMLStylesContext->GetStylesContainer( GetFamily() );
            if( !xFamilies.is() )
            {
                SAL_WARN("xmloff", "no styles container for family " << GetFamily());
                return;
            }

            bool bNew = false;
            if( xFamilies->hasByName( rName ) )
            {
                Any aAny = xFamilies->getByName( rName );
                aAny >>= mxStyle;
            }
            else
            {
                mxStyle = Create();
                if( !mxStyle.is() )
                    return;

                xFamilies->insertByName( rName, Any(mxStyle) );
                bNew = true;
            }

            Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY );
            Reference< XPropertySetInfo > xPropSetInfo =
                        xPropSet->getPropertySetInfo();
            if( !bNew && xPropSetInfo->hasPropertyByName( gsIsPhysical ) )
            {
                Any aAny = xPropSet->getPropertyValue( gsIsPhysical );
                bNew = !*o3tl::doAccess<bool>(aAny);
            }
            SetNew( bNew );
            if( rName != GetName() )
                GetImport().AddStyleDisplayName( GetFamily(), GetName(), rName );

            if( bOverwrite || bNew )
            {
                rtl::Reference < XMLPropertySetMapper > xPrMap;
                if( xImpPrMap.is() )
                    xPrMap = xImpPrMap->getPropertySetMapper();
                if( xPrMap.is() )
                {
                    Reference < XMultiPropertyStates > xMultiStates( xPropSet,
                                                                     UNO_QUERY );
                    if( xMultiStates.is() )
                    {
                        xMultiStates->setAllPropertiesToDefault();
                    }
                    else
                    {
                        std::set < OUString > aNameSet;
                        sal_Int32 nCount = xPrMap->GetEntryCount();
                        sal_Int32 i;
                        for( i = 0; i < nCount; i++ )
                        {
                            const OUString& rPrName = xPrMap->GetEntryAPIName( i );
                            if( xPropSetInfo->hasPropertyByName( rPrName ) )
                                aNameSet.insert( rPrName );
                        }
                        Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
                        if (xPropState.is())
                        {
                            nCount = aNameSet.size();
                            Sequence<OUString> aNames( comphelper::containerToSequence(aNameSet) );
                            Sequence < PropertyState > aStates( xPropState->getPropertyStates(aNames) );
                            const PropertyState *pStates = aStates.getConstArray();
                            OUString* pNames = aNames.getArray();

                            for( i = 0; i < nCount; i++ )
                            {
                                if( PropertyState_DIRECT_VALUE == *pStates++ )
                                    xPropState->setPropertyToDefault( pNames[i] );
                            }
                        }
                    }
                }

                if (mxStyle.is())
                    mxStyle->setParentStyle(OUString());

                FillPropertySet( xPropSet );
            }
            else
            {
                SetValid( false );
            }
        }
    }

    void XMLPropStyleContext::Finish( bool bOverwrite )
    {
        if( !mxStyle.is() || !(IsNew() || bOverwrite) )
            return;

        // The families container must exist
        Reference < XNameContainer > xFamilies =
            static_cast<SvXMLStylesContext *>(mxStyles.get())->GetStylesContainer( GetFamily() );
        SAL_WARN_IF( !xFamilies.is(), "xmloff", "Families lost" );
        if( !xFamilies.is() )
            return;

        // connect parent
        OUString sParent( GetParentName() );
        if( !sParent.isEmpty() )
            sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent );
        if( !sParent.isEmpty() && !xFamilies->hasByName( sParent ) )
            sParent.clear();

        if( sParent != mxStyle->getParentStyle() )
        {
            // this may except if setting the parent style forms a
            // circle in the style dependencies; especially if the parent
            // style is the same as the current style
            try
            {
                mxStyle->setParentStyle( sParent );
            }
            catch(const uno::Exception& e)
            {
                // according to the API definition, I would expect a
                // container::NoSuchElementException. But it throws an
                // uno::RuntimeException instead. I catch
                // uno::Exception in order to process both of them.

                // We can't set the parent style. For a proper
                // Error-Message, we should pass in the name of the
                // style, as well as the desired parent style.
                Sequence<OUString> aSequence(2);

                // getName() throws no non-Runtime exception:
                aSequence[0] = mxStyle->getName();
                aSequence[1] = sParent;

                GetImport().SetError(
                    XMLERROR_FLAG_ERROR | XMLERROR_PARENT_STYLE_NOT_ALLOWED,
                    aSequence, e.Message, nullptr );
            }
        }

        // connect follow
        OUString sFollow( GetFollow() );
        if( !sFollow.isEmpty() )
            sFollow = GetImport().GetStyleDisplayName( GetFamily(), sFollow );
        if( sFollow.isEmpty() || !xFamilies->hasByName( sFollow ) )
            sFollow = mxStyle->getName();

        Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY );
        Reference< XPropertySetInfo > xPropSetInfo =
            xPropSet->getPropertySetInfo();
        if( xPropSetInfo->hasPropertyByName( gsFollowStyle ) )
        {
            Any aAny = xPropSet->getPropertyValue( gsFollowStyle );
            OUString sCurrFollow;
            aAny >>= sCurrFollow;
            if( sCurrFollow != sFollow )
            {
                xPropSet->setPropertyValue( gsFollowStyle, Any(sFollow) );
            }
        }

        if ( xPropSetInfo->hasPropertyByName( "Hidden" ) )
        {
            xPropSet->setPropertyValue( "Hidden", uno::makeAny( IsHidden( ) ) );
        }

    }

    bool XMLPropStyleContext::doNewDrawingLayerFillStyleDefinitionsExist(
        const OUString& rFillStyleTag) const
    {
        if(maProperties.size() && rFillStyleTag.getLength())
        {
            const rtl::Reference< XMLPropertySetMapper >& rMapper = GetStyles()->GetImportPropertyMapper(GetFamily())->getPropertySetMapper();

            if(rMapper.is())
            {
                for(::std::vector< XMLPropertyState >::const_iterator a = maProperties.begin(); a != maProperties.end(); ++a)
                {
                    if(a->mnIndex != -1)
                    {
                        const OUString& rPropName = rMapper->GetEntryAPIName(a->mnIndex);

                        if(rPropName == rFillStyleTag)
                        {
                            FillStyle eFillStyle(FillStyle_NONE);

                            if(a->maValue >>= eFillStyle)
                            {
                                // okay, type was good, FillStyle is set
                            }
                            else
                            {
                                // also try an int (see XFillStyleItem::PutValue)
                                sal_Int32 nFillStyle(0);

                                if(a->maValue >>= nFillStyle)
                                {
                                    eFillStyle = static_cast< FillStyle >(nFillStyle);
                                }
                            }

                            // we found the entry, check it
                            return FillStyle_NONE != eFillStyle;
                        }
                    }
                }
            }
        }

        return false;
    }

    void XMLPropStyleContext::deactivateOldFillStyleDefinitions(
        const OldFillStyleDefinitionSet& rHashSetOfTags)
    {
        if(!rHashSetOfTags.empty() && maProperties.size())
        {
            const rtl::Reference< XMLPropertySetMapper >& rMapper = GetStyles()->GetImportPropertyMapper(GetFamily())->getPropertySetMapper();

            if(rMapper.is())
            {
                for(::std::vector< XMLPropertyState >::iterator a = maProperties.begin(); a != maProperties.end(); ++a)
                {
                    if(a->mnIndex != -1)
                    {
                        const OUString& rPropName = rMapper->GetEntryAPIName(a->mnIndex);

                        if(rHashSetOfTags.find(rPropName) != rHashSetOfTags.end())
                        {
                            // mark entry as inactive
                            a->mnIndex = -1;
                        }
                    }
                }
            }
        }
    }

    void XMLPropStyleContext::translateNameBasedDrawingLayerFillStyleDefinitionsToStyleDisplayNames()
    {
        if(maProperties.size())
        {
            const rtl::Reference< XMLPropertySetMapper >& rMapper = GetStyles()->GetImportPropertyMapper(GetFamily())->getPropertySetMapper();

            if(rMapper.is())
            {
                static OUString s_FillGradientName("FillGradientName");
                static OUString s_FillHatchName("FillHatchName");
                static OUString s_FillBitmapName("FillBitmapName");
                static OUString s_FillTransparenceGradientName("FillTransparenceGradientName");

                for(::std::vector< XMLPropertyState >::iterator a = maProperties.begin(); a != maProperties.end(); ++a)
                {
                    if(a->mnIndex != -1)
                    {
                        const OUString& rPropName = rMapper->GetEntryAPIName(a->mnIndex);
                        sal_uInt16 aStyleFamily(0);

                        if(rPropName == s_FillGradientName || rPropName == s_FillTransparenceGradientName)
                        {
                            aStyleFamily = XML_STYLE_FAMILY_SD_GRADIENT_ID;
                        }
                        else if(rPropName == s_FillHatchName)
                        {
                            aStyleFamily = XML_STYLE_FAMILY_SD_HATCH_ID;
                        }
                        else if(rPropName == s_FillBitmapName)
                        {
                            aStyleFamily = XML_STYLE_FAMILY_SD_FILL_IMAGE_ID;
                        }

                        if(aStyleFamily)
                        {
                            OUString sStyleName;

                            a->maValue >>= sStyleName;
                            sStyleName = GetImport().GetStyleDisplayName( aStyleFamily, sStyleName );
                            a->maValue <<= sStyleName;
                        }
                    }
                }
            }
        }
    }

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V547 Expression 'FillStyle_NONE != eFillStyle' is always false.