{**********************************************************************
{*
{* Darts uWindow -- Version 3.0  (implementation)
{*
{* Copyright (c)
{* Apple Computer, Inc.  1986-1990
{* All Rights Reserved.
{*
{* Developer Technical Support Apple II Sample Code
{*
{* Written by Steven E. Glass
{*
{* This file contains the code which implements  
{* windows in the program.
{*
{**********************************************************************}
{$R-}

{**********************************************************************
{*
{* InvalScore
{*
{* Invalidates a rectangle that holds the score for player one or two
{* so that it will be updated.
{*
{**********************************************************************}
procedure	InvalScore (PlayerNum : integer);
	var
		tempHandle : CtlRecHndl;
		id : longint;
		keepPort: GrafPortPtr;
		
	begin
		id := $60000;
		if PlayerNum = Player1 then id := $50000;
		tempHandle := GetCtlHandleFromID(theWindow,id);
		
		keepPort := GetPort;
		SetPort(theWindow);
		InvalRect (tempHandle^^.CtlRect);
		SetPort(keepPort);
	end;

{**********************************************************************
{*
{* drawThisWindow
{*
{* Draws the window whose port is the current port.
{*
{**********************************************************************}
procedure drawThisWindow;


	var
		tempRect : rect;
		
	begin
		firstUpdateComplete := true;	

		if GameType = 0 then
			begin
				GetPortRect (TempRect);
				tempRect.Left := tempRect.Left+(tempRect.Right-tempRect.Left) div 2;
				tempRect.Right := tempRect.Left+2;
				tempRect.Top := tempRect.Top+15;
				tempRect.Bottom := tempRect.bottom-18;
		
				PaintRect(tempRect);
			end;


		ScoreStrings[Player1] := IntToString(Score[Player1]);
		ScoreStrings[Player2] := IntToString(Score[Player2]);

		SetCtlParamPtr(@scoreStringArray);

		DrawControls(TheWindow);
		
	END;



{**********************************************************************
{*
{* drawListItem
{*
{* Draws the indicated list item.  
{*
{**********************************************************************}
procedure drawListItem	(var r : rect; myMemRecPtr : theMemRecPtr; listControl : Handle);
	var
		s : str255;
		theScore,
		mode: integer;
		selected: boolean;				

	begin
		
		theScore := integer(myMemRecPtr^.MemPtr);
		s := IntToString(TheScore);
		selected := (BAND(myMemRecPtr^.memFlag,$C0) = $80);

		mode := GetPenMode;
		if not selected then SetPenMode($8000);
		PaintRect(r);
		SetPenMode(mode);

		
		MoveTo(r.left+4,r.bottom-1);

		mode := GetTextMode;
		SetTextMode($8002);
 		DrawString(s);
		SetTextMode(mode);
	end;



{**********************************************************************
{*
{* addToList
{*
{* Adds the indicated score to the right list.  
{*
{**********************************************************************}
procedure	addToList		(playerNum : integer; amount : integer);
	var
		TopOfList : integer;
		TheHandle : ListCtlRecHndl;
		
	begin
		ListEntries[PlayerNum] := ListEntries[PlayerNum]+1;
		
		TopOfList := ListEntries[PlayerNum] - 3;
		if TopOfList < 1 then TopOfList := 1;
		
		If ListEntries[PlayerNum]*sizeof(theMemRec) >= gethandlesize (handle(ScoreList[PlayerNum])) then
			SetHandleSize((100+ListEntries[PlayerNum])*sizeOf(theMemRec),handle(ScoreList[PlayerNum]));
		
		ScoreList[PlayerNum]^^[ListEntries[PlayerNum]-1].MemPtr := ptr(Amount);
		ScoreList[PlayerNum]^^[ListEntries[PlayerNum]-1].MemFlag := 0;
		
		if PlayerNum = 1 then
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$30000))
		else
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$40000));
		NewList2	(@DrawListItem,							{ drawing routine addr }
					 TopOfList,								{ First Item to display }
					 Ref(ScoreList[PlayerNum]),				{ ref to mem rec array }
					 RefIsHandle,							{ List type }
					 ListEntries[PlayerNum],				{ Num Items }
					 CtlRecHndl(TheHandle));							{ List ctl handle }
end;
	
{*********************************************************************************}
{*
{* FixButtonTitle
{*
{* This routine is called only when the chosen game is crickett.  Its job
{* is to adjust the button title of the button associated with the amount
{* passed.
{*
{* There are four possible states of the button title.  Which state it is
{* in depends on the number times it has been pressed (contained in the
{* CrickettTables).
{*
{**********************************************************************************}
procedure	FixButtonTitle	(PlayerNum : integer; Amount : integer);
	var
		TheHandle : CtlRecHndl;
		TheID : LongInt;

	begin
		if PlayerNum = Player1 
			then TheID := Amount
			else TheID := $00008000 + Amount;
			
		theHandle := GetCtlHandleFromID(theWindow,theID);
		case crickettTables[playerNum][amount] of
			0:	SetCtlTitle(BlankStr,TheHandle);
			1:	SetCtlTitle(OneStr,TheHandle);
			2:	SetCtlTitle(TwoStr,TheHandle);
			otherwise	SetCtlTitle(ThreeStr,TheHandle);
		end; {case}
	end;
	
	
	
{**********************************************************************
{*
{* RemoveSelected
{*
{* Removes any selected scores from the list.
{*
{**********************************************************************}
procedure	RemoveSelected		(PlayerNum : integer);
	
	var
		K : integer;
		ItemToRemove : integer;
		TheHandle : ListCtlRecHndl;
		Amount : integer;
		TopOfList : integer;
	
	begin
	
		{ Use PlayerNum to get handle to list control }
		if PlayerNum = Player1 then
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$30000))
		else
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$40000));

		repeat
			ItemToRemove := NextMember2(0,CtlRecHndl(TheHandle));
			if ItemToRemove <> 0 then
				begin
					{ Value to remove is...}
					amount := LongInt(scoreList[playerNum]^^[itemToRemove-1].memPtr);


					{ Do it a little different depending on the game. }
					if GameType = 0 then
						Score[PlayerNum] := Score[PlayerNum] - Amount
					else 
						begin
							if CrickettTables[PlayerNum][Amount] > 3 then 
								Score[PlayerNum] := Score[PlayerNum]-Amount;
							CrickettTables[PlayerNum][Amount] := CrickettTables[PlayerNum][Amount] - 1;
							FixButtonTitle(PlayerNum,Amount);
						end;


					{ In all cases, we remove the item from the list and redisplay. }
					for k := ItemToRemove to ListEntries[PlayerNum]-1 do
						begin
							ScoreList[PlayerNum]^^[k-1].MemPtr := ScoreList[PlayerNum]^^[k].MemPtr;
							ScoreList[PlayerNum]^^[k-1].MemFlag := ScoreList[PlayerNum]^^[k].MemFlag;
						end;
					ListEntries[PlayerNum] := ListEntries[PlayerNum] -1;
					
					TopOfList := GetCtlValue(CtlRecHndl(TheHandle))-1;
					If TopOfList < 1 then TopOfList := 1;
					
					NewList2	(@DrawListItem,								{ drawing routine addr }
								 TopOfList,									{ First Item to display }
								 Ref(ScoreList[PlayerNum]),					{ ref to mem rec array }
								 RefIsHandle,								{ List type }
								 ListEntries[PlayerNum],					{ Num Items }
								 CtlRecHndl(TheHandle));					{ List ctl handle }
		
				end;
		until ItemToRemove = 0;
		InvalScore(PlayerNum);
	end;



{**********************************************************************
{*
{* ClearList
{*
{* Clears the indicated list.  
{*
{**********************************************************************}
procedure	ClearList		(PlayerNum : integer);
	var
		TheHandle : ListCtlRecHndl;
	begin
		if PlayerNum = Player1 then
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$30000))
		else
			TheHandle := ListCtlRecHndl(GetCtlHandleFromID(TheWindow,$40000));

		ListEntries[PlayerNum] := 0;
		
		NewList2	(@DrawListItem,							{ drawing routine addr }
					 0,										{ Item to display }
					 Ref(ScoreList[PlayerNum]),				{ ref to mem rec array }
					 RefIsHandle,							{ List type }
					 0,										{ Num Items }
					 CtlRecHndl(TheHandle));				{ List ctl handle }
	end;

{**********************************************************************************}
{*
{* StartUpRobinGame
{*
{* Opens the robin game window and zeros the scores.
{*
{**********************************************************************************}
procedure StartupRobinGame;
	begin
		TheWindow := NewWindow2		(	NIL,								{ Ref to title }
										1,										{ Ref Con }
										@DrawThisWindow,						{ Draw routine }
										NIL,									{ DefProc Ptr }
										RefIsResource, 							{ Ref Descriptor }
										REF(RobinWindow),						{ Input Ref }
										rWindParam1);							{ Resource Type }


		ListEntries[Player1] := 0;
		ListEntries[Player2] := 0;
		gameType := 0;
	end;


{**********************************************************************************}
{*
{* StartupCrickettGame
{*
{* Opens the crickett game window and zeros the scores.
{*
{**********************************************************************************}
procedure StartupCrickettGame;
	begin
		TheWindow := NewWindow2		(	NIL,								{ Ref to title }
										1,										{ Ref Con }
										@DrawThisWindow,						{ Draw routine }
										NIL,									{ DefProc Ptr }
										RefIsResource, 							{ Ref Descriptor }
										REF(CrickettWindow),						{ Input Ref }
										rWindParam1);							{ Resource Type }


		ListEntries[Player1] := 0;
		ListEntries[Player2] := 0;
		WeHaveAWinner := false;
		gameType := 1;
	end;
	
	
{**********************************************************************
{*
{* SetupWindows
{*
{* Inits any of the window unit variables we need to start up 
{* the game.  Calls the routine that opens the first window.
{*
{**********************************************************************}
procedure SetUpWindows;
	const
		InitListSize = 100;
		
	begin   {of SetUpWindows}
		FirstUpdateComplete := false;	

		ScoreList[Player1] := listArrayHandle(newhandle(sizeof(theMemRec)*InitListSize,userID,0,NIL));
		ScoreList[Player2] := listArrayHandle(newhandle(sizeof(theMemRec)*InitListSize,userID,0,NIL));

		ListEntries[Player1] := 0;
		ListEntries[Player2] := 0;

		StartupRobinGame;

	end;    {of SetUpWindows}
	
