//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/script.h                         $
// $Revision:: 12                                                             $
//   $Author:: Jimdose                                                        $
//     $Date:: 10/07/98 11:59p                                                $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/script.h                              $
// 
// 12    10/07/98 11:59p Jimdose
// changed script_p to offset in script markers
// 
// 11    9/21/98 10:15p Markd
// Putting archiving and unarchiving functions in
// 
// 10    6/09/98 4:24p Jimdose
// filename is now an str
// added close and filename
// 
// 9     5/26/98 11:59p Markd
// moved buffer out of protected for e3 demo
// 
// 8     5/24/98 4:48p Jimdose
// Made char *'s const
// 
// 7     3/02/98 8:49p Jimdose
// Changed CLASS_PROTOTYPE to only take the classname
// 
// 6     2/17/98 7:14p Jimdose
// Added MarkPosition and RestorePosition
// Added atString for determining if the next token is a quoted string
// 
// 5     2/03/98 10:54a Jimdose
// Updated to work with Quake 2 engine
// 
// 3     11/24/97 4:30p Markd
// Added GetVector 
// 
// 2     9/26/97 6:14p Jimdose
// Added standard Ritual headers
//
// DESCRIPTION:
// C++ implementaion of tokenizing text interpretation.  Class accepts filename
// to load or pointer to preloaded text data.  Standard tokenizing operations
// such as skip white-space, get string, get integer, get float, get token,
// and skip line are implemented.  
//
// Note: all '//', '#', and ';' are treated as comments.  Probably should
// make this behaviour toggleable.
// 

#ifndef __SCRIPT_H__
#define __SCRIPT_H__

#include "class.h"
#include "vector.h"
#include "str.h"

#define	MAXTOKEN	256

typedef struct
	{
	qboolean		tokenready;
   int         offset;
	int			line;		
	char			token[ MAXTOKEN ];
	} scriptmarker_t;

class Script : public Class
	{
	protected:
		qboolean		tokenready;
		
		str			filename;
		const char	*script_p;
		const char	*end_p;
		
		int			line;		
		char			token[ MAXTOKEN ];

		qboolean		releaseBuffer;

		qboolean		AtComment( void );
		void			CheckOverflow( void );

	public:
		const char	*buffer;
		int			length;

      CLASS_PROTOTYPE( Script );

		~Script();
		Script();
		void			Close( void );
		const char *Filename( void );
		int			GetLineNumber( void );
		void			Reset( void );	
		void			MarkPosition( scriptmarker_t *mark );
		void			RestorePosition( scriptmarker_t *mark );
		qboolean		SkipToEOL( void );
		void			SkipWhiteSpace( qboolean crossline );
		void			SkipNonToken( qboolean crossline );
		qboolean		TokenAvailable( qboolean crossline );
		qboolean		CommentAvailable( qboolean crossline );
		void			UnGetToken( void );
		qboolean		AtString( qboolean crossline );
		const char	*GetToken( qboolean crossline );
		const char	*GetLine( qboolean crossline );
		const char	*GetRaw( void );
		const char	*GetString( qboolean crossline );
		qboolean		GetSpecific( const char *string );
		int			GetInteger( qboolean crossline );
		double		GetDouble( qboolean crossline );
		float			GetFloat( qboolean crossline );
		Vector		GetVector( qboolean crossline );
		int			LinesInFile( void );
		void			Parse( const char *data, int length, const char *name );
		void			LoadFile( const char *name );
		const char	*Token( void );
      virtual void Archive( Archiver &arc );
      virtual void Unarchive( Archiver &arc );
	};

inline void Script::Archive
	(
	Archiver &arc
	)
   {
   Class::Archive( arc );

   arc.WriteString( filename );
   arc.WriteBoolean( tokenready );
   //
   // save out current pointer as an offset
   //
   arc.WriteInteger( script_p - buffer );
   arc.WriteInteger( line );
   arc.WriteRaw( token, sizeof( token ) );
   }

inline void Script::Unarchive
	(
	Archiver &arc
	)
   {
   int i;

   Class::Unarchive( arc );

   arc.ReadString( &filename );
   //
   // load the file in
   //
   LoadFile( filename.c_str() );

   arc.ReadBoolean( &tokenready );
   arc.ReadInteger( &i );
   //
   // restore the script pointer
   //
   script_p = buffer + i;
   arc.ReadInteger( &line );
   arc.ReadRaw( token, sizeof( token ) );
   }

#endif
