/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: txtwindw.h,v 1.1.2.2 2004/07/09 01:50:15 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

/////////////////////////////////////////////////////////////////////////////
//
//  TXTWINDW.H
//
//  TextWindow class declaration.
//
//	A class TextWindow object holds the location, size, background color,
//	...etc for the space on the screen where the text is to be rendered.
//
//
//

#if !defined(_TXTWINDW_HPP_)
#define _TXTWINDW_HPP_


class Dict;

#include "hxwintyp.h" //for struct HXxWindow.
#if defined(_WINDOWS)
#include <windows.h>
#elif defined(_MACINTOSH)
#ifndef _MAC_MACHO
#include <qdoffscreen.h>
#endif
#endif
#if defined(_UNIX) && !defined(_MAC_UNIX)
#include "hxmap.h"
#endif


#if defined(_WINDOWS)
#if !defined(_WIN16)  //XXXXXEH- OK in WIN16, too?  MS doc says no...
#define USE_DIB_SECTION
#endif
#endif

#define MIN_SCROLLRATE			    (-8192L)
#define MAX_SCROLLRATE			    (8192L)
#define MIN_CRAWLRATE			    (-8192L)
#define MAX_CRAWLRATE			    (8192L)

#define MIN_WINDOWWIDTH			    4
#define MIN_WINDOWHEIGHT		    4

/*  TextWindow::type possible values:  */
#define TYPE_UNSPECIFIED		    0x00000000 /*invalid type.*/
#define TYPE_GENERIC			    0x00000001 /*has no scroll/crawl.*/
#define TYPE_TICKERTAPE			    0x00000002 /*has a set crawlrate.*/
#define TYPE_SCROLLINGNEWS		    0x00000003 /*vertical scrollbar.*/
#define TYPE_TELEPROMPTER		    0x00000004 /*variable scrollrate.*/
#define TYPE_MARQUEE			    0x00000005 /*has a set crawlrate.*/

/*  Miscl invalid vals that signal that default must be dynamically chosen;
 *  e.g., one type RealText window may default to black background while
 *  another may default to white, so in creating a TextWindow object, invalid
 *  vals must be used so that, when a RealText window type is specified, the
 *  other textWindow values not specified can be defaulted appropriately:  */
#define WINDOW_DIMENSION_UNSPECIFIED	    (-1L)
#define BGCOLOR_NAME_UNSPECIFIED	    ""
#define BGCOLOR_NAME_LEN_UNSPECIFIED	    0L
#define BGCOLOR_RGB_UNSPECIFIED		    BAD_RGB_COLOR					
#define SCROLLRATE_UNSPECIFIED		    (MAX_SCROLLRATE+1) 
#define CRAWLRATE_UNSPECIFIED		    (MAX_CRAWLRATE+1) 
#define DOLOOP_UNSPECIFIED		    (-1L)
#define SCROLLTYPE_UNSPECIFIED		    0xFFFFFFFF

/*  TextWindow::scrollType possible values. Note that they can be combined
 *  with each other for hybrid types:  */
#define SCROLLTYPE_NOSCROLL		    0x00000000
#define SCROLLTYPE_VSCROLLBAR		    0x00000001
#define SCROLLTYPE_HSCROLLBAR		    0x00000002
#define SCROLLTYPE_TELEPROMPTER		    0x00000004
#define SCROLLTYPE_SETRATE		    0x00000008

/*  Other TextWindow defualts:  */
#define DEFAULT_BORDERSIZE		    1L

/*  Defaults to aspect ratio of movies, i.e., 16:9 ratio:  */
#define DEFAULT_WINDOWWIDTH		    320L
#define DEFAULT_WINDOWHEIGHT		    180L
#define DEFAULT_WINDOWWIDTH_GENERIC	    DEFAULT_WINDOWWIDTH
#define DEFAULT_WINDOWHEIGHT_GENERIC	    DEFAULT_WINDOWHEIGHT
#define DEFAULT_WINDOWWIDTH_SCROLLINGNEWS   DEFAULT_WINDOWWIDTH
#define DEFAULT_WINDOWHEIGHT_SCROLLINGNEWS  DEFAULT_WINDOWHEIGHT
#define DEFAULT_WINDOWWIDTH_TICKERTAPE	    500L
#define DEFAULT_WINDOWHEIGHT_TICKERTAPE	    30L
#define DEFAULT_WINDOWWIDTH_TELEPROMPTER    DEFAULT_WINDOWWIDTH
#define DEFAULT_WINDOWHEIGHT_TELEPROMPTER   DEFAULT_WINDOWHEIGHT
#define DEFAULT_WINDOWWIDTH_MARQUEE	    DEFAULT_WINDOWWIDTH_TICKERTAPE
#define DEFAULT_WINDOWHEIGHT_MARQUEE	    DEFAULT_WINDOWHEIGHT_TICKERTAPE

#define DEFAULT_IS_LIVE_SOURCE		    FALSE

#define DEFAULT_WINDOWUPPERLEFTX	    0L
#define DEFAULT_WINDOWUPPERLEFTY	    0L

#define DEFAULT_BGCOLOR_RGB		    0x00FFFFFF /*white*/
#define DEFAULT_BGCOLOR_RGB_GENERIC	    DEFAULT_BGCOLOR_RGB
#define DEFAULT_BGCOLOR_RGB_SCROLLINGNEWS   DEFAULT_BGCOLOR_RGB
#define DEFAULT_BGCOLOR_RGB_TICKERTAPE	    0x00000000 /*black*/
#define DEFAULT_BGCOLOR_RGB_TELEPROMPTER    DEFAULT_BGCOLOR_RGB
#define DEFAULT_BGCOLOR_RGB_MARQUEE	    DEFAULT_BGCOLOR_RGB

#define DEFAULT_SCROLLRATE		    0L /*pixels per second*/
#define DEFAULT_CRAWLRATE		    0L /*pixels per second*/
#define DEFAULT_SCROLLRATE_GENERIC	    DEFAULT_SCROLLRATE
#define DEFAULT_CRAWLRATE_GENERIC	    DEFAULT_CRAWLRATE
#define DEFAULT_SCROLLRATE_SCROLLINGNEWS    10L /*pixels per second*/
#define DEFAULT_CRAWLRATE_SCROLLINGNEWS	    0L /*pixels per second*/
#define DEFAULT_SCROLLRATE_TICKERTAPE	    0L /*pixels per second*/
#define DEFAULT_CRAWLRATE_TICKERTAPE	    20L /*pixels per second*/
#define DEFAULT_SCROLLRATE_TELEPROMPTER	    0L
#define DEFAULT_CRAWLRATE_TELEPROMPTER	    0L
#define DEFAULT_SCROLLRATE_MARQUEE	    DEFAULT_SCROLLRATE_TICKERTAPE
#define DEFAULT_CRAWLRATE_MARQUEE	    DEFAULT_CRAWLRATE_TICKERTAPE

#define DEFAULT_TYPE			    TYPE_GENERIC

#define DEFAULT_SCROLLTYPE		    SCROLLTYPE_NOSCROLL
#define DEFAULT_SCROLLTYPE_GENERIC	    DEFAULT_SCROLLTYPE
#define DEFAULT_SCROLLTYPE_SCROLLINGNEWS    SCROLLTYPE_VSCROLLBAR
#define DEFAULT_SCROLLTYPE_TICKERTAPE	    SCROLLTYPE_SETRATE
#define DEFAULT_SCROLLTYPE_TELEPROMPTER	    SCROLLTYPE_NOSCROLL
#define DEFAULT_SCROLLTYPE_MARQUEE	    DEFAULT_SCROLLTYPE_TICKERTAPE

#define DEFAULT_DOLOOP			    FALSE
#define DEFAULT_DOLOOP_GENERIC		    DEFAULT_DOLOOP
#define DEFAULT_DOLOOP_SCROLLINGNEWS	    FALSE
#define DEFAULT_DOLOOP_TICKERTAPE	    TRUE
#define DEFAULT_DOLOOP_TELEPROMPTER	    FALSE
#define DEFAULT_DOLOOP_MARQUEE		    TRUE

#define DEFAULT_DONT_IGNORE_EXTRA_SPACES    TRUE

#define DEFAULT_DO_UNDERLINE_HYPERLINKS	    TRUE
#define DEFAULT_USE_WORDWRAP		    TRUE
#define DEFAULT_EXPAND_TABS		    TRUE /* for plain text only*/
#define DEFAULT_LINKCOLOR		    0x000000FF  /* blue */
#define DEFAULT_FONT_WEIGHT		    400

  
/*  The following is the amount of blank pixels to add in x if a <BR> is
 *  seen in a crawl-only (i.e., scrollRate==0 and crawlRate!=0) window:  */
#define BREAK_WIDTH_IN_PIXELS		    10L
#define MIN_LINE_BREAK_SIZE		    5L
#define DEFAULT_LINE_BREAK_SIZE		    16L

/*  This is the X-offset that each Lower-text-Tickertape item is from the
 *  preceding upper-text item:  */
#define TICKER_GOINGLOWERITEM_SPACING	    10L
/*  This is the X-offset that each Upper-text-Tickertape item is from the
 *  preceding lower-text item:  */
#define TICKER_GOINGUPPERITEM_SPACING	    20L
/*  This is the Y-offset that Tickertape LowerText is from Tickertape
 *  UpperText:  */
#define TICKERLOWERTEXT_YOFFSET		    10L /*in pixels.*/

#define INVALID_LONG32			    0x80000001 /* ==-2147483647 */


typedef enum
{
    kHAlignLeft,
    kHAlignCenter,
    kHAlignRight,
    kHAlignInvalid
} textHorizAlign;

typedef enum
{
    kVAlignTop,
    kVAlignCenter,
    kVAlignBottom,
    kVAlignInvalid
} textVertAlign;



//////////////////////////////////////////////////////////////////////////////
//
//  TextWindowBase class.  This class contains all the junk needed by
//  both the text renderer and the text file format plugins;
//  class TextWindow, below, is what the renderer uses and TextWindowFF,
//  further below, is what the file format uses.  Each of these inherits
//  class TextWindowBase:
//
class TextWindowBase : public TextAttributeStacks, public TextContainerList
{
  public:
    TextWindowBase();
    
    ~TextWindowBase();

    TextLineList* m_pTLList;

    //This exists to keep track of where in the rtx file the </FONT> tags
    // are and what they "pop" to (i.e., what font attributes the text that
    // follows the </FONT> tag has).
    TextLineList* m_pFontUndoTagList;
    
    void reset();

    LONG32 getScrollRate() { return m_scrollRate; }
    LONG32 getCrawlRate() { return m_crawlRate; }
    BOOL setScrollRate(LONG32 sr);
    BOOL setScrollRate(_CHAR* pBuf, ULONG32 bufLen);

    BOOL setCrawlRate(LONG32 cr);
    BOOL setCrawlRate(_CHAR* pBuf, ULONG32 bufLen);

    BOOL isLooping() { return m_loop; }
    void loop(BOOL doLoop) { m_loop = doLoop; }
    BOOL setLoop(_CHAR* pBuf, ULONG32 bufLen);

    BOOL DontIgnoreExtraSpaces() { return m_bDontIgnoreExtraSpaces; }
    BOOL IgnoreExtraSpaces() { return !m_bDontIgnoreExtraSpaces; }
    BOOL SetExtraSpacesHandling(_CHAR* pBuf, ULONG32 bufLen);

    ULONG32 getNumBreakTagsEncountered() { return m_numBreakTagsEncountered;}
    void incrementNumBreakTagsEncountered() { m_numBreakTagsEncountered++; }
    void clearNumBreakTagsEncountered() { m_numBreakTagsEncountered = 0L; }

    //Takes "WINDOW [someString]" in headerTagBuf and parses the
    // <WINDOW ..> tag values out of "[someString]" and places those
    // values in the TextWindow.  Is in file "TW_Parse.cpp":
    BOOL parseHeaderTag(_CHAR* pHeaderTagBuf, ULONG32 headerTagBufLen,
	    ULONG32 ulRTFileFormatMarkupParsingMajorVersion,
	    ULONG32 ulRTFileFormatMarkupParsingMinorVersion);

    //Returns FALSE if colorName contains unrecognized color:
    BOOL setBackgroundColor(_CHAR* pColorName, ULONG32 colorNameLen);
    //Returns FALSE if colorName contains and invalid value:
    BOOL setBackgroundColorFromHexValString(
		    _CHAR* pColorHexVal, ULONG32 colorHexValLen);

    // Returns FALSE if ulOpacity is > 255.
    // Default value is 255 - fully opaque
    BOOL   setBackgroundOpacity(UINT32 ulOpacity);
    UINT32 getBackgroundOpacity() const { return m_ulBackgroundOpacity; }

    // Returns FALSE if ulOpacity is > 255.
    // Default value is 255 - fully opaque
    BOOL   setMediaOpacity(UINT32 ulOpacity);
    UINT32 getMediaOpacity() const { return m_ulMediaOpacity; }

    // Chroma key related members
    BOOL   isChromaKeySet()        const { return m_bIsChromaKeySet;      }
    UINT32 getChromaKey()          const { return m_ulChromaKey;          }
    BOOL   setChromaKey(UINT32 ulColor);
    UINT32 getChromaKeyTolerance() const { return m_ulChromaKeyTolerance; }
    BOOL   setChromaKeyTolerance(UINT32 ulTol);
    UINT32 getChromaKeyOpacity()   const { return m_ulChromaKeyOpacity;   }
    BOOL   setChromaKeyOpacity(UINT32 ulOpacity);

    BOOL setHeight(_CHAR* pBuf, ULONG32 bufLen);
    
    BOOL setWidth(_CHAR* pBuf, ULONG32 bufLen);

#if defined(_DEBUG)
    BOOL setDebugFlags(_CHAR* pBuf, ULONG32 bufLen);
    ULONG32 getDebugFlags() { return m_ulDebugFlags; }
#endif

    //Added the following functions so author can
    // specify the color of hyperlinked text:
    BOOL setLinkColor(_CHAR* pColorName, ULONG32 colorNameLen);
    COLORTYPE getLinkColor() { return m_linkColor; }

    //Added the following functions so author can
    // specify whether or not hyperlinks get underlined automatically:
    BOOL setUnderlineHyperlinks(_CHAR* pBuf, ULONG32 bufLen);
    BOOL usingUnderlineHyperlinks() { return m_bUnderlineHyperlinks; }

    //Added the following so that authors could change
    // the font color inside hyperlinked text and still have it go
    // back to the proper font color when the hyperlinked text is done:
    void setNumberOfFontColorPushesInsideLinkText(ULONG32 numPshs)
    {	m_ulNumberOfFontColorPushesInsideLinkText = numPshs; }
    ULONG32 getNumberOfFontColorPushesInsideLinkText()
    {	return m_ulNumberOfFontColorPushesInsideLinkText; }
    void incrementNumberOfFontColorPushesInsideLinkText()
    {	m_ulNumberOfFontColorPushesInsideLinkText++; }
    void decrementNumberOfFontColorPushesInsideLinkText()
    {	if(m_ulNumberOfFontColorPushesInsideLinkText)
	    m_ulNumberOfFontColorPushesInsideLinkText--;
    }

    //Added the following functions so author can
    // specify whether or not wordwrap is performed (but wordwrap is
    // NEVER done if there is a crawlrate only, i.e., perfectly
    // horizontal motion of the text):
    BOOL setWordwrap(_CHAR* pBuf, ULONG32 bufLen);
    void setWordwrap(BOOL bUseWrdWrp) { m_bUseWordwrap = bUseWrdWrp; }
    BOOL usingWordwrap() { return (m_bUseWordwrap  &&  (!m_crawlRate
	    ||  m_scrollRate) ); }

    void setExpandTabs(BOOL bExpTabs) { m_bExpandTabs = bExpTabs; }
    BOOL expandTabs() { return m_bExpandTabs; }

    textHorizAlign getHorizAlign() { return m_kHorizAlign; }
    void setHorizAlign(textHorizAlign kHzAl) { m_kHorizAlign = kHzAl; }
    textVertAlign getVertAlign() { return  m_kVertAlign; }
    void setVertAlign(textVertAlign kVtAl)
    {
	m_kVertAlign = kVtAl; m_bVertAlignWasExplicitlySet = TRUE;
    }
    BOOL wasVertAlignExplicitlySet() { return m_bVertAlignWasExplicitlySet; }

    void setRightToLeftReading(BOOL bRTL) { m_bRightToLeft = bRTL; }
    BOOL isRightToLeftReading() { return m_bRightToLeft; }

    void setUserPrefSizeIsRelative() { m_bUserPrefSizeIsRelative = TRUE; }
    void setUserPrefSizeIsAbsolute() { m_bUserPrefSizeIsRelative = FALSE; }

    HX_RESULT setUserPrefRelativeTextSizing(ULONG32 ulTextSizeScaleFactor);
    HX_RESULT setUserPrefAbsoluteTextSizing(ULONG32 ulTextPointSize);

    HX_RESULT setDefaultPtSize(ULONG32 ulPtSz);// /fails if user pref overrides
    ULONG32 getDefaultPtSize() { return m_ulDefaultPointSize; }
    HX_RESULT scaleDefaultPtSize(double dScaleFactor);// /user pref may override

    void setDefaultTextColor(COLORTYPE defaultTextColor) {
	    m_defaultTextColor = defaultTextColor; }
    COLORTYPE getDefaultTextColor() { return m_defaultTextColor; }

    void setDefaultTextBgColor(COLORTYPE defaultTextBgColor) {
	    m_defaultTextBgColor = defaultTextBgColor; }
    COLORTYPE getDefaultTextBgColor() { return m_defaultTextBgColor; }

    HX_RESULT setDefaultFontFaceString(const char* pszFace);
    const char* getDefaultFontFaceString()
    {
	return (const char*)m_pDefaultFontFaceString;
    }

    HX_RESULT setDefaultCharsetString(const char* pszCharset);
    const char* getDefaultCharsetString()
    {
	return (const char*)m_pDefaultCharsetString;
    }
    HX_RESULT getCharsetULONG32(const char* pszCharset,
	    UINT16 uiMaxLevelSupported,
	    ULONG32& ulCharset /*OUT*/);

    BOOL isCharsetTranslatedForOS() { return m_bIsCharsetTranslatedForOS; }
    void setCharsetTranslatedForOS(BOOL bCITFOS)
    {
	m_bIsCharsetTranslatedForOS = bCITFOS;
    }

    void setDefaultFontWeight(UINT32 ulWeight);
    UINT32 getDefaultFontWeight() { return m_ulDefaultFontWeight; }

    void setDefaultFontStyleIsItalic(BOOL bIsItalic)
    {
	m_bDefaultFontStyleIsItalic = bIsItalic;
    }
    BOOL isDefaultFontStyleItalic() { return m_bDefaultFontStyleIsItalic; }

    // /Angle of a line of text:
    double getPlainTextAngleOfEscapement()  { return m_dAngleOfEscapement; }
    void setPlainTextAngleOfEscapement(double dAngle)
	{ m_dAngleOfEscapement = dAngle; }

    // /Make sure this is same as above if no param (i.e., defaults to
    // angleOfEscapement()):
    // /XXXEH- If Chinese or Japanese, should this be 0 if escapement is 90 or 180?
    //base-line orientation angle (==escapement Win95):
    double getPlainTextAngleOfCharOrientation()
	{ return (m_bAngleOfCharOrientationWasExplicitlySet ?
	  m_dAngleOfCharOrientation : m_dAngleOfEscapement); }
    void setPlainTextAngleOfCharOrientation(double dAngle)
	{ m_dAngleOfCharOrientation = dAngle;
	  m_bAngleOfCharOrientationWasExplicitlySet = TRUE; }
    BOOL wasAngleOfCharOrientationExplicitlySet()
    { return m_bAngleOfCharOrientationWasExplicitlySet; }


    //Added the following function to keep track of live src:
    BOOL setIsLiveSource(_CHAR* pBuf, ULONG32 bufLen);
    BOOL isLiveSource() { return m_bIsLiveSource; }

    ULONG32 getTimeAtStartup() {return m_ulTimeAtStartup;}
    void setTimeAtStartup(ULONG32 ulTAS, ULONG32& ulTOLTS)
	{m_ulTimeAtStartup = ulTOLTS = ulTAS;}

    ULONG32 getScrollType() { return m_scrollType; }
#if defined(SHOW_CODE_CHANGE_MESSAGES)
#pragma message("EH- in "__FILE__", need setScrollType(_CHAR* pBuf) \
		    function; find out why it's not used in .cpp code yet")
#endif
    ULONG32 getType() { return m_type; }
    BOOL setType(_CHAR* pBbuf, ULONG32 bufLen);

    BOOL hasThinBorder() { return (m_borderSize > 0); }
    ULONG32 borderSize() { return (m_borderSize); }
    
    //The following four functions return the REQUESTED size and location
    // of the window (which the rtx-file author specified in the header but
    // that may be different from the ACTUAL values because a layout metafile
    // can override these values):
    LONG32 getUpperLeftX() { return m_upperLeftX;}
    LONG32 getUpperLeftY() { return m_upperLeftY;}
    LONG32 getWidth()      { return (m_width); } 
    LONG32 getHeight()     { return (m_height); }

    HX_RESULT overrideDefaultWindowWidth(LONG32 ulNewWindowWidth);
    HX_RESULT overrideDefaultWindowHeight(LONG32 ulNewWindowHeigth);

    BOOL setContentVersion(_CHAR* pBuf, ULONG32 bufLen);
    ULONG32 getMajorContentVersion() { return m_ulContentMajorVersion; }
    ULONG32 getMinorContentVersion() { return m_ulContentMinorVersion; }

    void setUpperLeftX(LONG32 x) { m_upperLeftX=x;}
    void setUpperLeftY(LONG32 y) { m_upperLeftY=y;}
    
    COLORTYPE getBackgroundColor() { return m_backgroundColor; }

    ULONG32 string_to_ULONG32(_CHAR* pBbuf, BOOL& didErrorOccur);

    double string_to_double(_CHAR* pBuf, BOOL& didErrorOccur,
	    ULONG32& ulIntegerPart, ULONG32& ulDecimalPart);

    LONG32 string_to_LONG32(_CHAR* pBuf, BOOL& didErrorOccur);

    BOOL string_to_BOOL(_CHAR* pBuf, ULONG32 bufLen, BOOL& didErrorOccur);

    //Added the following to keep track of when the last
    // <CLEAR> tag was sent (i.e., the time associated with it) so that
    // the loss of a packet with a <CLEAR> tag in it doesn't affect the
    // setting of the text of subsequent packets' positions in the window:
    void setTimeOfLastClearTag()
	    { m_ulTimeOfLastClearTag = GetLatestSentTimeToRender(); }
    void setTimeOfLastClearTag(ULONG32 timeOfLC)
	    { m_ulTimeOfLastClearTag=timeOfLC; }
    ULONG32 getTimeOfLastClearTag() { return m_ulTimeOfLastClearTag; }

    //Added the following so each packet can tell us
    // where to start drawing its text:
    void SetNewPktStartXAtTimeZero(LONG32 x) { m_newPktStartXAtTimeZero=x; }
    void SetNewPktStartYAtTimeZero(LONG32 y) { m_newPktStartYAtTimeZero=y; }
    LONG32 GetNewPktStartXAtTimeZero() { return m_newPktStartXAtTimeZero; }
    LONG32 GetNewPktStartYAtTimeZero() { return m_newPktStartYAtTimeZero; }

    BOOL m_bClearWasJustSent; //added this for <CLEAR>-tag handling.
    BOOL m_bUseXPOSVal; //For handling cas where <POS X=x/> immediately
			// follows packet header.
    BOOL m_bUseYPOSVal; //For handling cas where <POS Y=y/> immediately
			// follows packet header.

    //Tells whether we're currently parsing inside HTML-style comments, i.e.,
    // <!-- we're inside a comment --> :
    ULONG32 getCommentTagNestCount();
    void setInsideCommentTagNestCount(ULONG32 ulCTNC);
    ULONG32 incrementCommentTagNestCount();
    ULONG32 decrementCommentTagNestCount();

    ULONG32 GetNumNewlinesStatedInPacketHeader()
    {	return m_ulNumNewlinesStatedInPacketHeader;   }
    void SetNumNewlinesStatedInPacketHeader(ULONG32 ulNNlSIPH)
    {	m_ulNumNewlinesStatedInPacketHeader = ulNNlSIPH;   }

    LONG32 getCurrentTextLineEndX() { return m_currentTextLineEndX; }

    UINT32 m_ulDuration;

  protected:

    //As found in the <window version="maj.min"> string in the rt file:
    ULONG32 m_ulContentMajorVersion;
    ULONG32 m_ulContentMinorVersion;

    //The following are the initial coordinates of the window relative to
    // its parent window's client area coordinate system:
    LONG32 m_upperLeftX; //Upper left X of window
    LONG32 m_upperLeftY; //Upper left Y of window 
    LONG32 m_width; //Width of window's client area 
    LONG32 m_height; //Height of window's client area

    //In pixels; if >0, then window has WS_BORDER style;
    // If > 1, same as ==1 as of 12/29/1996:
    ULONG32 m_borderSize;

    //Units per second scrolling downward, where units are in
    // pixels if MAPMODE_PIXLES==m_mapMode, or
    // twips (1/1440th of an inch) if MAPMODE_TWIPS==m_mapMode:
    LONG32 m_scrollRate;
    //Units per second to the right, where units are in
    // pixels if MAPMODE_PIXLES==m_mapMode, or
    // twips (1/1440th of an inch) if MAPMODE_TWIPS==m_mapMode:
    LONG32 m_crawlRate;
    //The window type in which the text will be rendered;
    // TYPE_GENERIC for non-moving text:
    // TYPE_TICKERTAPE for tickertape text that moves horizontally,
    // TYPE_SCROLLINGNEWS for text that scrolls upward,
    // TYPE_TELEPROMPTER for text that scrolls upward,
    // TYPE_MARQUEE for vertically-centered text with a set crawlrate:
    ULONG32 m_type;  
    //Stores the scroll type, e.g. "setrate" SCROLLTYPE is 
    // SCROLLTYPE_SETRATE:
    ULONG32 m_scrollType;  //XXXEH- unfinished code; not implemented
    //Background color in 0x00bbggrr format:
    COLORTYPE m_backgroundColor;  
    // Opacity of background color (0=fully transparent, 255=fully opaque)
    // Default is 255.
    UINT32 m_ulBackgroundOpacity;
    // Opacity of foreground text color (0=fully transparent, 255=fully opaque)
    // Default is 255.
    UINT32 m_ulMediaOpacity;
    // Chroma-key-related members
    BOOL   m_bIsChromaKeySet;       // Default FALSE
    UINT32 m_ulChromaKey;
    UINT32 m_ulChromaKeyTolerance;  // Default 0x00000000
    UINT32 m_ulChromaKeyOpacity;    // Default 0 (fully transparent)
    //If true, re-shows buffered text at start of TextContainerList
    // when last text has been rendered in a scrolling or crawling window
    // (and no new text is being streamed at the moment).
    // Note: is ignored if window has a zero scrollrate and crawlrate):
    BOOL m_loop;	 
    //This tells us whether or not we should treat n contiguous spaces in
    // raw RealText as n spaces or as a single space:
    BOOL m_bDontIgnoreExtraSpaces;
    
    //Determines a new block of text's position:
    ULONG32 m_numBreakTagsEncountered; 
		    
    LONG32 m_currentTextLineStartY;
    LONG32 m_currentTextLineEndY;
    //Added the following vars needed to keep track of
    // current line's x-extent so that, if crawlrate !=0  &&  scrollrate !=0,
    // the insertion of the next line's text, i.e., the text immediately
    // following a <BR>, can be calculated at the proper angle relative to
    // the start location of the previous line of text:
    LONG32 m_currentTextLineStartX;
    LONG32 m_currentTextLineEndX;

    //Added the following for horizontal-motion-only
    // windows so that fake new lines can be made so the file format can
    // more intelligently break up the data into time-sensitive chunks
    // (like it does with wordwrapped and <BR>-filled text):
    LONG32 m_xOfFakeNewLine;

    ULONG32 m_ulNumNewlinesStatedInPacketHeader;

    //added the following 3 members;
    COLORTYPE m_linkColor; // Hyperlinked text color.
    BOOL m_bUnderlineHyperlinks;//specifies whether or not to underline links.
    BOOL m_bUseWordwrap;//specifies whether or not wordwrap should be done.

    // /Added the following for plain text; these values get set via <param>
    // elements as children of a plain text ref in a SMIL 2+ file:
    BOOL m_bExpandTabs; //For plain text: to treat tabs literally or not
    textHorizAlign m_kHorizAlign;
    textVertAlign m_kVertAlign;
    BOOL m_bVertAlignWasExplicitlySet;
    BOOL m_bRightToLeft;
    char* m_pDefaultFontFaceString;
    char* m_pDefaultCharsetString;
    BOOL m_bIsCharsetTranslatedForOS;
    ULONG32 m_ulDefaultPointSize;
    COLORTYPE m_defaultTextColor;
    COLORTYPE m_defaultTextBgColor;
    ULONG32 m_ulDefaultFontWeight;
    BOOL m_bDefaultFontStyleIsItalic;
    double m_dAngleOfEscapement;
    double m_dAngleOfCharOrientation;
    BOOL m_bAngleOfCharOrientationWasExplicitlySet;
    // /Added the following for plain text; these values get set by the user
    // via the player's user preferences:
    BOOL m_bUserTextSizingPrefIsSet; // /User's non-default pref for text size.
    BOOL m_bUserPrefSizeIsRelative;  // /absolute if FALSE, relative if TRUE.
    // /0 means default, otherwise is pt size if absolute, otherwise is
    // scale factor in percent, e.g., 120% for +1 size, 83.33% for -1 size:
    ULONG32 m_ulUserPrefTextSizeOrScaleFactorPct;


    //Added the following so that authors could change
    // the font color inside hyperlinked text and still have it go
    // back to the proper font color when the hyperlinked text is done:
    ULONG32 m_ulNumberOfFontColorPushesInsideLinkText;

    //Added the following to keep track of live source:
    BOOL m_bIsLiveSource;

    //This will be 0 unless we're live and wallclock-synch is active.
    // This is needed for properly calculating begin and end times of
    // TextContainers in a non-zero based time line:
    ULONG32 m_ulTimeAtStartup;

    //Added the following to keep track of when the last
    // <CLEAR> tag was sent (i.e., the time associated with it) so that
    // the loss of a packet with a <CLEAR> tag in it doesn't affect the
    // setting of the text of subsequent packets' positions in the window:
    ULONG32 m_ulTimeOfLastClearTag;

    //Added the following so each packet can tell us
    // where to start drawing its text:
    LONG32 m_newPktStartXAtTimeZero;
    LONG32 m_newPktStartYAtTimeZero;

    //Tells whether we're currently parsing inside HTML-style comments, i.e.,
    // <!-- we're inside a comment --> :
    ULONG32 m_ulInsideCommentTagNestCount;

    //[The following is not yet implemented:
    // <WINDOW ..> tag in the header will allow a parameter MAPMODE="mm"
    // where "mm" is "PIXELS", which means scrollrate and crawlrate are in
    // pixels per second, or "TWIPS", which means units are 1/1440th of an
    // inch.  X is always positive to the right and Y is always positive
    //  downward, even if "TWIPS" is specified:	  
    /*
    int m_mapMode;	
    */

#if defined(_DEBUG)
    ULONG32 m_ulDebugFlags;
#endif

  private:

      //These are in private section to keep them from being used:
    TextWindowBase(TextWindowBase& tw) : TextAttributeStacks(),
                                         TextContainerList() { ; }   
    TextWindowBase(TextWindowBase* tw) { ; }
    TextWindowBase& operator= (TextWindowBase) { return *this; }
}; //end class TextWindowBase.


//////////////////////////////////////////////////////////////////////////////
//
//	TextWindow class:
//
class TextWindow : public TextWindowBase
{
  public:
    TextWindow();
    
    ~TextWindow();

    //XXXEH- RTRender-only code:
#ifdef _WINDOWS
    //These receive TextOut()s of all rendered text and are then used in
    // OnPaint() to BitBlt() the rendered text to this's window:
    void* m_pDeviceContextMemory;  //memory DC for textWindow.
#if !defined(USE_DIB_SECTION)
    void* m_pBmpCompat;
    CHXDIBits*	m_hDIB;
#else //USE_DIB_SECTION:
    HBITMAP m_hBitmap;
    HBITMAP m_hOldBitmap;
    LPBITMAPINFO m_LPBITMAPINFO;
    BITMAPINFOHEADER m_BITMAPINFOHEADER;
    VOID* m_pBits;
    //Get new space for bitmapinfo struct (usually plus some bytes for color
    // masks):
    BOOL AllocNewLPBITMAPINFO(UINT32 ulNumBytes);
#endif
#endif //_WINDOWS.
#if defined(_MACINTOSH) || defined(_MAC_UNIX)
//	m_pOffScreenWorld used for offscreen drawing, works just like a port. 
	GWorldPtr	m_pOffScreenWorld;
#endif
    BOOL m_bHandlingWindowResizing;


    void clear_all();

    //Inserts a ptr to a TextContainer copy of *pTC into the
    // TextContainerList part of *this, and deletes pTC if deleteSentTcAtEnd
    // is TRUE; bCalledFromRendererCode is needed because there is some
    // code, e.g., CENTERing of text, that is only done in the renderer:
    BOOL insertAtEndOfList(TextContainer* pTC, BOOL bCalledFromRendererCode,
				   BOOL bDealingWithTabCharWithPre);

    //XXXEH- RTRender-only code:
    //The following four functions return the ACTUAL size and location
    // of the window (for more, see the four other functions that start
    //with getUpperLeftX() in class TextWindowBase):
    LONG32 getWindowUpperLeftX() { return 0;}//XXXEH- Always 0 now (?)
    LONG32 getWindowUpperLeftY() { return 0;}//XXXEH- Always 0 now (?)
    LONG32 getWindowWidth(){return m_visibleWindowWidth;}
    LONG32 getWindowHeight(){return m_visibleWindowHeight;}

    void setVisibleWindowWidth(LONG32 w) { m_visibleWindowWidth = w;}
    void setVisibleWindowHeight(LONG32 h) { m_visibleWindowHeight = h; }

    //This was added to keep track of how far everything was moved when
    // the last loop happened so incomming text can know where to be
    // moved relative to its packet-header <POS X0= Y0= > tag's values:
    LONG32 getCurrentXOffsetDueToLooping()
	    { return m_lCurrentXOffsetDueToLooping; }
    LONG32 getCurrentYOffsetDueToLooping()
	    { return m_lCurrentYOffsetDueToLooping; }
    void setCurrentXOffsetDueToLooping(LONG32 lXOffset)
	    { m_lCurrentXOffsetDueToLooping = lXOffset; }
    void setCurrentYOffsetDueToLooping(LONG32 lYOffset)
	    { m_lCurrentYOffsetDueToLooping = lYOffset; }

    LONG32 getCurrentYOffsetForTeleprompter()
	    { return m_lCurrentYOffsetForTeleprompter; }
    void setCurrentYOffsetForTeleprompter(LONG32 lYOffset)
	    { m_lCurrentYOffsetForTeleprompter = lYOffset; }

    ULONG32 textCntnrListSize() { return (TextContainerList::size()); }

    _CHAR* getURL();
    ULONG32 getLenURLbuf();
    BOOL hasValidURL();
    ULONG32 getTargetOfURL() { return m_ulTargetOfURL; }
    //returns FALSE if pNewURL is empty or NULL:
    BOOL setURL(_CHAR* newURL, ULONG32 newURLstrlen);
    void clearURL();
    //The values this can take are enum'd in txtattrb.h:
    void setTargetOfURL(ULONG32 ulTarget) {m_ulTargetOfURL = ulTarget;}

    //XXXEH- RTRender-only code:
    void setTimeOfLastTimeSync(ULONG32 ulTime)
	{ m_ulTimeOfLastTimeSync=ulTime; };
    ULONG32 getTimeOfLastTimeSync() { return m_ulTimeOfLastTimeSync; };

    //Goes through the list and, if any nodes' bounding boxes have
    // moved outside the window, deletes them.
    // Returns the number of nodes in the list that were deleted:
    ULONG32 deleteAllNoLongerVisible();

    //XXXEH- RTRender-only code:
    //Goes through last line of text and centers it (if it's got the
    // isCentered() value) based on the actual window width (via a call to
    // getWindowWidth() ):
    BOOL CenterPriorLine();
    BOOL getPriorLineAlreadyCentered()
	{ return m_bPriorLineAlreadyCentered; }
    void setPriorLineAlreadyCentered(BOOL bPLAC)
	{ m_bPriorLineAlreadyCentered=bPLAC; }


#if defined(_MACINTOSH)	|| defined(_MAC_UNIX)
    HXxEvent*  m_pEvent;
#endif
  
#if defined(_UNIX) && !defined(_MAC_UNIX)
    Dict* m_font_dict;
    CHXMapLongToObj m_color_list;
#endif

private:

    _CHAR* m_pURL;
    ULONG32 m_ulLenURLbuf;
    //The possible values for this are enum'd in txtattrb.h:
    ULONG32 m_ulTargetOfURL;
    ULONG32 m_ulTimeOfLastTimeSync;

    LONG32 m_visibleWindowWidth;
    LONG32 m_visibleWindowHeight;

    //This was added to keep track of how far everything was moved when
    // the last loop happened so incomming text can know where to be
    // moved relative to its packet-header <POS X0= Y0= > tag's values:
    LONG32  m_lCurrentXOffsetDueToLooping;
    LONG32  m_lCurrentYOffsetDueToLooping;

    //This was added to keep track of how much everything has "moved" up
    // due to lines of text arriving that extend past the lower edged of the
    // window in TYPE_TELEPROMPTER windows:
    LONG32 m_lCurrentYOffsetForTeleprompter;

    //This makes sure a line of text doesn't get centered twice (which would
    // happen if </CENTER> ends a packet of text and then, when the next
    // packet gets parsed, the line would get re-centered when a new
    // TextContainer was inserted into *this's list if it didn't know better:
    BOOL m_bPriorLineAlreadyCentered;

    //These are in private section to keep them from being used:
    TextWindow(TextWindow& tw) : TextWindowBase() { ; }
    TextWindow(TextWindow* tw) { ; }
    TextWindow& operator= (TextWindow) { return *this; }
};





#endif
