//===========================================================================//
// File:	VGADisp.hh                                                          //
// Project: MUNGA           Brick: Applications-specific controls module     //
// Contents: Interface specification for LBE4 VGA display                    //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  -----------------------------------------------------------//
// 02/03/95  CPB  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. All rights reserved //
//                      PROPRIETARY and CONFIDENTIAL                         //
//===========================================================================//

#if !defined(GRAPH2D_HPP)
#	define GRAPH2D_HPP

#	if !defined(STYLE_HPP)
#		include <style.hpp>
#	endif

#	if !defined(VECTOR2D_HPP)
#		include <vector2d.hpp>
#	endif

#	if !defined(RECT2D_HPP)
#		include <rect2d.hpp>
#	endif

#	if !defined(RESOURCE_HPP)
#		include <resource.hpp>
#	endif

#	if !defined(PLUG_HPP)
#		include <plug.hpp>
#	endif

	class BitMap;
	class PixelMap;
	class GraphicsDisplay;
	class GraphicsPort;
	class GraphicsViewRecord;
	class GraphicsView;
	class NotationFile;

	//########################################################################
	//################################ BitMap ################################
	//########################################################################
	//
	// The "raw" bit map is used by assembly-language routines.
	// It must not be burdened with signatures, etc.
	//
	struct RawBitMap
	{
		Vector2DOf<int> Size;
		int WidthInWords;
		Word	*MapPointer;
	};

	class BitMap :
   	public Plug
	{
	public:
		BitMap(int width, int height);
		BitMap(int width, int height, Word *body);
		BitMap(const char *filename);
		BitMap(NotationFile *notation_file, const char *page_name);
		~BitMap();

		Logical
			TestInstance() const;
		void
			ShowInstance(char *indent);
		static BitMap *
			Make(const char *file_name);
		static BitMap *
			Make(ResourceDescription::ResourceID new_resource_id);

		RawBitMap
      	Data;
	};

	//########################################################################
	//############################### Palette8 ###############################
	//########################################################################

	struct PaletteTriplet
	{
		Byte Red;			//0..255
		Byte Green;			//0..255
		Byte Blue;			//0..255

		friend ostream&
			operator<<(
				ostream& stream,
				const PaletteTriplet& p
			);

		PaletteTriplet&
			operator=(PaletteTriplet& t)
			{
				Red = t.Red;
				Green = t.Green;
				Blue = t.Blue;
				return t;
			}
		Logical
			operator==(const PaletteTriplet& t) const
			{
				return ((Red==t.Red) && (Green==t.Green) && (Blue==t.Blue));
			}
		Logical
			operator!=(const PaletteTriplet& t) const
			{
				return ((Red!=t.Red) || (Green!=t.Green) || (Blue!=t.Blue));
			}
	};

	class Palette8 SIGNATURED
	{
		friend class GraphicsPort;

	public:
		Palette8();
		Palette8(int count, PaletteTriplet *source);
		Palette8(const char *filename);
		~Palette8();

		void
			SetColorRange(
				int start,
				int end,
				PaletteTriplet new_color
			);
		void
			BuildColorRange(
				int start,
				int end,
				PaletteTriplet first_color,
				PaletteTriplet last_color
			);
		Logical
			TestInstance() const;
		void
			ShowInstance(char *indent);
		static Palette8 *
			Make(const char *file_name);
		static Palette8 *
			Make(ResourceDescription::ResourceID new_resource_id);

		Logical
			Valid;

		PaletteTriplet
			Color[256];
	};

	//########################################################################
	//############################## PixelMap8 ###############################
	//########################################################################

	//
	// The "raw" pixel map is used by assembly-language routines.
	// It must not be burdened with signatures, etc.
	//
	struct RawPixelMap8
	{
		Vector2DOf<int> Size;
		Byte	*MapPointer;
	};

	class PixelMap8 SIGNATURED
	{
		friend class GraphicsPort;

	public:
		PixelMap8(int width, int height);
		PixelMap8(Vector2DOf<int> size);
//			{PixelMap(size.x, size.y);}
		PixelMap8(const char *filename);
		PixelMap8()
			{
         	Data.Size.x = 0;
         	Data.Size.y = 0;
				Data.MapPointer = NULL;
			}
		~PixelMap8();

		Logical
			TestInstance() const;
		void
			ShowInstance(char *indent);
		static PixelMap8 *
			Make(const char *file_name);
		static PixelMap8 *
			Make(ResourceDescription::ResourceID new_resource_id);

		RawPixelMap8
			Data;
	};

	//########################################################################
	//############################## PixelMap16 ##############################
	//########################################################################

	//
	// The "raw" pixel map is used by assembly-language routines.
	// It must not be burdened with signatures, etc.
	//
	struct RawPixelMap16
	{
		Vector2DOf<int> Size;
		Word	*MapPointer;
	};

	class PixelMap16 SIGNATURED
	{
		friend class GraphicsPort;

	public:
		PixelMap16(int width, int height);
		PixelMap16(Vector2DOf<int> size);
//			{PixelMap(size.x, size.y);}
		PixelMap16(char *filename);
		PixelMap16()
			{
         	Data.Size.x = 0;
         	Data.Size.y = 0;
         	Data.MapPointer = NULL;
			}
		~PixelMap16();

		Logical
			TestInstance() const;

		void
			ShowInstance(char *indent);

		RawPixelMap16
			Data;
	};

	//########################################################################
	//########################### GraphicsDisplay ############################
	//########################################################################
	class GraphicsDisplay SIGNATURED
	{
	public:
		enum Operation {
			Replace=0, And, Or, Xor, NextOperation
		};

		enum FontNumber {
			SystemFont=0, NextFontNumber
		};

		enum Justification {
			Normal=0,
			Left=0x00, Horizontal=0x01, Right=0x02,
			Top=0x00,  Vertical=0x04, Bottom=0x08 
		};

	public:
		GraphicsDisplay(int x, int y);

		virtual ~GraphicsDisplay();

		Logical
			TestInstance() const;

		virtual void
			ShowInstance(char *indent);

		virtual Logical
			Update(Logical forceAll);

		virtual void
			WaitForUpdate();

		virtual Rectangle2D
			TextBounds(
				Enumeration fontNumber,
				Logical vertical,
				GraphicsDisplay::Justification justification,
				char *stringPointer
			);

		virtual void
			DrawPoint(
				int color,
				int bitmask,
				Enumeration operation,
				int x, int y
			);

		virtual void
			DrawLine(
				int color,
				int bitmask,
				Enumeration operation,
				int x1, int y1,
				int x2, int y2,
				Logical include_last_pixel
			);

		virtual void
			DrawFilledRectangle(
				int color,
				int bitmask,
				Enumeration operation,
				int x1, int y1,
				int x2, int y2
			);

		virtual void
			DrawText(
				int color,
				int bitmask,
				Enumeration operation,
				Logical opaque,
				int rotation,
				Enumeration fontNumber,
				Logical vertical,
				GraphicsDisplay::Justification justification,
				Rectangle2D	*clippingRectanglePtr,
				char *stringPointer
			);

		virtual void
			DrawBitMap(
				int color,
				int bitmask,
				Enumeration operation,
				int rotation,
				int x, int y,
				BitMap *bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawBitMapOpaque(
				int color,
				int background,
				int bitmask,
				Enumeration operation,
				int rotation,
				int x, int y,
				BitMap *bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawPixelMap8(
				int *translation_table,
				int bitmask,
				Enumeration operation,
				Logical opaque,
				int rotation,
				int x, int y,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawPixelMap8SingleColor(
				int color,
				int bitmask,
				Enumeration operation,
				int rotation,
				int x, int y,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

	public:
		Rectangle2D	bounds;
	};

	//########################################################################
	//############################ GraphicsPort ##############################
	//########################################################################
	class GraphicsPort  SIGNATURED
	{
	public:
		GraphicsPort(
			GraphicsDisplay *graphics_display,
			const char *name
		);

		virtual ~GraphicsPort();

		Logical
			TestInstance() const;

		virtual void
			ShowInstance(char *indent);

		virtual Rectangle2D
			TextBounds(
				Enumeration fontNumber,
				Logical vertical,
				GraphicsDisplay::Justification justification,
				char *stringPointer
			);

		virtual void
			SetColor(
				PaletteTriplet *source_color,
				int color_index
			);

		virtual void
			DrawPoint(
				int color,
				Enumeration operation,
				int x, int y
			);

		virtual void
			DrawLine(
				int color,
				Enumeration operation,
				int x1, int y1,
				int x2, int y2,
				Logical include_last_pixel
			);

		virtual void
			DrawFilledRectangle(
				int color,
				Enumeration operation,
				int x1, int y1,
				int x2, int y2
			);

		virtual void
			DrawText(
				int color,
				Enumeration operation,
				Logical opaque,
				int rotation,
				Enumeration fontNumber,
				Logical vertical,
				GraphicsDisplay::Justification justification,
				Rectangle2D	*clippingRectanglePtr,
				char *stringPointer
			);

		virtual void
			DrawBitMap(
				int color,
				Enumeration operation,
				int rotation,
				int x, int y,
				BitMap *bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawBitMapOpaque(
				int color,
				int background,
				Enumeration operation,
				int rotation,
				int x, int y,
				BitMap *bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawPixelMap8(
				Enumeration operation,
				Logical opaque,
				int rotation,
				int x, int y,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		virtual void
			DrawPixelMap8SingleColor(
				int color,
				Enumeration operation,
				int rotation,
				int x, int y,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

	public:
		Rectangle2D
			bounds;
		GraphicsDisplay
			*graphicsDisplay;

		char
			name[16];
	};

	//########################################################################
	//######################### GraphicsViewRecord ###########################
	//########################################################################
	class GraphicsViewRecord SIGNATURED
	{
		friend class GraphicsView;
	public:
		GraphicsViewRecord();
		~GraphicsViewRecord();
		Logical
			TestInstance() const;
		void
			Clear();
		void
			Draw(GraphicsView *graphics_view, int forced_color=-1);
	protected:
		enum
		{
			endCommand=0,
			pointCommand,
			lineCommand,
			frectCommand,
			bitmapCommand,
			bitmapOpaqueCommand,
			pixelmap8Command,
			pixelmap8SolidCommand,
		};

		void
			PutChar(int value);
		int
			GetChar();
		void
			PutLogical(Logical value);
		Logical
			GetLogical();
		void
			PutShort(int value);
		int
			GetShort();
		void
			PutPointer(void *pointer);
		void *
			GetPointer();

		int
			commandListLength,
			commandListIndex;
		char
			*commandList;
		GraphicsViewRecord
      	*link;
	};

	//########################################################################
	//############################ GraphicsView ##############################
	//########################################################################
	class GraphicsView  SIGNATURED
	{
   	friend class GraphicsViewRecord;
	public:
		GraphicsView(
			GraphicsPort *graphics_port,
			int x1, int y1, int x2, int y2
		);

		GraphicsView(
			GraphicsPort *graphics_port
		);

		virtual ~GraphicsView();

		Logical
			TestInstance() const;

		virtual void
			ShowInstance(char *indent);

		virtual void
			SetPositionWithinPort(
				int left,
				int bottom,
				int right,
				int top
			);

		virtual void
			SetOperation(GraphicsDisplay::Operation operation);

		virtual void
			SetOrigin(
				int x,
				int y
			);

		virtual void
			SetFont(
				Enumeration new_font_ID
			);

		virtual void
			SetColor(
				int new_color
			);

		virtual void
			SetClippingRectangle(
				Rectangle2D *clippingRectangle
			);

		virtual void
			ClearClippingRectangle();

		virtual void
			MoveToAbsolute(
				int x,
				int y
			);

		virtual void
			MoveToRelative(
				int x,
				int y
			);
		//
		//-----------------------------------------------------
		// These routines first clip the operation according to
		// clippingRectangle of the GraphicsView.
		// The clipped results are then passed on to the
		// corresponding routine in the GraphicsPort object.
		//-----------------------------------------------------
		//
		virtual void
			DrawPoint();

		virtual void
			DrawLineToAbsolute(int x, int y);

		virtual void
			DrawLineToRelative(int x, int y);

		virtual void
			DrawThickLineToAbsolute(int x, int y);

		virtual void
			DrawThickLineToRelative(int x, int y);

		virtual void
			DrawRectangleToAbsolute(int x, int y);

		virtual void
			DrawRectangleToRelative(int x, int y);

		virtual void
			DrawFilledRectangleToAbsolute(int x, int y);

		virtual void
			DrawFilledRectangleToRelative(int x, int y);

		virtual void
			DrawText(
				Logical opaque,
				Logical vertical,
				GraphicsDisplay::Justification justification,
				Rectangle2D	*clippingRectanglePtr,
				char *stringPointer
			);

		virtual void
			DrawBitMap(
				int rotation,
				BitMap	*bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		void
			DrawBitMap(
				int rotation,
				BitMap *bitmap
			)
				{
					DrawBitMap(
						rotation,
						bitmap,
						0, 0, bitmap->Data.Size.x-1, bitmap->Data.Size.y-1
					);
				}

		virtual void
			DrawBitMapOpaque(
				int background,
				int rotation,
				BitMap	*bitmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		void
			DrawBitMapOpaque(
				int background,
				int rotation,
				BitMap *bitmap
			)
				{
					DrawBitMapOpaque(
               	background,
						rotation,
						bitmap,
						0, 0, bitmap->Data.Size.x-1, bitmap->Data.Size.y-1
					);
				}

		virtual void
			DrawPixelMap8(
				Logical opaque,
				int rotation,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		void
			DrawPixelMap8(
				Logical opaque,
				int rotation,
				PixelMap8 *pixelmap
			)
				{
					DrawPixelMap8(
						opaque,
						rotation,
						pixelmap,
						0, 0, pixelmap->Data.Size.x-1, pixelmap->Data.Size.y-1
					);
				}

		virtual void
			DrawPixelMap8SingleColor(
				int rotation,
				PixelMap8	*pixelmap,
				int sx1, int sy1, int sx2, int sy2	// these are SOURCE coordinates
			);

		void
			DrawPixelMap8SingleColor(
				int rotation,
				PixelMap8 *pixelmap
			)
				{
					DrawPixelMap8SingleColor(
						rotation,
						pixelmap,
						0, 0, pixelmap->Data.Size.x-1, pixelmap->Data.Size.y-1
					);
				}

		virtual void
			AttachRecorder(GraphicsViewRecord *graphics_view_record);
		virtual void
			DetachRecorder();

		enum PointCode{
			IsWithin=0, IsLeft=0x01, IsRight=0x02, IsBelow=0x04, IsAbove=0x08
		};

		virtual int
			BuildPointCode(Vector2DOf<int> vector);

		Logical
			ClipImage(
				Rectangle2D *sourceRect,
				Vector2DOf<int> *position,
				Vector2DOf<int> imageLimits
			);

		virtual void
			SetColor(
				PaletteTriplet *source_color,
				int color_index
			);

	protected:
		void
			DrawThickLine(
				Vector2DOf<int> start,
				Vector2DOf<int> end
			);

		void
			DrawLine(
				Vector2DOf<int> start,
				Vector2DOf<int> end,
				Logical include_last_pixel
			);

		void
			DrawFilledRectangle(Rectangle2D r);

		Rectangle2D			areaWithinPort;
		Vector2DOf<int>	origin;
		Vector2DOf<int>	currentPosition;
		Enumeration			currentFontID;
		int					currentColor;
		Rectangle2D			clippingRectangle;
		GraphicsDisplay::Operation currentOperation;
		GraphicsPort		*graphicsPort;
		GraphicsViewRecord *recorder;
	};

#endif
