/**************************************************************
 * 
 * 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 <xmloff/XMLPageExport.hxx>
#include <tools/debug.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#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/container/XIndexReplace.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <xmloff/families.hxx>
#include <xmloff/xmlexp.hxx>
#include "PageMasterPropHdlFactory.hxx"
#ifndef _XMLOFF_PAGEMASTERSTYLEMAP_HXX
#include <xmloff/PageMasterStyleMap.hxx>
#endif
#ifndef _XMLOFF_PAGEMASTERPROPMAPPER_HXX
#include "PageMasterPropMapper.hxx"
#endif
#include "PageMasterExportPropMapper.hxx"
#include "PageMasterExportPropMapper.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 ::xmloff::token;


//______________________________________________________________________________

sal_Bool XMLPageExport::findPageMasterName( const OUString& rStyleName, OUString& rPMName ) const
{
	for( ::std::vector< XMLPageExportNameEntry >::const_iterator pEntry = aNameVector.begin();
			pEntry != aNameVector.end(); pEntry++ )
	{
		if( pEntry->sStyleName == rStyleName )
		{
			rPMName = pEntry->sPageMasterName;
			return sal_True;
		}
	}
	return sal_False;
}

void XMLPageExport::collectPageMasterAutoStyle(
		const Reference < XPropertySet > & rPropSet,
		OUString& rPageMasterName )
{
	DBG_ASSERT( xPageMasterPropSetMapper.is(), "page master family/XMLPageMasterPropSetMapper not found" );
	if( xPageMasterPropSetMapper.is() )
	{
		::std::vector<XMLPropertyState> xPropStates = xPageMasterExportPropMapper->Filter( rPropSet );
		if( !xPropStates.empty())
		{
			OUString sParent;
			rPageMasterName = rExport.GetAutoStylePool()->Find( XML_STYLE_FAMILY_PAGE_MASTER, sParent, xPropStates );
			if (!rPageMasterName.getLength())
				rPageMasterName = rExport.GetAutoStylePool()->Add(XML_STYLE_FAMILY_PAGE_MASTER, sParent, xPropStates);
		}
	}
}

void XMLPageExport::exportMasterPageContent(
				const Reference < XPropertySet > &,
				sal_Bool /*bAutoStyles*/ )
{

}

sal_Bool XMLPageExport::exportStyle(
			const Reference< XStyle >& rStyle,
			sal_Bool bAutoStyles )
{
	Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
	Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();

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

	if( bAutoStyles )
	{
		XMLPageExportNameEntry aEntry;
		collectPageMasterAutoStyle( xPropSet, aEntry.sPageMasterName );
		aEntry.sStyleName = rStyle->getName();
		aNameVector.push_back( aEntry );

		exportMasterPageContent( xPropSet, sal_True );
	}
	else
	{
		OUString sName( rStyle->getName() );
		sal_Bool bEncoded = sal_False;
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
						  GetExport().EncodeStyleName( sName, &bEncoded ) );

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

		OUString sPMName;
		if( findPageMasterName( sName, sPMName ) )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, GetExport().EncodeStyleName( sPMName ) );

        Reference<XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
        if ( xInfo.is() && xInfo->hasPropertyByName(sFollowStyle) )
        {
            OUString sNextName;
		    xPropSet->getPropertyValue( sFollowStyle ) >>= sNextName;
		    
		    if( sName != sNextName && sNextName.getLength() )
		    {
			    GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME,
				    GetExport().EncodeStyleName( sNextName ) );
		    }
        }
//		OUString sPageMaster = GetExport().GetAutoStylePool()->Find(
//											XML_STYLE_FAMILY_PAGE_MASTER,
//											xPropSet );
//		if( sPageMaster.getLength() )
//			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
//									  XML_PAGE_MASTER_NAME,
//									  sPageMaster );

		SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
								  XML_MASTER_PAGE, sal_True, sal_True );

		exportMasterPageContent( xPropSet, sal_False );
	}

	return sal_True;
}

XMLPageExport::XMLPageExport( SvXMLExport& rExp ) :
	rExport( rExp ),
	sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
	sFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) )
{
	xPageMasterPropHdlFactory = new XMLPageMasterPropHdlFactory;
	xPageMasterPropSetMapper = new XMLPageMasterPropSetMapper(
								(XMLPropertyMapEntry*) aXMLPageMasterStyleMap,
								xPageMasterPropHdlFactory  );
	xPageMasterExportPropMapper = new XMLPageMasterExportPropMapper(
									xPageMasterPropSetMapper, rExp);

	rExport.GetAutoStylePool()->AddFamily( XML_STYLE_FAMILY_PAGE_MASTER, OUString( RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_PAGE_MASTER_NAME ) ),
		xPageMasterExportPropMapper, OUString( RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_PAGE_MASTER_PREFIX ) ), sal_False );

	Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(),
													   UNO_QUERY );
	DBG_ASSERT( xFamiliesSupp.is(),
				"No XStyleFamiliesSupplier from XModel for export!" );
	if( xFamiliesSupp.is() )
	{
		Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
		DBG_ASSERT( xFamiliesSupp.is(),
					"getStyleFamilies() from XModel failed for export!" );
		if( xFamilies.is() )
		{
			const OUString aPageStyleName(
						RTL_CONSTASCII_USTRINGPARAM( "PageStyles" ));

			if( xFamilies->hasByName( aPageStyleName ) )
			{
                xPageStyles.set(xFamilies->getByName( aPageStyleName ),uno::UNO_QUERY);

				DBG_ASSERT( xPageStyles.is(),
							"Page Styles not found for export!" );
			}
		}
	}
}

XMLPageExport::~XMLPageExport()
{
}

void XMLPageExport::exportStyles( sal_Bool bUsed, sal_Bool bAutoStyles )
{
	if( xPageStyles.is() )
	{
        uno::Sequence< ::rtl::OUString> aSeq = xPageStyles->getElementNames();
        const ::rtl::OUString* pIter = aSeq.getConstArray();
        const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
        for(;pIter != pEnd;++pIter)
		{
            Reference< XStyle > xStyle(xPageStyles->getByName( *pIter ),uno::UNO_QUERY);
			if( !bUsed || xStyle->isInUse() )
				exportStyle( xStyle, bAutoStyles );
		}
	}
}

void XMLPageExport::exportAutoStyles()
{
	rExport.GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_PAGE_MASTER
        , rExport.GetDocHandler(), rExport.GetMM100UnitConverter(),
		rExport.GetNamespaceMap()
        );
}

void XMLPageExport::exportDefaultStyle()
{
	Reference < lang::XMultiServiceFactory > xFactory (GetExport().GetModel(), UNO_QUERY);
	if (xFactory.is())
	{
		OUString sTextDefaults ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.text.Defaults" ) );
		Reference < XPropertySet > xPropSet (xFactory->createInstance ( sTextDefaults ), UNO_QUERY);
		if (xPropSet.is())
		{
			// <style:default-style ...>
			GetExport().CheckAttrList();

			::std::vector< XMLPropertyState > xPropStates =
				xPageMasterExportPropMapper->FilterDefaults( xPropSet );
			
			sal_Bool bExport = sal_False;
			UniReference < XMLPropertySetMapper > aPropMapper(xPageMasterExportPropMapper->getPropertySetMapper());
			for( ::std::vector< XMLPropertyState >::iterator aIter = xPropStates.begin(); aIter != xPropStates.end(); ++aIter )
			{
        		XMLPropertyState *pProp = &(*aIter);
				sal_Int16 nContextId	= aPropMapper->GetEntryContextId( pProp->mnIndex );
				if( nContextId == CTF_PM_STANDARD_MODE )
				{
					bExport = sal_True;
					break;
				}
			}

		//	if ( xPropStates.size() != 0 &&
          //          ( xPropStates.size() != 1 || xPropStates[0].mnIndex != -1 ) )
			if( bExport )	
			{
				//<style:default-page-layout>
				SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
										  XML_DEFAULT_PAGE_LAYOUT,
										  sal_True, sal_True );

				xPageMasterExportPropMapper->exportXML( GetExport(), xPropStates,
									   	  XML_EXPORT_FLAG_IGN_WS );
			}
		}
	}
}
