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

#include "DocumentHelper.hxx"

#include "drawdoc.hxx"
#include "DrawDocShell.hxx"
#include "sdpage.hxx"
#include "glob.hxx"
#include "unmovss.hxx"
#include "strings.hrc"
#include "sdresid.hxx"
#include "undoback.hxx"
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPages.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include "stlpool.hxx"
#include <svx/xfillit0.hxx>
#include <tools/diagnose_ex.h>

using namespace ::com::sun::star;

namespace sd { namespace sidebar {

SdPage* DocumentHelper::CopyMasterPageToLocalDocument (
    SdDrawDocument& rTargetDocument,
    SdPage* pMasterPage)
{
    SdPage* pNewMasterPage = NULL;

    do
    {
        if (pMasterPage == NULL)
            break;

        // Check the presence of the source document.
        SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(
            pMasterPage->GetModel());
        if (pSourceDocument == NULL)
            break;

        // When the given master page already belongs to the target document
        // then there is nothing more to do.
        if (pSourceDocument == &rTargetDocument)
        {
            pNewMasterPage = pMasterPage;
            break;
        }

        // Test if the master pages of both the slide and its notes page are
        // present.  This is not the case when we are called during the
        // creation of the slide master page because then the notes master
        // page is not there.
        sal_uInt16 nSourceMasterPageCount = pSourceDocument->GetMasterPageCount();
        if (nSourceMasterPageCount%2 == 0)
            // There should be 1 handout page + n slide masters + n notes
            // masters = 2*n+1.  An even value indicates that a new slide
            // master but not yet the notes master has been inserted.
            break;
        sal_uInt16 nIndex = pMasterPage->GetPageNum();
        if (nSourceMasterPageCount <= nIndex+1)
            break;
        // Get the slide master page.
        if (pMasterPage != static_cast<SdPage*>(
            pSourceDocument->GetMasterPage(nIndex)))
            break;
        // Get the notes master page.
        SdPage* pNotesMasterPage = static_cast<SdPage*>(
            pSourceDocument->GetMasterPage(nIndex+1));
        if (pNotesMasterPage == NULL)
            break;


        // Check if a master page with the same name as that of the given
        // master page already exists.
        bool bPageExists (false);
        sal_uInt16 nMasterPageCount(rTargetDocument.GetMasterSdPageCount(PK_STANDARD));
        for (sal_uInt16 nMaster=0; nMaster<nMasterPageCount; nMaster++)
        {
            SdPage* pCandidate = static_cast<SdPage*>(
                rTargetDocument.GetMasterSdPage (nMaster, PK_STANDARD));
            if (pMasterPage!=NULL
                && pCandidate->GetName().CompareTo(pMasterPage->GetName())==0)
            {
                bPageExists = true;
                pNewMasterPage = pCandidate;
                break;
            }
        }
        if (bPageExists)
            break;

        // Create a new slide (and its notes page.)
        uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (
            rTargetDocument.getUnoModel(), uno::UNO_QUERY);
        if ( ! xSlideSupplier.is())
            break;
        uno::Reference<drawing::XDrawPages> xSlides (
            xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
        if ( ! xSlides.is())
            break;
        xSlides->insertNewByIndex (xSlides->getCount());

        // Set a layout.
        SdPage* pSlide = rTargetDocument.GetSdPage(
            rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
            PK_STANDARD);
        if (pSlide == NULL)
            break;
        pSlide->SetAutoLayout(AUTOLAYOUT_TITLE, sal_True);

        // Create a copy of the master page and the associated notes
        // master page and insert them into our document.
        pNewMasterPage = AddMasterPage(rTargetDocument, pMasterPage);
        if (pNewMasterPage==NULL)
            break;
        SdPage* pNewNotesMasterPage
            = AddMasterPage(rTargetDocument, pNotesMasterPage);
        if (pNewNotesMasterPage==NULL)
            break;

        // Make the connection from the new slide to the master page
        // (and do the same for the notes page.)
        rTargetDocument.SetMasterPage (
            rTargetDocument.GetSdPageCount(PK_STANDARD)-1,
            pNewMasterPage->GetName(),
            &rTargetDocument,
            sal_False, // Connect the new master page with the new slide but
                   // do not modify other (master) pages.
            sal_True);
    }
    while (false);

    // We are not interested in any automatisms for our modified internal
    // document.
    rTargetDocument.SetChanged (sal_False);

    return pNewMasterPage;
}




SdPage* DocumentHelper::GetSlideForMasterPage (SdPage* pMasterPage)
{
    SdPage* pCandidate = NULL;

    SdDrawDocument* pDocument = NULL;
    if (pMasterPage != NULL)
        pDocument = dynamic_cast<SdDrawDocument*>(pMasterPage->GetModel());

    // Iterate over all pages and check if it references the given master
    // page.
    if (pDocument!=NULL && pDocument->GetSdPageCount(PK_STANDARD) > 0)
    {
        // In most cases a new slide has just been inserted so start with
        // the last page.
        sal_uInt16 nPageIndex (pDocument->GetSdPageCount(PK_STANDARD)-1);
        bool bFound (false);
        while ( ! bFound)
        {
            pCandidate = pDocument->GetSdPage(
                nPageIndex,
                PK_STANDARD);
            if (pCandidate != NULL)
            {
                if (static_cast<SdPage*>(&pCandidate->TRG_GetMasterPage())
                    == pMasterPage)
                {
                    bFound = true;
                    break;
                }
            }

            if (nPageIndex == 0)
                break;
            else
                nPageIndex --;
        }

        // If no page was found that refernced the given master page reset
        // the pointer that is returned.
        if ( ! bFound)
            pCandidate = NULL;
    }

    return pCandidate;
}




SdPage* DocumentHelper::AddMasterPage (
    SdDrawDocument& rTargetDocument,
    SdPage* pMasterPage)
{
    SdPage* pClonedMasterPage = NULL;

    if (pMasterPage!=NULL)
    {
        try
        {
            // Duplicate the master page.
            pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());

            // Copy the necessary styles.
            SdDrawDocument* pSourceDocument
                = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
            if (pSourceDocument != NULL)
                ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);

            // Copy the precious flag.
            pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());

            // Now that the styles are available we can insert the cloned
            // master page.
            rTargetDocument.InsertMasterPage (pClonedMasterPage);
        }
        catch (uno::Exception& rException)
        {
            pClonedMasterPage = NULL;
            DBG_UNHANDLED_EXCEPTION();
        }
        catch (::std::exception rException)
        {
            pClonedMasterPage = NULL;
            OSL_TRACE ("caught general exception");
        }
        catch (...)
        {
            pClonedMasterPage = NULL;
            OSL_TRACE ("caught general exception");
        }
    }

    return pClonedMasterPage;
}




void DocumentHelper::ProvideStyles (
    SdDrawDocument& rSourceDocument,
    SdDrawDocument& rTargetDocument,
    SdPage* pPage)
{
    // Get the layout name of the given page.
    String sLayoutName (pPage->GetLayoutName());
    sLayoutName.Erase (sLayoutName.SearchAscii (SD_LT_SEPARATOR));

    // Copy the style sheet from source to target document.
	SdStyleSheetPool* pSourceStyleSheetPool =
        static_cast<SdStyleSheetPool*>(rSourceDocument.GetStyleSheetPool());
	SdStyleSheetPool* pTargetStyleSheetPool =
        static_cast<SdStyleSheetPool*>(rTargetDocument.GetStyleSheetPool());
    SdStyleSheetVector aCreatedStyles;
    pTargetStyleSheetPool->CopyLayoutSheets (
        sLayoutName,
        *pSourceStyleSheetPool,
        aCreatedStyles);

    // Add an undo action for the copied style sheets.
    if( !aCreatedStyles.empty() )
    {
     	::svl::IUndoManager* pUndoManager = rTargetDocument.GetDocSh()->GetUndoManager();
       if (pUndoManager != NULL)
       {
           SdMoveStyleSheetsUndoAction* pMovStyles =
               new SdMoveStyleSheetsUndoAction (
                   &rTargetDocument,
                   aCreatedStyles,
                   sal_True);
           pUndoManager->AddUndoAction (pMovStyles);
       }
    }
}




void DocumentHelper::AssignMasterPageToPageList (
    SdDrawDocument& rTargetDocument,
    SdPage* pMasterPage,
    const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
{
    do
    {
        if (pMasterPage == NULL && pMasterPage->IsMasterPage())
            break;

        // Make the layout name by stripping ouf the layout postfix from the
        // layout name of the given master page.
        String sFullLayoutName (pMasterPage->GetLayoutName());
        String sBaseLayoutName (sFullLayoutName);
        sBaseLayoutName.Erase (sBaseLayoutName.SearchAscii (SD_LT_SEPARATOR));

        if (rpPageList->empty())
            break;

        // Create a second list that contains only the valid pointers to
        // pages for which an assignment is necessary.
        ::std::vector<SdPage*>::const_iterator iPage;
        ::std::vector<SdPage*> aCleanedList;
        for (iPage=rpPageList->begin(); iPage!=rpPageList->end(); ++iPage)
        {
            OSL_ASSERT(*iPage!=NULL && (*iPage)->GetModel() == &rTargetDocument);
            if (*iPage != NULL
                && (*iPage)->GetLayoutName().CompareTo(sFullLayoutName)!=0)
            {
                aCleanedList.push_back(*iPage);
            }
        }
        if (aCleanedList.empty() )
            break;

		::svl::IUndoManager* pUndoMgr = rTargetDocument.GetDocSh()->GetUndoManager();
		if( pUndoMgr )
			pUndoMgr->EnterListAction(String(SdResId(STR_UNDO_SET_PRESLAYOUT)), String());

        SdPage* pMasterPageInDocument = ProvideMasterPage(rTargetDocument,pMasterPage,rpPageList);
        if (pMasterPageInDocument == NULL)
            break;

        // Assign the master pages to the given list of pages.
        for (iPage=aCleanedList.begin();
             iPage!=aCleanedList.end();
             ++iPage)
        {
            AssignMasterPageToPage (
                pMasterPageInDocument,
                sBaseLayoutName,
                *iPage);
        }

		if( pUndoMgr )
			pUndoMgr->LeaveListAction();
    }
    while (false);
}




SdPage* DocumentHelper::AddMasterPage (
    SdDrawDocument& rTargetDocument,
    SdPage* pMasterPage,
    sal_uInt16 nInsertionIndex)
{
    SdPage* pClonedMasterPage = NULL;

    if (pMasterPage!=NULL)
    {
        // Duplicate the master page.
        pClonedMasterPage = static_cast<SdPage*>(pMasterPage->Clone());

        // Copy the precious flag.
        pClonedMasterPage->SetPrecious(pMasterPage->IsPrecious());

        // Copy the necessary styles.
        SdDrawDocument* pSourceDocument
            = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
        if (pSourceDocument != NULL)
        {
            ProvideStyles (*pSourceDocument, rTargetDocument, pClonedMasterPage);

            // Now that the styles are available we can insert the cloned
            // master page.
            rTargetDocument.InsertMasterPage (pClonedMasterPage, nInsertionIndex);

            // Adapt the size of the new master page to that of the pages in
            // the document.
            Size aNewSize (rTargetDocument.GetSdPage(0, pMasterPage->GetPageKind())->GetSize());
            Rectangle aBorders (
                pClonedMasterPage->GetLftBorder(),
                pClonedMasterPage->GetUppBorder(),
                pClonedMasterPage->GetRgtBorder(),
                pClonedMasterPage->GetLwrBorder());
            pClonedMasterPage->ScaleObjects(aNewSize, aBorders, sal_True);
            pClonedMasterPage->SetSize(aNewSize);
            pClonedMasterPage->CreateTitleAndLayout(sal_True);
        }
    }

    return pClonedMasterPage;
}




/** In here we have to handle three cases:
    1. pPage is a normal slide.  We can use SetMasterPage to assign the
    master pages to it.
    2. pPage is a master page that is used by at least one slide.  We can
    assign the master page to these slides.
    3. pPage is a master page that is currently not used by any slide.
    We can delete that page and add copies of the given master pages
    instead.

    For points 2 and 3 where one master page A is assigned to another B we have
    to keep in mind that the master page that page A has already been
    inserted into the target document.
*/
void DocumentHelper::AssignMasterPageToPage (
    SdPage* pMasterPage,
    const String& rsBaseLayoutName,
    SdPage* pPage)
{
    // Leave early when the parameters are invalid.
    if (pPage == NULL || pMasterPage == NULL)
        return;
    SdDrawDocument* pDocument = dynamic_cast<SdDrawDocument*>(pPage->GetModel());
    if (pDocument == NULL)
        return;

    if ( ! pPage->IsMasterPage())
    {
        // 1. Remove the background object (so that that, if it exists, does
        // not override the new master page) and assign the master page to
        // the regular slide.
        pDocument->GetDocSh()->GetUndoManager()->AddUndoAction(
            new SdBackgroundObjUndoAction(
                *pDocument, *pPage, pPage->getSdrPageProperties().GetItemSet()),
            sal_True);
        pPage->getSdrPageProperties().PutItem(XFillStyleItem(XFILL_NONE));

        pDocument->SetMasterPage (
            (pPage->GetPageNum()-1)/2,
            rsBaseLayoutName,
            pDocument,
            sal_False,
            sal_False);
    }
    else
    {
        // Find first slide that uses the master page.
        SdPage* pSlide = NULL;
        sal_uInt16 nPageCount = pDocument->GetSdPageCount(PK_STANDARD);
        for (sal_uInt16 nPage=0; nPage<nPageCount&&pSlide==NULL; nPage++)
        {
            SdrPage* pCandidate = pDocument->GetSdPage(nPage,PK_STANDARD);
            if (pCandidate != NULL
                && pCandidate->TRG_HasMasterPage()
                && &(pCandidate->TRG_GetMasterPage()) == pPage)
            {
                pSlide = static_cast<SdPage*>(pCandidate);
            }
        }

        if (pSlide != NULL)
        {
            // 2. Assign the given master pages to the first slide that was
            // found above that uses the master page.
            pDocument->SetMasterPage (
                (pSlide->GetPageNum()-1)/2,
                rsBaseLayoutName,
                pDocument,
                sal_False,
                sal_False);
        }
        else
        {
            // 3. Replace the master page A by a copy of the given master
            // page B.
            pDocument->RemoveUnnecessaryMasterPages (
                pPage, sal_False);
        }
    }
}




SdPage* DocumentHelper::ProvideMasterPage (
    SdDrawDocument& rTargetDocument,
    SdPage* pMasterPage,
    const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList)
{
    // Make sure that both the master page and its notes master exist
    // in the source document.  If one is missing then return without
    // making any changes.
    if (pMasterPage == NULL)
    {
        // The caller should make sure that the master page is valid.
        OSL_ASSERT(pMasterPage != NULL);
        return NULL;
    }
    SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel());
    if (pSourceDocument == NULL)
        return NULL;
    SdPage* pNotesMasterPage = static_cast<SdPage*>(
        pSourceDocument->GetMasterPage(pMasterPage->GetPageNum()+1));
    if (pNotesMasterPage == NULL)
    {
        // The model is not in a valid state.  Maybe a new master page
        // is being (not finished yet) created?  Return without making
        // any changes.
        return NULL;
    }

    SdPage* pMasterPageInDocument = NULL;
    // Search for a master page with the same name as the given one in
    // the target document.
    const XubString sMasterPageLayoutName (pMasterPage->GetLayoutName());
    for (sal_uInt16 nIndex=0,nCount=rTargetDocument.GetMasterPageCount(); nIndex<nCount; ++nIndex)
    {
        SdPage* pCandidate = static_cast<SdPage*>(rTargetDocument.GetMasterPage(nIndex));
        if (pCandidate!=NULL
            && sMasterPageLayoutName==pCandidate->GetLayoutName())
        {
            // The requested master page does already exist in the
            // target document, return it.
            return pCandidate;
        }
    }

    // The given master page does not already belong to the target
    // document so we have to create copies and insert them into the
    // targer document.

    // Determine the position where the new master pages are inserted.
    // By default they are inserted at the end.  When we assign to a
    // master page then insert after the last of the (selected) pages.
    sal_uInt16 nInsertionIndex = rTargetDocument.GetMasterPageCount();
    if (rpPageList->front()->IsMasterPage())
    {
        nInsertionIndex = rpPageList->back()->GetPageNum();
    }

    // Clone the master page.
    if (pMasterPage->GetModel() != &rTargetDocument)
    {
        pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex);
        if( rTargetDocument.IsUndoEnabled() )
				rTargetDocument.AddUndo(
					rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument));
    }
    else
        pMasterPageInDocument = pMasterPage;

    // Clone the notes master.
    if (pNotesMasterPage->GetModel() != &rTargetDocument)
    {
        SdPage* pClonedNotesMasterPage
            = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1);
        if( rTargetDocument.IsUndoEnabled() )
            rTargetDocument.AddUndo(
                rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage));
    }

    return pMasterPageInDocument;
}





} } // end of namespace sd::sidebar
