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



#ifndef SDEXT_PRESENTER_TEXT_VIEW_HXX
#define SDEXT_PRESENTER_TEXT_VIEW_HXX

#include "PresenterTheme.hxx"
#include <com/sun/star/accessibility/XAccessibleText.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/geometry/RealPoint2D.hpp>
#include <com/sun/star/geometry/RealSize2D.hpp>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <com/sun/star/i18n/XScriptTypeDetector.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/basemutex.hxx>

namespace css = ::com::sun::star;
namespace cssu = ::com::sun::star::uno;
namespace cssa = ::com::sun::star::accessibility;

namespace sdext { namespace presenter {

class PresenterTextCaret
{
public:
    PresenterTextCaret (
        const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)>&
            rCharacterBoundsAccess,
        const ::boost::function<void(const css::awt::Rectangle&)>&
            rInvalidator);
    ~PresenterTextCaret (void);
        
    void ShowCaret (void);
    void HideCaret (void);

    sal_Int32 GetParagraphIndex (void) const;
    sal_Int32 GetCharacterIndex (void) const;
    void SetPosition (
        const sal_Int32 nParagraphIndex,
        const sal_Int32 nCharacterIndex);
    
    bool IsVisible (void) const;

    /** Set a (possibly empty) functor that broadcasts changes of the caret
        position.  This is used when a PresenterTextView object is set at
        the accessibility object so that accessibility events can be sent
        when the caret changes position.
    */
    void SetCaretMotionBroadcaster (
        const ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)>& rBroadcaster);

    css::awt::Rectangle GetBounds (void) const;

private:
    sal_Int32 mnParagraphIndex;
    sal_Int32 mnCharacterIndex;
    sal_Int32 mnCaretBlinkTaskId;
    bool mbIsCaretVisible;
    const ::boost::function<css::awt::Rectangle(const sal_Int32,const sal_Int32)> maCharacterBoundsAccess;
    const ::boost::function<void(const css::awt::Rectangle&)> maInvalidator;
    ::boost::function<void(sal_Int32,sal_Int32,sal_Int32,sal_Int32)> maBroadcaster;
    css::awt::Rectangle maCaretBounds;

    void InvertCaret (void);
};
typedef ::boost::shared_ptr<PresenterTextCaret> SharedPresenterTextCaret;




//===== PresenterTextParagraph ================================================

class PresenterTextParagraph
{
public:
    PresenterTextParagraph (
        const sal_Int32 nParagraphIndex,
        const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
        const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
        const cssu::Reference<css::text::XTextRange>& rxTextRange,
        const SharedPresenterTextCaret& rpCaret);
    PresenterTextParagraph (
        const sal_Int32 nParagraphIndex,
        const cssu::Reference<css::i18n::XBreakIterator>& rxBreakIterator,
        const cssu::Reference<css::i18n::XScriptTypeDetector>& rxScriptTypeDetector,
        const ::rtl::OUString& rsText,
        const SharedPresenterTextCaret& rpCaret);

    void Paint (
        const cssu::Reference<css::rendering::XCanvas>& rxCanvas,
        const css::geometry::RealSize2D& rSize,
        const PresenterTheme::SharedFontDescriptor& rpFont,
        const css::rendering::ViewState& rViewState,
        css::rendering::RenderState& rRenderState,
        const double nTopOffset,
        const double nClipTop,
        const double nClipBottom);

    sal_Int32 GetParagraphIndex (void) const;
    double GetTotalTextHeight (void);

    sal_Int32 GetCharacterOffset (void) const;
    void SetCharacterOffset (const sal_Int32 nCharacterOffset);
    sal_Int32 GetCharacterCount (void) const;
    sal_Unicode GetCharacter (const sal_Int32 nGlobalCharacterIndex) const;
    ::rtl::OUString GetText (void) const;
    cssa::TextSegment GetTextSegment (
        const sal_Int32 nOffset,
        const sal_Int32 nGlobalCharacterIndex,
        const sal_Int16 nTextType) const;
    cssa::TextSegment GetWordTextSegment (
        const sal_Int32 nOffset,
        const sal_Int32 nIndex) const;
    cssa::TextSegment CreateTextSegment (
        sal_Int32 nStartIndex,
        sal_Int32 nEndIndex) const;
    css::awt::Rectangle GetCharacterBounds (
        sal_Int32 nGlobalCharacterIndex,
        const bool bCaretBox);
    sal_Int32 GetIndexAtPoint (const css::awt::Point& rPoint) const;
    void SetupCellArray (
        const PresenterTheme::SharedFontDescriptor& rpFont);
    void Format (
        const double nY,
        const double nWidth,
        const PresenterTheme::SharedFontDescriptor& rpFont);
    sal_Int32 GetWordBoundary(
        const sal_Int32 nLocalCharacterIndex,
        const sal_Int32 nDistance);
    sal_Int32 GetCaretPosition (void) const;
    void SetCaretPosition (const sal_Int32 nPosition) const;
    void SetOrigin (const double nXOrigin, const double nYOrigin);
    css::awt::Point GetRelativeLocation (void) const;
    css::awt::Size GetSize (void);

private:
    ::rtl::OUString msParagraphText;
    const sal_Int32 mnParagraphIndex;
    SharedPresenterTextCaret mpCaret;

    /** A portion of a string that encodes one unicode cell.  It describes
        number of characters in the unicode string that make up the cell and its
        width in pixel (with respect to some configuration that is stored
        externally or implicitly).
    */
    class Cell
    {
    public:
        Cell (const sal_Int32 nCharacterIndex, const sal_Int32 nCharacterCount, const double nCellWidth);
        sal_Int32 mnCharacterIndex;
        sal_Int32 mnCharacterCount;
        double mnCellWidth;
    };

    class Line
    {
    public:
        Line (const sal_Int32 nLineStartCharacterIndex, const sal_Int32 nLineEndCharacterIndex);
        sal_Int32 mnLineStartCharacterIndex;
        sal_Int32 mnLineEndCharacterIndex;
        sal_Int32 mnLineStartCellIndex;
        sal_Int32 mnLineEndCellIndex;
        cssu::Reference<css::rendering::XTextLayout> mxLayoutedLine;
        double mnBaseLine;
        double mnWidth;
        cssu::Sequence<css::geometry::RealRectangle2D> maCellBoxes;
        
        sal_Int32 GetLength (void) const;
        void ProvideLayoutedLine (
            const ::rtl::OUString& rsParagraphText,
            const PresenterTheme::SharedFontDescriptor& rpFont,
            const sal_Int8 nTextDirection);
        void ProvideCellBoxes (void);
        bool IsEmpty (void) const;
    };


    cssu::Reference<css::i18n::XBreakIterator> mxBreakIterator;
    cssu::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
    ::std::vector<Line> maLines;
    ::std::vector<sal_Int32> maWordBoundaries;
    // Offset of the top of the paragraph with respect to the origin of the
    // whole text (specified by mnXOrigin and mnYOrigin).
    double mnVerticalOffset;
    double mnXOrigin;
    double mnYOrigin;
    double mnWidth;
    double mnAscent;
    double mnDescent;
    double mnLineHeight;
    css::style::ParagraphAdjust meAdjust;
    sal_Int8 mnWritingMode;
    /// The index of the first character in this paragraph with respect to
    /// the whole text.
    sal_Int32 mnCharacterOffset;
    ::std::vector<Cell> maCells;
    
    void AddWord (
        const double nWidth,
        css::i18n::Boundary& rCurrentLine,
        const sal_Int32 nWordBoundary,
        const PresenterTheme::SharedFontDescriptor& rpFont);
    void AddLine (
        css::i18n::Boundary& rCurrentLine);
    sal_Int8 GetTextDirection (void) const;
    bool IsTextReferencePointLeft (void) const;
};
typedef ::boost::shared_ptr<PresenterTextParagraph> SharedPresenterTextParagraph;




/** A simple text view that paints text onto a given canvas.
*/
class PresenterTextView
{
public:

    PresenterTextView (
        const css::uno::Reference<css::uno::XComponentContext>& rxContext,
        const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
        const ::boost::function<void(const ::css::awt::Rectangle&)>& rInvalidator);
    /** Create a new instance that does no output but only provides
        geometric information to an accessibility object.
    */
    PresenterTextView (
        const css::uno::Reference<css::uno::XComponentContext>& rxContext,
        const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);

    void SetText (const css::uno::Reference<css::text::XText>& rxText);
    void SetText (const ::rtl::OUString& rsText);
    void SetTextChangeBroadcaster (const ::boost::function<void(void)>& rBroadcaster);
    
    void SetLocation (const css::geometry::RealPoint2D& rLocation);
    void SetSize (const css::geometry::RealSize2D& rSize);
    double GetTotalTextHeight (void);
    
    void SetFont (const PresenterTheme::SharedFontDescriptor& rpFont);

    void SetOffset (
        const double nLeft,
        const double nTop);

    /** Move the caret forward or backward by character or by word.
        @param nDistance
            Should be either -1 or +1 to move caret backwards or forwards,
            respectively.
        @param nTextType
            Valid values are the
            com::sun::star::accessibility::AccessibleTextType constants.
    */
    void MoveCaret (
        const sal_Int32 nDistance,
        const sal_Int16 nTextType);
        
    void Paint (const css::awt::Rectangle& rUpdateBox);

    SharedPresenterTextCaret GetCaret (void) const;

    sal_Int32 GetParagraphCount (void) const;
    SharedPresenterTextParagraph GetParagraph (const sal_Int32 nParagraphIndex) const;

private:
    css::uno::Reference<css::rendering::XCanvas> mxCanvas;
    bool mbDoOuput;
    css::uno::Reference<css::i18n::XBreakIterator> mxBreakIterator;
    css::uno::Reference<css::i18n::XScriptTypeDetector> mxScriptTypeDetector;
    css::geometry::RealPoint2D maLocation;
    css::geometry::RealSize2D maSize;
    PresenterTheme::SharedFontDescriptor mpFont;
    ::std::vector<SharedPresenterTextParagraph> maParagraphs;
    SharedPresenterTextCaret mpCaret;
    double mnLeftOffset;
    double mnTopOffset;
    const ::boost::function<void(const ::css::awt::Rectangle&)> maInvalidator;
    bool mbIsFormatPending;
    sal_Int32 mnCharacterCount;
    ::boost::function<void(void)> maTextChangeBroadcaster;

    void RequestFormat (void);
    void Format (void);
    SharedPresenterTextParagraph GetParagraphForCharacterIndex (const sal_Int32 nCharacterIndex) const;
    sal_Int32 GetCharacterOffset (const sal_Int32 nParagraphIndex) const;
    css::awt::Rectangle GetCaretBounds (
        const sal_Int32 nParagraphIndex,
        const sal_Int32 nCharacterIndex) const;
};

} } // end of namespace ::sdext::presenter

#endif
