program robotfindskitten;

	uses
		TransSkel;

	const
		FONT_NUMBER = 3;								{  22 = Courier ; 0 = System Font}
		MENU_BAR_HEIGHT = 20;
		FONT_SIZE = 18;
		NUM_HEADER_LINES = 4;
		MAX_X = 73;
		MAX_Y = 53;

		VERSION = '1.7320508.406';
		PROG_NAME = 'robotfindskitten 1.7320508.406';
		NUM_MESSAGES = 406;
		NUM_NKI = 20;
		ROBOT_CHAR = '#';

	var
		{TransSkel}
		m: MenuHandle;
		dummy: Boolean;
		r: Rect;
		myWindow: WindowPtr;

		{Mac-centric Stuff}
		s: Str255;												{temp}

		myFontWidth, myFontHeight, myFullFontHeight: Integer;
		charsWide, charsHigh: Integer;

		{Game Stuff}


	type
		rfkScreen = array[0..MAX_X, 0..MAX_Y] of integer;

		rfkObject = record
				x, y: integer;
				c: char;
				message: str255;
			end;

	var
		myRobot, myKitten: rfkObject;
		myNKI: array[1..NUM_NKI] of rfkObject;
		myScreen: rfkScreen;


{-------------------------------->	Randomize	<---}


	function Randomize (range: INTEGER): INTEGER;
		var
			rawResult: LONGINT;

	begin
		rawResult := Random;
		rawResult := abs(rawResult);

		Randomize := (rawResult * range) div 32768;
	end;


	function randomChar: char;
	begin
		{randomChar := char(32 + randomize(256 - 32))}
		randomChar := char(32 + randomize(128 - 32))
	end;


	procedure getMessage (nki: integer);
		var
			s: str255;
	begin
		GetIndString(s, 128, Randomize(NUM_MESSAGES));
		myNKI[nki].message := s;
	end;

{---- DRAWING ---- }


	procedure placeChar (x: integer; y: integer; c: char);
	begin
		MoveTo((x) * myFontWidth, trunc((y) * (myFontHeight) + MENU_BAR_HEIGHT + (myFontHeight * NUM_HEADER_LINES)));
		DrawChar(c);
	end;


	procedure clearChar (x: integer; y: integer; c: char);
	begin
		MoveTo((x) * myFontWidth, trunc((y) * (myFontHeight) + MENU_BAR_HEIGHT + (myFontHeight * NUM_HEADER_LINES)));
		TextMode(4);
		DrawString('  ');
		TextMode(3);
	end;


	procedure eraseLine (y: integer);
	begin
		r.left := 0;
		r.right := myWindow^.portRect.right;
		r.top := (myFullFontHeight * (y - 1)) + MENU_BAR_HEIGHT - 2;
		r.bottom := r.top + myFullFontHeight;
		PaintRect(r);
	end;


	procedure paintLine;
	begin
		ForeColor(whiteColor);
		r.left := 0;
		r.right := myWindow^.portRect.right;
		r.top := (NUM_HEADER_LINES - 1) * myFontHeight + MENU_BAR_HEIGHT - 4;
		r.bottom := r.top + 2;
		PaintRect(r);
		ForeColor(blackColor);
	end;

	procedure printLine (y: integer; s: Str255);
	begin
		eraseLine(y);
		MoveTo(10, (myFontHeight * y) + MENU_BAR_HEIGHT);
		if (y = 2) and (screenBits.bounds.right < 520) then begin
			TextSize(14);
			TextFace([]);
		end;
		DrawString(s);
		TextFace([bold]);
	end;

	procedure drawNKIMessage (nki: integer);
	begin
		if length(myNKI[nki].message) < 1 then
			getMessage(nki);
		printLine(2, myNKI[nki].message);
	end;

	procedure robotfindskitten;
	begin
		printLine(2, 'You found kitten!  Way to go, Robot!');
	end;

	procedure moveXY (x, y: integer);
		var
			newX, newY, i, nki: integer;
	begin
		newX := myRobot.x + x;
		newY := myRobot.y + y;

		if (myKitten.x = newX) and (myKitten.y = newY) then begin
			sysbeep(1);
			sysbeep(1);
			robotfindskitten;
		end
		else

			if (newY > charsHigh) or (newY < 0) or (newX > charsWide) or (newX < 0) then
				TextSize(FONT_SIZE) {ie do nothing}
			else begin
				if myScreen[newX][newY] < 1 then begin
					clearChar(myRobot.x, myRobot.y, myRobot.c);
					myRobot.y := myRobot.y + y;
					myRobot.x := myRobot.x + x;
					placeChar(myRobot.x, myRobot.y, myRobot.c)
				end
				else begin
					for i := 0 to NUM_NKI do begin
						if (myNKI[i].x = newX) and (myNKI[i].y = newY) then
							nki := i;
					end;
					drawNKIMessage(nki)
				end;
			end;
	end;


{-------------------------------->	EVENTS	<---}

	procedure About;
	begin
	end;


	procedure Mouse (thePt: Point; t: longint; mods: integer);
	begin
{SetCursor(arrow);}
{ShowCursor;}
	end;


	procedure Idle;
	begin
	end;


	procedure Update (resized: Boolean);
	begin
	end;


	procedure Key (ch: char; mods: integer);
	begin
		ObscureCursor;
		case ch of
			'j', '2': 
				moveXY(0, 1);
			'k', '8': 
				moveXY(0, -1);
			'h', '4': 
				moveXY(-1, 0);
			'l', '6': 
				moveXY(1, 0);
		end;
	end;


{ ----- INIT ----- }

	procedure InitScreen;
		var
			myString: Str255;
			x, y: integer;
			r: Rect;
	begin

		printLine(1, PROG_NAME);
		paintLine;
		placeChar(myRobot.x, myRobot.y, myRobot.c);
		placeChar(myKitten.x, mykitten.y, myKitten.c);
	end;


	procedure initFont;
		var
			MyFontInfo: FontInfo;
	begin
		{ SET FONTS }
		TextMode(3);
		TextSize(FONT_SIZE);
		TextFace([bold]);
		TextFont(FONT_NUMBER);

		{ GET FONT INFO }
		GetFontInfo(myFontInfo);
		{myFontWidth := myFontInfo.widMax;}
		myFontWidth := CharWidth('X') + 4;

		myFullFontHeight := myFontInfo.ascent + myFontInfo.descent + myFontInfo.leading;		{I-173 IM}

		myFontHeight := myFontInfo.ascent;		{I-173 IM}
		myFontWidth := myFontHeight;

		charsWide := trunc(screenBits.bounds.right / myFontWidth);
		charsHigh := trunc((screenBits.bounds.bottom - MENU_BAR_HEIGHT) / myFontHeight) - NUM_HEADER_LINES;
	end;


	procedure initRobot;
		var
			x, y: integer;
	begin
		repeat
			x := randomize(charsWide);
			y := randomize(charsHigh);
		until myScreen[x][y] = 0;
		myRobot.x := x;
		myRobot.y := y;
		myRobot.c := ROBOT_CHAR;
	end;

	procedure initKitten;
		var
			x, y: integer;
	begin
		repeat
			x := randomize(charsWide);
			y := randomize(charsHigh);
		until myScreen[x][y] = 0;
		myKitten.x := x;
		myKitten.y := y;
		myKitten.c := randomChar;
	end;

	procedure initNonKittenItems;
		var
			x, y, i, j: integer;
			c: char;
	begin
		for i := 0 to MAX_X do
			for j := 0 to MAX_Y do
				myScreen[i][j] := 0;
		for i := 1 to NUM_NKI do begin
			repeat
				x := randomize(charsWide);
				y := randomize(charsHigh);
			until myScreen[x][y] = 0;
			repeat
				c := randomChar;
			until c <> '#';
			myNKI[i].x := x;
			myNKI[i].y := y;
			myNKI[i].c := c;
			placeChar(x, y, c);
			myScreen[x][y] := i;
		end;
	end;


	procedure startGame;
	begin
		PaintRect(myWindow^.portRect);

		ObscureCursor;
		initFont;
		initNonKittenItems;
		initRobot;
		initKitten;
		initScreen;
	end;


	procedure DoFileMenu (item: integer);
	begin
		case item of
			1: 
				startGame;
			3: 
				SkelWhoa;										{Tell SkelMain to quit}
		end; {case}
	end;



{ ______ BEGIN _______ }

begin

	GetDateTime(randSeed);
	SkelInit(6, nil);																					{ Initialize								}
	SkelApple('(About Robot Finds KittenÉ', @About);										{ Handle Desk Accessories			}
	m := NewMenu(2, 'File');																		{ Create Menu							}
	AppendMenu(m, 'New Game/N;(-;Quit/Q');
	dummy := SkelMenu(m, @DoFileMenu, nil, true);										{ Tell Transkel to handle it		}

	myWindow := NewWindow(nil, screenBits.bounds, '', true, documentProc, WindowPtr(-1), true, 0);

	SetPort(myWindow);
	dummy := SkelWindow(myWindow, @Mouse, @Key, @Update, nil, nil, nil, @Idle, true);
{ForeColor(cyanColor);}
	startGame;

	SkelMain;												{ loop til quit selected				}
	SkelClobber;											{ clean up								}

end.
