{**********************************************************************
{*
{* Teach uWindow.inc.p -- 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 Teach program.
{*
{**********************************************************************}
{$R-}



PROCEDURE Debug;  INLINE $0000;


{***********************************************************************
*
* smartGetWTitle
*
* This function returns a pointer to the window title pascal string.
* This is a little more complicated than it used to be, given that
* NewWindow2 clones the string for the window into an unlocked handle.
* GetWTitle returns a handle with the hi-bit set (to distinguish it
* from a reguler pointer).  If the hi-bit is set, then we want to
* dereference the handle to a pointer, and return that instead.
*
***********************************************************************}
function smartGetWTitle(wptr : GrafPortPtr): StringPtr;

var wtitle : Ptr;

begin
    wtitle := GetWTitle(wptr);
    if (BAND4(longint(wtitle),$80000000) <> 0) 
        then wtitle := Handle(BAND4(longint(wtitle), $7FFFFFFF))^;
    smartGetWTitle := StringPtr(wtitle);
end;

{**********************************************************************}
{
{ drawThisWindow
{
{ This routine draws the contents of all the windows.
{
{**********************************************************************}
procedure drawThisWindow;
    begin
        DrawControls(GetPort);
    END;
    
{**********************************************************************}
{
{ doCloseTop
{
{ This routine closes the topmost window.  We do a little work to
{ prevent the main window from being closed.
{
{**********************************************************************}
procedure doCloseTop;
    var
        refCon  : Longint;
        
    begin
        refCon := GetWRefCon(FrontWindow);
        { Get rid of the path name handle that we keep in the refcon. }
        { Note that it is zero if the window is untitled }
        if refCon <> 0 then DisposeHandle(handle(refCon));

        { Close the window.  (This kills the window title handle.) }
        CloseWindow(FrontWindow);
    end;

{**********************************************************************}
{
{ putFileIntoWindow
{
{ This routine opens the specified file, reads its contents in and
{ sets the text of the text edit control of the top window to that text
{
{**********************************************************************}
procedure   putFileIntoWindow (c1Hndl : handle);
    var
        openBlock : OpenRecGS;
        closeBlock : RefNumRecGS;
        readBlock : IORecGS;
        theHndl : handle;
        temp : integer;
        
    begin
        with openBlock do begin
            pCount := 15;
            pathname := GSString255Ptr(c1Hndl^);
            requestAccess := 0;
            resourceNumber := 0;
            optionList := NIL;
        end;
        
        OpenGS (OpenBlock);
        if _toolErr <> 0 then 
            begin
                temp := ErrorWindow(0,c1Hndl^,_ToolErr);
                exit(putfileIntoWindow);
            end;

        with CloseBlock do begin
            pCount := 1;
            refNum := OpenBlock.refNum;
        end;

        theHndl := NewHandle (openBlock.eof,userID,0,NIL);
        if _toolErr <> 0 then 
            begin
                temp := ErrorWindow(0,c1Hndl^,_ToolErr);
                CloseGS(closeBlock);
                exit(putfileIntoWindow);
            end;
            
        HLock (theHndl);

        with readBlock do begin
            pCount := 4;
            refNum := openBlock.refNum;
            DataBuffer := theHndl^;
            requestCount := openBlock.eof;
        end;
        ReadGS (readBlock);
        if _toolErr <> 0 then 
            begin
                temp := ErrorWindow(0,c1Hndl^,_ToolErr);
                DisposeHandle(theHndl);
                CloseGS(CloseBlock);
                exit(putfileIntoWindow);
            end;

        CloseGS (CloseBlock);
        if _ToolErr <> 0 then 
            begin
                temp := ErrorWindow(0,c1Hndl^,_ToolErr);
                DisposeHandle(theHndl);
                exit(putfileIntoWindow);
            end;

        
        TESetText ( 
            teDataIsTextBlock+refIsHandle*8,                { Text Descriptor }
            TETextRef(theHndl),                             { Text Ref }
            0,                                              { Text Length }
            0,                                              { Style Descriptor }
            TEStyleRef(0),                                  { Style Ref }
            TERecordHndl(GetCtlHandleFromID(
                            FrontWindow,MainWindowID))      { Control Handle }
            );
                    
        DisposeHandle(theHndl);
        
    end;

{**********************************************************************}
{
{ putWindowIntoFile
{
{ This routine opens the specified file, writes the window contents.
{
{**********************************************************************}
procedure   putWindowIntoFile (c1Hndl : Handle);
    var
        destroyBlock : NameRecGS;
        createBlock  : CreateRecGS;
        openBlock    : OpenRecGS;
        closeBlock   : RefNumRecGS;
        writeBlock   : IORecGS;
        theHndl      : Handle;
        temp, err    : Integer;
        totalSize    : LongInt;
        
    begin
        with DestroyBlock do begin
            pCount := 1;
            pathname := GSString255Ptr(c1Hndl^);
        end;
        
        DestroyGS(DestroyBlock);
        if _toolErr <> 0
            then if _toolErr <> fileNotFound then
                begin
                    temp := ErrorWindow(0,c1Hndl^, _toolErr);
                    exit(putWindowIntoFile);
                end;
        
        with CreateBlock do Begin
            pCount := 4;
            pathname := GSString255Ptr(c1Hndl^);
            access := $C3;
            fileType := $04;
            AuxType := 0;
        end;
        
        CreateGS (CreateBlock);
        if _ToolErr <> 0 then 
            begin
                temp := ErrorWindow(0,c1Hndl^,_ToolErr);
                exit(PutWindowIntoFile);
            end;
            
        with OpenBlock do begin
            pCount := 15;
            pathname := GSString255Ptr(c1Hndl^);
            requestAccess := 0;
            resourceNumber := 0;
            optionList := NIL;
        end;
        
        OpenGS (OpenBlock);
        err := _toolErr;
        if err <> 0 then 
            begin
                DestroyGS(destroyBlock);
                temp := ErrorWindow(0,c1Hndl^,err);
                exit(PutWindowIntoFile);
            end;

        with CloseBlock do begin
            pCount := 1;
            refNum := openBlock.refNum;
        end;

        theHndl := NewHandle(1, userID, 0, NIL);

        if _toolErr = 0 then
            totalSize := TEGetText (  
                            teDataIsTextBlock+refIsHandle*8,                    { Text Descriptor }
                            TETextRef(theHndl),                                 { Text Ref }
                            0,                                                  { Text Length }
                            0,                                                  { Style Descriptor }
                            TEStyleRef(0),                                      { Style Ref }
                            TERecordHndl(
                                GetCtlHandleFromID(FrontWindow,MainWindowID)
                                        ))                                      { Control Handle }
        else theHndl := NIL;                                    
        
        err := _toolErr;
        if err <> 0 then 
            begin
                if theHndl <> NIL then DisposeHandle(theHndl);
                CloseGS(CloseBlock);
                DestroyGS(destroyBlock);
                temp := ErrorWindow(0,c1Hndl^,err);
                exit(putWindowIntoFile);
            end;
            
        HLock (theHndl);
        with WriteBlock do begin
            pCount := 4;
            refNum := OpenBlock.refNum;
            dataBuffer := theHndl^;
            requestCount := totalSize;
        end;
        WriteGS (writeBlock);
        err := _toolErr;
        DisposeHandle(theHndl);
        if err <> 0 then 
            begin
                CloseGS(closeBlock);
                DestroyGS(destroyBlock);
                temp := ErrorWindow(0,c1Hndl^,err);
                exit(PutWindowIntoFile);
            end;

        CloseGS (CloseBlock);
        err := _toolErr;
        if err <> 0 then
            begin
                DestroyGS(destroyBlock);
                temp := ErrorWindow(0,c1Hndl^,err);
            end;
    end;


{**********************************************************************}
{
{ placeAndShowWindow
{
{ This routine moves the specified window based on stagger count
{ and shows it.
{
{**********************************************************************}
procedure placeAndShowWindow (theWindow : GrafPortPtr);

    begin
        MoveWindow (8+8*staggerCount,28+8*staggerCount,theWindow);
        staggerCount := staggerCount+1;
        ShowWindow(theWindow);
        SelectWindow(theWindow);                
    end;
    
{****************************************************************************}
{
{ doOpenWindow
{
{ This routine either asks the user what file to open and opens it.
{
{****************************************************************************}
procedure doOpenWindow;
    var
        myReply : SFReplyRec2;
        wptr    : GrafPortPtr;
        myPrompt: string;
        
    begin
        myPrompt := 'Pick a file, any file.';
        
        SFAllCaps (true);
        
        myReply.nameRefDesc := refIsNewHandle;
        myReply.pathRefDesc := refIsNewHandle;
        SFGetFile2 (10,35,
                    RefIsPointer,
                    Ref(@myPrompt),
                    NIL,        {filter proc}
                    NIL,        {type list}
                    myReply );
        
                    
        if myReply.good then
            begin
                { Convert the C1Output string into a C1Input string for the resource mangager }
                C1OutputToC1Input(myReply.pathRef.RefIsHandle);
                
                C1OutputToPString(myReply.nameRef.RefIsHandle);
                
                HLock(myReply.nameRef.RefIsHandle);
                
                wptr := NewWindow2  (StringPtr(myReply.nameRef.RefIsHandle^),           { Title reference}
                                     longint(myReply.pathRef.RefIsHandle),      { Ref con }
                                     @DrawThisWindow,                           { Draw routine }
                                     NIL,                                       { DefProc pointer }
                                     RefIsResource,                             { Param Table Descriptor }
                                     ref(MainWindowID),                         { Param Table Reference }
                                     rWindParam1);                              { Param Table Type }

                { Get rid of this handle }
                DisposeHandle(myReply.nameRef.RefIsHandle);
                
                placeAndShowWindow(wptr);
                
                putFileIntoWindow(myReply.pathRef.RefIsHandle);
            end;
  
    end;


{****************************************************************************}
{
{ doSaveAs
{
{ This routine saves the file  in the place indicated by the user.
{
{****************************************************************************}
procedure doSaveAs;
    var
        myPrompt : String;
        myReply : SFReplyRec2;
        origWinTitle : StringPtr;
        newWinTitle : Handle;
        temp : LongInt;
                
    begin;
        MyPrompt := 'Give it a name, any name.';
        SFAllCaps (true);
        
        myReply.nameRefDesc := refIsNewHandle;
        myReply.pathRefDesc := refIsNewHandle;

        { The current window title is the default name }
        origWinTitle := smartGetWTitle(FrontWindow);
                        
        { Get a C1String in  a new handle }
        newWinTitle := PStringToNewC1String(origWinTitle);
        
        HLock(newWinTitle);
        
        SFPutFile2 (180,35,
                    refIsPointer,
                    Ref(@MyPrompt),
                    refIsPointer,
                    Ref(newWinTitle^),
                    MyReply );
        
        { Don't need this default name any more }
        DisposeHandle(newWinTitle);
    
        if myReply.good then
            begin
                { Get rid of old path name handle in RefCon }
                DisposeHandle(Handle (GetWRefCon(FrontWindow)));

                { Convert the C1Output string into a C1Input string for the resource mangager }
                C1OutputToC1Input(myReply.pathRef.RefIsHandle);

                { Save the path name in the refcon of the window }
                SetWRefCon(LongInt(myReply.pathRef.RefIsHandle),FrontWindow);
                
                { Convert this C1 Output string into a pString for the window manager }
                C1OutputToPString(myReply.nameRef.RefIsHandle);
                
                SetWTitle (String255Ptr(myReply.nameRef.RefIsHandle^)^,FrontWindow);
                DisposeHandle(myReply.nameRef.RefisHandle);
                
                { Write the file out to disk }
                putWindowIntoFile(myReply.pathRef.RefIsHandle);
            end;
  
    end;
    

{****************************************************************************}
{
{ doSave
{
{ This routine either saves the file (unless it is new then it does a save 
{ as).
{
{****************************************************************************}
procedure doSave;
    var
        wptr : GrafPortPtr;
        refCon : LongInt;
        
    begin
    
        wptr := FrontWindow;
        refCon := GetWRefCon(wptr);
        
        if refCon = 0 then doSaveAs
        else  putWindowIntoFile(handle(refCon));
    end;
    
    


{****************************************************************************}
{
{ doNewWindow
{
{ This routine opens a new untitled window.
{
{****************************************************************************}
procedure   doNewWindow;
    var
        wptr : GrafPortPtr;
        tempStr : Str255;
    begin
        tempStr := 'Untitled';
        wptr := NewWindow2  (StringPtr(@tempStr),           { Title reference}
                             0,                     { Ref con }
                             @drawThisWindow,       { Draw routine }
                             NIL,                   { DefProc pointer }
                             RefIsResource,         { Param Table Descriptor }
                             Ref(MainWindowID),     { Param Table Reference }
                             rWindParam1);          { Param Table Type }
        
        placeAndShowWindow(wptr);

    end;
{*****************************************************************************}
{
{ setUpWindows
{
{ Opens the default window.
{
{*****************************************************************************}
procedure setUpWindows;
    begin   {of SetUpWindows}
        doNewWindow;
    end;    {of SetUpWindows}
    
