/**************************************************************
 * 
 * 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 <tools/debug.hxx>
#ifndef _SVSTDARR_STRINGSSORTDTOR_DECL
#define _SVSTDARR_STRINGSSORTDTOR
#include <svl/svstdarr.hxx>
#endif
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#ifndef _XMLOFF_XMLITMAP_HXX
//#include "xmlitmap.hxx"
#endif
#include <xmloff/xmluconv.hxx>
#include <xmloff/attrlist.hxx>
#include <xmloff/xmlprmap.hxx>
#include <xmloff/xmlexppr.hxx>
#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
#include <com/sun/star/document/XEventsSupplier.hpp>
#endif
#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
#include <xmloff/xmlaustp.hxx>
#ifndef _XMLOFF_STYLEEXP_HXX
#include <xmloff/styleexp.hxx>
#endif
#include <xmloff/xmlexp.hxx>
#include <xmloff/XMLEventExport.hxx>

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;

using ::com::sun::star::document::XEventsSupplier;

XMLStyleExport::XMLStyleExport(
		SvXMLExport& rExp,
		const ::rtl::OUString& rPoolStyleName,
		SvXMLAutoStylePoolP *pAutoStyleP ) :
	rExport( rExp ),
	sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
	sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) ),
	sFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) ),
	sNumberingStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyleName" ) ),
	sOutlineLevel( RTL_CONSTASCII_USTRINGPARAM( "OutlineLevel" ) ),//#outline level,add by zhaojianwei
	sPoolStyleName( rPoolStyleName ),
	pAutoStylePool( pAutoStyleP  )
{
}

XMLStyleExport::~XMLStyleExport()
{
}

void XMLStyleExport::exportStyleAttributes( const Reference< XStyle >& )
{
}

void XMLStyleExport::exportStyleContent( const Reference< XStyle >& )
{
}

sal_Bool XMLStyleExport::exportStyle(
		const Reference< XStyle >& rStyle,
	  	const OUString& rXMLFamily,
		const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
		const Reference< XNameAccess >& xStyles,		//#outline level,add by zhaojianwei
		const OUString* pPrefix )
{
	Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo =
			xPropSet->getPropertySetInfo();
	Any aAny;

	// Don't export styles that aren't existing really. This may be the
	// case for StarOffice Writer's pool styles.
	if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
	{
		aAny = xPropSet->getPropertyValue( sIsPhysical );
		if( !*(sal_Bool *)aAny.getValue() )
			return sal_False;
	}

	// <style:style ...>
	GetExport().CheckAttrList();

	// style:name="..."
	OUString sName;

	if(pPrefix)
		sName = *pPrefix;
	sName += rStyle->getName();

	sal_Bool bEncoded = sal_False;
	const OUString sEncodedStyleName(GetExport().EncodeStyleName( sName, &bEncoded ));
	GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sEncodedStyleName );

	if( bEncoded )
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
							  	 sName);

	// style:family="..."
	if( rXMLFamily.getLength() > 0 )
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, rXMLFamily);

	// style:parent-style-name="..."
	OUString sParentString(rStyle->getParentStyle());
	OUString sParent;

	if(sParentString.getLength())
	{
		if(pPrefix)
			sParent = *pPrefix;
		sParent += sParentString;
	}
	else
		sParent = sPoolStyleName;

	if( sParent.getLength() )
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
					  			  GetExport().EncodeStyleName( sParent ) );

	// style:next-style-name="..." (paragraph styles only)
	if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
	{
		aAny = xPropSet->getPropertyValue( sFollowStyle );
		OUString sNextName;
		aAny >>= sNextName;
		if( sName != sNextName )
		{
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME,
						  GetExport().EncodeStyleName( sNextName ) );
		}
	}

	// style:auto-update="..." (SW only)
	if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) )
	{
		aAny = xPropSet->getPropertyValue( sIsAutoUpdate );
		if( *(sal_Bool *)aAny.getValue() )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_AUTO_UPDATE,
                                      XML_TRUE );
	}

	// style:default-outline-level"..." //#outline level, add by zhaojianwei.0802
	sal_Int32 nOutlineLevel = 0;
	if( xPropSetInfo->hasPropertyByName( sOutlineLevel ) )
	{
		Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
		if( PropertyState_DIRECT_VALUE == xPropState->getPropertyState( sOutlineLevel ) )
		{
			aAny = xPropSet->getPropertyValue( sOutlineLevel );
			aAny >>= nOutlineLevel;
			if( nOutlineLevel > 0 )
			{
				OUStringBuffer sTmp;
				sTmp.append( static_cast<sal_Int32>(nOutlineLevel));
				GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                          XML_DEFAULT_OUTLINE_LEVEL,
                                          sTmp.makeStringAndClear() );
			}
			else
			{
                // --> OD 2009-12-29 #i104889#
                // empty value for style:default-outline-level does exist
                // since ODF 1.2. Thus, suppress its export for former versions.
                if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) != 0 &&
                     GetExport().getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
                // <--
                {
                    GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                              XML_DEFAULT_OUTLINE_LEVEL,
                                              OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
                }
			}
		}
	}//<-end,zhaojianwei

	// style:list-style-name="..." (SW paragarph styles only)
	if( xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
	{
		Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
		if( PropertyState_DIRECT_VALUE ==
				xPropState->getPropertyState( sNumberingStyleName  ) )
		{
			aAny = xPropSet->getPropertyValue( sNumberingStyleName );
			if( aAny.hasValue() )
			{
				OUString sListName;
				aAny >>= sListName;

                // --> OD 2006-09-21 #i69523#
                // An direct set empty list style has to be written. Otherwise,
                // this information is lost and causes an error, if the parent
                // style has a list style set.
                if ( !sListName.getLength() )
                {
                    GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                              XML_LIST_STYLE_NAME,
                                              sListName /* empty string */);
                }
                else
                {
                    // --> OD 2006-09-27 #i69627#
                    bool bSuppressListStyle( false );
                    {
                        if ( !GetExport().writeOutlineStyleAsNormalListStyle() )
                        {
                            Reference< XChapterNumberingSupplier > xCNSupplier
                                (GetExport().GetModel(), UNO_QUERY);

                            OUString sOutlineName;
                            if (xCNSupplier.is())
                            {
                                Reference< XIndexReplace > xNumRule
                                    ( xCNSupplier->getChapterNumberingRules() );
                                DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );

                                if (xNumRule.is())
                                {
                                    Reference< XPropertySet > xNumRulePropSet
                                        (xNumRule, UNO_QUERY);
                                    xNumRulePropSet->getPropertyValue(
                                        OUString(RTL_CONSTASCII_USTRINGPARAM("Name")) )
                                        >>= sOutlineName;
                                    bSuppressListStyle = ( sListName == sOutlineName );
                                }
                            }
                        }
                    }

                    if ( sListName.getLength() && !bSuppressListStyle )
                    // <--
                    {
                        GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                                  XML_LIST_STYLE_NAME,
                                  GetExport().EncodeStyleName( sListName ) );
                    }
                }
                // <--
			}
		}
		//#outline level, add by zhaojianwei.0802
		else if( nOutlineLevel > 0 )
		{

			bool bNoInheritedListStyle( true );

			/////////////////////////////////////////////////
			Reference<XStyle> xStyle( xPropState, UNO_QUERY );
			while ( xStyle.is() )
			{
				OUString aParentStyle( xStyle->getParentStyle() );
				if ( aParentStyle.getLength() == 0 ||
					!xStyles->hasByName( aParentStyle ) )
				{
					break;
				}
				else
				{
					xPropState = Reference< XPropertyState >( xStyles->getByName( aParentStyle ), UNO_QUERY );
					if ( !xPropState.is() )
					{
						break;
					}
					if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
					{
						bNoInheritedListStyle = false;
						break;
					}
					else
					{
						xStyle = Reference<XStyle>( xPropState, UNO_QUERY );
					}
				}
			}
			/////////////////////////////////////////////////
			if ( bNoInheritedListStyle )
                GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                          XML_LIST_STYLE_NAME,
                                          OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
		}
		//<-end,zhaojianwei
	}


	// style:pool-id="..." is not required any longer since we use
	// english style names only
	exportStyleAttributes( rStyle );

	// TODO: style:help-file-name="..." and style:help-id="..." can neither
	// be modified by UI nor by API and that for, have not to be exported
	// currently.

	{
		// <style:style>
		SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_STYLE,
								  sal_True, sal_True );

		rPropMapper->SetStyleName( sName );

		// <style:properties>
		::std::vector< XMLPropertyState > xPropStates =
			rPropMapper->Filter( xPropSet );
		rPropMapper->exportXML( GetExport(), xPropStates,
                                XML_EXPORT_FLAG_IGN_WS );

		rPropMapper->SetStyleName( OUString() );

		exportStyleContent( rStyle );

		// <script:events>, if they are supported by this style
		Reference<XEventsSupplier> xEventsSupp(rStyle, UNO_QUERY);
		GetExport().GetEventExport().Export(xEventsSupp);
	}
	return sal_True;
}

sal_Bool XMLStyleExport::exportDefaultStyle(
		const Reference< XPropertySet >& xPropSet,
	  	const OUString& rXMLFamily,
		const UniReference < SvXMLExportPropertyMapper >& rPropMapper )
{
	Reference< XPropertySetInfo > xPropSetInfo =
			xPropSet->getPropertySetInfo();

	Any aAny;

	// <style:default-style ...>
	GetExport().CheckAttrList();

	{
		// style:family="..."
		if( rXMLFamily.getLength() > 0 )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY,
                                      rXMLFamily );
		// <style:style>
		SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
								  XML_DEFAULT_STYLE,
								  sal_True, sal_True );
		// <style:properties>
		//::std::vector< XMLPropertyState > xPropStates =
		//	rPropMapper->FilterDefaults( xPropSet );
		::std::vector< XMLPropertyState > xPropStates =
			rPropMapper->FilterDefaults( xPropSet );
		rPropMapper->exportXML( GetExport(), xPropStates,
							   	  XML_EXPORT_FLAG_IGN_WS );
//		exportStyleContent( rStyle );
	}
	return sal_True;
}

#if 0
void XMLStyleExport::exportStyleFamily(
	const sal_Char *pFamily,
	const OUString& rXMLFamily,
	const UniReference < XMLPropertySetMapper >& rPropMapper,
	sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
{
	const OUString sFamily(OUString::createFromAscii(pFamily ));
	UniReference < SvXMLExportPropertyMapper > xExpPropMapper =
		new SvXMLExportPropertyMapper( rPropMapper );
	exportStyleFamily( sFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily,
					   pPrefix);
}

void XMLStyleExport::exportStyleFamily(
	const OUString& rFamily, const OUString& rXMLFamily,
	const UniReference < XMLPropertySetMapper >& rPropMapper,
	sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
{
	UniReference < SvXMLExportPropertyMapper > xExpPropMapper =
		new SvXMLExportPropertyMapper( rPropMapper );
	exportStyleFamily( rFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily,
					   pPrefix);
}
#endif

void XMLStyleExport::exportStyleFamily(
	const sal_Char *pFamily,
	const OUString& rXMLFamily,
	const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
	sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
{
	const OUString sFamily(OUString::createFromAscii(pFamily ));
	exportStyleFamily( sFamily, rXMLFamily, rPropMapper, bUsed, nFamily,
					   pPrefix);
}

void XMLStyleExport::exportStyleFamily(
	const OUString& rFamily, const OUString& rXMLFamily,
	const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
	sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
{
	DBG_ASSERT( GetExport().GetModel().is(), "There is the model?" );
	Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY );
	if( !xFamiliesSupp.is() )
		return; // family not available in current model

	Reference< XNameAccess > xStyleCont;

	Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
	if( xFamilies->hasByName( rFamily ) )
		xFamilies->getByName( rFamily ) >>= xStyleCont;

	if( !xStyleCont.is() )
		return;

	Reference< XNameAccess > xStyles( xStyleCont, UNO_QUERY );
   	// If next styles are supported and used styles should be exported only,
	// the next style may be unused but has to be exported, too. In this case
	// the names of all exported styles are remembered.
	SvStringsSortDtor *pExportedStyles = 0;
	sal_Bool bFirstStyle = sal_True;

    const uno::Sequence< ::rtl::OUString> aSeq = xStyles->getElementNames();
    const ::rtl::OUString* pIter = aSeq.getConstArray();
    const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
    for(;pIter != pEnd;++pIter)
    {
		Reference< XStyle > xStyle;
		try
		{
			xStyles->getByName( *pIter ) >>= xStyle;
		}
		catch( lang::IndexOutOfBoundsException )
		{
			// due to bugs in prior versions it is possible that
			// a binary file is missing some critical styles.
			// The only possible way to deal with this is to
			// not export them here and remain silent.
			continue;
		}

		DBG_ASSERT( xStyle.is(), "Style not found for export!" );
		if( xStyle.is() )
		{
			if( !bUsed || xStyle->isInUse() )
			{
				sal_Bool bExported = exportStyle( xStyle, rXMLFamily, rPropMapper,
											  xStyles,pPrefix );
				if( bUsed && bFirstStyle && bExported  )
				{
					// If this is the first style, find out wether next styles
					// are supported.
					Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
					Reference< XPropertySetInfo > xPropSetInfo =
						xPropSet->getPropertySetInfo();

					if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
						pExportedStyles = new SvStringsSortDtor;
					bFirstStyle = sal_False;
				}

				if( pExportedStyles && bExported )
				{
					// If next styles are supported, remember this style's name.
					String *pTmp = new String( xStyle->getName() );
					if( !pExportedStyles->Insert( pTmp ) )
						delete pTmp;
				}
			}

			// if an auto style pool is given, remember this style's name as a
			// style name that must not be used by automatic styles.
			if( pAutoStylePool )
				pAutoStylePool->RegisterName( nFamily, xStyle->getName() );
		}
	}

	if( pExportedStyles )
	{
		// if next styles are supported, export all next styles that are
		// unused and that for, haven't been exported in the first loop.
        pIter = aSeq.getConstArray();
		for(;pIter != pEnd;++pIter)
		{
			Reference< XStyle > xStyle;
			xStyles->getByName( *pIter ) >>= xStyle;

			DBG_ASSERT( xStyle.is(), "Style not found for export!" );
			if( xStyle.is() )
			{
				Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
				Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );

				// styles that aren't existing really are ignored.
				if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
				{
					Any aAny( xPropSet->getPropertyValue( sIsPhysical ) );
					if( !*(sal_Bool *)aAny.getValue() )
						continue;
				}

				if( !xStyle->isInUse() )
					continue;

				if( !xPropSetInfo->hasPropertyByName( sFollowStyle ) )
				{
					DBG_ASSERT( 0==sFollowStyle.getLength(),
								"no follow style???" );
					continue;
				}

				OUString sNextName;
				xPropSet->getPropertyValue( sFollowStyle ) >>= sNextName;
				String sTmp( sNextName );
				// if the next style hasn't been exported by now, export it now
				// and remember its name.
				if( xStyle->getName() != sNextName &&
					!pExportedStyles->Seek_Entry( &sTmp ) )
				{
					xStyleCont->getByName( sNextName ) >>= xStyle;
					DBG_ASSERT( xStyle.is(), "Style not found for export!" );

					if( xStyle.is() && exportStyle( xStyle, rXMLFamily, rPropMapper, xStyles,pPrefix ) )
						pExportedStyles->Insert( new String( sTmp ) );
				}
			}
		}
	}

	delete pExportedStyles;
}


