sources/UsherMinWindow.c

/*
    File:       UsherMinWindow.c
 
    Copyright:  © 2000-2001 by Apple Computer, Inc., all rights reserved.
 
 
*/
 
 
#include <ConditionalMacros.h>
#include <ControlDefinitions.h>
#include <Resources.h>
#include <TextUtils.h>
 
#include <FixMath.h>
 
#include <string.h>
#include <stdio.h>
 
#include <QuicktimeComponents.h>
#include <MoviesFormat.h>
#include <Movies.h>
 
#include <QuickTimeStreaming.h>
#include <QTStreamingComponents.h>
 
#include "AppSupport.h"
#include "QTSSampleCodeUtils.h"
#include "WindowSupport.h"
#include "UsherBroadcast.h"
#include "UsherCommands.h"
#include "usherminwindow.h"
#include "usherrezdefines.h"
 
#include "PresInfoWindow.h"
    
// ---------------------------------------------------------------------------
//      D E F I N I T I O N S
// ---------------------------------------------------------------------------
 
struct UsherMinWindowRecord {
    StandardWindowRecord        standard;
    UsherBroadcast              *broadcast;
    WindowPtr                   infoWindow;
 
    SInt32                      updateFlags;
    
    long                        lastUpdateTime;     // in ticks
    long                        updateInterval;     // in ticks
    UInt32                      dataRate;
    Str255                      presStateString;
    DateTimeRec                 dateTimeRec;
    UsherStoredMovieParams      storedMovieParams;
    QTSSourcerTimingParams      movieTimingParams;
    UnsignedFixed               frameRate;
 
 
    SimplePresState             presState;
 
    Handle                      ditlHandle;
    ControlRef                  startButton;
    Boolean                     startButtonIsStop;
    ControlRef                  skipToNextButton;
 
    SInt32                      drawingCount;
    GrafPtr                     oldPort;
    short                       labelFont;
    short                       labelFontSize;
    short                       font;
    short                       fontSize;
 
 
};
typedef struct UsherMinWindowRecord UsherMinWindowRecord, *UsherMinWindPeek;
 
// update flags
enum  {
    kMinWindUpdateFlag_PresState    = 0x00000001,
    kMinWindUpdateFlag_DataRate     = 0x00000002,
    kMinWindUpdateFlag_Time         = 0x00000004,
    kMinWindUpdateFlag_StoredMovie  = 0x00000008,
    kMinWindUpdateFlag_MovieTiming  = 0x00000010,
    kMinWindUpdateFlag_FrameRate    = 0x00000020
 
};
 
 
 
#define kUsherMinWindDefaultUpdateInterval      60  // in ticks
 
 
#define kUsherMinWindNoDataRate     0xFFFFFFFF
 
#define kUsherMinWindNoFrameRate    0xFFFFFFFF
 
 
//#define kUsherMinWindDefaultLabelFont     systemFont
#define kUsherMinWindDefaultLabelFont       applFont
#define kUsherMinWindDefaultLabelFontSize   9
 
#define kUsherMinWindDefaultFont            applFont
#define kUsherMinWindDefaultFontSize        9
 
 
enum  {
    kUsherMinWindDrawingFlag_Erase      = 0x00000001
};
 
// ---------------------------------------------------------------------------
//      P R O T O T Y P E S
// ---------------------------------------------------------------------------
 
static OSErr UsherMinWindPriv_LoadControls(UsherMinWindowRecord *inWindData);
 
static void UsherMinWindPriv_Dispose(UsherMinWindowRecord *inWindData);
static Boolean UsherMinWindPriv_GetWindData(WindowPtr inWindow, UsherMinWindowRecord **outWindData);
 
static void UsherMinWindPriv_Update(UsherMinWindowRecord *inWindData, Boolean inDraw, SInt32 inFlags);
 
static void UsherMinWindPriv_GetReadyToDraw(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_FinishedDrawing(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_DrawDataRate(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawFrameRate(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawStatus(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawStaticItems(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawState(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawTime(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawStoredMovie(UsherMinWindowRecord *inWindData, SInt32 inFlags);
static void UsherMinWindPriv_DrawMovieTiming(UsherMinWindowRecord *inWindData, SInt32 inFlags);
 
static void UsherMinWindPriv_DrawItemText(UsherMinWindowRecord *inWindData, DialogItemIndex inItemIndex,
                    const unsigned char *inText, UInt32 inTextLength, SInt32 inFlags);
 
static void UsherMinWindPriv_UpdateIfNecessary(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_UpdateDataRate(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_UpdateFrameRate(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_UpdateTime(UsherMinWindowRecord *inWindData);
static void UsherMinWindPriv_UpdateMovieTiming(UsherMinWindowRecord *inWindData);
 
static void UserMinWindPriv_DoControlClicked(UsherMinWindowRecord *inWindData,
                                ControlRef inControl, short inPart);
 
static void UsherMinWindPriv_SetStartButtonText(UsherMinWindowRecord *inWindData);
 
static OSErr GetDataRateString(UInt32 inDataRate, unsigned char *outString);
 
// ---------------------------------------------------------------------------
//      UsherMinWind_New
// ---------------------------------------------------------------------------
 
OSErr UsherMinWind_New(Boolean inUseAlt, WindowPtr *outWindow)
{
    OSErr                   err = noErr;
    WindowPtr               window = NULL;
    DialogTHndl             dlogHandle;
    Rect                    windowBounds;
    UsherMinWindowRecord    *windData = NULL;
    Str255                  tempString;
 
    if (inUseAlt)  {
        dlogHandle = (DialogTHndl)GetResource('DLOG', rDLOG_UsherMinWindowLarge);
    }  else  {
        dlogHandle = (DialogTHndl)GetResource('DLOG', rDLOG_UsherMinWindow);
    }
 
    if (dlogHandle == NULL)  {
        DEBUGF(("UsherMinWind_New - null dlog resource"));
        EXITERR( err = memFullErr );
    }
    windowBounds = (**dlogHandle).boundsRect;
 
#if TARGET_API_MAC_CARBON
    EXITIFERR( err = CreateNewWindow( kDocumentWindowClass, 
                kWindowCloseBoxAttribute /* + kWindowResizableAttribute, um */, 
                &windowBounds, 
                &window ) );
#else
    window = NewCWindow(nil, &windowBounds, (StringPtr)"",
                false, documentProc, (WindowPtr)kFirstWindowOfClass, true, 0L);
#endif
 
    if (window == NULL)  {
        DEBUGF(("UsherMinWind_New - null window"));
        EXITERR( err = memFullErr );
    }
    
    windData = (UsherMinWindowRecord*)QTSNewPtrClear(sizeof(*windData));
    EXITIFERR( err = MemError() );
    
    WindowSupport_InitStandardRecord(&windData->standard, kSignature_UsherMinWind, window);
    SetWRefCon(window, (long)windData);
    
    windData->updateInterval = kUsherMinWindDefaultUpdateInterval;
    windData->labelFont = kUsherMinWindDefaultLabelFont;
    windData->labelFontSize = kUsherMinWindDefaultLabelFontSize;
    windData->font = kUsherMinWindDefaultFont;
    windData->fontSize = kUsherMinWindDefaultFontSize;
    
    if (inUseAlt)  {
        windData->ditlHandle = GetResource('DITL', rDITL_UsherMinWindowLarge); 
    }  else  {
        windData->ditlHandle = GetResource('DITL', rDITL_UsherMinWindow); 
    }
 
    if (windData->ditlHandle == NULL)  {
        DEBUGF(("UsherMinWind_New - null ditlhandle"));
        EXITERR( err = memFullErr );
    }
    DetachResource(windData->ditlHandle);
 
    EXITIFERR( err = UsherMinWindPriv_LoadControls(windData) );
 
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_DefaultName);
    SetWTitle(window, tempString);
    //ShowWindow(window);
 
    *outWindow = window;
exit:
    if (err != noErr)  {
        if (windData != NULL)  {
            UsherMinWind_Close(window);
        }  else  {
        
        }
    }
    return err;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_LoadControls
// ---------------------------------------------------------------------------
 
static OSErr UsherMinWindPriv_LoadControls(UsherMinWindowRecord *inWindData)
{
    OSErr           err = noErr;
    WindowPtr       window;
    Rect            bounds;
    
    window = inWindData->standard.window;
    
    DITLGetItemRect(inWindData->ditlHandle, rMinWindDITLItem_StartButton, &bounds);
    inWindData->startButton = NewControl(window, &bounds, "\pStart", true, 0, 0, 0, pushButProc, (long)inWindData);
    if (inWindData->startButton == NULL)  {
        DEBUGF((" UsherMinWindPriv_LoadControls $%.8x-couldn't make start button"));
        EXITERR( err = resNotFound );
    }
        
    DITLGetItemRect(inWindData->ditlHandle, rMinWindDITLItem_SkipToNextButton, &bounds);
    inWindData->skipToNextButton = NewControl(window, &bounds, "\pSkip", true, 0, 0, 0, pushButProc, (long)inWindData);
    if (inWindData->skipToNextButton == NULL)  {
        DEBUGF((" UsherMinWindPriv_LoadControls $%.8x-couldn't make skip button"));
        EXITERR( err = resNotFound );
    }
    
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_Close
// ---------------------------------------------------------------------------
 
void UsherMinWind_Close(WindowPtr inWindow)
{
    UsherMinWindowRecord        *windData = NULL;
 
    if (inWindow != NULL)  {
        if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
            DEBUGF(("UsherMinWind_Close $%.8x - couldnt get wind data", inWindow));
            goto exit;
        }
        if (windData->infoWindow != NULL)  {
            PresInfoWind_Close(windData->infoWindow);
        }
        UsherMinWindPriv_Dispose(windData);
    }
    DisposeWindow(inWindow);
    
exit:
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_Dispose
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_Dispose(UsherMinWindowRecord *inWindData)
{
    if (inWindData != NULL)  {
        if ((inWindData->broadcast != NULL)  &&  (inWindData->standard.window != NULL))  {
            // tell the presentation we went away...
            UsherBroadcast_RemoveWindow(inWindData->broadcast, inWindData->standard.window);
        }
 
        DisposeHandle(inWindData->ditlHandle);
 
        DisposePtr((Ptr)inWindData);
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_GetWindData
// ---------------------------------------------------------------------------
 
static Boolean UsherMinWindPriv_GetWindData(WindowPtr inWindow, UsherMinWindowRecord **outWindData)
{
    *outWindData = NULL;
    if (inWindow != NULL)  {
        *outWindData = (UsherMinWindowRecord*)GetWRefCon(inWindow);
        if (*outWindData != NULL)  {
            if ((*outWindData)->standard.signature != kSignature_UsherMinWind)  {
                DEBUGF(("UsherMinWind_GetWindData $%.8x $%.8x bad signature '%.4s'", inWindow, *outWindData, &(*outWindData)->standard.signature));
                *outWindData = NULL;
            }
        }
    }
    return (*outWindData != NULL);
}
 
#pragma mark -
 
// ---------------------------------------------------------------------------
//      UsherMinWind_Idle
// ---------------------------------------------------------------------------
 
void UsherMinWind_Idle(WindowPtr inWindow)
{
    UsherMinWindowRecord        *windData;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_Idle $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
    
    UsherMinWindPriv_UpdateIfNecessary(windData);
 
    UsherMinWindPriv_Update(windData, true, kUsherMinWindDrawingFlag_Erase);
    
exit:
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_GetMenuCommand
// ---------------------------------------------------------------------------
 
long UsherMinWind_GetMenuCommand(WindowPtr inWindow, long inMenuResult, void **outCommandParams)
{
#pragma unused(outCommandParams)
    UsherMinWindowRecord        *windData;
    short                       menuID, menuItem;
    SInt32                      command = kCommand_Nothing;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_GetMenuCommand $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
 
    menuID = (short)MYHIWORD(inMenuResult);
    menuItem = (short)MYLOWORD(inMenuResult);
    switch (menuID)  {
        case rMenu_Presentation:
            switch (menuItem)  {
                case rMenuItem_GetPresInfo:
                    command = kCommand_GetPresInfo;
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    
    if (command == kCommand_Nothing)  {
        if (windData->broadcast != 0)  {
            command = UsherBroadcast_GetMenuCommand(windData->broadcast, inMenuResult, outCommandParams);
        }
    }
    
exit:
    return command;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_DoCommand
// ---------------------------------------------------------------------------
 
OSErr UsherMinWind_DoCommand(WindowPtr inWindow, long inCommand, void *inCommandParams)
{
#pragma unused(inCommandParams)
    UsherMinWindowRecord    *windData;
    OSErr                   err = noErr;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_DoCommand $%.8x - couldnt get wind data", inWindow));
        EXITERR( err = kErr_AppUnhandledCommand );
    }
    
    switch (inCommand)  {
        case kCommand_GetPresInfo:
            if (windData->infoWindow != NULL)  {
                SelectWindow(windData->infoWindow);
            }  else  {
                Point       newLoc;
                Rect        myWindowRect;
                GrafPtr     oldPort;
                
                GetPort(&oldPort);
                SetPortWindowPort(inWindow);                
                EXITIFERR( err = WindowSupport_NewWindowOfType(kSignature_PresInfoWind, false, &windData->infoWindow) );
                PresInfoWind_HandleMessage(windData->infoWindow, kMessage_SetUsherBroadcast, windData->broadcast);
                PresInfoWind_HandleMessage(windData->infoWindow, kMessage_SetParentWindow, inWindow);
                // move the window next to this one
                CopyPortBounds(GetWindowPort(inWindow), &myWindowRect);
                newLoc.h = myWindowRect.right + 20;
                newLoc.v = myWindowRect.top;
                LocalToGlobal(&newLoc);
                MacSetPort(oldPort);
 
                MacMoveWindow(windData->infoWindow, newLoc.h, newLoc.v, false);
                MacShowWindow(windData->infoWindow);
                SelectWindow(windData->infoWindow);
            }
            break;
 
        default:
            if (windData->broadcast != 0)  {
                err = UsherBroadcast_DoCommand(windData->broadcast, inCommand, inCommandParams);
            }  else  {
                err = kErr_AppUnhandledCommand;
            }
            break;
    }
 
exit:
    return err;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_GrowWindow
// ---------------------------------------------------------------------------
 
void UsherMinWind_GrowWindow(WindowPtr inWindow, EventRecord *inEvent)
{
#pragma unused(inEvent)
    UsherMinWindowRecord        *windData;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UserMinWind_GrowWindow $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
 
    // nothing to do for now...
 
exit:
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_DoContentClick
// ---------------------------------------------------------------------------
 
void UsherMinWind_DoContentClick(WindowPtr inWindow, EventRecord *inEvent)
{
    UsherMinWindowRecord    *windData;
    GrafPtr                 oldPort;
    short                   partCode;
    ControlRef              clickedControl;
    Point                   currentMouse;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_DoContentClick $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
    GetPort(&oldPort);
    SetPortWindowPort(inWindow);
    
    currentMouse = inEvent->where;
    GlobalToLocal(&currentMouse);
    partCode = FindControl(currentMouse, inWindow, &clickedControl);
    if (partCode != 0)  {
        partCode = TrackControl(clickedControl, currentMouse, NULL);
        if (partCode != 0)  {
            UserMinWindPriv_DoControlClicked(windData, clickedControl, partCode);
        }
    }
 
exit:
    MacSetPort(oldPort);
    return;
}
 
// ---------------------------------------------------------------------------
//      UserMinWindPriv_DoControlClicked
// ---------------------------------------------------------------------------
 
static void UserMinWindPriv_DoControlClicked(UsherMinWindowRecord *inWindData,
                                ControlRef inControl, short inPart)
{
#pragma unused(inPart)
    OSErr           err = noErr;
 
    if (inControl == inWindData->startButton)  {
        if (inWindData->broadcast != NULL)  {
            if (inWindData->presState <= kSimplePresState_Idle)  {
                UsherBroadcast_Start(inWindData->broadcast);
            }  else  {
                UsherBroadcast_Stop(inWindData->broadcast);
            }
        }
    }  else if (inControl == inWindData->skipToNextButton)  {
        if (inWindData->broadcast != NULL)  {
            err = UsherBroadcast_DoCommand(inWindData->broadcast, kCommand_SkipToNextMovie, NULL);
            if (err != noErr)  {
                DEBUGF(("kCommand_SkipToNextMovie returned err %ld", err));
                SysBeep(0);
            }
        }
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_ActivateWindow
// ---------------------------------------------------------------------------
 
void UsherMinWind_ActivateWindow(WindowPtr inWindow, Boolean inBecomingActive)
{
#pragma unused(inBecomingActive)
    UsherMinWindowRecord        *windData;
    Rect                        windowRect;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_ActivateWindow $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
    
    CopyPortBounds(GetWindowPort(inWindow), &windowRect);
    InvalWindowRect(inWindow, &windowRect); 
 
    // draw any stuff that should be different in active/inactive mode
    //UsherMinWind_Draw(inWindow);
 
exit:
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWind_HandleMessage
// ---------------------------------------------------------------------------
 
OSErr UsherMinWind_HandleMessage(WindowPtr inWindow, long inMessage, void *inMessageParams)
{
#pragma unused(inMessageParams)
    UsherMinWindowRecord    *windData;
    OSErr                   err = noErr;
    OSErr                   tempErr;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_HandleMessage $%.8x - couldnt get wind data", inWindow));
        EXITERR( err = qtsBadSelectorErr );
    }
    
    switch (inMessage)  {
        case kMessage_SetUsherBroadcast:
            windData->broadcast = (UsherBroadcast*)inMessageParams;
            if (windData->broadcast != 0)  {
                UsherBroadcastStringParams  stringParams;
                Str255                  pname;
                
                memset(&stringParams, 0, sizeof(stringParams));
                stringParams.ioString = (char*)pname;
                stringParams.inMaxLength = sizeof(pname)-1;
                tempErr = UsherBroadcast_DoCommand(windData->broadcast, kCommand_GetBroadcastName, &stringParams);
                if (tempErr == noErr)  {
                    if (stringParams.returnedStringLength > 0)  {
                        CopyCToPStr((char*)pname, pname);
                        SetWTitle(windData->standard.window, pname);
                    }
                }
                windData->updateFlags |= kMinWindUpdateFlag_PresState;
                
                tempErr = UsherBroadcast_DoCommand(windData->broadcast, kCommand_GetStoredMovieInfo, &windData->storedMovieParams);
                if (windData->skipToNextButton != 0)  {
                    if (windData->storedMovieParams.doingStoredMovies)  {
                        ShowControl(windData->skipToNextButton);
                    }  else  {
                        HideControl(windData->skipToNextButton);
                    }
                }
                
            }
            break;
 
        case kMessage_GetPresBox:
        {
            Rect        *presBox = (Rect*)inMessageParams;
            
            DITLGetItemRect(windData->ditlHandle, rMinWindDITLItem_VideoArea, presBox);
            break;
        }
 
 
        case kMessage_SendPresStatusChanged:
        {
            Rect        windowRect;
 
            CopyPortBounds(GetWindowPort(inWindow), &windowRect);
            InvalWindowRect(inWindow, &windowRect); 
            break;
        }
            
        case kMessage_WindowClosing:
        {
            WindowPtr       closingWindow = (WindowPtr)inMessageParams;
            
            if (closingWindow == windData->infoWindow)  {
                windData->infoWindow = NULL;
            }
            break;      
        }
 
        case kMessage_SendPresStateChanged:
            windData->updateFlags |= kMinWindUpdateFlag_PresState;
            windData->presState = (SimplePresState)inMessageParams;
            UsherMinWindPriv_SetStartButtonText(windData);
            break;
 
        case kMessage_UsherPresStoredMovieChanged:
            windData->updateFlags |= kMinWindUpdateFlag_StoredMovie;
            break;
 
        default:
            err = qtsBadSelectorErr;
            break;
    }
 
exit:
    return err;
}
 
#pragma mark -
 
// ---------------------------------------------------------------------------
//      UsherMinWind_Draw
// ---------------------------------------------------------------------------
 
void UsherMinWind_Draw(WindowPtr inWindow)
{
    UsherMinWindowRecord        *windData;
    Rect                        tempRect;
 
    if (!UsherMinWindPriv_GetWindData(inWindow, &windData))  {
        DEBUGF(("UsherMinWind_Draw $%.8x - couldnt get wind data", inWindow));
        goto exit;
    }
    
    UsherMinWindPriv_GetReadyToDraw(windData);
 
    CopyPortBounds(GetWindowPort(inWindow), &tempRect);
    EraseRect(&tempRect);
    
    DrawControls(inWindow);
        
    // ----- outline the video area
    DITLGetItemRect(windData->ditlHandle, rMinWindDITLItem_VideoArea, &tempRect);
    PenNormal();
    tempRect.left -= 1;
    tempRect.top -= 1;
    tempRect.right += 1;
    tempRect.bottom += 1;
    MacFrameRect(&tempRect);
 
    UsherMinWindPriv_DrawStaticItems(windData, 0L);
 
    TextFont(windData->font);
    TextSize(windData->fontSize);
    TextFace(0);
 
    UsherMinWindPriv_DrawStatus(windData, 0L);  
    UsherMinWindPriv_DrawDataRate(windData, 0L);
    UsherMinWindPriv_DrawState(windData, 0L);
    UsherMinWindPriv_DrawTime(windData, 0L);
    UsherMinWindPriv_DrawFrameRate(windData, 0L);
 
    if (windData->storedMovieParams.doingStoredMovies)  {
        UsherMinWindPriv_DrawStoredMovie(windData, 0L);
        UsherMinWindPriv_DrawMovieTiming(windData, 0L);
    }
        
    UsherMinWindPriv_FinishedDrawing(windData);
 
exit:
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_GetReadyToDraw
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_GetReadyToDraw(UsherMinWindowRecord *inWindData)
{
    if (inWindData->drawingCount < 0)  {
        DEBUGF(("UsherMinWindPriv_GetReadyToDraw $%.8x-drawingcount<0 $%.8x", inWindData, inWindData->drawingCount));
    }
 
    // if we're reentrant, we won't save the old port...i guess
    if (inWindData->drawingCount == 0)  {
        GetPort(&inWindData->oldPort);
    }
    ++inWindData->drawingCount;
    SetPortWindowPort(inWindData->standard.window);
    TextFont(inWindData->font);
    TextSize(inWindData->fontSize);
 
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_FinishedDrawing
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_FinishedDrawing(UsherMinWindowRecord *inWindData)
{
    --inWindData->drawingCount;
    if (inWindData->drawingCount == 0)  {
        MacSetPort(inWindData->oldPort);
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_Update
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_Update(UsherMinWindowRecord *inWindData, Boolean inDraw, SInt32 inFlags)
{
    OSErr                   err = noErr;
    UsherBroadcastStringParams  stringParams;
    Str255                  tempString;
 
    if (inWindData->updateFlags != 0)  {
        if (inDraw)  {
            UsherMinWindPriv_GetReadyToDraw(inWindData);
        }
 
        if (inWindData->updateFlags & kMinWindUpdateFlag_PresState)  {
            // get the string from the presentation
            if (inWindData->broadcast != 0)  {
                memset(&stringParams, 0, sizeof(stringParams));
                stringParams.ioString = (char*)inWindData->presStateString;
                stringParams.inMaxLength = sizeof(inWindData->presStateString)-1;
                err = UsherBroadcast_DoCommand(inWindData->broadcast, kCommand_GetBroadcastStateString, &stringParams);
                CopyCToPStr((char*)inWindData->presStateString, inWindData->presStateString);
            }  else  {
                err = -776;
            }
            if (err != noErr)  {
                DEBUGF(("UsherMinWindPriv_Update $%.8x-err %ld from cmd GetPresStateString", inWindData, err));
                GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_SPStateUnknownTemplate);
                CopyPToCStr(tempString, (char*)tempString);
                sprintf((char*)inWindData->presStateString, (char*)tempString, err); 
                CopyCToPStr((char*)inWindData->presStateString, inWindData->presStateString);
            }
            if (inDraw)  {
                UsherMinWindPriv_DrawState(inWindData, inFlags);
            }
            inWindData->updateFlags &= ~kMinWindUpdateFlag_PresState;
        }
        
        if (inWindData->updateFlags & kMinWindUpdateFlag_DataRate)  {
            inWindData->updateFlags &= ~kMinWindUpdateFlag_DataRate;
            if (inDraw)  {
                UsherMinWindPriv_DrawDataRate(inWindData, inFlags);
            }
        }
        if (inWindData->updateFlags & kMinWindUpdateFlag_FrameRate)  {
            inWindData->updateFlags &= ~kMinWindUpdateFlag_FrameRate;
            if (inDraw)  {
                UsherMinWindPriv_DrawFrameRate(inWindData, inFlags);
            }
        }
 
        if (inWindData->updateFlags & kMinWindUpdateFlag_Time)  {
            inWindData->updateFlags &= ~kMinWindUpdateFlag_Time;
            if (inDraw)  {
                UsherMinWindPriv_DrawTime(inWindData, inFlags);
            }
        }
 
        if (inWindData->updateFlags & kMinWindUpdateFlag_StoredMovie)  {
            inWindData->updateFlags &= ~kMinWindUpdateFlag_StoredMovie;
            memset(&inWindData->storedMovieParams, 0, sizeof(inWindData->storedMovieParams));
            if (inWindData->broadcast != 0)  {
                 UsherBroadcast_DoCommand(inWindData->broadcast, kCommand_GetStoredMovieInfo, &inWindData->storedMovieParams);
            }
 
            if (inDraw)  {
                UsherMinWindPriv_DrawStoredMovie(inWindData, inFlags);
            }
        }
 
        if (inWindData->updateFlags & kMinWindUpdateFlag_MovieTiming)  {
            inWindData->updateFlags &= ~kMinWindUpdateFlag_MovieTiming;
 
            if (inDraw)  {
                UsherMinWindPriv_DrawMovieTiming(inWindData, inFlags);
            }
        }
 
        if (inDraw)  {
            UsherMinWindPriv_FinishedDrawing(inWindData);
        }
 
    }
 
}
 
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawState
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawState(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_PresStateText,
            &inWindData->presStateString[1], inWindData->presStateString[0], inFlags);
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawDataRate
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawDataRate(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    Str255      tempString;
 
    // assumes the port, font, etc is already set
 
    //if (inWindData->dataRate == kUsherMinWindNoDataRate)  {
    if (0)  {
    }  else  {
        //NumToString(inWindData->dataRate, tempString);
        GetDataRateString(inWindData->dataRate, tempString);
    }
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_DataRateText,
                        &tempString[1], tempString[0], inFlags);
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawFrameRate
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawFrameRate(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    Str255      tempString;
 
    // assumes the port, font, etc is already set
    if (inWindData->frameRate != kUsherMinWindNoFrameRate)  {
        sprintf((char*)tempString, "%0.1f frames/sec", Fix2X(inWindData->frameRate));
        c2pstr((char*)tempString);
    } else  {
        pstrcpy(tempString, "\punknown");
    }
 
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_FrameRateText,
                        &tempString[1], tempString[0], inFlags);
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawTime
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawTime(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    char        tempString[256];
    
    DateTimeRecToString(&inWindData->dateTimeRec, tempString);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_TimeText,
                        (unsigned char*)tempString, strlen(tempString), inFlags);
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawStoredMovie
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawStoredMovie(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_StoredMovieText,
                        (unsigned char*)&(inWindData->storedMovieParams.currentMovieSpec.name[1]),
                        inWindData->storedMovieParams.currentMovieSpec.name[0], inFlags);
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawMovieTiming
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawMovieTiming(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    char            tempString[256];
    TimeValue64     temp64;
    
    if (inWindData->movieTimingParams.timeScale != 0)  {    
        if (inWindData->movieTimingParams.localCurrentTime < inWindData->movieTimingParams.localEndTime)  {
            temp64 = inWindData->movieTimingParams.localEndTime - inWindData->movieTimingParams.localCurrentTime;
        }  else  {
            temp64 = 0;
        }
        TimeValue64ToString(&temp64, inWindData->movieTimingParams.timeScale, tempString);
        UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_TimeRemainingText,
                            (unsigned char*)tempString, strlen(tempString), inFlags);
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawStatus
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawStatus(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    QTSStatusParams     *statusParams;
    Str255              tempString;
 
    // assumes the port, font, etc is already set
    if (inWindData->broadcast != 0)  {
        statusParams = UsherBroadcast_GetStatusParams(inWindData->broadcast);
        if (statusParams != NULL)  {
            if (statusParams->detailedStatusString != NULL)  {
                MacDrawText(statusParams->detailedStatusString, 0, (short)strlen(statusParams->detailedStatusString));
            }  else if (statusParams->statusString != NULL)  {
                MacDrawText(statusParams->statusString, 0, (short)strlen(statusParams->statusString));
            }  else  {
                NumToString(statusParams->status, tempString);
                UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_StatusText,
                        &tempString[1], tempString[0], inFlags);
            }
        }
 
    }
    
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawStaticItems
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawStaticItems(UsherMinWindowRecord *inWindData, SInt32 inFlags)
{
    Str255              tempString;
 
    TextFont(inWindData->labelFont);
    TextSize(inWindData->labelFontSize);
    TextFace(bold);
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_StatusLabel);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_StatusLabel,
                        &tempString[1], tempString[0], inFlags);
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_DataRateLabel);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_DataRateLabel,
                        &tempString[1], tempString[0], inFlags);
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_FrameRateLabel);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_FrameRateLabel,
                        &tempString[1], tempString[0], inFlags);
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_SPStateLabel);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_PresStateLabel,
                        &tempString[1], tempString[0], inFlags);
 
    GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_TimeLabel);
    UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_TimeLabel,
                        &tempString[1], tempString[0], inFlags);
 
    if (inWindData->storedMovieParams.doingStoredMovies)  {
        GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_StoredMovieLabel);
        UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_StoredMovieLabel,
                        &tempString[1], tempString[0], inFlags);
 
        GetIndString(tempString, rStringList_UsherMinWind, rUsherMinWindString_TimeRemainingLabel);
        UsherMinWindPriv_DrawItemText(inWindData, rMinWindDITLItem_TimeRemainingLabel,
                        &tempString[1], tempString[0], inFlags);
 
    }
 
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_DrawItemText
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_DrawItemText(UsherMinWindowRecord *inWindData, DialogItemIndex inItemIndex,
                    const unsigned char *inText, UInt32 inTextLength, SInt32 inFlags)
{
    Rect        itemRect;
 
    // assumes the port, font, etc is already set
    DITLGetItemRect(inWindData->ditlHandle, inItemIndex, &itemRect);
    if (inFlags & kUsherMinWindDrawingFlag_Erase)  {
        EraseRect(&itemRect);
    }
    MoveTo(itemRect.left, (short)(itemRect.bottom-3));
    MacDrawText(inText, 0, (short)inTextLength);
}
 
#pragma mark -
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_UpdateIfNecessary
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_UpdateIfNecessary(UsherMinWindowRecord *inWindData)
{
    if (inWindData->lastUpdateTime + inWindData->updateInterval < (SInt32)TickCount())  {
        UsherMinWindPriv_UpdateDataRate(inWindData);
        UsherMinWindPriv_UpdateFrameRate(inWindData);
        UsherMinWindPriv_UpdateTime(inWindData);
 
        if (inWindData->storedMovieParams.doingStoredMovies)  {
            inWindData->updateFlags |= kMinWindUpdateFlag_StoredMovie;
        }
 
        if (inWindData->storedMovieParams.doingStoredMovies)  {
            UsherMinWindPriv_UpdateMovieTiming(inWindData);
        }
        inWindData->lastUpdateTime = TickCount();
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_UpdateDataRate
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_UpdateDataRate(UsherMinWindowRecord *inWindData)
{
    if (inWindData->broadcast != 0)  {
        inWindData->dataRate = 0;
        if (UsherBroadcast_GetInfo(inWindData->broadcast,
                        kQTSTotalDataRateOutInfo, &inWindData->dataRate) != noErr)  {
            inWindData->dataRate = kUsherMinWindNoDataRate;
        }
    }  else  {
        inWindData->dataRate = kUsherMinWindNoDataRate;
    }
    inWindData->updateFlags |= kMinWindUpdateFlag_DataRate;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_UpdateFrameRate
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_UpdateFrameRate(UsherMinWindowRecord *inWindData)
{
#pragma unused (inWindData)
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_UpdateTime
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_UpdateTime(UsherMinWindowRecord *inWindData)
{
    OSErr               err = noErr;
    DateTimeRec         dateTimeRec;
    UsherBroadcastTimeParams    timeParams;
    
    memset(&dateTimeRec, 0, sizeof(dateTimeRec));
    memset(&timeParams, 0, sizeof(timeParams));
    if (inWindData->broadcast != 0)  {
        EXITIFERR( err = UsherBroadcast_DoCommand(inWindData->broadcast,
                            kCommand_GetBroadcastTime, &timeParams) );
        TimeValue64ToDateTimeRec(&timeParams.returnedTime, timeParams.timeScale, &dateTimeRec);
    }  else  {
        memset(&inWindData->dateTimeRec, 0, sizeof(inWindData->dateTimeRec));
    }
    
    if ( (dateTimeRec.day != inWindData->dateTimeRec.day)       ||
         (dateTimeRec.hour != inWindData->dateTimeRec.hour)     ||
         (dateTimeRec.minute != inWindData->dateTimeRec.minute) ||
         (dateTimeRec.second != inWindData->dateTimeRec.second) )  {
        BlockMoveData(&dateTimeRec, &inWindData->dateTimeRec, sizeof(dateTimeRec));
        inWindData->updateFlags |= kMinWindUpdateFlag_Time;
    }
exit:
    if (err != noErr)  {
        DEBUGF(("UsherMinWindPriv_UpdateTime $%.8x-err %ld getting time from pres", inWindData, err));
    }
    return;
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_UpdateMovieTiming
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_UpdateMovieTiming(UsherMinWindowRecord *inWindData)
{
    if (inWindData->broadcast != 0)  {
        memset(&inWindData->movieTimingParams, 0, sizeof(inWindData->movieTimingParams));
        // @@@ this is not quite right - what we want is the timing info of the movie,
        // not just one sourcer
        UsherBroadcast_GetInfo(inWindData->broadcast, kQTSInfo_SourcerTiming, &inWindData->movieTimingParams);
        inWindData->updateFlags |= kMinWindUpdateFlag_MovieTiming;
    }
}
 
// ---------------------------------------------------------------------------
//      UsherMinWindPriv_SetStartButtonText
// ---------------------------------------------------------------------------
 
static void UsherMinWindPriv_SetStartButtonText(UsherMinWindowRecord *inWindData)
{
    if (inWindData->presState <= kSimplePresState_Idle)  {
         if (inWindData->startButtonIsStop)  {
            SetControlTitle(inWindData->startButton, "\pStart");
            // currently, you can't start the presentation after you have stopped it
            HiliteControl(inWindData->startButton, 255);
            inWindData->startButtonIsStop = false;
         }
    }  else  {
         if (!inWindData->startButtonIsStop)  {
            SetControlTitle(inWindData->startButton, "\pStop");
            inWindData->startButtonIsStop = true;
         }
    }
}
 
 
 
// ---------------------------------------------------------------------------
//      GetDataRateString
// ---------------------------------------------------------------------------
 
static OSErr GetDataRateString(UInt32 inDataRate, unsigned char *outString)
{
    Fixed       adjRate;
    OSErr       err = noErr;
    char        tempString[256];
 
#define kKiloBitsPerSecCutoffRate       (1024 * 2)
#define kKiloBitsPerSecFixedDivisor     (1024 << 16)
#define kMegaBitsPerSecCutoffRate       (1024*1024)
#define kMegaBitsPerSecFirstDivisor     (1024)
#define kMegaBitsPerSecSecondDivisor    (1024)
#define kMegaBitsPerSecSecondFixedDivisor   (kMegaBitsPerSecSecondDivisor << 16)
 
    tempString[0] = 0;
    if (inDataRate < kKiloBitsPerSecCutoffRate)  {
        sprintf(tempString, "%ld bits/sec", inDataRate);
    }  else if (inDataRate < kMegaBitsPerSecCutoffRate)  {
        float       a;
 
        a = (float)inDataRate / 1024;
        sprintf(tempString, "%.1f kbits/sec", a);
    }  else  {
        inDataRate = inDataRate / kMegaBitsPerSecFirstDivisor;
        adjRate = FixDiv((Fixed)(inDataRate<<16), kMegaBitsPerSecSecondFixedDivisor);
        sprintf(tempString, "%.1f Mbits/sec", Fix2X(adjRate));
    }
    CopyCToPStr(tempString, outString);
    return err;
 
}