/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "comphelper/anytostring.hxx"
#include "cppuhelper/exc_hlp.hxx"

#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/presentation/XPresentationPage.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>

#include "oox/drawingml/theme.hxx"
#include "oox/drawingml/drawingmltypes.hxx"
#include "oox/drawingml/themefragmenthandler.hxx"
#include "oox/drawingml/textliststylecontext.hxx"
#include "oox/ppt/pptshape.hxx"
#include "oox/ppt/presentationfragmenthandler.hxx"
#include "oox/ppt/slidefragmenthandler.hxx"
#include "oox/ppt/layoutfragmenthandler.hxx"
#include "oox/ppt/pptimport.hxx"

using rtl::OUString;
using namespace ::com::sun::star;
using namespace ::oox::core;
using namespace ::oox::drawingml;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::xml::sax;

namespace oox { namespace ppt {

PresentationFragmentHandler::PresentationFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) throw()
: FragmentHandler( rFilter, rFragmentPath )
, mpTextListStyle( new TextListStyle )
{
	TextParagraphPropertiesVector& rParagraphDefaulsVector( mpTextListStyle->getListStyle() );
	TextParagraphPropertiesVector::iterator aParagraphDefaultIter( rParagraphDefaulsVector.begin() );
	while( aParagraphDefaultIter != rParagraphDefaulsVector.end() )
	{
		// ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
		// so this attribute needs to be set always
		(*aParagraphDefaultIter++)->getParaBottomMargin() = TextSpacing( 0 );
	}
}

PresentationFragmentHandler::~PresentationFragmentHandler() throw()
{

}
void PresentationFragmentHandler::startDocument() throw (SAXException, RuntimeException)
{
}

void ResolveTextFields( XmlFilterBase& rFilter )
{
	const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
	if ( rTextFields.size() )
	{
		Reference< frame::XModel > xModel( rFilter.getModel() );
		oox::core::TextFieldStack::const_iterator aIter( rTextFields.begin() );
		while( aIter != rTextFields.end() )
		{
	        const OUString sURL = CREATE_OUSTRING( "URL" );
			Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
			Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );

			const oox::core::TextField& rTextField( *aIter++ );
			Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
	        Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
			if ( xPropSetInfo->hasPropertyByName( sURL ) )
			{
				rtl::OUString aURL;
				if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
				{
					const OUString sSlide = CREATE_OUSTRING( "#Slide " );
					const OUString sNotes = CREATE_OUSTRING( "#Notes " );
					sal_Bool bNotes = sal_False;
					sal_Int32 nPageNumber = 0;
					if ( aURL.match( sSlide ) )
						nPageNumber = aURL.copy( sSlide.getLength() ).toInt32();
					else if ( aURL.match( sNotes ) )
					{
						nPageNumber = aURL.copy( sNotes.getLength() ).toInt32();
						bNotes = sal_True;
					}
					if ( nPageNumber )
					{
						try
						{
							Reference< XDrawPage > xDrawPage;
							xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
							if ( bNotes )
							{
								Reference< ::com::sun::star::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
					            xDrawPage = xPresentationPage->getNotesPage();
							}
							Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
							aURL = CREATE_OUSTRING( "#" ).concat( xNamed->getName() );
							xPropSet->setPropertyValue( sURL, Any( aURL ) );
							Reference< text::XTextContent > xContent( rTextField.xTextField, UNO_QUERY);
							Reference< text::XTextRange > xTextRange( rTextField.xTextCursor, UNO_QUERY );						
							rTextField.xText->insertTextContent( xTextRange, xContent, sal_True );
						}
						catch( uno::Exception& )
						{
						}
					}
				}
			}		
		}
	}
}

void PresentationFragmentHandler::endDocument() throw (SAXException, RuntimeException)
{
	// todo: localized progress bar text
	const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
	if ( rxStatusIndicator.is() )
		rxStatusIndicator->start( rtl::OUString(), 10000 );

	try
	{
        PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );

        Reference< frame::XModel > xModel( rFilter.getModel() );
		Reference< drawing::XDrawPage > xSlide;
		sal_uInt32 nSlide;

		// importing slide pages and its corresponding notes page
		Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
		Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );

		for( nSlide = 0; nSlide < maSlidesVector.size(); nSlide++ )
		{
			if ( rxStatusIndicator.is() )
				rxStatusIndicator->setValue( ( nSlide * 10000 ) / maSlidesVector.size() );

			if( nSlide == 0 )
				xDrawPages->getByIndex( 0 ) >>= xSlide;
			else
				xSlide = xDrawPages->insertNewByIndex( nSlide );

            OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
            if( aSlideFragmentPath.getLength() > 0 )
			{
				rtl::OUString aMasterFragmentPath;
				SlidePersistPtr pMasterPersistPtr;
                SlidePersistPtr pSlidePersistPtr( new SlidePersist( rFilter, sal_False, sal_False, xSlide,
									ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );

                FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );

				// importing the corresponding masterpage/layout
                OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideLayout" ) );
                if ( aLayoutFragmentPath.getLength() > 0 )
				{
					// importing layout
                    RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
                    aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideMaster" ) );
                    if( aMasterFragmentPath.getLength() )
                    {
                        // check if the corresponding masterpage+layout has already been imported
                        std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
                        std::vector< SlidePersistPtr >::iterator aIter( rMasterPages.begin() );
                        while( aIter != rMasterPages.end() )
                        {
                            if ( ( (*aIter)->getPath() == aMasterFragmentPath ) && ( (*aIter)->getLayoutPath() == aLayoutFragmentPath ) )
                            {
                                pMasterPersistPtr = *aIter;
                                break;
                            }
                            aIter++;
                        }
					}
				}

                if ( !pMasterPersistPtr.get() )
                {   // masterpersist not found, we have to load it
                    Reference< drawing::XDrawPage > xMasterPage;
                    Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
                    Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_QUERY_THROW );

                    if( !(rFilter.getMasterPages().size() ))
                        xMasterPages->getByIndex( 0 ) >>= xMasterPage;
                    else
                        xMasterPage = xMasterPages->insertNewByIndex( xMasterPages->getCount() );

                    pMasterPersistPtr = SlidePersistPtr( new SlidePersist( rFilter, sal_True, sal_False, xMasterPage,
                        ShapePtr( new PPTShape( Master, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
                    pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
                    rFilter.getMasterPages().push_back( pMasterPersistPtr );
                    rFilter.setActualSlidePersist( pMasterPersistPtr );

                    FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );

                    // set the correct theme
                    OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
                    if( aThemeFragmentPath.getLength() > 0 )
                    {
                        std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
                        std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
                        if( aIter2 == rThemes.end() )
                        {
                            oox::drawingml::ThemePtr pThemePtr( new oox::drawingml::Theme() );
                            pMasterPersistPtr->setTheme( pThemePtr );
                            rFilter.importFragment( new ThemeFragmentHandler( rFilter, aThemeFragmentPath, *pThemePtr ) );
                            rThemes[ aThemeFragmentPath ] = pThemePtr;
                        }
                        else
                        {
                            pMasterPersistPtr->setTheme( (*aIter2).second );
                        }
                    }
                    importSlide( xMasterFragmentHandler, pMasterPersistPtr );
                    rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
                    pMasterPersistPtr->createBackground( rFilter );
                    pMasterPersistPtr->createXShapes( rFilter );
                }

				// importing slide page
				pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
				pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
				Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
				if( xMasterPageTarget.is() )
					xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
                rFilter.getDrawPages().push_back( pSlidePersistPtr );
                rFilter.setActualSlidePersist( pSlidePersistPtr );
                importSlide( xSlideFragmentHandler, pSlidePersistPtr );
                pSlidePersistPtr->createBackground( rFilter );
                pSlidePersistPtr->createXShapes( rFilter );

				// now importing the notes page
                OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "notesSlide" ) );
                if( aNotesFragmentPath.getLength() > 0 )
                {
					Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
					if ( xPresentationPage.is() )
					{
						Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
						if ( xNotesPage.is() )
						{
                            SlidePersistPtr pNotesPersistPtr( new SlidePersist( rFilter, sal_False, sal_True, xNotesPage,
								ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
                            FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
							// import notesMaster slide for notes slide shapes format
							OUString aNotesMasterFragmentPath = xNotesFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "notesMaster" ) );
							SlidePersistPtr pNotesMasterPersistPtr( new SlidePersist( rFilter, sal_True/*sal_False*/, sal_True, xNotesPage,
								ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
							FragmentHandlerRef xNotesMasterFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesMasterFragmentPath, pNotesMasterPersistPtr, Slide ) );

                            // TODO: Theme support is missing, theme pointer in SlidePersist is null and used later
                            
							importSlide( xNotesMasterFragmentHandler, pNotesMasterPersistPtr );
							pNotesMasterPersistPtr->createXShapes( rFilter );
							pNotesPersistPtr->setMasterPersist(pNotesMasterPersistPtr);
                            rFilter.getNotesPages().push_back( pNotesPersistPtr );
                            rFilter.setActualSlidePersist( pNotesPersistPtr );
                            importSlide( xNotesFragmentHandler, pNotesPersistPtr );
                            pNotesPersistPtr->createBackground( rFilter );
                            pNotesPersistPtr->createXShapes( rFilter );
						}
					}
				}
			}
		}
		ResolveTextFields( rFilter ); 
	}
	catch( uno::Exception& )
	{
        OSL_ENSURE( false,
			(rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );

	}

	// todo	error handling;
	if ( rxStatusIndicator.is() )
		rxStatusIndicator->end();
}

// CT_Presentation
Reference< XFastContextHandler > PresentationFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
{
	Reference< XFastContextHandler > xRet;
	switch( aElementToken )
	{
	case PPT_TOKEN( presentation ):
	case PPT_TOKEN( sldMasterIdLst ):
	case PPT_TOKEN( notesMasterIdLst ):
	case PPT_TOKEN( sldIdLst ):
		break;
	case PPT_TOKEN( sldMasterId ):
		maSlideMasterVector.push_back( xAttribs->getOptionalValue( R_TOKEN( id ) ) );
		break;
	case PPT_TOKEN( sldId ):
		maSlidesVector.push_back( xAttribs->getOptionalValue( R_TOKEN( id ) ) );
		break;
	case PPT_TOKEN( notesMasterId ):
		maNotesMasterVector.push_back( xAttribs->getOptionalValue(R_TOKEN( id ) ) );
		break;
	case PPT_TOKEN( sldSz ):
		maSlideSize = GetSize2D( xAttribs );
		break;
	case PPT_TOKEN( notesSz ):
		maNotesSize = GetSize2D( xAttribs );
		break;
	case PPT_TOKEN( custShowLst ):
        xRet.set( new CustomShowListContext( *this, maCustomShowList ) );
		break;
	case PPT_TOKEN( defaultTextStyle ):
        xRet.set( new TextListStyleContext( *this, *mpTextListStyle ) );
		break;
	}
	if ( !xRet.is() )
        xRet = getFastContextHandler();
	return xRet;
}

bool PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
        const SlidePersistPtr pSlidePersistPtr )
{
	Reference< drawing::XDrawPage > xSlide( pSlidePersistPtr->getPage() );
	SlidePersistPtr pMasterPersistPtr( pSlidePersistPtr->getMasterPersist() );
	if ( pMasterPersistPtr.get() )
	{
        const OUString sLayout = CREATE_OUSTRING( "Layout" );
		uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
		xSet->setPropertyValue(	sLayout, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
	}
	while( xSlide->getCount() )
	{
		Reference< drawing::XShape > xShape;
		xSlide->getByIndex(0) >>= xShape;
		xSlide->remove( xShape );
	}

	Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
	if ( xPropertySet.is() )
	{
        static const OUString sWidth = CREATE_OUSTRING( "Width" );
        static const OUString sHeight = CREATE_OUSTRING( "Height" );
		awt::Size& rPageSize( pSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
		xPropertySet->setPropertyValue( sWidth, Any( rPageSize.Width ) );
		xPropertySet->setPropertyValue( sHeight, Any( rPageSize.Height ) );

		oox::ppt::HeaderFooter aHeaderFooter( pSlidePersistPtr->getHeaderFooter() );
		if ( !pSlidePersistPtr->isMasterPage() )
			aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = sal_False;
		try
		{
			static const OUString sIsHeaderVisible = CREATE_OUSTRING( "IsHeaderVisible" );
			static const OUString sIsFooterVisible = CREATE_OUSTRING( "IsFooterVisible" );
			static const OUString sIsDateTimeVisible = CREATE_OUSTRING( "IsDateTimeVisible" );
			static const OUString sIsPageNumberVisible = CREATE_OUSTRING( "IsPageNumberVisible" );

			if ( pSlidePersistPtr->isNotesPage() )
				xPropertySet->setPropertyValue( sIsHeaderVisible, Any( aHeaderFooter.mbHeader ) );
			xPropertySet->setPropertyValue( sIsFooterVisible, Any( aHeaderFooter.mbFooter ) );
			xPropertySet->setPropertyValue( sIsDateTimeVisible, Any( aHeaderFooter.mbDateTime ) );
			xPropertySet->setPropertyValue( sIsPageNumberVisible, Any( aHeaderFooter.mbSlideNumber ) );	
		}
		catch( uno::Exception& )
		{
		}
	}
    pSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
    return getFilter().importFragment( rxSlideFragmentHandler );
}

} }

