{**********************************************************************
{*
{* Darts uEvent -- Version 3.0  (implemenation)
{*
{* Copyright (c)
{* Steven E. Glass and Apple Computer, Inc.  1986-1989
{* All Rights Reserved.
{*
{* Developer Technical Support Apple II Sample Code
{*
{* This file contains the code which implements the 
{* main event loop used by the program.
{*
{**********************************************************************}
{$R-}

var
    lastWindow   : GrafPortPtr;     { This private global is used in checkFrontW
                                      to prevent extra work when the windows
                                      have not changed.  It is initialized
                                      at the beginning of mainEvent.
                                    }


{**********************************************************************************}
{*
{* doScore
{*
{* This procedure does all the scoring in this program.  It is only called when
{* the user presses a button that has a non-zero low word for an ID.
{*
{* How the scoreing works depends on the game being played.  There is a section
{* for scoring each of the games.
{*
{**********************************************************************************}
procedure   doScore(playerNum : integer;  amount : integer);
    var
        otherPlayer,
        playerHits,
        otherHits,
        i,j, junk       : integer;

    begin
        if gameType = 0 then
            begin
                score[playerNum] := score[playerNum] + amount;
                addToList(playerNum, amount);
                invalScore(playerNum);
            end
        else
            begin
                if playerNum = Player1 then otherPlayer := Player2
                else otherPlayer := Player1;
                
                playerHits := crickettTables[playerNum][amount];
                otherHits  := crickettTables[otherPlayer][amount];

                if ((playerHits < 3) or (otherHits < 3)) then
                    begin       { At least one player is open. }
                        playerHits := playerHits + 1;
                        crickettTables[playerNum][amount] := playerHits;
                        fixButtonTitle(playerNum, amount);

                        if ((playerHits > 3) and (otherHits < 3)) then
                            begin
                                score[playerNum] := score[playerNum] + amount;
                                invalScore(playerNum);
                            end;

                        addToList(playerNum, amount);
                    end;
                    
                if not weHaveAWinner then
                    begin
                        i := 0;
                        while i < 7 do
                            begin
                                j := i + 15;
                                if (i = 6) then j := 25;

                                if (crickettTables[playerNum][j] < 3) then
                                        i := 7;
                                i := i + 1;
                            end;
                            
                        { i is 7 when all are closed for this player. }
                        if (i = 7) and (score[playerNum] >= score[otherPlayer]) then
                            begin
                                weHaveAWinner := TRUE;
                                BeginUpdate(theWindow);
                                drawThisWindow;
                                EndUpdate(theWindow);
                                junk := AlertWindow(RefIsResource * 2,
                                            NIL,
                                            Ptr(3));
                            end;
                    end;
            end;
    end;



{**********************************************************************************}
{*
{* DoControls
{*
{* This procedure is called by MainEvent whenever taskmaster returns inControl.
{*
{**********************************************************************************}
procedure doControls;
    var
        whichButton : integer;
        buttonNum : integer;
        lastItem : integer;
        playerNum : integer;
        
    begin

        whichButton := event.wmTaskData4;
        
        { If the low word is not 0 its a scoring control }
        if WhichButton <> 0 then
            begin
                if 0 = BAND(whichButton,$8000) then playerNum := Player1
                else playerNum := Player2;
        
                whichButton := event.wmTaskData4;
                whichButton := BAND(whichButton,$7FFF);
                
                
                doScore(playerNum,whichButton);
            end
        { If the low word is zero, its not a scoring control }
        else
            begin
                whichButton := HiWord(event.wmTaskData4);
                if whichButton = 2 then doNewItem
                else if whichButton = 1 then 
                    begin
                        buttonNum := AlertWindow(RefIsResource*2,NIL,ptr(ConfirmTextID));
                        if buttonNum = 1 then 
                            doQuitItem;
                    end
                else if whichButton = 3 then
                    begin
                        if event.wmClickCount > 1 then 
                            begin
                                removeSelected(Player1);
                                event.wmClickCount := 0;
                            end;
                    end
                else if whichButton = 4 then
                    begin
                        if event.wmClickCount > 1 then 
                            begin
                                removeSelected(Player2);
                                event.wmClickCount := 0;
                            end;
                    end;
            end;
        
    end;




{**********************************************************************************}
{*
{* checkFrontW
{*
{* This routine adjusts the system menu bar depending on what window is selected.
{* It activates the edit menu if a desk accessory is opened and selected.  It
{* deactivates the edit menu if the game window becomes active again.
{*
{* We do this because it makes no sense to have progam menus active when a desk
{* accessory is active and there is no sense having the edit menu active when
{* this program does not use it.
{*
{* It is called every time through the event loop.  The global variable lastWindow
{* helps us from making lots of checks if nothing has changed.
{*
{**********************************************************************************}
procedure CheckFrontW;

    var 
        theWindow    : GrafPortPtr;



    procedure DisableItems;

    {Private routine to disable (dim) certain menu titles}

        begin   {of DisableItems}
            DisableMItem (NewItem);
            DisableMItem (QuitItem);
            DisableMItem (AboutItem);
        end;    {of DisableItems}



    procedure EnableItems;

    {Private routine to enable (undim) certain menu titles}

        begin   {of EnableItems}
            EnableMItem (NewItem);
            EnableMItem (QuitItem);
            EnableMItem (AboutItem);
        end;    {of EnableItems}



    begin   {of CheckFrontW}
        theWindow := FrontWindow;
        
        { Has anything changed? }
        if theWindow = lastWindow then Exit(CheckFrontW);
        
        { Something's changed so lets fix this stuff }
        if theWindow = nil then 
            begin
                SetMenuFlag ($0080,EditMenuID); { disable the edit menu }
                DrawMenuBar;
                DisableItems;
            end
        else 
            begin
                if GetSysWFlag (theWindow) <> false then 
                    begin
                        DisableItems;                       { Disable application items }
                        SetMenuFlag ($FF7F,EditMenuID);     { Enable the edit menu. }
                        SetMenuFlag ($0080,GameMenuID);     { disable the game menu }
                        DrawMenuBar;                        { Redraw after fixing above }
                    end
                else  
                    begin   
                        SetMenuFlag ($0080,EditMenuID);     { disable the edit menu }
                        SetMenuFlag ($FF7F,GameMenuID);     { enable the game menu }
                        DrawMenuBar;                        { Redraw after fixing above }
                        EnableItems;                        { Enable application items }
                    end;
            end;
        
        { Remember theWindow for next time. }
        lastWindow := theWindow;
    end;    {of CheckFrontW}





{**********************************************************************************}
{*
{* MainEvent
{*
{* This is the main routine in the program.  It continuously calls taskmaster and
{* handles any events that occur.  It also keeps the right menus active by 
{* calling checkFrontW.
{*
{**********************************************************************************}
procedure MainEvent;


    var 
        code : integer;
        checkFirstUpdate : boolean;
    
    begin   {of MainEvent}
        event.wmTaskMask := $001FFFFF;  {Allow TaskMaster to do everything}
        quitFlag             := false;      {Done flag will be set by Quit item}
        checkFirstUpdate := true;
        lastWindow := NIL;
        
        repeat
            CheckFrontW;
            code := TaskMaster ($FFFF,event);
            case code of
                wInSpecial,
                wInMenuBar      : doMenu;
                wInControl      : doControls;
                otherwise 
                    if checkFirstUpdate then
                        if firstUpdateComplete then
                            begin
                                InitCursor;
                                checkFirstUpdate := false;
                            end;
            end;
        until quitFlag;
    end;    {of MainEvent}
