/**************************************************************
 * 
 * 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 _ITRFORM2_HXX
#define _ITRFORM2_HXX
#include "itrpaint.hxx"

class SwFlyCntPortion;
class SwInterHyphInfo;
class SwDropPortion;
class SwFmtDrop;
class SwTxtAttr;
class SwNumberPortion;
class SwErgoSumPortion;
class SwExpandPortion;
class SwMultiPortion;
class SwFtnPortion;
class SvLongs;

/*************************************************************************
 *						class SwTxtFormatter
 *************************************************************************/

class SwTxtFormatter : public SwTxtPainter
{
	const SwFmtDrop *pDropFmt;
	SwMultiPortion* pMulti;	// during formatting a multi-portion
	sal_uInt8 nCntEndHyph;	// zaehlt aufeinanderfolgende Hyphens am Zeilenende
	sal_uInt8 nCntMidHyph;	// zaehlt aufeinanderfolgende Hyphens vor Flies
	xub_StrLen nLeftScanIdx; // for increasing performance during
	xub_StrLen nRightScanIdx;	  // scanning for portion ends
	sal_Bool bOnceMore : 1; // noch 'ne Runde?
	sal_Bool bFlyInCntBase : 1; // Base-Referenz der zeichengeb. Rahmen setzen
	sal_Bool bChanges : 1; // Flag, fuer die Berechnung des Repaint-Rechtecks
	sal_Bool bTruncLines : 1; // Flag, Repaint-Rechtecks ggf. erweitern
	sal_Bool bUnclipped : 1; // Flag, ob Repaint groesser als feste Zeilenhoehe
    sal_uInt16 m_nHintEndIndex; // HACK for TryNewNoLengthPortion
	SwLinePortion *NewPortion( SwTxtFormatInfo &rInf );
	SwTxtPortion  *NewTxtPortion( SwTxtFormatInfo &rInf );
	SwLinePortion *NewExtraPortion( SwTxtFormatInfo &rInf );
    SwTabPortion *NewTabPortion( SwTxtFormatInfo &rInf, bool bAuto ) const;
	SwNumberPortion *NewNumberPortion( SwTxtFormatInfo &rInf ) const;
    SwDropPortion *NewDropPortion( SwTxtFormatInfo &rInf );
	SwNumberPortion *NewFtnNumPortion( SwTxtFormatInfo &rInf ) const;
	SwErgoSumPortion *NewErgoSumPortion( SwTxtFormatInfo &rInf ) const;
	SwExpandPortion *NewFldPortion( SwTxtFormatInfo &rInf,
									const SwTxtAttr *pHt ) const;
	SwFtnPortion *NewFtnPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt );
	SwFlyCntPortion *NewFlyCntPortion( SwTxtFormatInfo &rInf,
									   SwTxtAttr *pHt ) const;
    SwLinePortion *WhichFirstPortion( SwTxtFormatInfo &rInf );
	SwTxtPortion *WhichTxtPor( SwTxtFormatInfo &rInf ) const;
    SwExpandPortion * TryNewNoLengthPortion( SwTxtFormatInfo & rInfo );

	// Das Herzstueck der Formatierung
	void BuildPortions( SwTxtFormatInfo &rInf );
	sal_Bool BuildMultiPortion( SwTxtFormatInfo &rInf, SwMultiPortion& rMulti );

	// Berechnung des emulierten rechten Rands
    void CalcFlyWidth( SwTxtFormatInfo &rInf );

	// wird von SwTxtFormatter wegen UpdatePos ueberladen
	void CalcAdjustLine( SwLineLayout *pCurr );

    // consideres line spacing attributes
    void CalcRealHeight( sal_Bool bNewLine = sal_False );

	// uebertraegt die Daten nach rInf
	void FeedInf( SwTxtFormatInfo &rInf ) const;

	// behandelt die Unterlaufsituationen
	SwLinePortion *UnderFlow( SwTxtFormatInfo &rInf );

	// errechnet den Ascent und die Hoehe aus der Fontmetric
	void CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor );

    // determines, if a optimized repaint rectange is allowed
    sal_Bool AllowRepaintOpt() const;

    // calculates and sets the optimized repaint offset
    long CalcOptRepaint( xub_StrLen nOldLineEnd, const SvLongs* pFlyStart );

    // wird von FormatLine gerufen.
	void FormatReset( SwTxtFormatInfo &rInf );

	// durch das Adjustment aendert sich die Position der Portions
	void UpdatePos( SwLineLayout *pCurr, Point aStart, xub_StrLen nStartIdx,
			sal_Bool bAllWays = sal_False ) const;

	// Setze alle FlyInCntFrms auf die uebergebene BaseLine
	void AlignFlyInCntBase( long nBaseLine ) const;

	// Unterlaufbedingungen bei Flys
	sal_Bool ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const;

	// Portion einfuegen.
	void InsertPortion( SwTxtFormatInfo &rInf, SwLinePortion *pPor ) const;

	// schaetzt die Hoehe fuer die DropPortion
	void GuessDropHeight( const MSHORT nLines );

public:
	// errechnet die Hoehe fuer die DropPortion
	void CalcDropHeight( const MSHORT nLines );

	// errechnet den Bottom des Absatzes, beruecksichtigt an diesem verankerte
	// Objekte mit Umlauf 1. Absatz.
	SwTwips CalcBottomLine() const;

	// Beruecksichtigt zeichengebundene Objekte bei der Repaintrechteck-
	// berechnung in Zeilen mit fester Zeilenhoehe
	void CalcUnclipped( SwTwips& rTop, SwTwips& rBottom );

	// u.a. fuer DropCaps
	sal_Bool CalcOnceMore();

	void CtorInitTxtFormatter( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf );
    inline SwTxtFormatter( SwTxtFrm *pTxtFrm, SwTxtFormatInfo *pTxtFmtInf ) : SwTxtPainter(pTxtFrm!=NULL?pTxtFrm->GetTxtNode():NULL)
           { CtorInitTxtFormatter( pTxtFrm, pTxtFmtInf ); }
	~SwTxtFormatter();

	xub_StrLen FormatLine( const xub_StrLen nStart );

	void RecalcRealHeight();

	// Wir formatieren eine Zeile fuer die interaktive Trennung
	sal_Bool Hyphenate( SwInterHyphInfo &rInf );

	// Spezialmethode fuer QuoVadis-Texte
	// nErgo ist die Seitennummer der ErgoSum-Ftn
	// Bei 0 ist es noch unklar.
	xub_StrLen FormatQuoVadis( const xub_StrLen nStart );

	// Die Notbremse: Formatierung abbrechen, Zeile verwerfen.
	inline sal_Bool IsStop() const { return GetInfo().IsStop(); }

	// Das Gegenstueck: Formatierung unbedingt fortsetzen.
	inline sal_Bool IsNewLine() const { return GetInfo().IsNewLine(); }

	// FormatQuick(); auffrischen von Formatinformationen
	inline sal_Bool IsQuick() const { return GetInfo().IsQuick(); }

	// erzeugt ggfs. ein SwLineLayout, dass Ftn/Fly--Oszillation unterbindet.
	void MakeDummyLine();

	// SwTxtIter-Funktionalitaet
	void Insert( SwLineLayout *pLine );

	// die noch verbleibende Hoehe bis zum Seitenrand
	KSHORT GetFrmRstHeight() const;

	// Wie breit waerest Du ohne rechte Begrenzungen (Flys etc.)?
    SwTwips _CalcFitToContent( );

	SwLinePortion* MakeRestPortion(const SwLineLayout* pLine, xub_StrLen nPos);

	inline const SwFmtDrop *GetDropFmt() const { return pDropFmt; }
	inline void ClearDropFmt() { pDropFmt = 0; }

	inline SwMultiPortion *GetMulti() const { return pMulti; }

	inline sal_Bool IsOnceMore() const { return bOnceMore; }
	inline void		  SetOnceMore( sal_Bool bNew ) { bOnceMore = bNew; }

	inline sal_Bool HasChanges() const { return bChanges; }
	inline void		  SetChanges()		 { bChanges = sal_True; }

	inline sal_Bool HasTruncLines() const { return bTruncLines; }
	inline void		  SetTruncLines( sal_Bool bNew ) { bTruncLines = bNew; }

	inline sal_Bool IsUnclipped() const { return bUnclipped; }
	inline void		  SetUnclipped( sal_Bool bNew ) { bUnclipped = bNew; }

	inline sal_Bool IsFlyInCntBase() const { return bFlyInCntBase; }
	inline void	 SetFlyInCntBase( sal_Bool bNew = sal_True ){ bFlyInCntBase = bNew; }

	inline SwTxtFormatInfo &GetInfo()
		{ return (SwTxtFormatInfo&)SwTxtIter::GetInfo(); }
	inline const SwTxtFormatInfo &GetInfo() const
		{ return (const SwTxtFormatInfo&)SwTxtIter::GetInfo(); }

	inline void InitCntHyph() { CntHyphens( nCntEndHyph, nCntMidHyph ); }
	inline const sal_uInt8 &CntEndHyph() const { return nCntEndHyph; }
	inline const sal_uInt8 &CntMidHyph() const { return nCntMidHyph; }
	inline sal_uInt8 &CntEndHyph() { return nCntEndHyph; }
	inline sal_uInt8 &CntMidHyph() { return nCntMidHyph; }
};



#endif
