//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
// software: you can redistribute it and/or modify it under the terms of 
// the GNU General Public License as published by the Free Software Foundation, 
// either version 3 of the License, or (at your option) any later version.

// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
// in the hope that it will be useful, but with permitted additional restrictions 
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
// distributed with this program. You should have received a copy of the 
// GNU General Public License along with permitted additional restrictions 
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection

/* $Header: /CounterStrike/MAPEDPLC.CPP 1     3/03/97 10:25a Joe_bostic $ */
/***************************************************************************
 **   C O N F I D E N T I A L --- W E S T W O O D    S T U D I O S        **
 ***************************************************************************
 *                                                                         *
 *                 Project Name : Command & Conquer                        *
 *                                                                         *
 *                    File Name : MAPEDPLC.CPP                             *
 *                                                                         *
 *                   Programmer : Bill Randolph                            *
 *                                                                         *
 *                   Start Date : November 18, 1994                        *
 *                                                                         *
 *                  Last Update : May 12, 1996 [JLB]                       *
 *                                                                         *
 *-------------------------------------------------------------------------*
 * Object-placement routines                                               *
 *-------------------------------------------------------------------------*
 * Functions:                                                              *
 *   MapEditClass::Build_Base_To -- builds the AI base to the given percent*
 *   MapEditClass::Cancel_Base_Building -- stops base-building mode        *
 *   MapEditClass::Cancel_Placement -- cancels placement mode              *
 *   MapEditClass::Place_Home -- homes the placement object                *
 *   MapEditClass::Place_Next -- while placing object, goes to next        *
 *   MapEditClass::Place_Next_Category -- places next object category      *
 *   MapEditClass::Place_Object -- attempts to place the current object    *
 *   MapEditClass::Place_Prev -- while placing object, goes to previous    *
 *   MapEditClass::Place_Prev_Category -- places previous object category  *
 *   MapEditClass::Place_Trigger -- assigns trigger to object or cell      *
 *   MapEditClass::Placement_Dialog -- adds an object to the scenario      *
 *   MapEditClass::Set_House_Buttons -- toggles house buttons for btn list *
 *   MapEditClass::Start_Base_Building -- starts base-building mode        *
 *   MapEditClass::Start_Placement -- enters placement mode                *
 *   MapEditClass::Start_Trigger_Placement -- enters trigger placement mode*
 *   MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode  *
 *   MapEditClass::Toggle_House -- toggles current placement object's house*
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include	"function.h"

#ifdef SCENARIO_EDITOR


/***************************************************************************
 * MapEditClass::Placement_Dialog -- adds an object to the scenario        *
 *                                                                         *
 * This function sets LastChoice & LastHouse to the values chosen          *
 * by the user. It's up to the caller to call Start_Placement to enter     *
 * placement mode.                                                         *
 *   This routine does not modify PendingObject or PendingHouse.           *
 *                                                                         *
 *  ��������������������������������������������������Ŀ                   *
 *  �   [GDI]  [NOD]  [Neutral]                        �                   *
 *  �                                                  �                   *
 *  �   �������������������������������Ŀ              �                   *
 *  �   �                               � [Template]   �                   *
 *  �   �                               � [Overlay ]   �                   *
 *  �   �                               � [Smudge  ]   �                   *
 *  �   �                               � [Terrain ]   �                   *
 *  �   �      (Object picture)         � [Unit    ]   �                   *
 *  �   �                               � [Infantry]   �                   *
 *  �   �                               � [Aircraft]   �                   *
 *  �   �                               � [Building]   �                   *
 *  �   �                               �              �                   *
 *  �   ���������������������������������     ������Ŀ �                   *
 *  �             [<-]  [->]                  �(Grid)� �                   *
 *  �                                         �      � �                   *
 *  �         [OK]        [Cancel]            �������� �                   *
 *  ����������������������������������������������������                   *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      0 = OK, -1 = cancel                                                *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   10/21/1994 BR : Created.                                              *
 *   12/13/1995 JLB : Fixed house buttons to handle expanded house list.   *
 *   05/12/1996 JLB : Handles hi-res.                                      *
 *=========================================================================*/
int MapEditClass::Placement_Dialog(void)
{
	HousesType house;
	RemapControlType * scheme = GadgetClass::Get_Color_Scheme();

	/*
	**	Dialog & button dimensions
	*/
	enum {
		D_DIALOG_W = 400,
		D_DIALOG_H = 180,
		D_DIALOG_X = 0,
		D_DIALOG_Y = 0,
		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),

		D_TXT8_H = 11,
		D_MARGIN = 7,

		D_PICTURE_W = 152,					// must be divisible by 8!
		D_PICTURE_H = 105,
		D_PICTURE_X = D_DIALOG_X + 35,		// must start on a byte boundary!
		D_PICTURE_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN,
		D_PICTURE_CX = D_PICTURE_X + D_PICTURE_W / 2,

		D_GDI_W = 65,
		D_GDI_H = 9,
		D_GDI_X = D_PICTURE_X+D_PICTURE_W+5,
		D_GDI_Y = D_PICTURE_Y,

		D_LEFT_W = 45,
		D_LEFT_H = 9,
		D_LEFT_X = D_PICTURE_CX - 5 - D_LEFT_W,
		D_LEFT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,

		D_RIGHT_W = 45,
		D_RIGHT_H = 9,
		D_RIGHT_X = D_PICTURE_CX + 5,
		D_RIGHT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,

		D_TEMPLATE_W = 70,
		D_TEMPLATE_H = 9,
		D_TEMPLATE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TEMPLATE_W - 30,
		D_TEMPLATE_Y = D_PICTURE_Y,

		D_OVERLAY_W = 70,
		D_OVERLAY_H = 9,
		D_OVERLAY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_OVERLAY_W - 30,
		D_OVERLAY_Y = D_TEMPLATE_Y + D_TEMPLATE_H,

		D_SMUDGE_W = 70,
		D_SMUDGE_H = 9,
		D_SMUDGE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_SMUDGE_W - 30,
		D_SMUDGE_Y = D_OVERLAY_Y + D_OVERLAY_H,

		D_TERRAIN_W = 70,
		D_TERRAIN_H = 9,
		D_TERRAIN_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TERRAIN_W - 30,
		D_TERRAIN_Y = D_SMUDGE_Y + D_SMUDGE_H,

		D_UNIT_W = 70,
		D_UNIT_H = 9,
		D_UNIT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_UNIT_W - 30,
		D_UNIT_Y = D_TERRAIN_Y + D_TERRAIN_H,

		D_INFANTRY_W = 70,
		D_INFANTRY_H = 9,
		D_INFANTRY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_INFANTRY_W - 30,
		D_INFANTRY_Y = D_UNIT_Y + D_UNIT_H,

		D_AIRCRAFT_W = 70,
		D_AIRCRAFT_H = 9,
		D_AIRCRAFT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIRCRAFT_W - 30,
		D_AIRCRAFT_Y = D_INFANTRY_Y + D_INFANTRY_H,

		D_BUILDING_W = 70,
		D_BUILDING_H = 9,
		D_BUILDING_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_BUILDING_W - 30,
		D_BUILDING_Y = D_AIRCRAFT_Y + D_AIRCRAFT_H,

		D_AIR_W = 70,
		D_AIR_H = 9,
		D_AIR_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIR_W - 30,
		D_AIR_Y = D_BUILDING_Y + D_BUILDING_H,

		D_OK_W = 45,
		D_OK_H = 9,
		D_OK_X = D_PICTURE_CX - D_OK_W - 5,
		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN - 15,

		D_CANCEL_W = 45,
		D_CANCEL_H = 9,
		D_CANCEL_X = D_PICTURE_CX + 5,
		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN - 15,

		GRIDSIZE = 10,
		GRIDBLOCK_W = 3,
		GRIDBLOCK_H = 3,
		D_GRID_X = D_DIALOG_X + D_DIALOG_W - (GRIDSIZE * GRIDBLOCK_W) - D_MARGIN - 35,
		D_GRID_Y = D_DIALOG_Y + D_DIALOG_H - (GRIDSIZE * GRIDBLOCK_H) - D_MARGIN - 35,
	};

	/*
	**	Button enumerations:
	*/
	enum {
		BUTTON_GDI=100,
		BUTTON_HOUSE,
		BUTTON_NEXT,
		BUTTON_PREV,
		BUTTON_OK,
		BUTTON_CANCEL,
		BUTTON_TEMPLATE,
		BUTTON_OVERLAY,
		BUTTON_SMUDGE,
		BUTTON_TERRAIN,
		BUTTON_UNIT,
		BUTTON_INFANTRY,
		BUTTON_AIRCRAFT,
		BUTTON_BUILDING,
		BUTTON_AIR,
	};

	/*
	**	Dialog variables
	*/
	bool cancel = false;							// true = user cancels
	const ObjectTypeClass * curobj;			// Working object pointer.
	int x,y;											// for drawing the grid
	KeyNumType input;								// user input
	short const * occupy;							// ptr into object's OccupyList
	int cell;										// cell index for parsing OccupyList
	int i;
	int typeindex;									// index of class type

	/*
	**	Buttons
	*/
	ControlClass * commands;

	ListClass housebtn(BUTTON_HOUSE,
		D_GDI_X, D_GDI_Y, 60, 8*16,
		TPF_EFNT | TPF_NOSHADOW,
		MFCD::Retrieve("EBTN-UP.SHP"),
		MFCD::Retrieve("EBTN-DN.SHP"));
	for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
		housebtn.Add_Item(HouseTypeClass::As_Reference(house).IniName);
	}
	house = HOUSE_FIRST;

	TextButtonClass nextbtn(BUTTON_NEXT, TXT_RIGHT, TPF_EBUTTON, D_RIGHT_X, D_RIGHT_Y, D_RIGHT_W, D_RIGHT_H);
	TextButtonClass prevbtn(BUTTON_PREV, TXT_LEFT, TPF_EBUTTON, D_LEFT_X, D_LEFT_Y, D_LEFT_W, D_LEFT_H);
	TextButtonClass okbtn(BUTTON_OK, "OK", TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
	TextButtonClass cancelbtn(BUTTON_CANCEL, "Cancel", TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
	TextButtonClass templatebtn(BUTTON_TEMPLATE, "Template", TPF_EBUTTON, D_TEMPLATE_X, D_TEMPLATE_Y, D_TEMPLATE_W, D_TEMPLATE_H);
	TextButtonClass overlaybtn(BUTTON_OVERLAY, "Overlay", TPF_EBUTTON, D_OVERLAY_X, D_OVERLAY_Y, D_OVERLAY_W, D_OVERLAY_H);
	TextButtonClass smudgebtn(BUTTON_SMUDGE, "Smudge", TPF_EBUTTON, D_SMUDGE_X, D_SMUDGE_Y, D_SMUDGE_W, D_SMUDGE_H);
	TextButtonClass terrainbtn(BUTTON_TERRAIN, "Terrain", TPF_EBUTTON, D_TERRAIN_X, D_TERRAIN_Y, D_TERRAIN_W, D_TERRAIN_H);
	TextButtonClass unitbtn(BUTTON_UNIT, "Unit", TPF_EBUTTON, D_UNIT_X, D_UNIT_Y, D_UNIT_W, D_UNIT_H);
	TextButtonClass infantrybtn(BUTTON_INFANTRY, "Infantry", TPF_EBUTTON, D_INFANTRY_X, D_INFANTRY_Y, D_INFANTRY_W, D_INFANTRY_H);
	TextButtonClass aircraftbtn(BUTTON_AIRCRAFT, "Ships", TPF_EBUTTON, D_AIRCRAFT_X, D_AIRCRAFT_Y, D_AIRCRAFT_W, D_AIRCRAFT_H);
	TextButtonClass buildingbtn(BUTTON_BUILDING, "Building", TPF_EBUTTON, D_BUILDING_X, D_BUILDING_Y, D_BUILDING_W, D_BUILDING_H);
	TextButtonClass airbtn(BUTTON_AIR, "Aircraft", TPF_EBUTTON, D_AIR_X, D_AIR_Y, D_AIR_W, D_AIR_H);

	/*
	**	Initialize addable objects list; we must do this every time in case one
	**	of the object pools has become exhausted; that object won't be available
	**	for adding.  (Skip aircraft, since they won't be used in the editor.)
	*/
	Clear_List();
	TemplateTypeClass::Prep_For_Add();
	OverlayTypeClass::Prep_For_Add();
	SmudgeTypeClass::Prep_For_Add();
	TerrainTypeClass::Prep_For_Add();
	UnitTypeClass::Prep_For_Add();
	InfantryTypeClass::Prep_For_Add();
	VesselTypeClass::Prep_For_Add();
	BuildingTypeClass::Prep_For_Add();
	AircraftTypeClass::Prep_For_Add();

	/*
	**	Compute offset of each class type in the Objects array
	*/
	TypeOffset[0] = 0;
	for (i = 1; i < NUM_EDIT_CLASSES; i++) {
		TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
	}

	/*
	**	Return if no objects to place
	*/
	if (!ObjCount)  {
		return(-1);
	}

	/*
	**	Initialize
	*/
	Set_Logic_Page(SeenBuff);
	if (LastChoice >= ObjCount) {
		LastChoice = 0;
	}
	curobj = Objects[LastChoice];		// current object to choose

	commands = &nextbtn;
	housebtn.Add_Tail(*commands);
	prevbtn.Add_Tail(*commands);
	okbtn.Add_Tail(*commands);
	cancelbtn.Add_Tail(*commands);
	templatebtn.Add_Tail(*commands);
	overlaybtn.Add_Tail(*commands);
	smudgebtn.Add_Tail(*commands);
	terrainbtn.Add_Tail(*commands);
	unitbtn.Add_Tail(*commands);
	infantrybtn.Add_Tail(*commands);
	aircraftbtn.Add_Tail(*commands);
	buildingbtn.Add_Tail(*commands);
	airbtn.Add_Tail(*commands);

	/*
	**	Make sure the recorded house selection matches the house list
	**	box selection.
	*/
	LastHouse = HousesType(housebtn.Current_Index());

	/*
	**	Main processing loop
	*/
	bool display = true;
	bool process = true;
	while (process) {

		/*
		**	Invoke game callback
		*/
		Call_Back();

		/*
		**	Refresh display if needed
		*/
		if (display) {

			/*
			**	Display the dialog box
			*/
			Hide_Mouse();
			Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
			Draw_Caption(TXT_PLACE_OBJECT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);

			/*
			**	Display the current object:
			**	- save the current window dimensions
			**	- adjust the window size to the actual drawable area
			**	- draw the shape
			**	- reset the window dimensions
			*/
			WindowList[WINDOW_EDITOR][WINDOWX] = D_PICTURE_X;
			WindowList[WINDOW_EDITOR][WINDOWY] = D_PICTURE_Y;
			WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W;
			WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H;
			Change_Window((int)WINDOW_EDITOR);
			Draw_Box(D_PICTURE_X, D_PICTURE_Y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_DOWN, false);
			curobj->Display(WinW/2, WinH>>1, WINDOW_EDITOR, LastHouse);
//			curobj->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, LastHouse);

			/*
			**	Erase the grid
			*/
			LogicPage->Fill_Rect(D_GRID_X - GRIDBLOCK_W * 2, D_GRID_Y,
				D_GRID_X + GRIDSIZE * GRIDBLOCK_W,
				D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, BLACK);

			/*
			**	Draw a box for every cell occupied
			*/
			occupy = curobj->Occupy_List();
			while ( (*occupy) != REFRESH_EOL) {
				cell = (*occupy);
				occupy++;
				x = D_GRID_X + ((cell % MAP_CELL_W) * GRIDBLOCK_W);
				y = D_GRID_Y + ((cell / MAP_CELL_W) * GRIDBLOCK_H);
				LogicPage->Fill_Rect(x, y, x + GRIDBLOCK_W - 1, y + GRIDBLOCK_H - 1, scheme->Bright);
			}

			/*
			**	Draw the grid itself
			*/
			for (y = 0; y <= GRIDSIZE; y++) {
				for (x = 0; x <= GRIDSIZE; x++) {
					LogicPage->Draw_Line(D_GRID_X + x * GRIDBLOCK_W, D_GRID_Y,
						D_GRID_X + x * GRIDBLOCK_W,
						D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, scheme->Shadow);
				}
				LogicPage->Draw_Line(D_GRID_X, D_GRID_Y + y * GRIDBLOCK_H,
					D_GRID_X + GRIDSIZE * GRIDBLOCK_W, D_GRID_Y + y * GRIDBLOCK_H,
					scheme->Shadow);
			}

			/*
			**	Print the object's label from the class's Full_Name().
			**	Warning: Text_String returns an EMS pointer, so standard string
			**	functions won't work!
			*/
			Fancy_Text_Print (curobj->Full_Name(),
				D_PICTURE_CX, D_PICTURE_Y + D_MARGIN, scheme, TBLACK,
				TPF_CENTER | TPF_EFNT | TPF_NOSHADOW);

			/*
			**	Redraw buttons
			**	Figure out which class category we're in & highlight that button
			**	This updates 'typeindex', which is used below, and it also updates
			**	the category button states.
			*/
			i = 0;
			for (typeindex = 0; typeindex < NUM_EDIT_CLASSES; typeindex++) {
				i += NumType[typeindex];
				if (LastChoice < i) break;
			}
			templatebtn.Turn_Off();
			overlaybtn.Turn_Off();
			smudgebtn.Turn_Off();
			terrainbtn.Turn_Off();
			unitbtn.Turn_Off();
			infantrybtn.Turn_Off();
			aircraftbtn.Turn_Off();
			airbtn.Turn_Off();
			buildingbtn.Turn_Off();
			switch (typeindex + BUTTON_TEMPLATE) {
				case BUTTON_TEMPLATE:
					templatebtn.Turn_On();
					break;

				case BUTTON_OVERLAY:
					overlaybtn.Turn_On();
					break;

				case BUTTON_SMUDGE:
					smudgebtn.Turn_On();
					break;

				case BUTTON_TERRAIN:
					terrainbtn.Turn_On();
					break;

				case BUTTON_UNIT:
					unitbtn.Turn_On();
					break;

				case BUTTON_INFANTRY:
					infantrybtn.Turn_On();
					break;

				case BUTTON_AIRCRAFT:
					aircraftbtn.Turn_On();
					break;

				case BUTTON_AIR:
					airbtn.Turn_On();
					break;

				case BUTTON_BUILDING:
					buildingbtn.Turn_On();
					break;
			}

			/*
			**	Redraw buttons
			*/
			commands->Draw_All();
			Show_Mouse();
			display = false;

		}

		/*
		**	Get user input
		*/
		input = commands->Input();

		/*
		**	Process user input
		*/
		switch (input) {

			/*
			**	GDI House
			*/
			case (BUTTON_HOUSE | KN_BUTTON):
				house = HousesType(housebtn.Current_Index());

				/*
				**	Set flags & buttons
				*/
				LastHouse = house;
				display = true;
				break;

			/*
			**	Next in list
			*/
			case (KN_RIGHT):
			case (BUTTON_NEXT | KN_BUTTON):
				/*
				**	Increment to next obj
				*/
				LastChoice++;
				if (LastChoice == ObjCount) {
					LastChoice = 0;
				}
				curobj = Objects[LastChoice];

				nextbtn.Turn_Off();
				display = true;
				break;

			/*
			**	Previous in list
			*/
			case (KN_LEFT):
			case (BUTTON_PREV | KN_BUTTON):

				/*
				**	Decrement to prev obj
				*/
				LastChoice--;
				if (LastChoice < 0) {
					LastChoice = ObjCount-1;
				}
				curobj = Objects[LastChoice];
				prevbtn.Turn_Off();
				display = true;
				break;

			/*
			**	Select a class type
			*/
			case (BUTTON_TEMPLATE | KN_BUTTON):
			case (BUTTON_OVERLAY | KN_BUTTON):
			case (BUTTON_SMUDGE | KN_BUTTON):
			case (BUTTON_TERRAIN | KN_BUTTON):
			case (BUTTON_UNIT | KN_BUTTON):
			case (BUTTON_INFANTRY | KN_BUTTON):
			case (BUTTON_AIRCRAFT | KN_BUTTON):
			case (BUTTON_BUILDING | KN_BUTTON):
			case (BUTTON_AIR | KN_BUTTON):

				/*
				**	Find index of class
				*/
				typeindex = input - (BUTTON_TEMPLATE | KN_BUTTON);

				/*
				**	If no objects of that type, do nothing
				*/
				if (NumType[typeindex]==0) {
					display = true;
					break;
				}

				/*
				**	Set current object
				*/
				LastChoice = TypeOffset[typeindex];
				curobj = Objects[LastChoice];
				display = true;
				break;

			/*
			**	Next category
			*/
			case KN_PGDN:
				typeindex++;
				if (typeindex==NUM_EDIT_CLASSES) {
					typeindex = 0;
				}

				/*
				**	Set current object
				*/
				LastChoice = TypeOffset[typeindex];
				curobj = Objects[LastChoice];
				display = true;
				break;

			/*
			**	Previous category
			*/
			case KN_PGUP:
				typeindex--;
				if (typeindex < 0) {
					typeindex = NUM_EDIT_CLASSES - 1;
				}

				/*
				**	Set current object
				*/
				LastChoice = TypeOffset[typeindex];
				curobj = Objects[LastChoice];
				display = true;
				break;

			/*
			**	Jump to 1st choice
			*/
			case KN_HOME:
				LastChoice = 0;

				/*
				**	Set current object
				*/
				curobj = Objects[LastChoice];
				display = true;
				break;

			/*
			**	OK
			*/
			case (KN_RETURN):
			case (BUTTON_OK | KN_BUTTON):
				cancel = false;
				process = false;
				break;

			/*
			**	Cancel
			*/
			case (KN_ESC):
			case (BUTTON_CANCEL | KN_BUTTON):
				cancel = true;
				process = false;
				break;

			default:
				break;
		}

	}

	/*
	**	Redraw the display
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();

	if (cancel) {
		return(-1);
	}

	return(0);
}


/***************************************************************************
 * MapEditClass::Start_Placement -- enters placement mode                  *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/04/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Start_Placement(void)
{

	/*
	**	Initialize addable objects list; we must do this every time in case one
	**	of the object pools has become exhausted; that object won't be available
	**	for adding. These must be added in the same order expected by the
	**	object selection dialog (same as button order).
	*/
	Clear_List();
	TemplateTypeClass::Prep_For_Add();
	OverlayTypeClass::Prep_For_Add();
	SmudgeTypeClass::Prep_For_Add();
	TerrainTypeClass::Prep_For_Add();
	UnitTypeClass::Prep_For_Add();
	InfantryTypeClass::Prep_For_Add();
	VesselTypeClass::Prep_For_Add();
	BuildingTypeClass::Prep_For_Add();
	AircraftTypeClass::Prep_For_Add();

	/*
	**	Compute offset of each class type in the Objects array
	*/
	TypeOffset[0] = 0;
	for (int i = 1; i < NUM_EDIT_CLASSES; i++) {
		TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
	}

	/*
	**	Create the placement object:
	**	- For normal placement mode, use the last-used index into Objects
	**	  (LastChoice), and the last-used house (LastHouse).
	**	- For base-building mode, force the object to be a building, and use the
	**	  House specified in the Base object
	*/
	if (!BaseBuilding) {
		if (LastChoice >= ObjCount) {
			LastChoice = ObjCount - 1;
		}
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
	} else {
		if (LastChoice < TypeOffset[7]) {
			LastChoice = TypeOffset[7];
		}
		if (LastChoice >= ObjCount) {
			LastChoice = ObjCount - 1;
		}
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse = Base.House;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
	}

	/*
	**	Error if no more objects available
	*/
	if (!PendingObjectPtr) {
		WWMessageBox().Process("No more objects of this type available.");
		HidPage.Clear();
		Flag_To_Redraw(true);
		Render();
		PendingObject = NULL;
		if (BaseBuilding) {
			Cancel_Base_Building();
		}
		return;
	}

	/*
	**	Set the placement cursor
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(PendingObject->Occupy_List());
}


/***************************************************************************
 * MapEditClass::Place_Object -- attempts to place the current object      *
 *                                                                         *
 * Placement of "real" objects is simply checked via their Unlimbo routine.*
 * Placement of templates is more complex:                                 *
 * - for every cell in the template's OccupyList, check for objects        *
 *     already in that cell by looking at the cell's OccupyList &          *
 *     OverlapList                                                         *
 * - "lift" all the objects in the cell by Mark'ing them                   *
 * - temporarily place the template in that cell                           *
 * - try to Unlimbo all the objects that were in the cell. If any          *
 *     objects fail to Unlimbo onto that template, the template cannot     *
 *     be placed here                                                      *
 *                                                                         *
 * It is assumed that the object being placed is a "new" object; the       *
 * object's strength & mission are not set during Unlimbo.                 *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      0 = OK, -1 = unable to place                                       *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/04/1994 BR : Created.                                              *
 *=========================================================================*/
int MapEditClass::Place_Object(void)
{
	CELL template_cell;						// cell being checked for template
	COORDINATE obj_coord;							// coord of occupier object
	int okflag;									// OK to place a template?
	short const * occupy;						// ptr into template's OccupyList
	ObjectClass * occupier;					// occupying object
	TemplateType save_ttype;				// for saving cell's TType
	unsigned char save_ticon;				// for saving cell's TIcon
//	BaseNodeClass node;						// for adding to an AI Base

	/*
	**	Placing a template:
	**	- first lift up any objects in the cell
	**	- place the template, and try to replace the objects; if they won't go
	**	  back, the template can't go there
	*/
	//ScenarioInit++;
	if (PendingObject->What_Am_I() == RTTI_TEMPLATETYPE) {

		/*
		**	Loop through all cells this template will occupy
		*/
		okflag = true;
		occupy = PendingObject->Occupy_List();
		while ((*occupy) != REFRESH_EOL) {

			/*
			**	Check this cell for an occupier
			*/
			template_cell = (ZoneCell+ZoneOffset) + (*occupy);
			if ((*this)[template_cell].Cell_Occupier()) {
				occupier = (*this)[template_cell].Cell_Occupier();

				/*
				**	Save object's coordinates
				*/
				obj_coord = occupier->Coord;

				/*
				**	Place the object in limbo
				*/
				occupier->Mark(MARK_UP);

				/*
				**	Set the cell's template values
				*/
				save_ttype = (*this)[template_cell].TType;
				save_ticon = (*this)[template_cell].TIcon;
				(*this)[template_cell].TType =
					((TemplateTypeClass *)PendingObject)->Type;
				(*this)[template_cell].TIcon = Cell_X(*occupy) + Cell_Y(*occupy) *
					((TemplateTypeClass *)PendingObject)->Width;
				(*this)[template_cell].Recalc_Attributes();

				/*
				**	Try to put the object back down
				*/
				if (occupier->Can_Enter_Cell(Coord_Cell(obj_coord)) != MOVE_OK) {
					okflag = false;
				}

				/*
				**	Put everything back the way it was
				*/
				(*this)[template_cell].TType = save_ttype;
				(*this)[template_cell].TIcon = save_ticon;
				(*this)[template_cell].Recalc_Attributes();

				/*
				**	Major error if can't replace the object now
				*/
				occupier->Mark(MARK_DOWN);
			}
			occupy++;
		}

		/*
		**	If it's still OK after ALL THAT, place the template
		*/
		if (okflag) {
			if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {

				/*
				**	Loop through all cells occupied by this template, and clear the
				**	smudge & overlay.
				*/
				occupy = PendingObject->Occupy_List();
				while ((*occupy) != REFRESH_EOL) {

					/*
					**	Get cell for this occupy item
					*/
					template_cell = (ZoneCell+ZoneOffset) + (*occupy);

					/*
					**	Clear smudge & overlay
					*/
					(*this)[template_cell].Overlay = OVERLAY_NONE;
					(*this)[template_cell].OverlayData = 0;
					(*this)[template_cell].Smudge = SMUDGE_NONE;

					/*
					**	make adjacent cells recalc attrib's
					*/
					(*this)[template_cell].Recalc_Attributes();
					(*this)[template_cell].Wall_Update();
					(*this)[template_cell].Concrete_Calc();

					occupy++;
				}

				/*
				**	Set flags etc
				*/
				PendingObjectPtr = 0;
				PendingObject = 0;
				PendingHouse = HOUSE_NONE;
				Set_Cursor_Shape(0);
				//ScenarioInit--;
				TotalValue = Overpass();
				Flag_To_Redraw(false);
				return(0);
			}

			/*
			**	Failure to deploy results in a returned failure code.
			*/
			//ScenarioInit--;
			return(-1);
		}

		/*
		**	Not OK; return error
		*/
		//ScenarioInit--;
		return(-1);
	}

	/*
	**	Placing infantry: Infantry can go into cell sub-positions, so find the
	**	sub-position closest to the mouse & put him there
	*/
	if (PendingObject->What_Am_I() == RTTI_INFANTRYTYPE) {

		/*
		**	Find cell sub-position
		*/
		if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()))) {
			obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
		} else {
			obj_coord = NULL;
		}

		/*
		**	No free spots; don't place the object
		*/
		if (obj_coord == NULL) {
			//ScenarioInit--;
			return(-1);
		}

		/*
		**	Unlimbo the object
		*/
		if (PendingObjectPtr->Unlimbo(obj_coord)) {
			((InfantryClass *)PendingObjectPtr)->Set_Occupy_Bit(obj_coord);
//			Map[obj_coord].Flag.Composite |=
//				(1 << CellClass::Spot_Index(obj_coord));
			PendingObjectPtr = 0;
			PendingObject = 0;
			PendingHouse = HOUSE_NONE;
			Set_Cursor_Shape(0);
			//ScenarioInit--;
			return(0);
		}

		//ScenarioInit--;
		return(-1);
	}

	/*
	**	Placing an object
	*/
	if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {

		/*
		** Update the Tiberium computation if we're placing an overlay
		*/
		if (PendingObject->What_Am_I() == RTTI_OVERLAYTYPE &&
			((OverlayTypeClass *)PendingObject)->IsTiberium) {
			TotalValue = Overpass();
			Flag_To_Redraw(false);
		}

		/*
		** If we're building a base, add this building to the base's Node list.
		*/
		if (BaseBuilding && PendingObject->What_Am_I() == RTTI_BUILDINGTYPE) {
//			node.Type = ((BuildingTypeClass *)PendingObject)->Type;
//			node.Cell = Coord_Cell(PendingObjectPtr->Coord);
			Base.Nodes.Add(BaseNodeClass(((BuildingTypeClass *)PendingObject)->Type, Coord_Cell(PendingObjectPtr->Coord)));
		}

		PendingObjectPtr = 0;
		PendingObject = 0;
		PendingHouse = HOUSE_NONE;
		Set_Cursor_Shape(0);
		//ScenarioInit--;
		return(0);
	}

	return(-1);
}


/***************************************************************************
 * MapEditClass::Cancel_Placement -- cancels placement mode                *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/04/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Cancel_Placement(void)
{
	/*
	**	Delete the placement object
	*/
	delete PendingObjectPtr;
	PendingObject = 0;
	PendingObjectPtr = 0;
	PendingHouse = HOUSE_NONE;

	/*
	**	Restore cursor shape
	*/
	Set_Cursor_Shape(0);

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Place_Next -- while placing object, goes to next          *
 *                                                                         *
 * - Deletes the current 'PendingObjectPtr'                                *
 * - Increments LastChoice                                                 *
 * - Tries to create a new 'PendingObjectPtr'; if fails, keeps             *
 *   incrementing until it gets it                                         *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/03/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Next(void)
{
	delete PendingObjectPtr;
	PendingObjectPtr = NULL;
	PendingObject = NULL;

	/*
	**	Loop until we create a valid object
	*/
	while (!PendingObjectPtr) {
		/*
		**	Go to next object in Objects list
		*/
		LastChoice++;
		if (LastChoice == ObjCount) {

			/*
			** If we're in normal placement mode, wrap to the 1st object;
			** if we're in base-building mode, wrap to the 1st building
			*/
			if (!BaseBuilding) {
				LastChoice = 0;
			} else {
				LastChoice = TypeOffset[7];
			}
		}

		/*
		**	Create placement object
		*/
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
		if (!PendingObjectPtr) {
			PendingObject = NULL;
		}
	}

	/*
	**	Set the new cursor shape
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(0);
	Set_Cursor_Shape(PendingObject->Occupy_List());

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Place_Prev -- while placing object, goes to previous      *
 *                                                                         *
 * - Deletes the current 'PendingObjectPtr'                                *
 * - Decrements LastChoice                                                 *
 * - Tries to create a new 'PendingObjectPtr'; if fails, keeps             *
 *   decrementing until it gets it                                         *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/03/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Prev(void)
{
	delete PendingObjectPtr;
	PendingObjectPtr = NULL;
	PendingObject = NULL;

	/*
	**	Loop until we create a valid object
	*/
	while (!PendingObjectPtr) {

		/*
		**	Go to prev object in Objects list
		*/
		LastChoice--;

		/*
		** If we're in normal placement mode, wrap at the 1st object.
		** If we're building a base, wrap at the 1st building.
		*/
		if (!BaseBuilding) {
			if (LastChoice < 0) {
				LastChoice = ObjCount - 1;
			}
		} else {
			if (LastChoice < TypeOffset[7]) {
				LastChoice = ObjCount - 1;
			}
		}

		/*
		**	Create placement object
		*/
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
		if (!PendingObjectPtr) {
			PendingObject = NULL;
		}
	}

	/*
	**	Set the new cursor shape
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(0);
	Set_Cursor_Shape(PendingObject->Occupy_List());

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Place_Next_Category -- places next category of object     *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/03/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Next_Category(void)
{
	int i;

	/*
	** Don't allow this command if we're building a base; the only valid
	** category for base-building is buildings.
	*/
	if (BaseBuilding) {
		return;
	}

	delete PendingObjectPtr;
	PendingObjectPtr = NULL;
	PendingObject = NULL;

	/*
	**	Go to next category in Objects list
	*/
	i = LastChoice;
	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
		i++;
		if (i == ObjCount) {
			i = 0;
		}
	}
	LastChoice = i;

	/*
	**	Loop until we create a valid object
	*/
	while (!PendingObjectPtr) {

		/*
		**	Get house for this object type
		*/
//		if (!Verify_House(LastHouse, Objects[LastChoice])) {
//			LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
//		}

		/*
		**	Create placement object
		*/
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));

		/*
		**	If this one failed, try the next
		*/
		if (!PendingObjectPtr) {
			PendingObject = NULL;
			LastChoice++;
			if (LastChoice == ObjCount) {
				LastChoice = 0;
			}
		}
	}

	/*
	**	Set the new cursor shape
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(0);
	Set_Cursor_Shape(PendingObject->Occupy_List());

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Place_Prev_Category -- places previous category of object *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/03/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Prev_Category(void)
{
	int i;

	/*
	** Don't allow this command if we're building a base; the only valid
	** category for base-building is buildings.
	*/
	if (BaseBuilding) {
		return;
	}

	delete PendingObjectPtr;
	PendingObjectPtr = NULL;
	PendingObject = NULL;

	/*
	**	Go to prev category in Objects list
	*/
	i = LastChoice;

	/*
	**	Scan for start of this category
	*/
	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
		i--;
		if (i < 0) {
			i = ObjCount - 1;
		}
	}

	i--;
	if (i < 0) i = ObjCount-1;
	LastChoice = i;

	/*
	**	Scan for the previous category
	*/
	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
		i--;
		if (i < 0) {
			i = ObjCount - 1;
		}
	}

	i++;
	if (i >= ObjCount) i = 0;
	LastChoice = i;

	/*
	**	Loop until we create a valid object
	*/
	while (!PendingObjectPtr) {

		/*
		**	Get house for this object type
		*/
//		if (!Verify_House(LastHouse, Objects[LastChoice])) {
//			LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
//		}

		/*
		**	Create placement object
		*/
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));

		/*
		**	If this one failed, try the next
		*/
		if (!PendingObjectPtr) {
			PendingObject = NULL;
			LastChoice--;
			if (LastChoice < 0) {
				LastChoice = ObjCount - 1;
			}
		}
	}

	/*
	**	Set the new cursor shape
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(0);
	Set_Cursor_Shape(PendingObject->Occupy_List());

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Place_Home -- homes the placement object                  *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/03/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Home(void)
{
	delete PendingObjectPtr;
	PendingObjectPtr = NULL;
	PendingObject = NULL;

	/*
	** Don't allow this command if we're building a base; the only valid
	** category for base-building is buildings.
	*/
	if (BaseBuilding) {
		return;
	}

	/*
	**	Loop until we create a valid object
	*/
	LastChoice = 0;
	while (!PendingObjectPtr) {

		/*
		**	Get house for this object type
		*/
		if (!Verify_House(LastHouse, Objects[LastChoice])) {
			LastHouse = Cycle_House(LastHouse, Objects[LastChoice]);
		}

		/*
		**	Create placement object
		*/
		PendingObject = Objects[LastChoice];
		PendingHouse = LastHouse;
		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));

		/*
		**	If this one failed, try the next
		*/
		if (!PendingObjectPtr) {
			PendingObject = NULL;
			LastChoice++;
			if (LastChoice == ObjCount) {
				LastChoice = 0;
			}
		}
	}

	/*
	**	Set the new cursor shape
	*/
	Set_Cursor_Pos();
	Set_Cursor_Shape(0);
	Set_Cursor_Shape(PendingObject->Occupy_List());

	/*
	**	Redraw the map to erase old leftovers
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
	Render();
}


/***************************************************************************
 * MapEditClass::Toggle_House -- toggles current placement object's house  *
 *                                                                         *
 * INPUT:                                                                  *
 *                                                                         *
 * OUTPUT:                                                                 *
 *                                                                         *
 * WARNINGS:                                                               *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/04/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Toggle_House(void)
{
	TechnoClass *tp;

	/*
	** Don't allow this command if we're building a base; the only valid
	** house for base-building is the one assigned to the base.
	*/
	if (BaseBuilding) {
		return;
	}

	/*
	**	Only techno objects can be owned by a house; return if not a techno
	*/
	if (!PendingObjectPtr->Is_Techno()) {
		return;
	}

	/*
	**	Select the house that will own this object
	*/
	LastHouse = Cycle_House(PendingObjectPtr->Owner(), PendingObject);

	/*
	**	Change the house
	*/
	tp = (TechnoClass *)PendingObjectPtr;
	tp->House = HouseClass::As_Pointer(LastHouse);

	/*
	**	Set house variables to new house
	*/
	PendingHouse = LastHouse;
}


/***************************************************************************
 * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list   *
 *                                                                         *
 * Looks in the given button list for the given GDI, NOD & Neutral button  *
 * id's. Sets the On/Off state of the buttons based on the given house,    *
 * only if that button is found in the list.                               *
 *                                                                         *
 * INPUT:                                                                  *
 *      house            house to set buttons to                           *
 *      btnlist         ptr to button list to search                       *
 *      base_id         button ID for GDI; assumes other id's are sequential*
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   11/23/1994 BR : Created.                                              *
 *   01/26/1996 JLB : Uses new house selection list method.                *
 *=========================================================================*/
void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass *, int )
//void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass * btnlist, int base_id)
{
	HouseList->Set_Selected_Index(house);

#ifdef NEVER
	HousesType h;
	int id;
	TextButtonClass * btn;

	/*
	**	Loop through all houses, searching the button list for each one.
	*/
	for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) {

		/*
		**	Compute the desired button ID; get a pointer to the button
		*/
		id = (int)h + base_id;
		btn = (TextButtonClass *)btnlist->Extract_Gadget(id);
		if (btn) {

			/*
			**	If this house value is the desired one, turn the button on;
			**	otherwise, turn it off.
			*/
			if (h == house) {
				btn->Turn_On();
			} else {
				btn->Turn_Off();
			}
		}
	}
#endif
}


/***************************************************************************
 * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode  *
 *                                                                         *
 * INPUT:                                                                  *
 *                                                                         *
 * OUTPUT:                                                                 *
 *                                                                         *
 * WARNINGS:                                                               *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Start_Trigger_Placement(void)
{
	Set_Default_Mouse(MOUSE_CAN_MOVE);
	Override_Mouse_Shape(MOUSE_CAN_MOVE);
}


/***************************************************************************
 * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode    *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Stop_Trigger_Placement(void)
{
	CurTrigger = NULL;
	Set_Default_Mouse(MOUSE_NORMAL);
	Override_Mouse_Shape(MOUSE_NORMAL);
}


/***************************************************************************
 * MapEditClass::Place_Trigger -- assigns trigger to object or cell        *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Place_Trigger(void)
{
	ObjectClass * object=NULL;		// Generic object clicked on.
	int x,y;
	CELL cell;									// Cell that was selected.

	/*
	**	See if an object was clicked on
	*/
	x = Keyboard->MouseQX;
	y = Keyboard->MouseQY;

	/*
	**	Get cell for x,y
	*/
	cell = Click_Cell_Calc(x, y);

	/*
	**	Convert x,y to offset from cell upper-left
	*/
	x = (x-TacPixelX) % ICON_PIXEL_W;
	y = (y-TacPixelY) % ICON_PIXEL_H;

	/*
	**	Get object at that x,y
	*/
	object = Cell_Object(cell, x, y);

	/*
	**	Assign trigger to an object
	*/
	AttachType a1 = CurTrigger->Attaches_To();
	if (object && (a1 & ATTACH_OBJECT) != 0) {
		if (CurTrigger) {
			TriggerClass * tt = Find_Or_Make(CurTrigger);
			if (tt) {
				object->Trigger = tt;
			}
		}
	} else {

		/*
		**	Assign trigger to a cell
		*/
		if ((a1 & ATTACH_CELL) != 0) {
			if (CurTrigger) {
				TriggerClass * tt = Find_Or_Make(CurTrigger);
				Map[cell].Trigger = tt;
			}
//			CellTriggers[cell] = CurTrigger;
		}
	}

	/*
	**	Force map to redraw
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
}


/***************************************************************************
 * MapEditClass::Start_Base_Building -- starts base-building mode          *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Start_Base_Building(void)
{
	/*
	** Fully build the base so the user can edit it
	*/
	Build_Base_To(100);

	/*
	** Start placement mode
	*/
	BaseBuilding = true;
	Start_Placement();

	/*
	** Force map to redraw
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
}


/***************************************************************************
 * MapEditClass::Cancel_Base_Building -- stops base-building mode          *
 *                                                                         *
 * INPUT:                                                                  *
 *      none.                                                              *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Cancel_Base_Building(void)
{
	/*
	** Build the base to the proper amount
	*/
	Build_Base_To(Scen.Percent);

	/*
	** Cancel placement mode
	*/
	Cancel_Placement();
	BaseBuilding = false;

	/*
	** Force map to redraw
	*/
	HidPage.Clear();
	Flag_To_Redraw(true);
}


/***************************************************************************
 * MapEditClass::Build_Base_To -- builds the AI base to the given percent  *
 *                                                                         *
 * INPUT:                                                                  *
 *      percent      percentage to build base to                           *
 *                                                                         *
 * OUTPUT:                                                                 *
 *      none.                                                              *
 *                                                                         *
 * WARNINGS:                                                               *
 *      none.                                                              *
 *                                                                         *
 * HISTORY:                                                                *
 *   12/01/1994 BR : Created.                                              *
 *=========================================================================*/
void MapEditClass::Build_Base_To(int percent)
{
	int i;
	int num_buildings;
	BuildingTypeClass const * objtype;
	BuildingClass * obj;

	//ScenarioInit++;

	/*
	** Completely dismantle the base, so we start at a known point
	*/
	for (i = 0; i < Base.Nodes.Count(); i++) {
		if (Base.Is_Built(i)) {
			obj = Base.Get_Building(i);
			delete obj;
		}
	}

	/*
	** Compute number of buildings to build
	*/
	num_buildings = (Base.Nodes.Count() * percent) / 100;

	/*
	** Build the base to the desired amount
	*/
	for (i = 0; i < num_buildings; i++) {
		/*
		** Get a ptr to the type of building to build, create one, and unlimbo it.
		*/
		objtype = &BuildingTypeClass::As_Reference(Base.Nodes[i].Type);
		obj = (BuildingClass *)objtype->Create_One_Of(HouseClass::As_Pointer(Base.House));

		/*
		** If unlimbo fails, error out
		*/
		ScenarioInit++;
		if (!obj->Unlimbo(Cell_Coord(Base.Nodes[i].Cell))) {
			delete obj;
			WWMessageBox().Process("Unable to build base!");
			ScenarioInit--;
			return;
		}
		ScenarioInit--;
	}

	//ScenarioInit--;
}


#endif