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

#include "PageMasterImportContext.hxx"
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "PageMasterPropHdl.hxx"
#include "PagePropertySetContext.hxx"
#include "PageHeaderFooterContext.hxx"
#include "PageMasterPropMapper.hxx"
#include "PageMasterImportPropMapper.hxx"
#include <xmloff/PageMasterStyleMap.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>

//UUUU
#include <xmlsdtypes.hxx>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <xmloff/xmlerror.hxx>

using namespace ::com::sun::star;
using namespace ::xmloff::token;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;

//UUUU
using namespace ::com::sun::star::beans;

void PageStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
                                        const rtl::OUString& rLocalName,
                                        const rtl::OUString& rValue )
{
    // TODO: use a map here
    if( XML_NAMESPACE_STYLE == nPrefixKey && IsXMLToken( rLocalName, XML_PAGE_USAGE ) )
    {
        sPageUsage = rValue;
    }
    else
    {
        XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
    }
}

TYPEINIT1( PageStyleContext, XMLPropStyleContext );

PageStyleContext::PageStyleContext( SvXMLImport& rImport,
        sal_uInt16 nPrfx, const rtl::OUString& rLName,
        const uno::Reference< xml::sax::XAttributeList > & xAttrList,
        SvXMLStylesContext& rStyles,
        sal_Bool bDefaultStyle) :
    XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, XML_STYLE_FAMILY_PAGE_MASTER, bDefaultStyle),
    sPageUsage(),
    m_bIsFillStyleAlreadyConverted(false) //UUUU
{
}

PageStyleContext::~PageStyleContext()
{
}

SvXMLImportContext *PageStyleContext::CreateChildContext(
        sal_uInt16 nPrefix,
        const rtl::OUString& rLocalName,
        const uno::Reference< xml::sax::XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = NULL;

    if( XML_NAMESPACE_STYLE == nPrefix &&
        ((IsXMLToken(rLocalName, XML_HEADER_STYLE )) ||
         (IsXMLToken(rLocalName, XML_FOOTER_STYLE )) ) )
    {
        sal_Bool bHeader = IsXMLToken(rLocalName, XML_HEADER_STYLE);
        UniReference < SvXMLImportPropertyMapper > xImpPrMap =
            GetStyles()->GetImportPropertyMapper( GetFamily() );
        if( xImpPrMap.is() )
        {
            const UniReference< XMLPropertySetMapper >& rMapper = xImpPrMap->getPropertySetMapper();
            sal_Int32 nFlag;
            if (bHeader)
                nFlag = CTF_PM_HEADERFLAG;
            else
                nFlag = CTF_PM_FOOTERFLAG;
            sal_Int32 nStartIndex (-1);
            sal_Int32 nEndIndex (-1);
            sal_Bool bFirst(sal_False);
            sal_Bool bEnd(sal_False);
            sal_Int32 nIndex = 0;
            while ( nIndex < rMapper->GetEntryCount() && !bEnd)
            {
                if ((rMapper->GetEntryContextId( nIndex ) & CTF_PM_FLAGMASK) == nFlag)
                {
                    if (!bFirst)
                    {
                        bFirst = sal_True;
                        nStartIndex = nIndex;
                    }
                }
                else if (bFirst)
                {
                    bEnd = sal_True;
                    nEndIndex = nIndex;
                }
                nIndex++;
            }
            if (!bEnd)
                nEndIndex = nIndex;
            pContext = new PageHeaderFooterContext(GetImport(), nPrefix, rLocalName,
                            xAttrList, GetProperties(), xImpPrMap, nStartIndex, nEndIndex, bHeader);
        }
    }
    if( XML_NAMESPACE_STYLE == nPrefix && 
        IsXMLToken(rLocalName, XML_PAGE_LAYOUT_PROPERTIES) )
    {
        UniReference < SvXMLImportPropertyMapper > xImpPrMap =
            GetStyles()->GetImportPropertyMapper( GetFamily() );
        if( xImpPrMap.is() )
        {
            const UniReference< XMLPropertySetMapper >& rMapper = xImpPrMap->getPropertySetMapper();
            sal_Int32 nEndIndex (-1);
            sal_Bool bEnd(sal_False);
            sal_Int32 nIndex = 0;
            sal_Int16 nContextID;
            while ( nIndex < rMapper->GetEntryCount() && !bEnd)
            {
                nContextID = rMapper->GetEntryContextId( nIndex );
                if (nContextID && ((nContextID & CTF_PM_FLAGMASK) != XML_PM_CTF_START))
                {
                    nEndIndex = nIndex;
                    bEnd = sal_True;
                }
                nIndex++;
            }
            if (!bEnd)
                nEndIndex = nIndex;
            PageContextType aType = Page;
            pContext = new PagePropertySetContext( GetImport(), nPrefix,
                                                    rLocalName, xAttrList,
													XML_TYPE_PROP_PAGE_LAYOUT,
                                                    GetProperties(),
                                                    xImpPrMap, 0, nEndIndex, aType);
        }
    }

    if (!pContext)
        pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
                                                           xAttrList );
    return pContext;
}

void PageStyleContext::FillPropertySet(const uno::Reference<beans::XPropertySet > & rPropSet)
{
    //UUUU need to filter out old fill definitions when the new ones are used. The new
    // ones are used when a FillStyle is defined
    if(!m_bIsFillStyleAlreadyConverted && GetProperties().size())
    {
        static ::rtl::OUString s_FillStyle(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
        static ::rtl::OUString s_HeaderFillStyle(RTL_CONSTASCII_USTRINGPARAM("HeaderFillStyle"));
        static ::rtl::OUString s_FooterFillStyle(RTL_CONSTASCII_USTRINGPARAM("FooterFillStyle"));

        if(doNewDrawingLayerFillStyleDefinitionsExist(s_FillStyle))
        {
            deactivateOldFillStyleDefinitions(getStandardSet());
        }

        if(doNewDrawingLayerFillStyleDefinitionsExist(s_HeaderFillStyle))
        {
            deactivateOldFillStyleDefinitions(getHeaderSet());
        }

        if(doNewDrawingLayerFillStyleDefinitionsExist(s_FooterFillStyle))
        {
            deactivateOldFillStyleDefinitions(getFooterSet());
        }

        m_bIsFillStyleAlreadyConverted = true;
    }

    //UUUU do not use XMLPropStyleContext::FillPropertySet, we need to handle this ourselves since
    // we have properties which use the MID_FLAG_NO_PROPERTY_IMPORT flag since they need some special
    // handling
    UniReference < SvXMLImportPropertyMapper > xImpPrMap = GetStyles()->GetImportPropertyMapper(GetFamily());

    if(xImpPrMap.is())
    {
        // properties that need special handling because they need the used name to be translated first
        struct _ContextID_Index_Pair aContextIDs[] =
        {
            { CTF_PM_FILLGRADIENTNAME, -1 },
            { CTF_PM_FILLTRANSNAME, -1 },
            { CTF_PM_FILLHATCHNAME, -1 },
            { CTF_PM_FILLBITMAPNAME, -1 },

            // also need to special handling for header entries
            { CTF_PM_HEADERFILLGRADIENTNAME, -1 },
            { CTF_PM_HEADERFILLTRANSNAME, -1 },
            { CTF_PM_HEADERFILLHATCHNAME, -1 },
            { CTF_PM_HEADERFILLBITMAPNAME, -1 },

            // also need to special handling for footer entries
            { CTF_PM_FOOTERFILLGRADIENTNAME, -1 },
            { CTF_PM_FOOTERFILLTRANSNAME, -1 },
            { CTF_PM_FOOTERFILLHATCHNAME, -1 },
            { CTF_PM_FOOTERFILLBITMAPNAME, -1 },

            {-1, -1}
        };

        // the style families associated with the same index modulo 4
        static sal_uInt16 aFamilies[] =
        {
            XML_STYLE_FAMILY_SD_GRADIENT_ID,
            XML_STYLE_FAMILY_SD_GRADIENT_ID,
            XML_STYLE_FAMILY_SD_HATCH_ID,
            XML_STYLE_FAMILY_SD_FILL_IMAGE_ID
        };

        //UUUU Fill PropertySet, but let it handle special properties not itself
        xImpPrMap->FillPropertySet(GetProperties(), rPropSet, aContextIDs);

        // get property set mapper
        const UniReference< XMLPropertySetMapper >& rMapper = xImpPrMap->getPropertySetMapper();
        Reference< XPropertySetInfo > xInfo;

        //UUUU handle special attributes which have MID_FLAG_NO_PROPERTY_IMPORT set
        for(sal_uInt16 i = 0; aContextIDs[i].nContextID != -1; i++)
        {
            sal_Int32 nIndex = aContextIDs[i].nIndex;

            if(nIndex != -1) 
            {
                switch(aContextIDs[i].nContextID)
                {
                    case CTF_PM_FILLGRADIENTNAME:
                    case CTF_PM_FILLTRANSNAME:
                    case CTF_PM_FILLHATCHNAME:
                    case CTF_PM_FILLBITMAPNAME:

                    case CTF_PM_HEADERFILLGRADIENTNAME:
                    case CTF_PM_HEADERFILLTRANSNAME:
                    case CTF_PM_HEADERFILLHATCHNAME:
                    case CTF_PM_HEADERFILLBITMAPNAME:

                    case CTF_PM_FOOTERFILLGRADIENTNAME:
                    case CTF_PM_FOOTERFILLTRANSNAME:
                    case CTF_PM_FOOTERFILLHATCHNAME:
                    case CTF_PM_FOOTERFILLBITMAPNAME:
                    {
                        struct XMLPropertyState& rState = GetProperties()[nIndex];
                        rtl::OUString sStyleName;
                        rState.maValue >>= sStyleName;

                        //UUUU translate the used name from ODF intern to the name used in the Model
                        sStyleName = GetImport().GetStyleDisplayName(aFamilies[i%4], sStyleName);

                        try
                        {
                            // set property
                            const rtl::OUString& rPropertyName = rMapper->GetEntryAPIName(rState.mnIndex);

                            if(!xInfo.is())
                            {
                                xInfo = rPropSet->getPropertySetInfo();
                            }

                            if(xInfo->hasPropertyByName(rPropertyName))
                            {
                                rPropSet->setPropertyValue(rPropertyName,Any(sStyleName));
                            }
                        }
                        catch(::com::sun::star::lang::IllegalArgumentException& e)
                        {
                            Sequence< rtl::OUString > aSeq(1);
                            aSeq[0] = sStyleName;
                            GetImport().SetError(
                                XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
                                aSeq,e.Message,NULL);
                        }
                        break;
                    }
                }
            }
        }
    }
    else
    {
        OSL_ENSURE(xImpPrMap.is(), "Got no SvXMLImportPropertyMapper (!)");
    }

    //UUUU old code, replaced by above stuff
    // XMLPropStyleContext::FillPropertySet(rPropSet);

    if (sPageUsage.getLength())
    {
        uno::Any aPageUsage;
        XMLPMPropHdl_PageStyleLayout aPageUsageHdl;
        if (aPageUsageHdl.importXML(sPageUsage, aPageUsage, GetImport().GetMM100UnitConverter()))
            rPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageStyleLayout")), aPageUsage);
    }
}

// text grid enhancement for better CJK support
//set default page layout style
void PageStyleContext::SetDefaults( )
{
	Reference < XMultiServiceFactory > xFactory ( GetImport().GetModel(), UNO_QUERY);
	if (xFactory.is())
	{
		Reference < XInterface > xInt = xFactory->createInstance (
	    rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.text.Defaults" ) ) );
	    Reference < beans::XPropertySet > xProperties ( xInt, UNO_QUERY );
	    if ( xProperties.is() )
	    	FillPropertySet ( xProperties );
	}
}

//eof
