/**************************************************************
 * 
 * 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 _PORMULTI_HXX
#define _PORMULTI_HXX

#include "porlay.hxx"
#include "porexp.hxx"

class SwTxtFormatInfo;
class SwFldPortion;
class SwTxtCursor;
class SwLineLayout;
class SwTxtPaintInfo;
class SwTxtAttr;
class SfxPoolItem;
class SwFont;

/*-----------------02.02.01 15:01-------------------
 * SwMultiCreator is a small structur to create a multiportion.
 * It contains the kind of multiportion and a textattribute
 * or a poolitem.
 * The GetMultiCreator-function fills this structur and
 * the Ctor of the SwMultiPortion uses it.
 * --------------------------------------------------*/

#define SW_MC_DOUBLE	0
#define SW_MC_RUBY		1
#define SW_MC_ROTATE	2
#define SW_MC_BIDI      3

struct SwMultiCreator
{
	const SwTxtAttr* pAttr;
	const SfxPoolItem* pItem;
	sal_uInt8 nId;
    sal_uInt8 nLevel;
};

/*-----------------25.10.00 16:19-------------------
 * A two-line-portion (SwMultiPortion) could have surrounding brackets,
 * in this case the structur SwBracket will be used.
 * --------------------------------------------------*/

struct SwBracket
{
	xub_StrLen nStart;		// Start of text attribute determins the font
	KSHORT nAscent;         // Ascent of the brackets
	KSHORT nHeight;			// Height of them
	KSHORT nPreWidth;		// Width of the opening bracket
	KSHORT nPostWidth;      // Width of the closing bracket
	sal_Unicode cPre;       // Initial character, e.g. '('
	sal_Unicode cPost;      // Final character, e.g. ')'
	sal_uInt8 nPreScript;		// Script of the initial character
	sal_uInt8 nPostScript;       // Script of the final character
};

/*-----------------16.10.00 12:45-------------------
 * The SwMultiPortion is line portion inside a line portion,
 * it's a group of portions,
 * e.g. a double line portion in a line
 * or phonetics (ruby)
 * or combined characters
 * or a rotated portion.
 * --------------------------------------------------*/

class SwMultiPortion : public SwLinePortion
{
	SwLineLayout aRoot;		// One or more lines
	SwFldPortion *pFldRest;	// Field rest from the previous line
	sal_Bool bTab1		:1; // First line tabulator
	sal_Bool bTab2		:1; // Second line includes tabulator
	sal_Bool bDouble	:1; // Double line
	sal_Bool bRuby		:1; // Phonetics
    sal_Bool bBidi      :1;
    sal_Bool bTop       :1; // Phonetic position
	sal_Bool bFormatted :1; // Already formatted
	sal_Bool bFollowFld :1; // Field follow inside
	sal_uInt8 nDirection:2; // Direction (0/90/180/270 degrees)
	sal_Bool bFlyInCntnt:1; // Fly as character inside
protected:
	SwMultiPortion( xub_StrLen nEnd ) : pFldRest( 0 ), bTab1( sal_False ),
        bTab2( sal_False ), bDouble( sal_False ), bRuby( sal_False ),
        bBidi( sal_False ), bFormatted( sal_False ), bFollowFld( sal_False ),
        nDirection( 0 ), bFlyInCntnt( sal_False )
        { SetWhichPor( POR_MULTI ); SetLen( nEnd ); }
	inline void SetDouble() { bDouble = sal_True; }
	inline void SetRuby() { bRuby = sal_True; }
    inline void SetBidi() { bBidi = sal_True; }
    inline void SetTop( sal_Bool bNew ) { bTop = bNew; }
	inline void SetTab1( sal_Bool bNew ) { bTab1 = bNew; }
	inline void SetTab2( sal_Bool bNew ) { bTab2 = bNew; }
	inline void SetDirection( sal_uInt8 nNew ) { nDirection = nNew; }
	inline sal_Bool GetTab1() const { return bTab1; }
	inline sal_Bool GetTab2() const { return bTab2; }
public:
	~SwMultiPortion();
	const SwLineLayout& GetRoot() const { return aRoot; }
	SwLineLayout& GetRoot() { return aRoot; }
	SwFldPortion* GetFldRest() { return pFldRest; }
	void SetFldRest( SwFldPortion* pNew ) { pFldRest = pNew; }

	inline sal_Bool HasTabulator() const { return bTab1 || bTab2; }
	inline sal_Bool IsFormatted() const { return bFormatted; }
	inline void SetFormatted() { bFormatted = sal_True; }
	inline sal_Bool IsFollowFld() const { return bFollowFld; }
	inline void SetFollowFld() { bFollowFld = sal_True; }
	inline sal_Bool HasFlyInCntnt() const { return bFlyInCntnt; }
	inline void SetFlyInCntnt( sal_Bool bNew ) { bFlyInCntnt = bNew; }
	inline sal_Bool IsDouble() const { return bDouble; }
	inline sal_Bool IsRuby() const { return bRuby; }
    inline sal_Bool IsBidi() const { return bBidi; }
    inline sal_Bool OnTop() const { return bTop; }
	void ActualizeTabulator();

	virtual void Paint( const SwTxtPaintInfo &rInf ) const;
    virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
    virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;

	// Summarize the internal lines to calculate the (external) size
	void CalcSize( SwTxtFormatter& rLine, SwTxtFormatInfo &rInf );

    inline sal_Bool HasBrackets() const;
	inline sal_Bool HasRotation() const { return 0 != (1 & nDirection); }
	inline sal_Bool IsRevers() const { return 0 != (2 & nDirection); }
	inline sal_uInt8 GetDirection() const { return nDirection; }
	inline sal_uInt16 GetFontRotation() const
		{ return ( HasRotation() ? ( IsRevers() ? 2700 : 900 ) : 0 ); }

    // Accessibility: pass information about this portion to the PortionHandler
    virtual void HandlePortion( SwPortionHandler& rPH ) const;

	OUTPUT_OPERATOR
};

class SwDoubleLinePortion : public SwMultiPortion
{
	SwBracket* pBracket;	// Surrounding brackets
	SwTwips	nLineDiff;		// Difference of the width of the both lines
	xub_StrLen nBlank1;     // Number of blanks in the first line
	xub_StrLen nBlank2;     // Number of blanks in the second line
public:
    SwDoubleLinePortion( SwDoubleLinePortion& rDouble, xub_StrLen nEnd );
	SwDoubleLinePortion( const SwMultiCreator& rCreate, xub_StrLen nEnd );
	~SwDoubleLinePortion();

	inline SwBracket* GetBrackets() const { return pBracket; }
	void SetBrackets( const SwDoubleLinePortion& rDouble );
    void PaintBracket( SwTxtPaintInfo& rInf, long nSpaceAdd, sal_Bool bOpen ) const;
	void FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth );
	inline KSHORT PreWidth() const { return pBracket->nPreWidth; };
	inline KSHORT PostWidth() const { return pBracket->nPostWidth; }
	inline void ClearBrackets()
		{ pBracket->nPreWidth = pBracket->nPostWidth=0; Width( 0 ); }
	inline KSHORT BracketWidth(){ return PreWidth() + PostWidth(); }

	void CalcBlanks( SwTxtFormatInfo &rInf );
    static void ResetSpaceAdd( SwLineLayout* pCurr );
	inline SwTwips GetLineDiff() const { return nLineDiff; }
	inline xub_StrLen GetSpaceCnt() const
		{ return ( nLineDiff < 0 ) ? nBlank2 : nBlank1; }
	inline xub_StrLen GetSmallerSpaceCnt() const
		{ return ( nLineDiff < 0 ) ? nBlank1 : nBlank2; }
	inline xub_StrLen GetBlank1() const { return nBlank1; }
	inline xub_StrLen GetBlank2() const { return nBlank2; }

    virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
    virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;
};

class SwRubyPortion : public SwMultiPortion
{
	xub_StrLen nRubyOffset;
	sal_uInt16 nAdjustment;
	void _Adjust( SwTxtFormatInfo &rInf);
public:
    SwRubyPortion( const SwRubyPortion& rRuby, xub_StrLen nEnd );

    SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
                   const IDocumentSettingAccess& rIDocumentSettingAccess,
                   xub_StrLen nEnd, xub_StrLen nOffs,
                   const sal_Bool* pForceRubyPos );

    void CalcRubyOffset();
	inline void Adjust( SwTxtFormatInfo &rInf )
		{ if(nAdjustment && GetRoot().GetNext()) _Adjust(rInf); }
	inline sal_uInt16 GetAdjustment() const { return nAdjustment; }
	inline xub_StrLen GetRubyOffset() const { return nRubyOffset; }
};

class SwRotatedPortion : public SwMultiPortion
{
public:
	SwRotatedPortion( xub_StrLen nEnd, sal_uInt8 nDir = 1 )
		: SwMultiPortion( nEnd ) { SetDirection( nDir ); }
    SwRotatedPortion( const SwMultiCreator& rCreate, xub_StrLen nEnd,
                      sal_Bool bRTL );
};

class SwBidiPortion : public SwMultiPortion
{
    sal_uInt8 nLevel;

public:
    SwBidiPortion( xub_StrLen nEnd, sal_uInt8 nLv );

    inline sal_uInt8 GetLevel() const { return nLevel; }
    // Get number of blanks for justified alignment
    xub_StrLen GetSpaceCnt( const SwTxtSizeInfo &rInf ) const;
    // Calculates extra spacing based on number of blanks
    virtual long CalcSpacing( long nSpaceAdd, const SwTxtSizeInfo &rInf ) const;
    // Manipulate the spacing array at pCurr
    virtual sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, long nSpaceAdd ) const;
};

// For cursor travelling in multiportions

class SwTxtCursorSave
{
	SwTxtCursor* pTxtCrsr;
	SwLineLayout* pCurr;
	SwTwips nWidth;
	xub_StrLen nStart;
	sal_uInt8 nOldProp;
	sal_Bool bSpaceChg;
public:
    SwTxtCursorSave( SwTxtCursor* pTxtCursor, SwMultiPortion* pMulti,
        SwTwips nY, sal_uInt16& nX, xub_StrLen nCurrStart, long nSpaceAdd );
    ~SwTxtCursorSave();
};

/*************************************************************************
 *					inline - Implementations
 *************************************************************************/

inline sal_Bool SwMultiPortion::HasBrackets() const
{
    return sal::static_int_cast< sal_Bool >( IsDouble() ?
                                             0 != ((SwDoubleLinePortion*)this)->GetBrackets() :
                                             sal_False );
}

CLASSIO( SwMultiPortion )

#endif
