{**********************************************************************
{*
{* Darts uWindow -- Version 3.0  (implementation)
{*
{* Copyright (c)
{* Apple Computer, Inc.  1986-1989
{* All Rights Reserved.
{*
{* Developer Technical Support Apple II Sample Code
{*
{* 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}
    
