/******************************************************************************
 JHTMLScanner.h

	Interface for the HTML scanner class

	Copyright © 1998 by John Lindal. All rights reserved.

 ******************************************************************************/

#ifndef _H_JHTMLScanner
#define _H_JHTMLScanner

#ifndef _H_JHTMLScannerL
#undef yyFlexLexer
#define yyFlexLexer JHTMLFlexLexer
#include <FlexLexer.h>
#endif

#include <JStringPtrMap.h>
#include <JString.h>

class JHTMLScanner : public JHTMLFlexLexer
{
public:

	virtual ~JHTMLScanner();

protected:

#ifdef __VCPP__
public:
#endif

	enum HTMLError
	{
		kEmptyTag,
		kEmptyAttrName,
		kUnclosedTag
	};

protected:

	JHTMLScanner();

	void	LexHTML(const JCharacter* text);
	void	LexHTML(istream& input);

	virtual JBoolean	HandleHTMLWord(const JCharacter* word, const JIndexRange& range);
	virtual JBoolean	HandleHTMLWhitespace(const JCharacter* space, const JIndexRange& range);
	virtual JBoolean	HandleHTMLTag(const JString& name, const JStringPtrMap<JString>& attr,
									  const JIndexRange& range);
	virtual JBoolean	HandleHTMLComment(const JIndexRange& range);
	virtual JBoolean	HandleHTMLError(const HTMLError err, const JCharacter* errStr,
										const JIndexRange& range);

private:

	struct TagInfo
	{
		JString					name;
		JString					lastAttr;
		JString					valueBuffer;
		JStringPtrMap<JString>	attr;
		JIndexRange				range;
	};

private:

	JIndexRange	itsMatchRange;			// range of current token

	JBoolean	itsTagOpenFlag;			// kTrue while accumulating tag
	TagInfo*	itsTagInfo;				// NULL when not lexing to save space

	JIndexRange	itsCommentRange;		// range of comment passed to HandleHTMLComment()

private:

	virtual int	yylex();

	void		NewTag();
	JBoolean	TagFinished();
	void		SaveAttributeValue();

	JBoolean	HandleChar(const JCharacter c);

	void		UpdatePosition();

	// not allowed

	JHTMLScanner(const JHTMLScanner& source);
	const JHTMLScanner& operator=(const JHTMLScanner& source);
};


/******************************************************************************
 UpdatePosition (private)

 ******************************************************************************/

inline void
JHTMLScanner::UpdatePosition()
{
	const JIndex prevEnd = itsMatchRange.last;
	itsMatchRange.Set(prevEnd+1, prevEnd+yyleng);
}

#endif
