// WANNE: EDITOR: todo

#ifdef PRECOMPILEDHEADERS
	#include "Editor All.h"
#else
	#include "builddefines.h"
#endif

#ifdef JA2EDITOR

#ifndef PRECOMPILEDHEADERS
	#include "tiledef.h"
	#include "vsurface.h"
	#include "worlddat.h"
	#include "random.h"
	#include "sysutil.h"
	#include "Font Control.h"
	#include "selectwin.h"
	#include "EditorDefines.h"
	#include "Editor Taskbar Utils.h"
#endif

#include "vobject_blitters.h"
#include "Text.h"

extern BOOLEAN gfOverheadMapDirty;

//extern void SetClippingRect(SGPRect *clip);
//extern void GetClippingRect(SGPRect *clip);


extern INT32 iEditorToolbar;

extern BOOLEAN fDontUseRandom;

extern UINT16 GenericButtonFillColors[40];

BOOLEAN gfRenderSquareArea = FALSE;
INT16 iStartClickX,iStartClickY;
INT16 iEndClickX,iEndClickY;


INT32 iButtonIcons[4];
INT32 iSelectWin,iCancelWin,iScrollUp,iScrollDown,iOkWin;

BOOLEAN fAllDone=FALSE;
BOOLEAN fButtonsPresent=FALSE;

SGPPoint SelWinSpacing, SelWinStartPoint, SelWinEndPoint;

//These definitions help define the start and end of the various wall indices.
//This needs to be maintained if the walls change.
#define WALL_LAST_WALL_OFFSET						30
#define	WALL_FIRST_AFRAME_OFFSET				31
#define WALL_LAST_AFRAME_OFFSET					34
#define	WALL_FIRST_WINDOW_OFFSET				35
#define WALL_LAST_WINDOW_OFFSET					46
#define WALL_FIRST_BROKEN_WALL_OFFSET		47
#define WALL_LAST_BROKEN_WALL_OFFSET		54
#define WALL_FIRST_APPENDED_WALL_OFFSET	55
#define WALL_LAST_APPENDED_WALL_OFFSET	56
#define WALL_FIRST_WEATHERED_WALL_OFFSET 57
#define WALL_LAST_WEATHERED_WALL_OFFSET	64

//I've added these definitions to add readability, and minimize conversion time for changes
//incase there are new values, etc.
#define OSTRUCTS_NUMELEMENTS		( LASTOSTRUCT - FIRSTFULLSTRUCT + 22 )
#define OSTRUCTS1_NUMELEMENTS					5
#define OSTRUCTS2_NUMELEMENTS					12
#define BANKSLIST_NUMELEMENTS					5
#define ROADSLIST_NUMELEMENTS					1
#define DEBRISLIST_NUMELEMENTS				( LASTDEBRIS - DEBRISROCKS + 2 + 1 ) //+1 for ANOTHERDEBRIS

#define SINGLEWALL_NUMELEMENTS				( (LASTWALL-FIRSTWALL+1) * 2 )
#define SINGLEDOOR_NUMELEMENTS				(( LASTDOOR - FIRSTDOOR + 1 ) * 5)
#define SINGLEWINDOW_NUMELEMENTS			( LASTWALL - FIRSTWALL + 1 )
#define SINGLEROOF_NUMELEMENTS				( (LASTROOF-FIRSTROOF+1) + (LASTSLANTROOF-FIRSTSLANTROOF+1) + \
																				(LASTWALL-FIRSTWALL+1) + (SECONDONROOF-FIRSTONROOF+1) )
#define SINGLENEWROOF_NUMELEMENTS			(LASTROOF-FIRSTROOF+1)
#define SINGLEBROKENWALL_NUMELEMENTS	( (LASTDECORATIONS-FIRSTDECORATIONS+1) + (LASTWALL-FIRSTWALL+1)*2 )
#define SINGLEDECOR_NUMELEMENTS				( LASTISTRUCT - FIRSTISTRUCT + 1 )
#define SINGLEDECAL_NUMELEMENTS				( LASTWALLDECAL - FIRSTWALLDECAL + EIGTHWALLDECAL - FIFTHWALLDECAL + 3 )
#define SINGLEFLOOR_NUMELEMENTS				( LASTFLOOR - FIRSTFLOOR + 1 )
#define SINGLETOILET_NUMELEMENTS			( EIGHTISTRUCT - FIFTHISTRUCT + 1 )
//#define ROOM_NUMELEMENTS							( (LASTWALL-FIRSTWALL+1) + (LASTFLOOR-FIRSTFLOOR+1) + \
//																				(LASTROOF-FIRSTROOF+1) + (LASTSLANTROOF-FIRSTSLANTROOF+1) )
#define ROOM_NUMELEMENTS							( (LASTWALL-FIRSTWALL+1) + (LASTFLOOR-FIRSTFLOOR+1) + \
																				(LASTROOF-FIRSTROOF+1) + (2 ))


//This is a special case for trees which may have varying numbers.	There was a problem
//in which we loaded a new tileset which had one less tree in it.	When we called BuildSelectionWindow(),
//it would crash because it thought there was an extra tree which was now invalid.
UINT16	gusNumOStructs = 0;

// List of objects to display in the selection window
DisplaySpec OStructs[ OSTRUCTS_NUMELEMENTS ];
DisplaySpec OStructs1[ OSTRUCTS1_NUMELEMENTS ];
DisplaySpec OStructs2[ OSTRUCTS2_NUMELEMENTS ];
DisplaySpec BanksList[ BANKSLIST_NUMELEMENTS ];
DisplaySpec RoadsList[ ROADSLIST_NUMELEMENTS ];
DisplaySpec DebrisList[ DEBRISLIST_NUMELEMENTS ];
DisplaySpec SingleWall[ SINGLEWALL_NUMELEMENTS ];
DisplaySpec SingleDoor[ SINGLEDOOR_NUMELEMENTS ];
DisplaySpec SingleWindow[ SINGLEWINDOW_NUMELEMENTS ];
DisplaySpec SingleRoof[ SINGLEROOF_NUMELEMENTS ];
DisplaySpec SingleNewRoof[ SINGLENEWROOF_NUMELEMENTS ];
DisplaySpec SingleBrokenWall[ SINGLEBROKENWALL_NUMELEMENTS ];
DisplaySpec SingleDecor[ SINGLEDECOR_NUMELEMENTS ];
DisplaySpec SingleDecal[ SINGLEDECAL_NUMELEMENTS ];
DisplaySpec SingleFloor[ SINGLEFLOOR_NUMELEMENTS ];
DisplaySpec SingleToilet[ SINGLETOILET_NUMELEMENTS ];
DisplaySpec Room[ ROOM_NUMELEMENTS ];

//These are all of the different selection lists.	Changing the max_selections will
//change the number of selections values you can have at a time.	This is Bret's gay code,
//though I've cleaned it up a lot.
Selections	SelOStructs[MAX_SELECTIONS]				=		{ {FIRSTFULLSTRUCT, 0, 1} };	// Default selections
Selections	SelOStructs1[MAX_SELECTIONS]				=		{ {FOURTHOSTRUCT, 0, 1} };	// Default selections
Selections	SelOStructs2[MAX_SELECTIONS]				=		{ {THIRDOSTRUCT, 0, 1} };	// Default selections
Selections	SelBanks[MAX_SELECTIONS]					=		{ {FIRSTCLIFF, 0, 1} };
Selections	SelRoads[MAX_SELECTIONS]					=		{ {FIRSTROAD, 0, 1} };
Selections	SelDebris[MAX_SELECTIONS]					=		{ {DEBRISROCKS, 0, 1} };
Selections	SelSingleWall[MAX_SELECTIONS]			=		{ {FIRSTWALL, 0, 1} };
Selections	SelSingleDoor[MAX_SELECTIONS]			=		{ {FIRSTDOOR, 0, 1} };
Selections	SelSingleWindow[MAX_SELECTIONS]		=		{ {FIRSTWALL, 44, 1} };
Selections	SelSingleRoof[MAX_SELECTIONS] =				{ {FIRSTROOF, 0, 1} };
Selections	SelSingleNewRoof[MAX_SELECTIONS] =		{ {FIRSTROOF, 0, 1} };
Selections	SelSingleBrokenWall[MAX_SELECTIONS] = { {FIRSTDECORATIONS, 0, 1} };
Selections	SelSingleDecor[MAX_SELECTIONS]=				{ {FIRSTISTRUCT, 0, 1} };
Selections	SelSingleDecal[MAX_SELECTIONS]	=		{ {FIRSTWALLDECAL, 0, 1} };
Selections	SelSingleFloor[MAX_SELECTIONS] =			{ {FIRSTFLOOR, 0, 1} };
Selections	SelSingleToilet[MAX_SELECTIONS] =			{ {FIFTHISTRUCT, 0, 1} };
Selections	SelRoom[MAX_SELECTIONS]			=					{ {FIRSTWALL, 0, 1} };

// Number of objects currently in the selection list
INT32				iNumOStructsSelected = 1;
INT32				iNumOStructs1Selected = 1;
INT32				iNumOStructs2Selected = 1;
INT32				iNumBanksSelected = 1;
INT32				iNumRoadsSelected = 1;
INT32				iNumDebrisSelected = 1;

INT32				iNumWallsSelected = 1;
INT32				iNumDoorsSelected = 1;
INT32				iNumWindowsSelected = 1;
INT32				iNumDecorSelected = 1;
INT32				iNumDecalsSelected = 1;
INT32				iNumBrokenWallsSelected = 1;
INT32				iNumFloorsSelected = 1;
INT32		iNumToiletsSelected = 1;
INT32				iNumRoofsSelected = 1;
INT32				iNumNewRoofsSelected = 1;
INT32				iNumRoomsSelected = 1;

// Holds the previous selection list when a selection window is up. Used for canceling the selection window
Selections	OldSelList[MAX_SELECTIONS];
INT32				iOldNumSelList;

// Global pointers for selection list
Selections	*pSelList;
INT32				*pNumSelList;

// Global used to indicate which selection to use (changes with the PGUP/PGDWN keys in editor)
INT32				iCurBank = 0;

DisplayList *pDispList;
INT16 iTopWinCutOff,iBotWinCutOff;
DisplayList Selection;

UINT16 SelWinFillColor = 0x0000;					// Black
UINT16 SelWinHilightFillColor = 0x23BA;		//blue, formerly 0x000d a kind of medium dark blue (not contrasty)

//----------------------------------------------------------------------------------------------
//	CreateJA2SelectionWindow
//
//	Creates a selection window of the given type.
//
void CreateJA2SelectionWindow( INT16 sWhat )
{
	DisplaySpec *pDSpec;
	UINT16 usNSpecs;

	fAllDone = FALSE;

	DisableEditorTaskbar( );

	// Load up the button images
	iButtonIcons[ SEL_WIN_CANCEL_ICON ] = LoadGenericButtonIcon( "EDITOR//bigX.sti" );
	iButtonIcons[ SEL_WIN_UP_ICON ]		= LoadGenericButtonIcon( "EDITOR//lgUpArrow.sti" );
	iButtonIcons[ SEL_WIN_DOWN_ICON ]	= LoadGenericButtonIcon( "EDITOR//lgDownArrow.sti" );
	iButtonIcons[ SEL_WIN_OK_ICON ]		= LoadGenericButtonIcon( "EDITOR//checkmark.sti" );

	iSelectWin = CreateHotSpot(0, 0, 600, 360, MSYS_PRIORITY_HIGH,
														DEFAULT_MOVE_CALLBACK, SelWinClkCallback);

	iOkWin = CreateIconButton((INT16)iButtonIcons[SEL_WIN_OK_ICON], 0,
														BUTTON_USE_DEFAULT, 600, 0,
														40, 40, BUTTON_TOGGLE,
														MSYS_PRIORITY_HIGH,
														DEFAULT_MOVE_CALLBACK, OkClkCallback);
	SetButtonFastHelpText(iOkWin,pDisplaySelectionWindowButtonText[0]);

	iCancelWin = CreateIconButton((INT16)iButtonIcons[SEL_WIN_CANCEL_ICON], 0,
														BUTTON_USE_DEFAULT, 600, 40,
														40, 40, BUTTON_TOGGLE,
 														MSYS_PRIORITY_HIGH,
														DEFAULT_MOVE_CALLBACK, CnclClkCallback);
	SetButtonFastHelpText(iCancelWin,pDisplaySelectionWindowButtonText[1]);

	iScrollUp = CreateIconButton((INT16)iButtonIcons[SEL_WIN_UP_ICON], 0,
														BUTTON_USE_DEFAULT, 600, 80,
														40, 160, BUTTON_NO_TOGGLE,
														MSYS_PRIORITY_HIGH,
														DEFAULT_MOVE_CALLBACK, UpClkCallback);
	SetButtonFastHelpText(iScrollUp,pDisplaySelectionWindowButtonText[2]);

	iScrollDown = CreateIconButton((INT16)iButtonIcons[SEL_WIN_DOWN_ICON], 0,
														BUTTON_USE_DEFAULT, 600, 240,
														40, 160, BUTTON_NO_TOGGLE,
														MSYS_PRIORITY_HIGH,
														DEFAULT_MOVE_CALLBACK, DwnClkCallback);
	SetButtonFastHelpText(iScrollDown,pDisplaySelectionWindowButtonText[3]);

	fButtonsPresent = TRUE;

	SelWinSpacing.iX = 2;
	SelWinSpacing.iY = 2;

	SelWinStartPoint.iX = 1;
	SelWinStartPoint.iY = 15;

	iTopWinCutOff = 15;

	SelWinEndPoint.iX = 599;
	SelWinEndPoint.iY = 359;

	iBotWinCutOff = 359;

	switch( sWhat )
	{
		case SELWIN_OSTRUCTS:
			pDSpec = OStructs;
			usNSpecs = gusNumOStructs;//OSTRUCTS_NUMELEMENTS;
			pSelList = SelOStructs;
			pNumSelList = &iNumOStructsSelected;
			break;

		case SELWIN_OSTRUCTS1:
			pDSpec = OStructs1;
			usNSpecs = OSTRUCTS1_NUMELEMENTS;
			pSelList = SelOStructs1;
			pNumSelList = &iNumOStructs1Selected;
			break;

		case SELWIN_OSTRUCTS2:
			pDSpec = OStructs2;
			usNSpecs = OSTRUCTS2_NUMELEMENTS;
			pSelList = SelOStructs2;
			pNumSelList = &iNumOStructs2Selected;
			break;

		case SELWIN_BANKS:
			pDSpec = BanksList;
			usNSpecs = BANKSLIST_NUMELEMENTS;
			pSelList = SelBanks;
			pNumSelList = &iNumBanksSelected;
			break;

		case SELWIN_ROADS:
			pDSpec = RoadsList;
			usNSpecs = ROADSLIST_NUMELEMENTS;
			pSelList = SelRoads;
			pNumSelList = &iNumRoadsSelected;
			break;

		case SELWIN_DEBRIS:
			pDSpec = DebrisList;
			usNSpecs = DEBRISLIST_NUMELEMENTS;
			pSelList = SelDebris;
			pNumSelList = &iNumDebrisSelected;
			break;

		case SELWIN_SINGLEWALL:
			pDSpec = SingleWall;
			usNSpecs = SINGLEWALL_NUMELEMENTS;
			pSelList = SelSingleWall;
			pNumSelList = &iNumWallsSelected;
			break;
		case SELWIN_SINGLEDOOR:
			pDSpec = SingleDoor;
			usNSpecs = SINGLEDOOR_NUMELEMENTS;
			pSelList = SelSingleDoor;
			pNumSelList = &iNumDoorsSelected;
			break;
		case SELWIN_SINGLEWINDOW:
			pDSpec = SingleWindow;
			usNSpecs = SINGLEWINDOW_NUMELEMENTS;
			pSelList = SelSingleWindow;
			pNumSelList = &iNumWindowsSelected;
			break;
		case SELWIN_SINGLEROOF:
			pDSpec = SingleRoof;
			usNSpecs = SINGLEROOF_NUMELEMENTS;
			pSelList = SelSingleRoof;
			pNumSelList = &iNumRoofsSelected;
			break;
		case SELWIN_SINGLENEWROOF:
			pDSpec = SingleNewRoof;
			usNSpecs = SINGLENEWROOF_NUMELEMENTS;
			pSelList = SelSingleNewRoof;
			pNumSelList = &iNumNewRoofsSelected;
			break;
		case SELWIN_SINGLEBROKENWALL:
			pDSpec = SingleBrokenWall;
			usNSpecs = SINGLEBROKENWALL_NUMELEMENTS;
			pSelList = SelSingleBrokenWall;
			pNumSelList = &iNumBrokenWallsSelected;
			break;
		case SELWIN_SINGLEDECOR:
			pDSpec = SingleDecor;
			usNSpecs = SINGLEDECOR_NUMELEMENTS;
			pSelList = SelSingleDecor;
			pNumSelList = &iNumDecorSelected;
			break;
		case SELWIN_SINGLEDECAL:
			pDSpec = SingleDecal;
			usNSpecs = SINGLEDECAL_NUMELEMENTS;
			pSelList = SelSingleDecal;
			pNumSelList = &iNumDecalsSelected;
			break;
		case SELWIN_SINGLEFLOOR:
			pDSpec = SingleFloor;
			usNSpecs = SINGLEFLOOR_NUMELEMENTS;
			pSelList = SelSingleFloor;
			pNumSelList = &iNumFloorsSelected;
			break;
		case SELWIN_SINGLETOILET:
			pDSpec = SingleToilet;
			usNSpecs = SINGLETOILET_NUMELEMENTS;
			pSelList = SelSingleToilet;
			pNumSelList = &iNumToiletsSelected;
			break;
		case SELWIN_ROOM:
			pDSpec = Room;
			usNSpecs = ROOM_NUMELEMENTS;
			pSelList = SelRoom;
			pNumSelList = &iNumRoomsSelected;
			break;
		default:
			// If none of these, don't create anything!
			AssertMsg( 0, "Unknown window creation type");
			return;
	}

	BuildDisplayWindow( pDSpec, usNSpecs, &pDispList, &SelWinStartPoint, &SelWinEndPoint,
										&SelWinSpacing, CLEAR_BACKGROUND);
}


//The selection window method is initialized here.	This is where all the graphics for all
//the categories are organized and loaded.	If you wish to move things around, then this is
//where the initialization part is done.	I have also changed this from previously being loaded
//every single time you go into a selection window which was redundant and CPU consuming.
void InitJA2SelectionWindow( void )
{
	INT32 iCount;
	INT32 iCount2;
	INT32 iCount3;

	UINT16			usETRLEObjects;
	HVOBJECT		hVObject;


	pDispList = NULL;

	// Init the display spec lists for the types of selection windows

	// Trees & bushes (The tree button in the "terrain" toolbar)
	for ( iCount3 = 0, iCount = 0; iCount < (LASTOSTRUCT - FIRSTFULLSTRUCT + 1); iCount++ )
	{
		hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTFULLSTRUCT + iCount]].hTileSurface;
		usETRLEObjects = hVObject->usNumberOfObjects;


		for ( iCount2 = 0; iCount2 < usETRLEObjects; iCount2 += 3, iCount3++)
		{
			OStructs[ iCount3 ].ubType = DISPLAY_GRAPHIC;
			OStructs[ iCount3 ].hVObject = hVObject;
			OStructs[ iCount3 ].usStart = (UINT16)iCount2;
			OStructs[ iCount3 ].usEnd = (UINT16)iCount2;
			OStructs[ iCount3 ].uiObjIndx = (FIRSTFULLSTRUCT + iCount);
		}
	}

	OStructs[ iCount3 ].ubType = DISPLAY_GRAPHIC;
	OStructs[ iCount3 ].hVObject = gTileDatabase[gTileTypeStartIndex[SIXTHOSTRUCT]].hTileSurface;
	OStructs[ iCount3 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs[ iCount3 ].usEnd = 0;
	OStructs[ iCount3 ].uiObjIndx = SIXTHOSTRUCT;

	gusNumOStructs = (UINT16)iCount3 + 1;

	// Rocks & barrels! (the "1" button in the "terrain" toolbar)
	OStructs1[ 0 ].ubType = DISPLAY_GRAPHIC;
	OStructs1[ 0 ].hVObject = gTileDatabase[gTileTypeStartIndex[FOURTHOSTRUCT]].hTileSurface;
	OStructs1[ 0 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs1[ 0 ].usEnd = 0;
	OStructs1[ 0 ].uiObjIndx = FOURTHOSTRUCT;

	for ( iCount = 0; iCount < (THIRDOSTRUCT - FIRSTOSTRUCT); iCount++ )
	{
		OStructs1[ iCount + 1 ].ubType = DISPLAY_GRAPHIC;
		OStructs1[ iCount + 1 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTOSTRUCT + iCount]].hTileSurface;
		OStructs1[ iCount + 1 ].usStart = DISPLAY_ALL_OBJECTS;
		OStructs1[ iCount + 1 ].usEnd = 0;
		OStructs1[ iCount + 1 ].uiObjIndx = FIRSTOSTRUCT + iCount;
	}


	// Other junk! (the "2" button in the "terrain" toolbar)
	OStructs2[ 0 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 0 ].hVObject = gTileDatabase[gTileTypeStartIndex[THIRDOSTRUCT]].hTileSurface;
	OStructs2[ 0 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 0 ].usEnd = 0;
	OStructs2[ 0 ].uiObjIndx = THIRDOSTRUCT;

	OStructs2[ 1 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 1 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIFTHOSTRUCT]].hTileSurface;
	OStructs2[ 1 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 1 ].usEnd = 0;
	OStructs2[ 1 ].uiObjIndx = FIFTHOSTRUCT;

	OStructs2[ 2 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 2 ].hVObject = gTileDatabase[gTileTypeStartIndex[SEVENTHOSTRUCT]].hTileSurface;
	OStructs2[ 2 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 2 ].usEnd = 0;
	OStructs2[ 2 ].uiObjIndx = SEVENTHOSTRUCT;

	OStructs2[ 3 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 3 ].hVObject = gTileDatabase[gTileTypeStartIndex[EIGHTOSTRUCT]].hTileSurface;
	OStructs2[ 3 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 3 ].usEnd = 0;
	OStructs2[ 3 ].uiObjIndx = EIGHTOSTRUCT;

	OStructs2[ 4 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 4 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTVEHICLE]].hTileSurface;
	OStructs2[ 4 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 4 ].usEnd = 0;
	OStructs2[ 4 ].uiObjIndx = FIRSTVEHICLE;

	OStructs2[ 5 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 5 ].hVObject = gTileDatabase[gTileTypeStartIndex[SECONDVEHICLE]].hTileSurface;
	OStructs2[ 5 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 5 ].usEnd = 0;
	OStructs2[ 5 ].uiObjIndx = SECONDVEHICLE;

	OStructs2[ 6 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 6 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDEBRISSTRUCT]].hTileSurface;
	OStructs2[ 6 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 6 ].usEnd = 0;
	OStructs2[ 6 ].uiObjIndx = FIRSTDEBRISSTRUCT;

	OStructs2[ 7 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 7 ].hVObject = gTileDatabase[gTileTypeStartIndex[SECONDDEBRISSTRUCT]].hTileSurface;
	OStructs2[ 7 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 7 ].usEnd = 0;
	OStructs2[ 7 ].uiObjIndx = SECONDDEBRISSTRUCT;

	OStructs2[ 8 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 8 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTLARGEEXPDEBRIS]].hTileSurface;
	OStructs2[ 8 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 8 ].usEnd = 0;
	OStructs2[ 8 ].uiObjIndx = FIRSTLARGEEXPDEBRIS;

	OStructs2[ 9 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 9 ].hVObject = gTileDatabase[gTileTypeStartIndex[SECONDLARGEEXPDEBRIS]].hTileSurface;
	OStructs2[ 9 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 9 ].usEnd = 0;
	OStructs2[ 9 ].uiObjIndx = SECONDLARGEEXPDEBRIS;

	OStructs2[ 10 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 10 ].hVObject = gTileDatabase[gTileTypeStartIndex[NINTHOSTRUCT]].hTileSurface;
	OStructs2[ 10 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 10 ].usEnd = 0;
	OStructs2[ 10 ].uiObjIndx = NINTHOSTRUCT;

	OStructs2[ 11 ].ubType = DISPLAY_GRAPHIC;
	OStructs2[ 11 ].hVObject = gTileDatabase[gTileTypeStartIndex[TENTHOSTRUCT]].hTileSurface;
	OStructs2[ 11 ].usStart = DISPLAY_ALL_OBJECTS;
	OStructs2[ 11 ].usEnd = 0;
	OStructs2[ 11 ].uiObjIndx = TENTHOSTRUCT;

	// River banks and cliffs (the "river" button on the "terrain" toolbar)
	BanksList[0].ubType = DISPLAY_GRAPHIC;
	BanksList[0].hVObject = gTileDatabase[gTileTypeStartIndex[ANIOSTRUCT]].hTileSurface;
	BanksList[0].usStart = DISPLAY_ALL_OBJECTS;
	BanksList[0].usEnd = 0;
	BanksList[0].uiObjIndx = ANIOSTRUCT;

	BanksList[1].ubType = DISPLAY_GRAPHIC;
	BanksList[1].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTCLIFF]].hTileSurface;
	BanksList[1].usStart = DISPLAY_ALL_OBJECTS;
	BanksList[1].usEnd = 0;
	BanksList[1].uiObjIndx = FIRSTCLIFF;

	BanksList[2].ubType = DISPLAY_GRAPHIC;
	BanksList[2].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTCLIFFHANG]].hTileSurface;
	BanksList[2].usStart = DISPLAY_ALL_OBJECTS;
	BanksList[2].usEnd = 0;
	BanksList[2].uiObjIndx = FIRSTCLIFFHANG;

	BanksList[3].ubType = DISPLAY_GRAPHIC;
	BanksList[3].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTROAD]].hTileSurface;
	BanksList[3].usStart = DISPLAY_ALL_OBJECTS;
	BanksList[3].usEnd = 0;
	BanksList[3].uiObjIndx = FIRSTROAD;

	BanksList[4].ubType = DISPLAY_GRAPHIC;
	BanksList[4].hVObject = gTileDatabase[gTileTypeStartIndex[FENCESTRUCT]].hTileSurface;
	BanksList[4].usStart = DISPLAY_ALL_OBJECTS;
	BanksList[4].usEnd = 0;
	BanksList[4].uiObjIndx = FENCESTRUCT;

	RoadsList[0].ubType = DISPLAY_GRAPHIC;
	RoadsList[0].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTROAD]].hTileSurface;
	RoadsList[0].usStart = DISPLAY_ALL_OBJECTS;
	RoadsList[0].usEnd = 0;
	RoadsList[0].uiObjIndx = FIRSTROAD;

	// Debris (the "bent can" button on the "terrain", and "buildings" toolbars)
	for ( iCount = 0; iCount < (LASTDEBRIS - DEBRISROCKS + 1); iCount++ )
	{
		DebrisList[ iCount ].ubType = DISPLAY_GRAPHIC;
		DebrisList[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[DEBRISROCKS + iCount]].hTileSurface;
		DebrisList[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		DebrisList[ iCount ].usEnd = 0;
		DebrisList[ iCount ].uiObjIndx = DEBRISROCKS + iCount;
	}
	// Add one more for new misc debris
	DebrisList[ iCount ].ubType = DISPLAY_GRAPHIC;
	DebrisList[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[DEBRIS2MISC ] ].hTileSurface;
	DebrisList[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
	DebrisList[ iCount ].usEnd = 0;
	DebrisList[ iCount ].uiObjIndx = DEBRIS2MISC;
	//Add yet another one...
	iCount++;
	DebrisList[ iCount ].ubType = DISPLAY_GRAPHIC;
	DebrisList[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[ANOTHERDEBRIS ] ].hTileSurface;
	DebrisList[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
	DebrisList[ iCount ].usEnd = 0;
	DebrisList[ iCount ].uiObjIndx = ANOTHERDEBRIS;

	// Rooms
	for ( iCount = 0; iCount < (LASTWALL - FIRSTWALL + 1); iCount++ )
	{
		Room[ iCount ].ubType = DISPLAY_GRAPHIC;
		Room[iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount]].hTileSurface;
		Room[ iCount ].usStart = 0;
		Room[ iCount ].usEnd = 0;
		Room[ iCount ].uiObjIndx = FIRSTWALL + iCount;
	}
	for ( iCount2 = 0; iCount2 < (LASTFLOOR - FIRSTFLOOR + 1); iCount2++, iCount++ )
	{
		Room[ iCount ].ubType = DISPLAY_GRAPHIC;
		Room[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTFLOOR + iCount2]].hTileSurface;
		Room[ iCount ].usStart = 0;
		Room[ iCount ].usEnd = 0;
		Room[ iCount ].uiObjIndx = FIRSTFLOOR + iCount2;
	}
	for ( iCount2 = 0; iCount2 < (LASTROOF - FIRSTROOF + 1); iCount2++, iCount++ )
	{
		Room[ iCount ].ubType = DISPLAY_GRAPHIC;
		Room[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTROOF + iCount2]].hTileSurface;
		Room[ iCount ].usStart = 0;
		Room[ iCount ].usEnd = 0;
		Room[ iCount ].uiObjIndx = FIRSTROOF + iCount2;
	}
	for ( iCount2 = 0; iCount2 < 2/*(LASTSLANTROOF - FIRSTSLANTROOF + 1)*/; iCount2++, iCount++ )
	{
		Room[ iCount ].ubType = DISPLAY_GRAPHIC;
		Room[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTSLANTROOF + iCount2]].hTileSurface;
		Room[ iCount ].usStart = 0;
		Room[ iCount ].usEnd = 0;
		Room[ iCount ].uiObjIndx = FIRSTSLANTROOF + iCount2;
	}

	//Walls
	for ( iCount = 0, iCount2 = 0; iCount < (LASTWALL - FIRSTWALL + 1); iCount++, iCount2+=2 )
	{
		SingleWall[ iCount2 ].ubType = DISPLAY_GRAPHIC;
		SingleWall[ iCount2 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount]].hTileSurface;
		SingleWall[ iCount2 ].usStart = 0;
		SingleWall[ iCount2 ].usEnd = WALL_LAST_WALL_OFFSET;
		SingleWall[ iCount2 ].uiObjIndx = FIRSTWALL + iCount;
		//New appended walls
		SingleWall[ iCount2+1 ].ubType = DISPLAY_GRAPHIC;
		SingleWall[ iCount2+1 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount]].hTileSurface;
		SingleWall[ iCount2+1 ].usStart = WALL_FIRST_APPENDED_WALL_OFFSET;
		SingleWall[ iCount2+1 ].usEnd = WALL_LAST_APPENDED_WALL_OFFSET;
		SingleWall[ iCount2+1 ].uiObjIndx = FIRSTWALL + iCount;
	}

	//Doors
	for ( iCount = 0, iCount2 = 0; iCount < (LASTDOOR - FIRSTDOOR + 1); iCount++, iCount2+=5)
	{
		//closed
		SingleDoor[ iCount2 ].ubType = DISPLAY_GRAPHIC;
		SingleDoor[ iCount2 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDOOR + iCount]].hTileSurface;
		SingleDoor[ iCount2 ].usStart = 0;
		SingleDoor[ iCount2 ].usEnd = 0;
		SingleDoor[ iCount2 ].uiObjIndx = FIRSTDOOR + iCount;
		//open, closed
		SingleDoor[ iCount2+1 ].ubType = DISPLAY_GRAPHIC;
		SingleDoor[ iCount2+1 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDOOR + iCount]].hTileSurface;
		SingleDoor[ iCount2+1 ].usStart = 4;
		SingleDoor[ iCount2+1 ].usEnd = 5;
		SingleDoor[ iCount2+1 ].uiObjIndx = FIRSTDOOR + iCount;
		//open, closed
		SingleDoor[ iCount2+2 ].ubType = DISPLAY_GRAPHIC;
		SingleDoor[ iCount2+2 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDOOR + iCount]].hTileSurface;
		SingleDoor[ iCount2+2 ].usStart = 9;
		SingleDoor[ iCount2+2 ].usEnd = 10;
		SingleDoor[ iCount2+2 ].uiObjIndx = FIRSTDOOR + iCount;
		//open, closed
		SingleDoor[ iCount2+3 ].ubType = DISPLAY_GRAPHIC;
		SingleDoor[ iCount2+3 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDOOR + iCount]].hTileSurface;
		SingleDoor[ iCount2+3 ].usStart = 14;
		SingleDoor[ iCount2+3 ].usEnd = 15;
		SingleDoor[ iCount2+3 ].uiObjIndx = FIRSTDOOR + iCount;
		//open
		SingleDoor[ iCount2+4 ].ubType = DISPLAY_GRAPHIC;
		SingleDoor[ iCount2+4 ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDOOR + iCount]].hTileSurface;
		SingleDoor[ iCount2+4 ].usStart = 19;
		SingleDoor[ iCount2+4 ].usEnd = 19;
		SingleDoor[ iCount2+4 ].uiObjIndx = FIRSTDOOR + iCount;
	}
	//Windows
	for ( iCount = 0; iCount < (LASTWALL - FIRSTWALL + 1); iCount++ )
	{
		SingleWindow[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleWindow[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount]].hTileSurface;
		SingleWindow[ iCount ].usStart = WALL_FIRST_WINDOW_OFFSET;
		SingleWindow[ iCount ].usEnd = WALL_LAST_WINDOW_OFFSET;
		SingleWindow[ iCount ].uiObjIndx = FIRSTWALL + iCount;
	}
	//Roofs and slant roofs
	for ( iCount = 0; iCount < (LASTROOF - FIRSTROOF + 1); iCount++ )
	{	//Flat roofs
		SingleRoof[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleRoof[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTROOF + iCount]].hTileSurface;
		SingleRoof[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleRoof[ iCount ].usEnd = 0;
		SingleRoof[ iCount ].uiObjIndx = FIRSTROOF + iCount;
	}
	for ( iCount2 = 0; iCount2 < (LASTSLANTROOF - FIRSTSLANTROOF + 1); iCount2++, iCount++ )
	{	//Slanted roofs
		SingleRoof[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleRoof[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTSLANTROOF + iCount2]].hTileSurface;
		SingleRoof[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleRoof[ iCount ].usEnd = 0;
		SingleRoof[ iCount ].uiObjIndx = FIRSTSLANTROOF + iCount2;
	}
	for( iCount2 = 0; iCount2 < (LASTWALL - FIRSTWALL + 1); iCount2++, iCount++ )
	{	//A-Frames
		SingleRoof[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleRoof[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount2]].hTileSurface;
		SingleRoof[ iCount ].usStart = WALL_FIRST_AFRAME_OFFSET;
		SingleRoof[ iCount ].usEnd = WALL_LAST_AFRAME_OFFSET;
		SingleRoof[ iCount ].uiObjIndx = FIRSTWALL + iCount2;
	}
	for( iCount2 = 0; iCount2 < (SECONDONROOF - FIRSTONROOF + 1); iCount2++, iCount++ )
	{	//On roofs
		SingleRoof[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleRoof[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTONROOF + iCount2]].hTileSurface;
		SingleRoof[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleRoof[ iCount ].usEnd = 0;
		SingleRoof[ iCount ].uiObjIndx = FIRSTONROOF + iCount2;
	}

	//New replacement roofs
	for ( iCount = 0; iCount < (LASTROOF - FIRSTROOF + 1); iCount++ )
	{	//Flat roofs
		SingleNewRoof[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleNewRoof[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTROOF + iCount]].hTileSurface;
		SingleNewRoof[ iCount ].usStart = 9;
		SingleNewRoof[ iCount ].usEnd = 9;
		SingleNewRoof[ iCount ].uiObjIndx = FIRSTROOF + iCount;
	}

	//Broken walls
	for ( iCount = 0; iCount < (LASTDECORATIONS - FIRSTDECORATIONS + 1); iCount++ )
	{	//Old obsolete wall decals, but should be replaced with multitiled decals such as banners, etc.
		SingleBrokenWall[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleBrokenWall[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTDECORATIONS + iCount]].hTileSurface;
		SingleBrokenWall[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleBrokenWall[ iCount ].usEnd = 0;
		SingleBrokenWall[ iCount ].uiObjIndx = FIRSTDECORATIONS + iCount;
	}
	for( iCount2 = 0; iCount2 < (LASTWALL - FIRSTWALL + 1); iCount2++, iCount++ )
	{	//Broken walls
		SingleBrokenWall[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleBrokenWall[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount2]].hTileSurface;
		SingleBrokenWall[ iCount ].usStart = WALL_FIRST_BROKEN_WALL_OFFSET;
		SingleBrokenWall[ iCount ].usEnd = WALL_LAST_BROKEN_WALL_OFFSET;
		SingleBrokenWall[ iCount ].uiObjIndx = FIRSTWALL + iCount2;
	}
	for( iCount2 = 0; iCount2 < (LASTWALL - FIRSTWALL + 1); iCount2++, iCount++ )
	{	//Cracked and smudged walls
		SingleBrokenWall[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleBrokenWall[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALL + iCount2]].hTileSurface;
		SingleBrokenWall[ iCount ].usStart = WALL_FIRST_WEATHERED_WALL_OFFSET;
		SingleBrokenWall[ iCount ].usEnd = WALL_LAST_WEATHERED_WALL_OFFSET;
		SingleBrokenWall[ iCount ].uiObjIndx = FIRSTWALL + iCount2;
	}

	// Decorations
	for ( iCount = 0; iCount < (LASTISTRUCT - FIRSTISTRUCT + 1); iCount++ )
	{
		SingleDecor[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleDecor[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTISTRUCT + iCount]].hTileSurface;
		SingleDecor[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleDecor[ iCount ].usEnd = 0;
		SingleDecor[ iCount ].uiObjIndx = FIRSTISTRUCT + iCount;
	}

	// Wall decals
	for ( iCount = 0; iCount < (LASTWALLDECAL - FIRSTWALLDECAL + 1); iCount++ )
	{
		SingleDecal[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleDecal[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTWALLDECAL + iCount]].hTileSurface;
		SingleDecal[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleDecal[ iCount ].usEnd = 0;
		SingleDecal[ iCount ].uiObjIndx = FIRSTWALLDECAL + iCount;
	}
	for ( iCount2 = 0; iCount2 < (EIGTHWALLDECAL - FIFTHWALLDECAL + 1); iCount++, iCount2++ )
	{
		SingleDecal[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleDecal[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIFTHWALLDECAL + iCount2]].hTileSurface;
		SingleDecal[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleDecal[ iCount ].usEnd = 0;
		SingleDecal[ iCount ].uiObjIndx = FIFTHWALLDECAL + iCount2;
	}
	SingleDecal[ iCount ].ubType = DISPLAY_GRAPHIC;
	SingleDecal[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTSWITCHES]].hTileSurface;
	SingleDecal[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
	SingleDecal[ iCount ].usEnd = 0;
	SingleDecal[ iCount ].uiObjIndx = FIRSTSWITCHES;

	//Floors
	for ( iCount = 0; iCount < (LASTFLOOR - FIRSTFLOOR + 1); iCount++ )
	{
		SingleFloor[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleFloor[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIRSTFLOOR + iCount]].hTileSurface;
		SingleFloor[ iCount ].usStart = 0;
		SingleFloor[ iCount ].usEnd = 7;
		SingleFloor[ iCount ].uiObjIndx = FIRSTFLOOR + iCount;
	}

	//Toilets
	for ( iCount = 0; iCount < (EIGHTISTRUCT - FIFTHISTRUCT + 1); iCount++ )
	{
		SingleToilet[ iCount ].ubType = DISPLAY_GRAPHIC;
		SingleToilet[ iCount ].hVObject = gTileDatabase[gTileTypeStartIndex[FIFTHISTRUCT + iCount]].hTileSurface;
		SingleToilet[ iCount ].usStart = DISPLAY_ALL_OBJECTS;
		SingleToilet[ iCount ].usEnd = 0;
		SingleToilet[ iCount ].uiObjIndx = FIFTHISTRUCT + iCount;
	}

}


//----------------------------------------------------------------------------------------------
//	ShutdownJA2SelectionWindow
//
//	Unloads selection window button images and makes sure any display list that may remain in memory
//	is removed.
//
void ShutdownJA2SelectionWindow( void )
{
	INT16 x;

	for (x = 0; x < 4; x++)
		UnloadGenericButtonIcon( (INT16)iButtonIcons[x] );

	if (pDispList != NULL)
	{
		pDispList = TrashList(pDispList);
	}
	gfRenderWorld = TRUE;
}


//----------------------------------------------------------------------------------------------
//	RemoveJA2SelectionWindow
//
//	Removes the selection window from the screen.
//
void RemoveJA2SelectionWindow( void )
{
	RemoveButton(iSelectWin);
	RemoveButton(iCancelWin);
	RemoveButton(iScrollUp);
	RemoveButton(iScrollDown);
	RemoveButton(iOkWin);

	gfRenderSquareArea = FALSE;

	if (pDispList != NULL)
	{
		pDispList = TrashList(pDispList);
	}
	gfRenderTaskbar = TRUE;

	gfOverheadMapDirty = TRUE;
	EnableEditorTaskbar( );
}


//----------------------------------------------------------------------------------------------
//	TrashList
//
//	Free the current display list for the selection window.
//
DisplayList *TrashList( DisplayList *pNode )
{
	if (pNode == NULL)
		return(NULL);

	if (pNode->pNext != NULL)
		pNode->pNext = TrashList(pNode->pNext);

	if (pNode->pNext == NULL)
		MemFree(pNode);

	return(NULL);
}


//----------------------------------------------------------------------------------------------
//	RenderSelectionWindow
//
//	Displays the current selection window
//
void RenderSelectionWindow( void )
{
	GUI_BUTTON *button;
	INT32 iSX,iSY,iEX,iEY;
	UINT16 usFillColor;
	static UINT8 usFillGreen = 0;
	static UINT8 usDir = 5;


	if (!fButtonsPresent)
		return;

	ColorFillVideoSurfaceArea(FRAME_BUFFER,
													0, 0, 600, 400,
													GenericButtonFillColors[0]);
	DrawSelections( );
	MarkButtonsDirty();
	RenderButtons( );

	if ( gfRenderSquareArea )
	{
		button = ButtonList[iSelectWin];
		if ( button == NULL )
			return;

		if ( (abs( iStartClickX - button->Area.MouseXPos ) > 9) ||
			(abs( iStartClickY - (button->Area.MouseYPos + iTopWinCutOff - (INT16)SelWinStartPoint.iY)) > 9) )
		{
//			iSX = (INT32)iStartClickX;
//			iEX = (INT32)button->Area.MouseXPos;
//			iSY = (INT32)iStartClickY;
//			iEY = (INT32)(button->Area.MouseYPos + iTopWinCutOff - (INT16)SelWinStartPoint.iY);

			iSX = iStartClickX;
			iSY = iStartClickY - iTopWinCutOff + SelWinStartPoint.iY;
			iEX = gusMouseXPos;
			iEY = gusMouseYPos;


			if (iEX < iSX)
			{
				iEX ^= iSX;
				iSX ^= iEX;
				iEX ^= iSX;
			}

			if (iEY < iSY)
			{
				iEY ^= iSY;
				iSY ^= iEY;
				iEY ^= iSY;
			}

			iEX = min( iEX, 600 );
			iSY = max( SelWinStartPoint.iY, iSY );
			iEY = min( 359, iEY );
			iEY = max( SelWinStartPoint.iY, iEY );

			usFillColor = Get16BPPColor(FROMRGB(255, usFillGreen, 0));
			usFillGreen += usDir;
			if( usFillGreen > 250 )
				usDir = 251;
			else if( usFillGreen < 5 )
				usDir = 5;

			ColorFillVideoSurfaceArea(FRAME_BUFFER, iSX, iSY, iEX, iSY+1, usFillColor );
			ColorFillVideoSurfaceArea(FRAME_BUFFER, iSX, iEY, iEX, iEY+1, usFillColor );
			ColorFillVideoSurfaceArea(FRAME_BUFFER, iSX, iSY, iSX+1, iEY, usFillColor );
			ColorFillVideoSurfaceArea(FRAME_BUFFER, iEX, iSY, iEX+1, iEY, usFillColor );
		}
	}
}


//----------------------------------------------------------------------------------------------
//	SelWinClkCallback
//
//	Button callback function for the main selection window. Checks if user clicked on an image,
//	if so selects or de-selects that object. Also handles the multi-object selection (left-click
//	and drag to get the selection rectangle)
//
void SelWinClkCallback( GUI_BUTTON *button, INT32 reason )
{
	DisplayList *pNode;
	BOOLEAN fDone;
	INT16 iClickX,iClickY, iYInc, iXInc;


	if (!(button->uiFlags & BUTTON_ENABLED))
		return;

	iClickX = button->Area.MouseXPos;
	iClickY = button->Area.MouseYPos + iTopWinCutOff - (INT16)SelWinStartPoint.iY;

	if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
	{
		button->uiFlags |= BUTTON_CLICKED_ON;
		iStartClickX = iClickX;
		iStartClickY = iClickY;
		gfRenderSquareArea = TRUE;
	}
	else if (reason & MSYS_CALLBACK_REASON_RBUTTON_DWN)
	{
		button->uiFlags |= BUTTON_CLICKED_ON;

		if ( gfRenderSquareArea )
		{
			gfRenderSquareArea = FALSE;
			return;
		}

		// Code to figure out what image user wants goes here
		pNode = pDispList;

		fDone = FALSE;
		while( (pNode != NULL) && !fDone )
		{
			if ( (iClickX >= pNode->iX) && (iClickX < (pNode->iX + pNode->iWidth)) &&
					(iClickY >= pNode->iY) && (iClickY < (pNode->iY + pNode->iHeight)) )
			{
				fDone = TRUE;
				if ( RemoveFromSelectionList(pNode) )
					pNode->fChosen = FALSE;
			}
			else
				pNode = pNode->pNext;
		}
	}
	else if (reason & MSYS_CALLBACK_REASON_RBUTTON_UP )
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON);
	}
	else if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON);

		if( !gfRenderSquareArea )
			return;

		iEndClickX = iClickX;
		iEndClickY = iClickY;

		gfRenderSquareArea = FALSE;

		if( iEndClickX < iStartClickX )
		{
			iStartClickX ^= iEndClickX;
			iEndClickX ^= iStartClickX;
			iStartClickX ^= iEndClickX;
		}

		if( iEndClickY < iStartClickY )
		{
			iStartClickY ^= iEndClickY;
			iEndClickY ^= iStartClickY;
			iStartClickY ^= iEndClickY;
		}

		iXInc = iYInc = 1;
		for( iClickY = iStartClickY; iClickY <= iEndClickY; iClickY += iYInc )
		{
			iYInc = 1;
			for( iClickX = iStartClickX; iClickX <= iEndClickX; iClickX += iXInc )
			{
				iXInc = 1;
				// Code to figure out what image user wants goes here
				pNode = pDispList;

				fDone = FALSE;
				while( (pNode != NULL) && !fDone )
				{
					if ( (iClickX >= pNode->iX) && (iClickX < (pNode->iX + pNode->iWidth)) &&
							(iClickY >= pNode->iY) && (iClickY < (pNode->iY + pNode->iHeight)) )
					{
						fDone = TRUE;
						AddToSelectionList(pNode);
						pNode->fChosen = TRUE;
						iXInc = (pNode->iX + pNode->iWidth) - iClickX;
						if ( iYInc < ((pNode->iY + pNode->iHeight) - iClickY) )
							iYInc = (pNode->iY + pNode->iHeight) - iClickY;
					}
					else
						pNode = pNode->pNext;
				}
			}
		}
	}
}

//When a selection window is up, the file information of the picture will display
//at the top of the screen.
void DisplaySelectionWindowGraphicalInformation()
{
	DisplayList *pNode;
	BOOLEAN fDone;
	//UINT16 usObjIndex, usIndex;
	UINT16 y;
	//Determine if there is a valid picture at cursor position.
	//iRelX = gusMouseXPos;
	//iRelY = gusMouseYPos + iTopWinCutOff - (INT16)SelWinStartPoint.iY;

	y = gusMouseYPos + iTopWinCutOff - (UINT16)SelWinStartPoint.iY;
	pNode = pDispList;
	fDone = FALSE;
	while( (pNode != NULL) && !fDone )
	{
		if ( (gusMouseXPos >= pNode->iX) && (gusMouseXPos < (pNode->iX + pNode->iWidth)) &&
				(y >= pNode->iY) && (y < (pNode->iY + pNode->iHeight)) )
		{
			fDone = TRUE;
			//pNode->fChosen = TRUE;
			//iXInc = (pNode->iX + pNode->iWidth) - iClickX;
			//if ( iYInc < ((pNode->iY + pNode->iHeight) - iClickY) )
			//	iYInc = (pNode->iY + pNode->iHeight) - iClickY;
		}
		else
			pNode = pNode->pNext;
	}
	SetFont( FONT12POINT1 );
	SetFontForeground( FONT_WHITE );
	if( pNode )
	{
		//usObjIndex = (UINT16)pNode->uiObjIndx;
		//usIndex = pNode->uiIndex;
		if( !gTilesets[ giCurrentTilesetID].TileSurfaceFilenames[ pNode->uiObjIndx ][0] )
		{
			mprintf( 2, 2, pDisplaySelectionWindowGraphicalInformationText[0],
				gTilesets[0].TileSurfaceFilenames[ pNode->uiObjIndx ],
				pNode->uiIndex, gTilesets[0].zName,
				gTileTypeStartIndex[pNode->uiObjIndx]+pNode->uiIndex,
				gTileSurfaceName[ pNode->uiObjIndx ] );
		}
		else
		{
			mprintf( 2, 2, pDisplaySelectionWindowGraphicalInformationText[1],
				gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ pNode->uiObjIndx ],
				pNode->uiIndex, gTileTypeStartIndex[pNode->uiObjIndx]+pNode->uiIndex,
				gTileSurfaceName[ pNode->uiObjIndx ] );
		}
	}
	mprintf( 390, 2, pDisplaySelectionWindowGraphicalInformationText[2],  gTilesets[ giCurrentTilesetID ].zName );
}

//----------------------------------------------------------------------------------------------
//	AddToSelectionList
//
//	Add an object in the display list to the selection list. If the object already exists in the
//	selection list, then it's count is incremented.
//
void AddToSelectionList( DisplayList *pNode )
{
	INT32 iIndex, iUseIndex = -1;

	for (iIndex = 0; iIndex < (*pNumSelList); iIndex++ )
	{
		if ( pNode->uiObjIndx == pSelList[ iIndex ].uiObject &&
				pNode->uiIndex == pSelList[ iIndex ].usIndex )
		{
			iUseIndex = iIndex;
			break;
		}
	}

	if ( iUseIndex >= 0 )
	{
		// Was already in the list, so bump up the count
		pSelList[ iUseIndex ].sCount++;
	}
	else
	{
		// Wasn't in the list, so add to end (if space available)
		if ( (*pNumSelList) < MAX_SELECTIONS )
		{
			pSelList[ (*pNumSelList) ].uiObject = pNode->uiObjIndx;
			pSelList[ (*pNumSelList) ].usIndex = pNode->uiIndex;
			pSelList[ (*pNumSelList) ].sCount = 1;

			(*pNumSelList)++;
		}
	}
}



//----------------------------------------------------------------------------------------------
//	ClearSelectionList
//
//	Removes everything from the current selection list
//
BOOLEAN ClearSelectionList( void )
{
	INT32 iIndex;
	DisplayList *pNode;


	if (pNumSelList == NULL )
		return( FALSE );

	pNode = pDispList;
	while ( pNode != NULL )
	{
		pNode->fChosen = FALSE;
		pNode = pNode->pNext;
	}

	for (iIndex = 0; iIndex < (*pNumSelList); iIndex++ )
		pSelList[ iIndex ].sCount = 0;

	(*pNumSelList) = 0;
	return( TRUE );
}


//----------------------------------------------------------------------------------------------
//	RemoveFromSelectionList
//
//	Removes the object given n a display list from the selection list. If the objects count is
//	greater than one, then the count is decremented and the object remains in the list.
//
BOOLEAN RemoveFromSelectionList( DisplayList *pNode )
{
	INT32 iIndex, iUseIndex = -1;
	BOOLEAN fRemoved;

	// Abort if no entries in list (pretend we removed a node)
	if ( (*pNumSelList) <= 0 )
		return( TRUE );

	fRemoved = FALSE;
	for (iIndex = 0; iIndex < (*pNumSelList); iIndex++ )
	{
		if ( pNode->uiObjIndx == pSelList[ iIndex ].uiObject &&
				pNode->uiIndex == pSelList[ iIndex ].usIndex )
		{
			iUseIndex = iIndex;
			break;
		}
	}

	if ( iUseIndex >= 0 )
	{
		// Was already in the list, so bump up the count
		pSelList[ iUseIndex ].sCount--;

		if ( pSelList[ iUseIndex ].sCount <= 0 )
		{
			// Squash the list to remove old entry
			for ( iIndex = iUseIndex; iIndex < ((*pNumSelList) - 1); iIndex++ )
				pSelList[ iIndex ] = pSelList[ iIndex + 1 ];

			(*pNumSelList)--;
			fRemoved = TRUE;
		}
	}

	return ( fRemoved );
}


//----------------------------------------------------------------------------------------------
//	GetRandomSelection
//
//	Randomly selects an item in the selection list. The object counts are taken into account so
//	that objects with higher counts will be chosen more often.
//
INT32 GetRandomSelection( void )
{
	INT32 iRandNum, iTotalCounts;
	INT32 iIndex, iSelectedIndex, iNextCount;

	if ( fDontUseRandom )
	{
		//fDontUseRandom = FALSE;//dnl ch8 210909 this was old way when random was almost always selected, new way is enable/disable through switching with key 'R'
		return( iCurBank );
	}

	iTotalCounts = 0;
	for (iIndex = 0; iIndex < (*pNumSelList); iIndex++ )
		iTotalCounts += (INT32)pSelList[ iIndex ].sCount;

	iRandNum = Random( iTotalCounts );

	iSelectedIndex = -1;
	iNextCount = 0;
	for (iIndex = 0; iIndex < (*pNumSelList) && iSelectedIndex == -1; iIndex++ )
	{
		iNextCount += (INT32)pSelList[ iIndex ].sCount;
		if ( iRandNum < iNextCount )
			iSelectedIndex = iIndex;
	}

	return ( iSelectedIndex );
}


//----------------------------------------------------------------------------------------------
//	IsInSelectionList
//
//	Verifies if a particular display list object exists in the current selection list.
//
BOOLEAN IsInSelectionList( DisplayList *pNode )
{
	INT32 iIndex;
	BOOLEAN fFound;

	fFound = FALSE;
	for (iIndex = 0; iIndex < (*pNumSelList) && !fFound; iIndex++ )
	{
		if ( pNode->uiObjIndx == pSelList[ iIndex ].uiObject &&
				pNode->uiIndex == pSelList[ iIndex ].usIndex )
		{
			fFound = TRUE;
		}
	}

	return ( fFound );
}


//----------------------------------------------------------------------------------------------
//	FindInSelectionList
//
//	Finds an occurance of a particular display list object in the current selection list.
//	if found, returns the selection list's index where it can be found. otherwise it
//	returns -1
//
INT32 FindInSelectionList( DisplayList *pNode )
{
	INT32 iIndex,iUseIndex;
	BOOLEAN fFound;

	fFound = FALSE;
	iUseIndex = -1;
	for (iIndex = 0; iIndex < (*pNumSelList) && !fFound; iIndex++ )
	{
		if ( pNode->uiObjIndx == pSelList[ iIndex ].uiObject &&
				pNode->uiIndex == pSelList[ iIndex ].usIndex )
		{
			fFound = TRUE;
			iUseIndex = iIndex;
		}
	}

	return ( iUseIndex );
}


//----------------------------------------------------------------------------------------------
//	SaveSelectionList
//
//	Copies the current selection list to a save buffer. Used in case we want to cancel a
//	selection window.
//
void SaveSelectionList( void )
{
	INT32 iIndex;

	for (iIndex = 0; iIndex < MAX_SELECTIONS; iIndex++ )
		OldSelList[ iIndex ] = pSelList[ iIndex ];

	iOldNumSelList = (*pNumSelList);
}


//----------------------------------------------------------------------------------------------
//	RestoreSelectionList
//
//	Copies the selection list in the save buffer back to the current selection list.
//
void RestoreSelectionList( void )
{
	INT32 iIndex;

	for (iIndex = 0; iIndex < MAX_SELECTIONS; iIndex++ )
		pSelList[ iIndex ] = OldSelList[ iIndex ];

	(*pNumSelList) = iOldNumSelList;
}


//----------------------------------------------------------------------------------------------
//	OkClkCallback
//
//	Button callback function for the selection window's OK button
void OkClkCallback( GUI_BUTTON *button, INT32 reason )
{


	if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		button->uiFlags |= BUTTON_CLICKED_ON;
	}
	else if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON);
		fAllDone = TRUE;
	}
}


//----------------------------------------------------------------------------------------------
//	CnclClkCallback
//
//	Button callback function for the selection window's CANCEL button
//
void CnclClkCallback( GUI_BUTTON *button, INT32 reason )
{
	if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		button->uiFlags |= BUTTON_CLICKED_ON;
	}
	else if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON);
		fAllDone = TRUE;
		RestoreSelectionList();
	}
}


//----------------------------------------------------------------------------------------------
//	UpClkCallback
//
//	Button callback function for scrolling the selection window up
//
void UpClkCallback( GUI_BUTTON *button, INT32 reason )
{
	if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
	{
		button->uiFlags |= BUTTON_CLICKED_ON;
	}
	else if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON );
		ScrollSelWinUp();
	}
}


//----------------------------------------------------------------------------------------------
//	ScrollSelWinUp
//
//	Performs the calculations required to actually scroll a selection window up by one line.
//
void ScrollSelWinUp(void)
{
	DisplayList *pNode;
	INT16 iCutOff,iBotCutOff;
	BOOLEAN fDone;

	// Code to scroll window up!
	pNode = pDispList;
	iCutOff = iTopWinCutOff;

	fDone = FALSE;
	while( (pNode != NULL) && !fDone )
	{
		if (pNode->iY >= iTopWinCutOff)
		{
			iCutOff = pNode->iY;
			pNode = pNode->pNext;
		}
		else
		{
			iCutOff = pNode->iY;
			fDone = TRUE;
		}
	}

	iBotCutOff = iBotWinCutOff - iTopWinCutOff + iCutOff;
	iTopWinCutOff = iCutOff;
}


//----------------------------------------------------------------------------------------------
//	ScrollSelWinDown
//
//	Performs the actual calculations for scrolling a selection window down.
//
void ScrollSelWinDown(void)
{
	DisplayList *pNode;
	INT16 iCutOff,iBotCutOff;
	BOOLEAN fDone;

	pNode = pDispList;
	iCutOff = iTopWinCutOff;

	fDone = FALSE;
	while( (pNode != NULL) && !fDone )
	{
		if (pNode->iY > iTopWinCutOff)
		{
			iCutOff = pNode->iY;
			pNode = pNode->pNext;
		}
		else
			fDone = TRUE;
	}

	iBotCutOff = iBotWinCutOff - iTopWinCutOff + iCutOff;
	iTopWinCutOff = iCutOff;
}


//----------------------------------------------------------------------------------------------
//	DwnClkCallback
//
//	Button callback function to scroll the selection window down.
//
void DwnClkCallback( GUI_BUTTON *button, INT32 reason )
{
	if (reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
	{
		button->uiFlags |= BUTTON_CLICKED_ON;
	}
	else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
	{
		button->uiFlags &= (~BUTTON_CLICKED_ON);
		ScrollSelWinDown();
	}
}



//----------------------------------------------------------------------------------------------
//	DrawSelections
//
//	Displays the objects in the display list to the selection window.
//
void DrawSelections( void )
{
	SGPRect					ClipRect, NewRect;

	NewRect.iLeft = SelWinStartPoint.iX;
	NewRect.iTop = SelWinStartPoint.iY;
	NewRect.iRight = SelWinEndPoint.iX;
	NewRect.iBottom = SelWinEndPoint.iY;

	GetClippingRect(&ClipRect);
	SetClippingRect(&NewRect);

//	SetFont( gpSmallFont );
	SetFont( gpLargeFontType1 );
	SetObjectShade( gvoLargeFontType1, 0 );
//	SetObjectShade( gvoLargeFont, 0 );

	DisplayWindowFunc( pDispList, iTopWinCutOff, iBotWinCutOff, &SelWinStartPoint, CLEAR_BACKGROUND );

	SetObjectShade( gvoLargeFontType1, 4 );

	SetClippingRect(&ClipRect);
}


//----------------------------------------------------------------------------------------------
//	BuildDisplayWindow
//
//	Creates a display list from a display specification list. It also sets variables up for
//	properly scrolling the window etc.
//
BOOLEAN BuildDisplayWindow( DisplaySpec *pDisplaySpecs, UINT16 usNumSpecs, DisplayList **pDisplayList,
														SGPPoint * pUpperLeft, SGPPoint * pBottomRight,
														SGPPoint * pSpacing, UINT16 fFlags )
{
	INT32						iCurrX = pUpperLeft->iX;
	INT32						iCurrY = pUpperLeft->iY;
	UINT16					usGreatestHeightInRow = 0;
	UINT16					usSpecLoop;
	UINT16					usETRLELoop;
	UINT16					usETRLEStart;
	UINT16					usETRLEEnd;
	DisplaySpec *		pDisplaySpec;
	ETRLEObject *		pETRLEObject;
	DisplayList			*pCurNode;

	SaveSelectionList();

	for (usSpecLoop = 0; usSpecLoop < usNumSpecs; usSpecLoop++)
	{
		pDisplaySpec = &(pDisplaySpecs[usSpecLoop]);
		if (pDisplaySpec->ubType == DISPLAY_GRAPHIC)
		{
			if( !pDisplaySpec->hVObject )
				return FALSE;
			usETRLEStart = pDisplaySpec->usStart;
			usETRLEEnd = pDisplaySpec->usEnd;

			if ( usETRLEStart == DISPLAY_ALL_OBJECTS )
			{
				usETRLEStart = 0;
				usETRLEEnd = pDisplaySpec->hVObject->usNumberOfObjects - 1;
			}

			if( usETRLEStart > usETRLEEnd )
				return FALSE;
			if( usETRLEEnd >= pDisplaySpec->hVObject->usNumberOfObjects )
				return FALSE;

			for( usETRLELoop = usETRLEStart; usETRLELoop <= usETRLEEnd; usETRLELoop++)
			{
				pETRLEObject = &(pDisplaySpec->hVObject->pETRLEObject[usETRLELoop]);

				if ((iCurrX + pETRLEObject->usWidth > pBottomRight->iX) || (fFlags & ONE_COLUMN))
				{
					if (fFlags & ONE_ROW)
					{
						break;
					}
					iCurrX = pUpperLeft->iX;
					iCurrY += usGreatestHeightInRow + pSpacing->iY;
					usGreatestHeightInRow = 0;
				}

				if ((pCurNode = (DisplayList *)MemAlloc(sizeof(DisplayList))) != FALSE)
				{
					pCurNode->hObj = pDisplaySpec->hVObject;
					pCurNode->uiIndex = usETRLELoop;
					pCurNode->iX = (INT16)iCurrX;
					pCurNode->iY = (INT16)iCurrY;
					pCurNode->iWidth = pETRLEObject->usWidth;
					pCurNode->iHeight = pETRLEObject->usHeight;
					pCurNode->pNext = *pDisplayList;
					pCurNode->uiObjIndx = pDisplaySpec->uiObjIndx;

					if ( IsInSelectionList( pCurNode ) )
						pCurNode->fChosen = TRUE;
					else
						pCurNode->fChosen = FALSE;

					*pDisplayList = pCurNode;
				}
				else
					return(FALSE);

				if (pETRLEObject->usHeight > usGreatestHeightInRow)
				{
					usGreatestHeightInRow = pETRLEObject->usHeight;
				}

				iCurrX += pETRLEObject->usWidth + pSpacing->iX;
			}
		}
	}

	return( TRUE );
}


//----------------------------------------------------------------------------------------------
//	DisplayWindowFunc
//
//	Blits the actual object images in the display list on the selection window. The objects that
//	have been selected (in the selection list) are highlighted and the count placed in the upper
//	left corner of the image.
//
BOOLEAN DisplayWindowFunc( DisplayList *pNode, INT16 iTopCutOff, INT16 iBottomCutOff, SGPPoint *pUpperLeft, UINT16 fFlags)
{
	INT16						iCurrY;
	INT16						sTempOffsetX;
	INT16						sTempOffsetY;
	BOOLEAN					fReturnVal;
	ETRLEObject *		pETRLEObject;
	UINT16					usFillColor;
	INT16						sCount;

	if ( pNode == NULL )
		return(TRUE);

	if ( pNode->iY < iTopCutOff )
		return(TRUE);

	fReturnVal = FALSE;
	if (DisplayWindowFunc(pNode->pNext, iTopCutOff, iBottomCutOff, pUpperLeft, fFlags))
	{
		iCurrY = (INT16) pUpperLeft->iY + pNode->iY - iTopCutOff;

		if ( iCurrY > iBottomCutOff )
			return(TRUE);

		pETRLEObject = &(pNode->hObj->pETRLEObject[pNode->uiIndex]);

		// We have to store the offset data in temp variables before zeroing them and blitting
		sTempOffsetX = pETRLEObject->sOffsetX;
		sTempOffsetY = pETRLEObject->sOffsetY;

		// Set the offsets used for blitting to 0
		pETRLEObject->sOffsetX = 0;
		pETRLEObject->sOffsetY = 0;


		if (fFlags & CLEAR_BACKGROUND)
		{
			usFillColor = SelWinFillColor;
			if (pNode->fChosen)
				usFillColor = SelWinHilightFillColor;

			ColorFillVideoSurfaceArea( FRAME_BUFFER, pNode->iX, iCurrY,
												pNode->iX + pNode->iWidth,
												iCurrY + pNode->iHeight, usFillColor);
		}

		sCount = 0;
		if (pNode->fChosen)
			sCount = pSelList[ FindInSelectionList( pNode ) ].sCount;

		SetObjectShade( pNode->hObj, DEFAULT_SHADE_LEVEL );
		fReturnVal = BltVideoObject( FRAME_BUFFER, pNode->hObj, pNode->uiIndex,
														(UINT16)pNode->iX, (UINT16)iCurrY,
														VO_BLT_SRCTRANSPARENCY, NULL);

		if ( sCount != 0)
		{
			SetFontShade(LARGEFONT1, FONT_SHADE_WHITE);
			gprintf( pNode->iX, iCurrY, L"%d", sCount );
		}

		pETRLEObject->sOffsetX = sTempOffsetX;
		pETRLEObject->sOffsetY = sTempOffsetY;
	}

	return(fReturnVal);
}





#endif






