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

#include "AccessibleDocumentPagePreview.hxx"
#include "AccessiblePreviewTable.hxx"
#include "AccessiblePageHeader.hxx"
#include "AccessibilityHints.hxx"
#include "AccessibleText.hxx"
#include "document.hxx"
#include "prevwsh.hxx"
#include "prevloc.hxx"
#include "unoguard.hxx"
#include "drwlayer.hxx"
#include "editsrc.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include "DrawModelBroadcaster.hxx"
#include "docsh.hxx"
#include "drawview.hxx"
#include "preview.hxx"
#include "postit.hxx"

#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>

#include <unotools/accessiblestatesethelper.hxx>
#include <tools/debug.hxx>
#include <tools/gen.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdobj.hxx>
#include <svx/AccessibleTextHelper.hxx>
#include <svx/AccessibleShape.hxx>
#include <svx/ShapeTypeHandler.hxx>
#include <toolkit/helper/convert.hxx>
#include <svx/unoshape.hxx>
#include <unotools/accessiblerelationsethelper.hxx>

#include <vector>
#include <list>
#include <algorithm>
#include <memory>

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

//=========================================================================

typedef std::list< uno::Reference< XAccessible > > ScXAccList;


struct ScAccNote
{
    String      maNoteText;
    Rectangle   maRect;
    ScAddress   maNoteCell;
    ::accessibility::AccessibleTextHelper* mpTextHelper;
    sal_Int32   mnParaCount;
    sal_Bool    mbMarkNote;

                ScAccNote() : mpTextHelper(NULL), mnParaCount(0) {}
};

class ScNotesChilds
{
public:
    ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
    ~ScNotesChilds();
    void Init(const Rectangle& rVisRect, sal_Int32 nOffset);

    sal_Int32 GetChildsCount() const;
    uno::Reference<XAccessible> GetChild(sal_Int32 nIndex) const;
    uno::Reference<XAccessible> GetAt(const awt::Point& rPoint) const;

    void DataChanged(const Rectangle& rVisRect);
    void SetOffset(sal_Int32 nNewOffset);
private:
    ScPreviewShell*         mpViewShell;
    ScAccessibleDocumentPagePreview* mpAccDoc;
    typedef std::vector<ScAccNote> ScAccNotes;
    mutable ScAccNotes      maNotes;
    mutable ScAccNotes      maMarks;
    sal_Int32               mnParagraphs;
    sal_Int32               mnOffset;

    ::accessibility::AccessibleTextHelper* CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const;
    sal_Int32 AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes);

    sal_Int8 CompareCell(const ScAddress& aCell1, const ScAddress& aCell2);
    void CollectChilds(const ScAccNote& rNote, ScXAccList& rList);
    sal_Int32 CheckChanges(const ScPreviewLocationData& rData, const Rectangle& rVisRect,
        sal_Bool bMark, ScAccNotes& rOldNotes, ScAccNotes& rNewNotes,
        ScXAccList& rOldParas, ScXAccList& rNewParas);

    inline ScDocument* GetDocument() const;
};

ScNotesChilds::ScNotesChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
    : mpViewShell(pViewShell),
    mpAccDoc(pAccDoc),
    mnParagraphs(0),
    mnOffset(0)
{
}

struct DeleteAccNote
{
    void operator()(ScAccNote& rNote)
    {
        if (rNote.mpTextHelper)
            DELETEZ( rNote.mpTextHelper);
    }
};

ScNotesChilds::~ScNotesChilds()
{
    std::for_each(maNotes.begin(), maNotes.end(), DeleteAccNote());
    std::for_each(maMarks.begin(), maMarks.end(), DeleteAccNote());
}

::accessibility::AccessibleTextHelper* ScNotesChilds::CreateTextHelper(const String& rString, const Rectangle& rVisRect, const ScAddress& aCellPos, sal_Bool bMarkNote, sal_Int32 nChildOffset) const
{
    ::accessibility::AccessibleTextHelper* pTextHelper = NULL;

    ::std::auto_ptr < ScAccessibleTextData > pAccessiblePreviewHeaderCellTextData
		(new ScAccessibleNoteTextData(mpViewShell, rString, aCellPos, bMarkNote));
	::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessiblePreviewHeaderCellTextData));

	pTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource);

    if (pTextHelper)
    {
        pTextHelper->SetEventSource(mpAccDoc);
        pTextHelper->SetStartIndex(nChildOffset);
        pTextHelper->SetOffset(rVisRect.TopLeft());
    }

    return pTextHelper;
}

sal_Int32 ScNotesChilds::AddNotes(const ScPreviewLocationData& rData, const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rNotes)
{
    sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);

    rNotes.reserve(nCount);

    sal_Int32 nParagraphs(0);
    ScDocument* pDoc = GetDocument();
    if (pDoc)
    {
        ScAccNote aNote;
        aNote.mbMarkNote = bMark;
        if (bMark)
            aNote.mnParaCount = 1;
        for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
        {
            if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
            {
                if (bMark)
                {
	                // Document not needed, because only the cell address, but not the tablename is needed
	                aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
                }
                else
                {
                    if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
                        aNote.maNoteText = pNote->GetText();
                    aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
                    if (aNote.mpTextHelper)
                        aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
                }
                nParagraphs += aNote.mnParaCount;
                rNotes.push_back(aNote);
            }
        }
    }
    return nParagraphs;
}

void ScNotesChilds::Init(const Rectangle& rVisRect, sal_Int32 nOffset)
{
    if (mpViewShell && !mnParagraphs)
    {
        mnOffset = nOffset;
        const ScPreviewLocationData& rData = mpViewShell->GetLocationData();

        mnParagraphs = AddNotes(rData, rVisRect, sal_False, maMarks);
        mnParagraphs += AddNotes(rData, rVisRect, sal_True, maNotes);
    }
}

sal_Int32 ScNotesChilds::GetChildsCount() const
{
    return mnParagraphs;
}

struct ScParaFound
{
    sal_Int32 mnIndex;
    ScParaFound(sal_Int32 nIndex) : mnIndex(nIndex) {}
    sal_Bool operator() (const ScAccNote& rNote)
    {
        sal_Bool bResult(sal_False);
        if (rNote.mnParaCount > mnIndex)
            bResult = sal_True;
        else
            mnIndex -= rNote.mnParaCount;
        return bResult;
    }
};

uno::Reference<XAccessible> ScNotesChilds::GetChild(sal_Int32 nIndex) const
{
    uno::Reference<XAccessible> xAccessible;

    if (nIndex < mnParagraphs)
    {
        if (nIndex < static_cast<sal_Int32>(maMarks.size()))
        {
            ScAccNotes::iterator aEndItr = maMarks.end();
            ScParaFound aParaFound(nIndex);
            ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aParaFound);
            if (aItr != aEndItr)
            {
                DBG_ASSERT((aItr->maNoteCell == maMarks[nIndex].maNoteCell) && (aItr->mbMarkNote == maMarks[nIndex].mbMarkNote), "wrong note found");
            }
            else
            {
                DBG_ERRORFILE("wrong note found");
            }
            if (!aItr->mpTextHelper)
                aItr->mpTextHelper = CreateTextHelper(maMarks[nIndex].maNoteText, maMarks[nIndex].maRect, maMarks[nIndex].maNoteCell, maMarks[nIndex].mbMarkNote, nIndex + mnOffset); // the marks are the first and every mark has only one paragraph
            xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
        }
        else
        {
            nIndex -= maMarks.size();
            ScAccNotes::iterator aEndItr = maNotes.end();
            ScParaFound aParaFound(nIndex);
            ScAccNotes::iterator aItr = std::find_if(maNotes.begin(), aEndItr, aParaFound);
            if (aEndItr != aItr)
            {
                if (!aItr->mpTextHelper)
                    aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, (nIndex - aParaFound.mnIndex) + mnOffset + maMarks.size());
                xAccessible = aItr->mpTextHelper->GetChild(aParaFound.mnIndex + aItr->mpTextHelper->GetStartIndex());
            }
        }
    }

    return xAccessible;
}

struct ScPointFound
{
    Rectangle maPoint;
    sal_Int32 mnParagraphs;
    ScPointFound(const Point& rPoint) : maPoint(rPoint, Size(0, 0)), mnParagraphs(0) {}
    sal_Bool operator() (const ScAccNote& rNote)
    {
        sal_Bool bResult(sal_False);
        if (maPoint.IsInside(rNote.maRect))
            bResult = sal_True;
        else
            mnParagraphs += rNote.mnParaCount;
        return bResult;
    }
};

uno::Reference<XAccessible> ScNotesChilds::GetAt(const awt::Point& rPoint) const
{
    uno::Reference<XAccessible> xAccessible;

    ScPointFound aPointFound(Point(rPoint.X, rPoint.Y));

    ScAccNotes::iterator aEndItr = maMarks.end();
    ScAccNotes::iterator aItr = std::find_if(maMarks.begin(), aEndItr, aPointFound);
    if (aEndItr == aItr)
    {
        aEndItr = maNotes.end();
        aItr = std::find_if(maNotes.begin(), aEndItr, aPointFound);
    }
    if (aEndItr != aItr)
    {
        if (!aItr->mpTextHelper)
            aItr->mpTextHelper = CreateTextHelper(aItr->maNoteText, aItr->maRect, aItr->maNoteCell, aItr->mbMarkNote, aPointFound.mnParagraphs + mnOffset);
        xAccessible = aItr->mpTextHelper->GetAt(rPoint);
    }

    return xAccessible;
}

sal_Int8 ScNotesChilds::CompareCell(const ScAddress& aCell1, const ScAddress& aCell2)
{
    DBG_ASSERT(aCell1.Tab() == aCell2.Tab(), "the notes should be on the same table");
    sal_Int8 nResult(0);
    if (aCell1 != aCell2)
    {
        if (aCell1.Row() == aCell2.Row())
            nResult = (aCell1.Col() < aCell2.Col()) ? -1 : 1;
        else
            nResult = (aCell1.Row() < aCell2.Row()) ? -1 : 1;
    }
    return nResult;
}

void ScNotesChilds::CollectChilds(const ScAccNote& rNote, ScXAccList& rList)
{
    if (rNote.mpTextHelper)
        for (sal_Int32 i = 0; i < rNote.mnParaCount; ++i)
            rList.push_back(rNote.mpTextHelper->GetChild(i + rNote.mpTextHelper->GetStartIndex()));
}

sal_Int32 ScNotesChilds::CheckChanges(const ScPreviewLocationData& rData,
            const Rectangle& rVisRect, sal_Bool bMark, ScAccNotes& rOldNotes,
            ScAccNotes& rNewNotes, ScXAccList& rOldParas, ScXAccList& rNewParas)
{
    sal_Int32 nCount = rData.GetNoteCountInRange(rVisRect, bMark);

    rNewNotes.reserve(nCount);

    sal_Int32 nParagraphs(0);
    ScDocument* pDoc = GetDocument();
    if (pDoc)
    {
        ScAccNote aNote;
        aNote.mbMarkNote = bMark;
        if (bMark)
            aNote.mnParaCount = 1;
        ScAccNotes::iterator aItr = rOldNotes.begin();
        ScAccNotes::iterator aEndItr = rOldNotes.end();
        sal_Bool bAddNote(sal_False);
        for (sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex)
        {
            if (rData.GetNoteInRange(rVisRect, nIndex, bMark, aNote.maNoteCell, aNote.maRect))
            {
                if (bMark)
                {
	                // Document not needed, because only the cell address, but not the tablename is needed
	                aNote.maNoteCell.Format( aNote.maNoteText, SCA_VALID, NULL );
                }
                else
                {
                    if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) )
                        aNote.maNoteText = pNote->GetText();
                }

                sal_Int8 nCompare(-1); // if there are no more old childs it is always a new one
                if (aItr != aEndItr)
                    nCompare = CompareCell(aNote.maNoteCell, aItr->maNoteCell);
                if (nCompare == 0)
                {
                    if (aNote.maNoteText == aItr->maNoteText)
                    {
                        aNote.mpTextHelper = aItr->mpTextHelper;
                        if (aNote.maRect != aItr->maRect)  //neue VisArea setzen
                        {
                            aNote.mpTextHelper->SetOffset(aNote.maRect.TopLeft());
                            aNote.mpTextHelper->UpdateChildren();
                            //DBG_ASSERT(aItr->maRect.GetSize() == aNote.maRect.GetSize(), "size should be the same, because the text is not changed");
                            // could be changed, because only a part of the note is visible
                        }
                    }
                    else
                    {
                        aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
                        if (aNote.mpTextHelper)
                            aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
                        // collect removed childs
                        CollectChilds(*aItr, rOldParas);
                        DELETEZ(aItr->mpTextHelper);
                        // collect new childs
                        CollectChilds(aNote, rNewParas);
                    }
                    bAddNote = sal_True;
                    // not necessary, because this branch should not be reached if it is the end
                    //if (aItr != aEndItr)
                    ++aItr;
                }
                else if (nCompare < 0)
                {
                    aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset);
                    if (aNote.mpTextHelper)
                        aNote.mnParaCount = aNote.mpTextHelper->GetChildCount();
                    // collect new childs
                    CollectChilds(aNote, rNewParas);
                    bAddNote = sal_True;
                }
                else
                {
                    // collect removed childs
                    CollectChilds(*aItr, rOldParas);
                    DELETEZ(aItr->mpTextHelper);

                    // no note to add
                    // not necessary, because this branch should not be reached if it is the end
                    //if (aItr != aEndItr)
                    ++aItr;
                }
                if (bAddNote)
                {
                    nParagraphs += aNote.mnParaCount;
                    rNewNotes.push_back(aNote);
                    bAddNote = sal_False;
                }
            }
        }
    }
    return nParagraphs;
}

struct ScChildGone
{
    ScAccessibleDocumentPagePreview* mpAccDoc;
    ScChildGone(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
    void operator() (const uno::Reference<XAccessible>& xAccessible) const
    {
        if (mpAccDoc)
        {
			AccessibleEventObject aEvent;
			aEvent.EventId = AccessibleEventId::CHILD;
			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
			aEvent.OldValue <<= xAccessible;

			mpAccDoc->CommitChange(aEvent); // gone child - event
        }
    }
};

struct ScChildNew
{
    ScAccessibleDocumentPagePreview* mpAccDoc;
    ScChildNew(ScAccessibleDocumentPagePreview* pAccDoc) : mpAccDoc(pAccDoc) {}
    void operator() (const uno::Reference<XAccessible>& xAccessible) const
    {
        if (mpAccDoc)
        {
			AccessibleEventObject aEvent;
			aEvent.EventId = AccessibleEventId::CHILD;
			aEvent.Source = uno::Reference< XAccessibleContext >(mpAccDoc);
			aEvent.NewValue <<= xAccessible;

			mpAccDoc->CommitChange(aEvent); // new child - event
        }
    }
};

void ScNotesChilds::DataChanged(const Rectangle& rVisRect)
{
    if (mpViewShell && mpAccDoc)
    {
        ScXAccList aNewParas;
        ScXAccList aOldParas;
        ScAccNotes aNewMarks;
        mnParagraphs = CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_True, maMarks, aNewMarks, aOldParas, aNewParas);
        maMarks = aNewMarks;
        ScAccNotes aNewNotes;
        mnParagraphs += CheckChanges(mpViewShell->GetLocationData(), rVisRect, sal_False, maNotes, aNewNotes, aOldParas, aNewParas);
        maNotes = aNewNotes;

        std::for_each(aOldParas.begin(), aOldParas.end(), ScChildGone(mpAccDoc));
        std::for_each(aNewParas.begin(), aNewParas.end(), ScChildNew(mpAccDoc));
    }
}

struct ScChangeOffset
{
    sal_Int32 mnDiff;
    ScChangeOffset(sal_Int32 nDiff) : mnDiff(nDiff) {}
    void operator() (const ScAccNote& rNote)
    {
        if (rNote.mpTextHelper)
            rNote.mpTextHelper->SetStartIndex(rNote.mpTextHelper->GetStartIndex() + mnDiff);
    }
};

void ScNotesChilds::SetOffset(sal_Int32 nNewOffset)
{
    sal_Int32 nDiff(nNewOffset - mnOffset);
    if (nDiff != 0)
    {
        std::for_each(maMarks.begin(), maMarks.end(), ScChangeOffset(nDiff));
        std::for_each(maNotes.begin(), maNotes.end(), ScChangeOffset(nDiff));
        mnOffset = nNewOffset;
    }
}

inline ScDocument* ScNotesChilds::GetDocument() const
{
    ScDocument* pDoc = NULL;
    if (mpViewShell)
        pDoc = mpViewShell->GetDocument();
    return pDoc;
}

class ScIAccessibleViewForwarder : public ::accessibility::IAccessibleViewForwarder
{
public:
    ScIAccessibleViewForwarder();
    ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
                                ScAccessibleDocumentPagePreview* pAccDoc,
                                const MapMode& aMapMode);
    ~ScIAccessibleViewForwarder();

	///=====  IAccessibleViewForwarder  ========================================

	virtual sal_Bool IsValid (void) const;
    virtual Rectangle GetVisibleArea() const;
    virtual Point LogicToPixel (const Point& rPoint) const;
    virtual Size LogicToPixel (const Size& rSize) const;
    virtual Point PixelToLogic (const Point& rPoint) const;
    virtual Size PixelToLogic (const Size& rSize) const;

private:
    ScPreviewShell*                     mpViewShell;
    ScAccessibleDocumentPagePreview*    mpAccDoc;
    MapMode                             maMapMode;
    sal_Bool                            mbValid;
};

ScIAccessibleViewForwarder::ScIAccessibleViewForwarder()
    : mbValid(sal_False)
{
}

ScIAccessibleViewForwarder::ScIAccessibleViewForwarder(ScPreviewShell* pViewShell,
                                ScAccessibleDocumentPagePreview* pAccDoc,
                                const MapMode& aMapMode)
    : mpViewShell(pViewShell),
    mpAccDoc(pAccDoc),
    maMapMode(aMapMode),
    mbValid(sal_True)
{
}

ScIAccessibleViewForwarder::~ScIAccessibleViewForwarder()
{
}

///=====  IAccessibleViewForwarder  ========================================

sal_Bool ScIAccessibleViewForwarder::IsValid (void) const
{
    ScUnoGuard aGuard;
    return mbValid;
}

Rectangle ScIAccessibleViewForwarder::GetVisibleArea() const
{
    ScUnoGuard aGuard;
    Rectangle aVisRect;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin)
    {
        aVisRect.SetSize(pWin->GetOutputSizePixel());
        aVisRect.SetPos(Point(0, 0));

        aVisRect = pWin->PixelToLogic(aVisRect, maMapMode);
    }

    return aVisRect;
}

Point ScIAccessibleViewForwarder::LogicToPixel (const Point& rPoint) const
{
    ScUnoGuard aGuard;
    Point aPoint;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin && mpAccDoc)
    {
    	Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
        aPoint = pWin->LogicToPixel(rPoint, maMapMode) + aRect.TopLeft();
    }

    return aPoint;
}

Size ScIAccessibleViewForwarder::LogicToPixel (const Size& rSize) const
{
    ScUnoGuard aGuard;
    Size aSize;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin)
        aSize = pWin->LogicToPixel(rSize, maMapMode);
    return aSize;
}

Point ScIAccessibleViewForwarder::PixelToLogic (const Point& rPoint) const
{
    ScUnoGuard aGuard;
    Point aPoint;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin && mpAccDoc)
    {
    	Rectangle aRect(mpAccDoc->GetBoundingBoxOnScreen());
        aPoint = pWin->PixelToLogic(rPoint - aRect.TopLeft(), maMapMode);
    }
    return aPoint;
}

Size ScIAccessibleViewForwarder::PixelToLogic (const Size& rSize) const
{
    ScUnoGuard aGuard;
    Size aSize;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin)
        aSize = pWin->PixelToLogic(rSize, maMapMode);
    return aSize;
}

struct ScShapeChild
{
    ScShapeChild() : mpAccShape(NULL) {}
    ScShapeChild(const ScShapeChild& rOld);
    ~ScShapeChild();
	mutable ::accessibility::AccessibleShape* mpAccShape;
	com::sun::star::uno::Reference< com::sun::star::drawing::XShape > mxShape;
    sal_Int32 mnRangeId;
};

ScShapeChild::ScShapeChild(const ScShapeChild& rOld)
:
mpAccShape(rOld.mpAccShape),
mxShape(rOld.mxShape),
mnRangeId(rOld.mnRangeId)
{
    if (mpAccShape)
        mpAccShape->acquire();
}

ScShapeChild::~ScShapeChild()
{
    if (mpAccShape)
    {
        mpAccShape->dispose();
        mpAccShape->release();
    }
}

struct ScShapeChildLess
{
    sal_Bool operator()(const ScShapeChild& rChild1, const ScShapeChild& rChild2) const
    {
      sal_Bool bResult(sal_False);
      if (rChild1.mxShape.is() && rChild2.mxShape.is())
	      bResult = (rChild1.mxShape.get() < rChild2.mxShape.get());
      return bResult;
    }
};

typedef std::vector<ScShapeChild> ScShapeChildVec;

struct ScShapeRange
{
    ScShapeChildVec maBackShapes;
    ScShapeChildVec maForeShapes; // inclusive internal shapes
    ScShapeChildVec maControls;
    Rectangle       maPixelRect;
    MapMode         maMapMode;
    ScIAccessibleViewForwarder maViewForwarder;
};

typedef std::vector<ScShapeRange> ScShapeRangeVec;

class ScShapeChilds : public SfxListener,
        public ::accessibility::IAccessibleParent
{
public:
    ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc);
    ~ScShapeChilds();

    ///=====  SfxListener  =====================================================

	virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    ///=====  IAccessibleParent  ==============================================

    virtual sal_Bool ReplaceChild (
        ::accessibility::AccessibleShape* pCurrentChild,
		const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
		const long _nIndex,
		const ::accessibility::AccessibleShapeTreeInfo& _rShapeTreeInfo
	)	throw (::com::sun::star::uno::RuntimeException);

    ///=====  Internal  ========================================================

    void Init();

    sal_Int32 GetBackShapeCount() const;
    uno::Reference<XAccessible> GetBackShape(sal_Int32 nIndex) const;
    sal_Int32 GetForeShapeCount() const;
    uno::Reference<XAccessible> GetForeShape(sal_Int32 nIndex) const;
    sal_Int32 GetControlCount() const;
    uno::Reference<XAccessible> GetControl(sal_Int32 nIndex) const;
    uno::Reference<XAccessible> GetForegroundShapeAt(const awt::Point& rPoint) const; // inclusive controls
    uno::Reference<XAccessible> GetBackgroundShapeAt(const awt::Point& rPoint) const;

    void DataChanged();
    void VisAreaChanged() const;

    void SetDrawBroadcaster();
private:
    ScAccessibleDocumentPagePreview* mpAccDoc;
    ScPreviewShell* mpViewShell;
    ScShapeRangeVec maShapeRanges;

    void FindChanged(ScShapeChildVec& aOld, ScShapeChildVec& aNew) const;
    void FindChanged(ScShapeRange& aOld, ScShapeRange& aNew) const;
    ::accessibility::AccessibleShape* GetAccShape(const ScShapeChild& rShape) const;
    ::accessibility::AccessibleShape* GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const;
    void FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId);
//UNUSED2008-05  sal_Bool FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const;

//    void AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
//    void RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID);
    SdrPage* GetDrawPage() const;
};

ScShapeChilds::ScShapeChilds(ScPreviewShell* pViewShell, ScAccessibleDocumentPagePreview* pAccDoc)
    :
    mpAccDoc(pAccDoc),
    mpViewShell(pViewShell),
    maShapeRanges(SC_PREVIEW_MAXRANGES)
{
    if (pViewShell)
    {
	    SfxBroadcaster* pDrawBC = pViewShell->GetDocument()->GetDrawBroadcaster();
	    if (pDrawBC)
		    StartListening(*pDrawBC);
    }
}

ScShapeChilds::~ScShapeChilds()
{
    if (mpViewShell)
    {
	    SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
	    if (pDrawBC)
		    EndListening(*pDrawBC);
    }
}

void ScShapeChilds::SetDrawBroadcaster()
{
    if (mpViewShell)
    {
	    SfxBroadcaster* pDrawBC = mpViewShell->GetDocument()->GetDrawBroadcaster();
	    if (pDrawBC)
		    StartListening(*pDrawBC, sal_True);
    }
}

void ScShapeChilds::Notify(SfxBroadcaster&, const SfxHint& rHint)
{
	if ( rHint.ISA( SdrHint ) )
	{
		const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
        if (pSdrHint)
        {
            SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject());
            if (pObj && (pObj->GetPage() == GetDrawPage()))
            {
                switch (pSdrHint->GetKind())
                {
                    case HINT_OBJCHG :         // Objekt geaendert
                    {
                    }
                    break;
                    // no longer necessary
/*                    case HINT_OBJINSERTED :    // Neues Zeichenobjekt eingefuegt
                    {
                        uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
                        if (xShape.is())
                            AddShape(xShape, pObj->GetLayer());
                    }
                    break;
                    case HINT_OBJREMOVED :     // Zeichenobjekt aus Liste entfernt
                    {
                        uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY);
                        if (xShape.is())
                            RemoveShape(xShape, pObj->GetLayer());
                    }
                    break;*/
                    default :
                    {
                        // other events are not interesting
                    }
                    break;
                }
            }
        }
    }
}

void ScShapeChilds::FindChanged(ScShapeChildVec& rOld, ScShapeChildVec& rNew) const
{
    ScShapeChildVec::iterator aOldItr = rOld.begin();
    ScShapeChildVec::iterator aOldEnd = rOld.end();
    ScShapeChildVec::const_iterator aNewItr = rNew.begin();
    ScShapeChildVec::const_iterator aNewEnd = rNew.begin();
    uno::Reference<XAccessible> xAcc;
    while ((aNewItr != aNewEnd) && (aOldItr != aOldEnd))
    {
        if (aNewItr->mxShape.get() == aOldItr->mxShape.get())
        {
            ++aOldItr;
            ++aNewItr;
        }
        else if (aNewItr->mxShape.get() < aOldItr->mxShape.get())
        {
            xAcc = GetAccShape(*aNewItr);
            AccessibleEventObject aEvent;
            aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
            aEvent.EventId = AccessibleEventId::CHILD;
            aEvent.NewValue <<= xAcc;
            mpAccDoc->CommitChange(aEvent);
            ++aNewItr;
        }
        else
        {
            xAcc = GetAccShape(*aOldItr);
            AccessibleEventObject aEvent;
            aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
            aEvent.EventId = AccessibleEventId::CHILD;
            aEvent.OldValue <<= xAcc;
            mpAccDoc->CommitChange(aEvent);
            ++aOldItr;
        }
    }
    while (aOldItr != aOldEnd)
    {
        xAcc = GetAccShape(*aOldItr);
        AccessibleEventObject aEvent;
        aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
        aEvent.EventId = AccessibleEventId::CHILD;
        aEvent.OldValue <<= xAcc;
        mpAccDoc->CommitChange(aEvent);
        ++aOldItr;
    }
    while (aNewItr != aNewEnd)
    {
        xAcc = GetAccShape(*aNewItr);
        AccessibleEventObject aEvent;
        aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
        aEvent.EventId = AccessibleEventId::CHILD;
        aEvent.NewValue <<= xAcc;
        mpAccDoc->CommitChange(aEvent);
        ++aNewItr;
    }
}

void ScShapeChilds::FindChanged(ScShapeRange& rOld, ScShapeRange& rNew) const
{
    FindChanged(rOld.maBackShapes, rNew.maBackShapes);
    FindChanged(rOld.maForeShapes, rNew.maForeShapes);
    FindChanged(rOld.maControls, rNew.maControls);
}

void ScShapeChilds::DataChanged()
{
    ScShapeRangeVec aOldShapeRanges(maShapeRanges);
    maShapeRanges.clear();
    maShapeRanges.resize(SC_PREVIEW_MAXRANGES);
    Init();
    for (sal_Int32 i = 0; i < SC_PREVIEW_MAXRANGES; ++i)
    {
        FindChanged(aOldShapeRanges[i], maShapeRanges[i]);
    }
}

struct ScVisAreaChanged
{
    const ScIAccessibleViewForwarder* mpViewForwarder;
    ScVisAreaChanged(const ScIAccessibleViewForwarder* pViewForwarder) : mpViewForwarder(pViewForwarder) {}
	void operator() (const ScShapeChild& rAccShapeData) const
    {
	    if (rAccShapeData.mpAccShape)
        {
            rAccShapeData.mpAccShape->ViewForwarderChanged(::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, mpViewForwarder);
        }
    }
};

void ScShapeChilds::VisAreaChanged() const
{
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    while (aItr != aEndItr)
    {
        ScVisAreaChanged aVisAreaChanged(&(aItr->maViewForwarder));
        std::for_each(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), aVisAreaChanged);
        std::for_each(aItr->maControls.begin(), aItr->maControls.end(), aVisAreaChanged);
        std::for_each(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), aVisAreaChanged);
        ++aItr;
    }
}

    ///=====  IAccessibleParent  ==============================================

sal_Bool ScShapeChilds::ReplaceChild (::accessibility::AccessibleShape* /* pCurrentChild */,
    const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& /* _rxShape */,
        const long /* _nIndex */, const ::accessibility::AccessibleShapeTreeInfo& /* _rShapeTreeInfo */)
        throw (uno::RuntimeException)
{
    DBG_ERRORFILE("should not be called in the page preview");
    return sal_False;
}

    ///=====  Internal  ========================================================

void ScShapeChilds::Init()
{
    if(mpViewShell)
    {
        const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
        MapMode aMapMode;
        Rectangle aPixelPaintRect;
        sal_uInt8 nRangeId;
        sal_uInt16 nCount(rData.GetDrawRanges());
        for (sal_uInt16 i = 0; i < nCount; ++i)
        {
            rData.GetDrawRange(i, aPixelPaintRect, aMapMode, nRangeId);
            FillShapes(aPixelPaintRect, aMapMode, nRangeId);
        }
    }
}

sal_Int32 ScShapeChilds::GetBackShapeCount() const
{
    sal_Int32 nCount(0);
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
        nCount += aItr->maBackShapes.size();
    return nCount;
}

uno::Reference<XAccessible> ScShapeChilds::GetBackShape(sal_Int32 nIndex) const
{
    uno::Reference<XAccessible> xAccessible;
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    while ((aItr != aEndItr) && !xAccessible.is())
    {
        sal_Int32 nCount(aItr->maBackShapes.size());
        if(nIndex < nCount)
            xAccessible = GetAccShape(aItr->maBackShapes, nIndex);
        else
            ++aItr;
        nIndex -= nCount;
    }

    if (nIndex >= 0)
        throw lang::IndexOutOfBoundsException();

   return xAccessible;
}

sal_Int32 ScShapeChilds::GetForeShapeCount() const
{
    sal_Int32 nCount(0);
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
        nCount += aItr->maForeShapes.size();
    return nCount;
}

uno::Reference<XAccessible> ScShapeChilds::GetForeShape(sal_Int32 nIndex) const
{
    uno::Reference<XAccessible> xAccessible;
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    while ((aItr != aEndItr) && !xAccessible.is())
    {
        sal_Int32 nCount(aItr->maForeShapes.size());
        if(nIndex < nCount)
            xAccessible = GetAccShape(aItr->maForeShapes, nIndex);
        else
            ++aItr;
        nIndex -= nCount;
    }

    if (nIndex >= 0)
        throw lang::IndexOutOfBoundsException();

   return xAccessible;
}

sal_Int32 ScShapeChilds::GetControlCount() const
{
    sal_Int32 nCount(0);
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    for ( ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin(); aItr != aEndItr; ++aItr )
        nCount += aItr->maControls.size();
    return nCount;
}

uno::Reference<XAccessible> ScShapeChilds::GetControl(sal_Int32 nIndex) const
{
    uno::Reference<XAccessible> xAccessible;
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    while ((aItr != aEndItr) && !xAccessible.is())
    {
        sal_Int32 nCount(aItr->maControls.size());
        if(nIndex < nCount)
            xAccessible = GetAccShape(aItr->maControls, nIndex);
        else
            ++aItr;
        nIndex -= nCount;
    }

    if (nIndex >= 0)
        throw lang::IndexOutOfBoundsException();

   return xAccessible;
}

struct ScShapePointFound
{
    Point maPoint;
    ScShapePointFound(const awt::Point& rPoint) : maPoint(VCLPoint(rPoint)) {}
    sal_Bool operator() (const ScShapeChild& rShape)
    {
        sal_Bool bResult(sal_False);
        if ((VCLRectangle(rShape.mpAccShape->getBounds())).IsInside(maPoint))
            bResult = sal_True;
        return bResult;
    }
};

uno::Reference<XAccessible> ScShapeChilds::GetForegroundShapeAt(const awt::Point& rPoint) const //inclusive Controls
{
    uno::Reference<XAccessible> xAcc;

    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    while((aItr != aEndItr) && !xAcc.is())
    {
        ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maForeShapes.begin(), aItr->maForeShapes.end(), ScShapePointFound(rPoint));
        if (aFindItr != aItr->maForeShapes.end())
            xAcc = GetAccShape(*aFindItr);
        else
        {
            ScShapeChildVec::const_iterator aCtrlItr = std::find_if(aItr->maControls.begin(), aItr->maControls.end(), ScShapePointFound(rPoint));
            if (aCtrlItr != aItr->maControls.end())
                xAcc = GetAccShape(*aCtrlItr);
            else
                ++aItr;
        }
    }

    return xAcc;
}

uno::Reference<XAccessible> ScShapeChilds::GetBackgroundShapeAt(const awt::Point& rPoint) const
{
    uno::Reference<XAccessible> xAcc;

    ScShapeRangeVec::const_iterator aItr = maShapeRanges.begin();
    ScShapeRangeVec::const_iterator aEndItr = maShapeRanges.end();
    while((aItr != aEndItr) && !xAcc.is())
    {
        ScShapeChildVec::const_iterator aFindItr = std::find_if(aItr->maBackShapes.begin(), aItr->maBackShapes.end(), ScShapePointFound(rPoint));
        if (aFindItr != aItr->maBackShapes.end())
            xAcc = GetAccShape(*aFindItr);
        else
            ++aItr;
    }

    return xAcc;
}

::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChild& rShape) const
{
	if (!rShape.mpAccShape)
	{
		::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
        ::accessibility::AccessibleShapeInfo aShapeInfo(rShape.mxShape, mpAccDoc, const_cast<ScShapeChilds*>(this));

        if (mpViewShell)
        {
            ::accessibility::AccessibleShapeTreeInfo aShapeTreeInfo;
            aShapeTreeInfo.SetSdrView(mpViewShell->GetPreview()->GetDrawView());
            aShapeTreeInfo.SetController(NULL);
            aShapeTreeInfo.SetWindow(mpViewShell->GetWindow());
            aShapeTreeInfo.SetViewForwarder(&(maShapeRanges[rShape.mnRangeId].maViewForwarder));
		    rShape.mpAccShape = rShapeHandler.CreateAccessibleObject(aShapeInfo, aShapeTreeInfo);
		    if (rShape.mpAccShape)
            {
			    rShape.mpAccShape->acquire();
                rShape.mpAccShape->Init();
            }
        }
	}
    return rShape.mpAccShape;
}

::accessibility::AccessibleShape* ScShapeChilds::GetAccShape(const ScShapeChildVec& rShapes, sal_Int32 nIndex) const
{
	return (GetAccShape(rShapes[nIndex]));
}

void ScShapeChilds::FillShapes(const Rectangle& aPixelPaintRect, const MapMode& aMapMode, sal_uInt8 nRangeId)
{
    DBG_ASSERT(nRangeId < maShapeRanges.size(), "this is not a valid range for draw objects");
    SdrPage* pPage = GetDrawPage();
    Window* pWin = mpViewShell->GetWindow();
    if (pPage && pWin)
    {
        sal_Bool bForeAdded(sal_False);
        sal_Bool bBackAdded(sal_False);
        sal_Bool bControlAdded(sal_False);
        Rectangle aClippedPixelPaintRect(aPixelPaintRect);
        if (mpAccDoc)
        {
            Rectangle aRect2(Point(0,0), mpAccDoc->GetBoundingBoxOnScreen().GetSize());
            aClippedPixelPaintRect = aPixelPaintRect.GetIntersection(aRect2);
        }
        maShapeRanges[nRangeId].maPixelRect = aClippedPixelPaintRect;
        maShapeRanges[nRangeId].maMapMode = aMapMode;
        ScIAccessibleViewForwarder aViewForwarder(mpViewShell, mpAccDoc, aMapMode);
        maShapeRanges[nRangeId].maViewForwarder = aViewForwarder;
        sal_uInt32 nCount(pPage->GetObjCount());
        for (sal_uInt32 i = 0; i < nCount; ++i)
        {
            SdrObject* pObj = pPage->GetObj(i);
            if (pObj)
            {
                uno::Reference< drawing::XShape > xShape(pObj->getUnoShape(), uno::UNO_QUERY);
                if (xShape.is())
                {
                    Rectangle aRect(pWin->LogicToPixel(VCLPoint(xShape->getPosition()), aMapMode), pWin->LogicToPixel(VCLSize(xShape->getSize()), aMapMode));
                    if(!aClippedPixelPaintRect.GetIntersection(aRect).IsEmpty())
                    {
                        ScShapeChild aShape;
                        aShape.mxShape = xShape;
                        aShape.mnRangeId = nRangeId;
                        switch (pObj->GetLayer())
                        {
                            case SC_LAYER_INTERN:
                            case SC_LAYER_FRONT:
                            {
                                maShapeRanges[nRangeId].maForeShapes.push_back(aShape);
                                bForeAdded = sal_True;
                            }
                            break;
                            case SC_LAYER_BACK:
                            {
                                maShapeRanges[nRangeId].maBackShapes.push_back(aShape);
                                bBackAdded = sal_True;
                            }
                            break;
                            case SC_LAYER_CONTROLS:
                            {
                                maShapeRanges[nRangeId].maControls.push_back(aShape);
                                bControlAdded = sal_True;
                            }
                            break;
                            default:
                            {
                                DBG_ERRORFILE("I don't know this layer.");
                            }
                            break;
                        }
                    }
                }
            }
        }
        if (bForeAdded)
            std::sort(maShapeRanges[nRangeId].maForeShapes.begin(), maShapeRanges[nRangeId].maForeShapes.end(),ScShapeChildLess());
        if (bBackAdded)
            std::sort(maShapeRanges[nRangeId].maBackShapes.begin(), maShapeRanges[nRangeId].maBackShapes.end(),ScShapeChildLess());
        if (bControlAdded)
            std::sort(maShapeRanges[nRangeId].maControls.begin(), maShapeRanges[nRangeId].maControls.end(),ScShapeChildLess());
    }
}

//UNUSED2008-05  sal_Bool ScShapeChilds::FindShape(ScShapeChildVec& rShapes, const uno::Reference <drawing::XShape>& xShape, ScShapeChildVec::iterator& rItr) const
//UNUSED2008-05  {
//UNUSED2008-05      sal_Bool bResult(sal_False);
//UNUSED2008-05      ScShapeChild aShape;
//UNUSED2008-05      aShape.mxShape = xShape;
//UNUSED2008-05      rItr = std::lower_bound(rShapes.begin(), rShapes.end(), aShape, ScShapeChildLess());
//UNUSED2008-05      if (rItr->mxShape.get() == xShape.get())
//UNUSED2008-05          bResult = sal_True; // if the shape is found
//UNUSED2008-05
//UNUSED2008-05  /*#ifdef DBG_UTIL // test whether it finds truly the correct shape (perhaps it is not really sorted)
//UNUSED2008-05      ScShapeChildVec::iterator aDebugItr = std::find(rShapes.begin(), rShapes.end(), aShape);
//UNUSED2008-05      DBG_ASSERT(rItr == aDebugItr, "wrong Shape found");
//UNUSED2008-05  #endif*/
//UNUSED2008-05      return bResult;
//UNUSED2008-05  }

/*void ScShapeChilds::AddShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
{
    uno::Reference < XAccessible > xNew;
    Window* pWin = mpViewShell->GetWindow();
    if (pWin)
    {
        ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
        ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
        sal_Bool bNotify(sal_False);
        uno::Reference <XAccessible> xAcc;
        while (aItr != aEndItr)
        {
            Rectangle aLogicPaintRect(pWin->PixelToLogic(aItr->maPixelRect, aItr->maMapMode));
            Rectangle aRect(VCLPoint(xShape->getPosition()), VCLSize(xShape->getSize()));
            if(!aRect.GetIntersection(aLogicPaintRect).IsEmpty())
            {
                ScShapeChild aShape;
                aShape.mxShape = xShape;
                switch (aLayerID)
                {
                    case SC_LAYER_INTERN:
                    case SC_LAYER_FRONT:
                    {
                        SetAnchor(aShape);
                        aItr->maForeShapes.push_back(aShape);
                        std::sort(aItr->maForeShapes.begin(), aItr->maForeShapes.end(),ScShapeChildLess());

                    }
                    break;
                    case SC_LAYER_BACK:
                    {
                        aItr->maBackShapes.push_back(aShape);
                        std::sort(aItr->maBackShapes.begin(), aItr->maBackShapes.end(),ScShapeChildLess());
                    }
                    break;
                    case SC_LAYER_CONTROLS:
                    {
                        SetAnchor(aShape);
                        aItr->maControls.push_back(aShape);
                        std::sort(aItr->maControls.begin(), aItr->maControls.end(),ScShapeChildLess());
                    }
                    break;
                    default:
                    {
                        DBG_ERRORFILE("I don't know this layer.");
                    }
                    break;
                }
                if (bNotify)
                {
                    xAcc = GetAccShape(aShape);
                    AccessibleEventObject aEvent;
                    aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
                    aEvent.EventId = AccessibleEventId::CHILD;
                    aEvent.NewValue <<= xAcc;
                    mpAccDoc->CommitChange(aEvent);
                    bNotify = sal_False;
                }
                xAcc = NULL;
            }
            ++aItr;
        }
    }
}*/

/*sal_Bool HaveToNotify(uno::Reference<XAccessible>& xAcc, ScShapeChildVec::iterator aItr)
{
    sal_Bool bResult(sal_False);
    if (aItr->mpAccShape)
    {
        bResult = sal_True;
        xAcc = aItr->mpAccShape;
    }
    else
        DBG_ERRORFILE("No Accessible object found. Don't know how to notify.");
    return bResult;
}*/

/*void ScShapeChilds::RemoveShape(const uno::Reference<drawing::XShape>& xShape, SdrLayerID aLayerID)
{
    ScShapeRangeVec::iterator aEndItr = maShapeRanges.end();
    ScShapeRangeVec::iterator aItr = maShapeRanges.begin();
    ScShapeChildVec::iterator aEraseItr;
    sal_Bool bNotify(sal_False);
    uno::Reference <XAccessible> xAcc;
    while (aItr != aEndItr)
    {
        switch (aLayerID)
        {
            case SC_LAYER_INTERN:
            case SC_LAYER_FRONT:
            {
                if (FindShape(aItr->maForeShapes, xShape, aEraseItr))
                {
                    bNotify = HaveToNotify(xAcc, aEraseItr);
                    aItr->maForeShapes.erase(aEraseItr);
                }
            }
            break;
            case SC_LAYER_BACK:
            {
                if (FindShape(aItr->maBackShapes, xShape, aEraseItr))
                {
                    bNotify = HaveToNotify(xAcc, aEraseItr);
                    aItr->maBackShapes.erase(aEraseItr);
                }
            }
            break;
            case SC_LAYER_CONTROLS:
            {
                if (FindShape(aItr->maControls, xShape, aEraseItr))
                {
                    bNotify = HaveToNotify(xAcc, aEraseItr);
                    aItr->maControls.erase(aEraseItr);
                }
            }
            break;
            default:
            {
                DBG_ERRORFILE("I don't know this layer.");
            }
            break;
        }
        if (bNotify)
        {
            AccessibleEventObject aEvent;
            aEvent.Source = uno::Reference<XAccessibleContext> (mpAccDoc);
            aEvent.EventId = AccessibleEventId::CHILD;
            aEvent.OldValue <<= xAcc;
            mpAccDoc->CommitChange(aEvent);
            bNotify = sal_False;
        }
        xAcc = NULL;
        ++aItr;
    }
}*/

SdrPage* ScShapeChilds::GetDrawPage() const
{
	SCTAB nTab( mpViewShell->GetLocationData().GetPrintTab() );
	SdrPage* pDrawPage = NULL;
	if (mpViewShell)
	{
		ScDocument* pDoc = mpViewShell->GetDocument();
		if (pDoc && pDoc->GetDrawLayer())
		{
			ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
			if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
				pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(static_cast<sal_Int16>(nTab)));
		}
	}
	return pDrawPage;
}

struct ScPagePreviewCountData
{
	//	order is background shapes, header, table or notes, footer, foreground shapes, controls

    Rectangle aVisRect;
	long nBackShapes;
	long nHeaders;
	long nTables;
    long nNoteParagraphs;
	long nFooters;
	long nForeShapes;
	long nControls;

	ScPagePreviewCountData( const ScPreviewLocationData& rData, Window* pSizeWindow,
        ScNotesChilds* pNotesChilds, ScShapeChilds* pShapeChilds );

	long GetTotal() const
	{
		return nBackShapes + nHeaders + nTables + nNoteParagraphs + nFooters + nForeShapes + nControls;
	}
};

ScPagePreviewCountData::ScPagePreviewCountData( const ScPreviewLocationData& rData,
                                Window* pSizeWindow, ScNotesChilds* pNotesChilds,
                                ScShapeChilds* pShapeChilds) :
	nBackShapes( 0 ),
	nHeaders( 0 ),
	nTables( 0 ),
    nNoteParagraphs( 0 ),
	nFooters( 0 ),
	nForeShapes( 0 ),
	nControls( 0 )
{
	Size aOutputSize;
	if ( pSizeWindow )
		aOutputSize = pSizeWindow->GetOutputSizePixel();
    Point aPoint;
	aVisRect = Rectangle( aPoint, aOutputSize );

	Rectangle aObjRect;

	if ( rData.GetHeaderPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
		nHeaders = 1;

	if ( rData.GetFooterPosition( aObjRect ) && aObjRect.IsOver( aVisRect ) )
		nFooters = 1;

	if ( rData.HasCellsInRange( aVisRect ) )
		nTables = 1;

	//!	shapes...
    nBackShapes = pShapeChilds->GetBackShapeCount();
    nForeShapes = pShapeChilds->GetForeShapeCount();
    nControls = pShapeChilds->GetControlCount();

    // there are only notes if there is no table
    if (nTables == 0)
        nNoteParagraphs = pNotesChilds->GetChildsCount();
}

//=====  internal  ========================================================

ScAccessibleDocumentPagePreview::ScAccessibleDocumentPagePreview(
        const uno::Reference<XAccessible>& rxParent, ScPreviewShell* pViewShell ) :
	ScAccessibleDocumentBase(rxParent),
	mpViewShell(pViewShell),
	mpNotesChilds(NULL),
    mpShapeChilds(NULL),
    mpTable(NULL),
    mpHeader(NULL),
    mpFooter(NULL)
{
	if (pViewShell)
		pViewShell->AddAccessibilityObject(*this);

//    GetNotesChilds(); not neccessary and reduces the creation performance
//    GetShapeChilds();
}

ScAccessibleDocumentPagePreview::~ScAccessibleDocumentPagePreview(void)
{
	if (!ScAccessibleDocumentBase::IsDefunc() && !rBHelper.bInDispose)
	{
		// increment refcount to prevent double call off dtor
		osl_incrementInterlockedCount( &m_refCount );
		// call dispose to inform object wich have a weak reference to this object
		dispose();
	}
}

void SAL_CALL ScAccessibleDocumentPagePreview::disposing()
{
    ScUnoGuard aGuard;
    if (mpTable)
    {
	    mpTable->release();
        mpTable = NULL;
    }
    if (mpHeader)
    {
	    mpHeader->release();
        mpHeader = NULL;
    }
    if (mpFooter)
    {
	    mpFooter->release();
        mpFooter = NULL;
    }

	if (mpViewShell)
	{
		mpViewShell->RemoveAccessibilityObject(*this);
		mpViewShell = NULL;
	}

    // #100593# no need to Dispose the AccessibleTextHelper,
    // as long as mpNotesChilds are destructed here
	if (mpNotesChilds)
	    DELETEZ(mpNotesChilds);

    if (mpShapeChilds)
        DELETEZ(mpShapeChilds);

	ScAccessibleDocumentBase::disposing();
}

//=====  SfxListener  =====================================================

void ScAccessibleDocumentPagePreview::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
	if (rHint.ISA( SfxSimpleHint ) )
	{
		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
		// only notify if child exist, otherwise it is not necessary
		if ((rRef.GetId() == SC_HINT_DATACHANGED))
        {
            if (mpTable) // if there is no table there is nothing to notify, because no one recongnizes the change
            {
                {
                    uno::Reference<XAccessible> xAcc = mpTable;
                    AccessibleEventObject aEvent;
                    aEvent.EventId = AccessibleEventId::CHILD;
					aEvent.Source = uno::Reference< XAccessibleContext >(this);
                    aEvent.OldValue <<= xAcc;
                    CommitChange(aEvent);
                }

                mpTable->dispose();
                mpTable->release();
                mpTable = NULL;
            }

	        Size aOutputSize;
            Window* pSizeWindow = mpViewShell->GetWindow();
	        if ( pSizeWindow )
		        aOutputSize = pSizeWindow->GetOutputSizePixel();
            Point aPoint;
	        Rectangle aVisRect( aPoint, aOutputSize );
            GetNotesChilds()->DataChanged(aVisRect);

            GetShapeChilds()->DataChanged();

            const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
		    ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );

            if (aCount.nTables > 0)
            {
				//!	order is background shapes, header, table or notes, footer, foreground shapes, controls
				sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);

				mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
                mpTable->acquire();
				mpTable->Init();

                {
                    uno::Reference<XAccessible> xAcc = mpTable;
                    AccessibleEventObject aEvent;
                    aEvent.EventId = AccessibleEventId::CHILD;
					aEvent.Source = uno::Reference< XAccessibleContext >(this);
                    aEvent.NewValue <<= xAcc;
                    CommitChange(aEvent);
                }
            }
        }
        else if (rRef.GetId() == SC_HINT_ACC_MAKEDRAWLAYER)
        {
            GetShapeChilds()->SetDrawBroadcaster();
        }
        else if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
        {
	        Size aOutputSize;
            Window* pSizeWindow = mpViewShell->GetWindow();
	        if ( pSizeWindow )
		        aOutputSize = pSizeWindow->GetOutputSizePixel();
            Point aPoint;
	        Rectangle aVisRect( aPoint, aOutputSize );
            GetNotesChilds()->DataChanged(aVisRect);

            GetShapeChilds()->VisAreaChanged();

            AccessibleEventObject aEvent;
            aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
			aEvent.Source = uno::Reference< XAccessibleContext >(this);
            CommitChange(aEvent);
        }
    }
    else if ( rHint.ISA(ScAccWinFocusLostHint) )
    {
        CommitFocusLost();
    }
    else if ( rHint.ISA(ScAccWinFocusGotHint) )
    {
        CommitFocusGained();
    }
	ScAccessibleDocumentBase::Notify(rBC, rHint);
}

//=====  XAccessibleComponent  ============================================

uno::Reference< XAccessible > SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleAtPoint( const awt::Point& rPoint )
								throw (uno::RuntimeException)
{
	uno::Reference<XAccessible> xAccessible;
    if (containsPoint(rPoint))
    {
	    ScUnoGuard aGuard;
        IsObjectValid();

	    if ( mpViewShell )
	    {
            xAccessible = GetShapeChilds()->GetForegroundShapeAt(rPoint);
            if (!xAccessible.is())
            {
		        const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
		        ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );

/*		        if ( rData.HasCellsInRange( Rectangle( rPoint, rPoint ) ) )
		        {
			        if ( !mpTable && (aCount.nTables > 0) )
			        {
				        //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
				        sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);

				        mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
                        mpTable->acquire();
				        mpTable->Init();
			        }
			        xAccessible = mpTable;
		        }*/
			    if ( !mpTable && (aCount.nTables > 0) )
			    {
				    //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
				    sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);

				    mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
                    mpTable->acquire();
				    mpTable->Init();
			    }
                if (mpTable && VCLRectangle(mpTable->getBounds()).IsInside(VCLPoint(rPoint)))
			        xAccessible = mpTable;
            }
            if (!xAccessible.is())
                xAccessible = GetNotesChilds()->GetAt(rPoint);
            if (!xAccessible.is())
            {
	            if (!mpHeader || !mpFooter)
                {
		            const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
		            ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );

                    if (!mpHeader)
                    {
                        mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, aCount.nBackShapes + aCount.nHeaders - 1);
                        mpHeader->acquire();
                    }
                    if (!mpFooter)
                    {
                        mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters - 1 );
                        mpFooter->acquire();
                    }
                }

                Point aPoint(VCLPoint(rPoint));

                if (VCLRectangle(mpHeader->getBounds()).IsInside(aPoint))
                    xAccessible = mpHeader;
                else if (VCLRectangle(mpFooter->getBounds()).IsInside(aPoint))
                    xAccessible = mpFooter;
            }
            if (!xAccessible.is())
                xAccessible = GetShapeChilds()->GetBackgroundShapeAt(rPoint);
	    }
    }

	return xAccessible;
}

void SAL_CALL ScAccessibleDocumentPagePreview::grabFocus() throw (uno::RuntimeException)
{
	ScUnoGuard aGuard;
    IsObjectValid();
	if (getAccessibleParent().is())
	{
		uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
		if (xAccessibleComponent.is())
		{
			// just grab the focus for the window
			xAccessibleComponent->grabFocus();
		}
	}
}

//=====  XAccessibleContext  ==============================================

sal_Int32 SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChildCount(void) throw (uno::RuntimeException)
{
	ScUnoGuard aGuard;
    IsObjectValid();

	long nRet = 0;
	if ( mpViewShell )
	{
		ScPagePreviewCountData aCount( mpViewShell->GetLocationData(), mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
		nRet = aCount.GetTotal();
	}

	return nRet;
}

uno::Reference<XAccessible> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleChild(sal_Int32 nIndex)
			    throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
{
	ScUnoGuard aGuard;
    IsObjectValid();
	uno::Reference<XAccessible> xAccessible;

	if ( mpViewShell )
	{
		const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
		ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );

		if ( nIndex < aCount.nBackShapes )
		{
			xAccessible = GetShapeChilds()->GetBackShape(nIndex);
		}
		else if ( nIndex < aCount.nBackShapes + aCount.nHeaders )
		{
			if ( !mpHeader )
            {
                mpHeader = new ScAccessiblePageHeader( this, mpViewShell, sal_True, nIndex );
                mpHeader->acquire();
            }

			xAccessible = mpHeader;
		}
		else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables )
		{
			if ( !mpTable )
            {
				mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
                mpTable->acquire();
				mpTable->Init();
            }
			xAccessible = mpTable;
		}
        else if ( nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nNoteParagraphs )
        {
            xAccessible = GetNotesChilds()->GetChild(nIndex - aCount.nBackShapes - aCount.nHeaders);
        }
		else if ( (nIndex < aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters) )
		{
			if ( !mpFooter )
            {
				mpFooter = new ScAccessiblePageHeader( this, mpViewShell, sal_False, nIndex );
                mpFooter->acquire();
            }
			xAccessible = mpFooter;
		}
		else
        {
            sal_Int32 nIdx(nIndex - (aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs + aCount.nFooters));
            if (nIdx < aCount.nForeShapes)
                xAccessible = GetShapeChilds()->GetForeShape(nIdx);
            else
                xAccessible = GetShapeChilds()->GetControl(nIdx - aCount.nForeShapes);
        }
	}

	if ( !xAccessible.is() )
		throw lang::IndexOutOfBoundsException();

	return xAccessible;
}

    ///	Return the set of current states.
uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDocumentPagePreview::getAccessibleStateSet(void)
					    throw (uno::RuntimeException)
{
	ScUnoGuard aGuard;
	uno::Reference<XAccessibleStateSet> xParentStates;
	if (getAccessibleParent().is())
	{
		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
		xParentStates = xParentContext->getAccessibleStateSet();
	}
	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
	if (IsDefunc(xParentStates))
		pStateSet->AddState(AccessibleStateType::DEFUNC);
    else
    {
	    // never editable
	    pStateSet->AddState(AccessibleStateType::ENABLED);
	    pStateSet->AddState(AccessibleStateType::OPAQUE);
	    if (isShowing())
		    pStateSet->AddState(AccessibleStateType::SHOWING);
	    if (isVisible())
		    pStateSet->AddState(AccessibleStateType::VISIBLE);
    }
	return pStateSet;
}

	//=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::getImplementationName(void)
				    throw (uno::RuntimeException)
{
	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScAccessibleDocumentPagePreview"));
}

uno::Sequence< ::rtl::OUString> SAL_CALL ScAccessibleDocumentPagePreview::getSupportedServiceNames(void)
			        throw (uno::RuntimeException)
{
	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
    sal_Int32 nOldSize(aSequence.getLength());
    aSequence.realloc(nOldSize + 1);
    ::rtl::OUString* pNames = aSequence.getArray();

	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.AccessibleSpreadsheetPageView"));

	return aSequence;
}

//=====  XTypeProvider  =======================================================

uno::Sequence<sal_Int8> SAL_CALL
	ScAccessibleDocumentPagePreview::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
	static uno::Sequence<sal_Int8> aId;
	if (aId.getLength() == 0)
	{
		aId.realloc (16);
		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
	}
	return aId;
}

//=====  internal  ========================================================

::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleDescription(void)
				    throw (uno::RuntimeException)
{
    rtl::OUString sDescription = String(ScResId(STR_ACC_PREVIEWDOC_DESCR));
	return sDescription;
}

::rtl::OUString SAL_CALL ScAccessibleDocumentPagePreview::createAccessibleName(void)
				    throw (uno::RuntimeException)
{
    rtl::OUString sName = String(ScResId(STR_ACC_PREVIEWDOC_NAME));
	return sName;
}

Rectangle ScAccessibleDocumentPagePreview::GetBoundingBoxOnScreen() const throw (uno::RuntimeException)
{
	Rectangle aRect;
	if (mpViewShell)
	{
		Window* pWindow = mpViewShell->GetWindow();
		if (pWindow)
			aRect = pWindow->GetWindowExtentsRelative(NULL);
	}
	return aRect;
}

Rectangle ScAccessibleDocumentPagePreview::GetBoundingBox() const throw (uno::RuntimeException)
{
	Rectangle aRect;
	if (mpViewShell)
	{
		Window* pWindow = mpViewShell->GetWindow();
		if (pWindow)
			aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
	}
	return aRect;
}

sal_Bool ScAccessibleDocumentPagePreview::IsDefunc(
	const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
	return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
		(rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
}

ScNotesChilds* ScAccessibleDocumentPagePreview::GetNotesChilds()
{
    if (!mpNotesChilds && mpViewShell)
    {
        mpNotesChilds = new ScNotesChilds(mpViewShell, this);

		const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
		ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );

        //!	order is background shapes, header, table or notes, footer, foreground shapes, controls
        mpNotesChilds->Init(aCount.aVisRect, aCount.nBackShapes + aCount.nHeaders);
    }
    return mpNotesChilds;
}

ScShapeChilds* ScAccessibleDocumentPagePreview::GetShapeChilds()
{
    if (!mpShapeChilds && mpViewShell)
    {
        mpShapeChilds = new ScShapeChilds(mpViewShell, this);
        mpShapeChilds->Init();
    }

    return mpShapeChilds;
}

//UNUSED2009-05 uno::Reference < XAccessible > ScAccessibleDocumentPagePreview::GetCurrentAccessibleTable()
//UNUSED2009-05 {
//UNUSED2009-05     if (!mpTable)
//UNUSED2009-05     {
//UNUSED2009-05         if ( mpViewShell )
//UNUSED2009-05         {
//UNUSED2009-05             const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
//UNUSED2009-05             ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
//UNUSED2009-05             //! order is background shapes, header, table or notes, footer, foreground shapes, controls
//UNUSED2009-05             sal_Int32 nIndex (aCount.nBackShapes + aCount.nHeaders);
//UNUSED2009-05 
//UNUSED2009-05             mpTable = new ScAccessiblePreviewTable( this, mpViewShell, nIndex );
//UNUSED2009-05             mpTable->acquire();
//UNUSED2009-05             mpTable->Init();
//UNUSED2009-05         }
//UNUSED2009-05     }
//UNUSED2009-05     return mpTable;
//UNUSED2009-05 }

//UNUSED2009-05 void ScAccessibleDocumentPagePreview::ChildCountChanged()
//UNUSED2009-05 {
//UNUSED2009-05     if (mpViewShell)
//UNUSED2009-05     {
//UNUSED2009-05         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
//UNUSED2009-05         ScPagePreviewCountData aCount( rData, mpViewShell->GetWindow(), GetNotesChilds(), GetShapeChilds() );
//UNUSED2009-05         //! order is background shapes, header, table or notes, footer, foreground shapes, controls
//UNUSED2009-05         if(mpHeader)
//UNUSED2009-05             mpHeader->SetCurrentIndexInParent(aCount.nBackShapes);
//UNUSED2009-05         if (mpTable)
//UNUSED2009-05             mpTable->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders);
//UNUSED2009-05         if (mpFooter)
//UNUSED2009-05             mpFooter->SetCurrentIndexInParent(aCount.nBackShapes + aCount.nHeaders + aCount.nTables + aCount.nNoteParagraphs);
//UNUSED2009-05 
//UNUSED2009-05         if (mpNotesChilds)
//UNUSED2009-05             mpNotesChilds->SetOffset(aCount.nBackShapes + aCount.nHeaders);
//UNUSED2009-05     }
//UNUSED2009-05 }
