/*
 * QuickTime Data Handler
 *
 * Copyright 2011 Aric Stewart for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#define ULONG CoreFoundation_ULONG
#define HRESULT CoreFoundation_HRESULT

#define LoadResource __carbon_LoadResource
#define CompareString __carbon_CompareString
#define GetCurrentThread __carbon_GetCurrentThread
#define GetCurrentProcess __carbon_GetCurrentProcess
#define AnimatePalette __carbon_AnimatePalette
#define EqualRgn __carbon_EqualRgn
#define FillRgn __carbon_FillRgn
#define FrameRgn __carbon_FrameRgn
#define GetPixel __carbon_GetPixel
#define InvertRgn __carbon_InvertRgn
#define LineTo __carbon_LineTo
#define OffsetRgn __carbon_OffsetRgn
#define PaintRgn __carbon_PaintRgn
#define Polygon __carbon_Polygon
#define ResizePalette __carbon_ResizePalette
#define SetRectRgn __carbon_SetRectRgn

#define CheckMenuItem __carbon_CheckMenuItem
#define DeleteMenu __carbon_DeleteMenu
#define DrawMenuBar __carbon_DrawMenuBar
#define EnableMenuItem __carbon_EnableMenuItem
#define EqualRect __carbon_EqualRect
#define FillRect __carbon_FillRect
#define FrameRect __carbon_FrameRect
#define GetCursor __carbon_GetCursor
#define GetMenu __carbon_GetMenu
#define InvertRect __carbon_InvertRect
#define IsWindowVisible __carbon_IsWindowVisible
#define MoveWindow __carbon_MoveWindow
#define OffsetRect __carbon_OffsetRect
#define PtInRect __carbon_PtInRect
#define SetCursor __carbon_SetCursor
#define SetRect __carbon_SetRect
#define ShowCursor __carbon_ShowCursor
#define ShowWindow __carbon_ShowWindow
#define UnionRect __carbon_UnionRect

#include <QuickTime/QuickTimeComponents.h>

#undef LoadResource
#undef CompareString
#undef GetCurrentThread
#undef _CDECL
#undef DPRINTF
#undef GetCurrentProcess
#undef AnimatePalette
#undef EqualRgn
#undef FillRgn
#undef FrameRgn
#undef GetPixel
#undef InvertRgn
#undef LineTo
#undef OffsetRgn
#undef PaintRgn
#undef Polygon
#undef ResizePalette
#undef SetRectRgn
#undef CheckMenuItem
#undef DeleteMenu
#undef DrawMenuBar
#undef EnableMenuItem
#undef EqualRect
#undef FillRect
#undef FrameRect
#undef GetCursor
#undef GetMenu
#undef InvertRect
#undef IsWindowVisible
#undef MoveWindow
#undef OffsetRect
#undef PtInRect
#undef SetCursor
#undef SetRect
#undef ShowCursor
#undef ShowWindow
#undef UnionRect

#undef ULONG
#undef HRESULT
#undef DPRINTF
#undef STDMETHODCALLTYPE

#include <assert.h>
#include <stdio.h>
#include <stdarg.h>

#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "winuser.h"
#include "dshow.h"

#include <assert.h>

#include "wine/unicode.h"
#include "wine/debug.h"

#include "qtprivate.h"

WINE_DEFAULT_DEBUG_CHANNEL(qtdatahandler);

static ComponentDescription myType =
{
    'dhlr',
    'WINE',
    'WINE',
    0,
    0
};

typedef struct DHData
{
    WineDataRefRecord dataRef;

   Ptr AsyncPtr;
   long AsyncRefCon;
   DataHCompletionUPP AsyncCompletionRtn;
} DHData;

static pascal ComponentResult myComponentRoutineProc ( ComponentParameters *
cp, Handle componentStorage);

void RegisterWineDataHandler( void )
{
    ComponentRoutineUPP MyComponentRoutineUPP;

    MyComponentRoutineUPP = NewComponentRoutineUPP(&myComponentRoutineProc);
    RegisterComponent( &myType , MyComponentRoutineUPP, 0, NULL, NULL, NULL);
}

static pascal ComponentResult myDataHCanUseDataRef ( DataHandler dh,
                                       Handle dataRef,
                                       long *useFlags
)
{
    WineDataRefRecord *record = (WineDataRefRecord*)(*dataRef);
    TRACE("%p %p %p\n",dh,dataRef,useFlags);
    if (record->pReader == NULL)
        return badComponentSelector;
    *useFlags = kDataHCanRead;
    return noErr;
}

static pascal ComponentResult myDataHSetDataRef ( DataHandler dh, Handle dataRef)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    WineDataRefRecord* newRef = (WineDataRefRecord*)(*dataRef);
    TRACE("\n");
    if (newRef->pReader != data->dataRef.pReader)
        IAsyncReader_AddRef(newRef->pReader);
    data->dataRef = *newRef;
    return noErr;
}

static pascal ComponentResult myDataHGetAvailableFileSize ( DataHandler dh,
                                                   long *fileSize)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    LONGLONG total;
    LONGLONG avaliable;

    TRACE("%p\n",dh);

    IAsyncReader_Length(data->dataRef.pReader,&total,&avaliable);
    *fileSize = avaliable;
    return noErr;
}

static pascal ComponentResult myDataHGetFileSize ( DataHandler dh, long *fileSize)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    LONGLONG total;
    LONGLONG avaliable;

    TRACE("%p\n",dh);

    IAsyncReader_Length(data->dataRef.pReader,&total,&avaliable);
    *fileSize = total;
    return noErr;
}

static pascal ComponentResult myDataHScheduleData ( DataHandler dh,
                                             Ptr PlaceToPutDataPtr,
                                             long FileOffset,
                                             long DataSize,
                                             long RefCon,
                                             DataHSchedulePtr scheduleRec,
                                             DataHCompletionUPP CompletionRtn)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    HRESULT hr;
    LONGLONG offset = FileOffset;
    BYTE* buffer = (BYTE*)PlaceToPutDataPtr;

    TRACE("%p %p %li %li %li %p %p\n",dh, PlaceToPutDataPtr, FileOffset, DataSize, RefCon, scheduleRec, CompletionRtn);

    hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
    TRACE("result %x\n",hr);
    if (CompletionRtn)
    {
        if (data->AsyncCompletionRtn)
            InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);

        data->AsyncPtr = PlaceToPutDataPtr;
        data->AsyncRefCon = RefCon;
        data->AsyncCompletionRtn = CompletionRtn;
    }

    return noErr;
}

static pascal ComponentResult myDataHFinishData (DataHandler dh, Ptr PlaceToPutDataPtr, Boolean Cancel)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    if (!data->AsyncCompletionRtn)
        return noErr;
    if (!PlaceToPutDataPtr || PlaceToPutDataPtr == data->AsyncPtr)
    {
        if (!Cancel)
            InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
        data->AsyncPtr = NULL;
        data->AsyncRefCon = 0;
        data->AsyncCompletionRtn = NULL;
    }
    return noErr;
}

static pascal ComponentResult myDataHGetData ( DataHandler dh,
                                        Handle h,
                                        long hOffset,
                                        long offset,
                                        long size)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    BYTE *target = (BYTE*)*h;
    LONGLONG off = offset;
    HRESULT hr;

    TRACE("%p %p %li %li %li\n",dh, h, hOffset, offset, size);
    hr = IAsyncReader_SyncRead(data->dataRef.pReader, off, size, target+hOffset);
    TRACE("result %x\n",hr);

    return noErr;
}

static pascal ComponentResult myDataHCompareDataRef ( DataHandler dh,
                                               Handle dataRef, Boolean *equal)
{
    WineDataRefRecord *ptr1;
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    TRACE("\n");

    ptr1 = (WineDataRefRecord*)dataRef;

    *equal = (ptr1->pReader == data->dataRef.pReader);
    return noErr;
}

static pascal ComponentResult myDataHGetDataRef ( DataHandler dh, Handle *dataRef)
{
    Handle storage = GetComponentInstanceStorage(dh);
    TRACE("\n");
    *dataRef = storage;
    HandToHand(dataRef);
    return noErr;
}

static pascal ComponentResult myDataHGetScheduleAheadTime ( DataHandler dh,
                                                       long *millisecs)
{
    TRACE("\n");
    *millisecs = 1000;
    return noErr;
}

static pascal ComponentResult myDataHGetInfoFlags ( DataHandler dh, UInt32 *flags)
{
    TRACE("\n");
    *flags = 0;
    return noErr;
}

static pascal ComponentResult myDataHGetFileTypeOrdering ( DataHandler dh,
                           DataHFileTypeOrderingHandle *orderingListHandle)
{
    OSType orderlist[1] = {kDataHFileTypeExtension};
    TRACE("\n");
    PtrToHand( &orderlist, (Handle*)orderingListHandle, sizeof(OSType));
    return noErr;
}

static pascal ComponentResult myDataHGetFileName ( DataHandler dh, Str255 str)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    TRACE("%p %s\n",str,debugstr_guid(&data->dataRef.streamSubtype));

    /* Todo Expand this list */
    if (IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1Video) ||
        IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1System))
        CFStringGetPascalString(CFSTR("video.mpg"),str,256,kCFStringEncodingMacRoman);
    else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Asf))
        CFStringGetPascalString(CFSTR("video.asf"),str,256,kCFStringEncodingMacRoman);
    else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Avi))
        CFStringGetPascalString(CFSTR("video.avi"),str,256,kCFStringEncodingMacRoman);
    else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_QTMovie))
        CFStringGetPascalString(CFSTR("video.mov"),str,256,kCFStringEncodingMacRoman);
    else
        return badComponentSelector;

    return noErr;
}

static pascal ComponentResult myDataHOpenForRead(DataHandler dh)
{
    TRACE("\n");
    return noErr;
}

static pascal ComponentResult myDataHTask(DataHandler dh)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;

    if (data->AsyncCompletionRtn)
    {
        TRACE("Sending Completion\n");
        InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
        data->AsyncPtr = NULL;
        data->AsyncRefCon = 0;
        data->AsyncCompletionRtn = NULL;
    }
    return noErr;
}

static pascal ComponentResult myDataHPlaybackHints(DataHandler dh, long flags,
                unsigned long minFileOffset, unsigned long maxFileOffset,
                long bytesPerSecond)
{
    TRACE("%lu %lu %li\n",minFileOffset, maxFileOffset, bytesPerSecond);
    return noErr;
}

static pascal ComponentResult myDataHGetFileSize64(DataHandler dh, wide * fileSize)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    LONGLONG total;
    LONGLONG avaliable;
    SInt64 total64;

    TRACE("%p\n",dh);

    IAsyncReader_Length(data->dataRef.pReader,&total,&avaliable);
    total64 = total;
    *fileSize = SInt64ToWide(total64);
    return noErr;
}

static pascal ComponentResult myDataHGetAvailableFileSize64(DataHandler dh, wide * fileSize)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    LONGLONG total;
    LONGLONG avaliable;
    SInt64 total64;

    TRACE("%p\n",dh);

    IAsyncReader_Length(data->dataRef.pReader,&total,&avaliable);
    total64 = avaliable;
    *fileSize = SInt64ToWide(total64);
    return noErr;
}

static pascal ComponentResult myDataHScheduleData64( DataHandler dh,
                                          Ptr PlaceToPutDataPtr,
                                          const wide * FileOffset,
                                          long DataSize,
                                          long RefCon,
                                          DataHSchedulePtr scheduleRec,
                                          DataHCompletionUPP CompletionRtn)
{
    Handle storage = GetComponentInstanceStorage(dh);
    DHData *data = (DHData*)*storage;
    HRESULT hr;
    SInt64 fileOffset64 = WideToSInt64(*FileOffset);
    LONGLONG offset = fileOffset64;
    BYTE* buffer = (BYTE*)PlaceToPutDataPtr;

    TRACE("%p %p %lli %li %li %p %p\n",dh, PlaceToPutDataPtr, offset, DataSize, RefCon, scheduleRec, CompletionRtn);

    hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
    TRACE("result %x\n",hr);
    if (CompletionRtn)
    {
        if (data->AsyncCompletionRtn)
            InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);

        data->AsyncPtr = PlaceToPutDataPtr;
        data->AsyncRefCon = RefCon;
        data->AsyncCompletionRtn = CompletionRtn;
    }

    return noErr;
}

static const struct { LPVOID proc; ProcInfoType type;} componentFunctions[] =
{
    {NULL, 0}, /* 0 */
    {NULL, 0}, /* 1 */
    {myDataHGetData,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
}, /* kDataHGetDataSelect                        */
    {NULL, 0}, /* kDataHPutDataSelect                        */
    {NULL, 0}, /* kDataHFlushDataSelect                      */
    {NULL, 0}, /* kDataHOpenForWriteSelect                   */
    {NULL, 0}, /* kDataHCloseForWriteSelect                  */
    {NULL, 0}, /* 7 */
    {myDataHOpenForRead, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
}, /* kDataHOpenForReadSelect
*/
    {NULL, 0}, /* kDataHCloseForReadSelect                   */
    {myDataHSetDataRef,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
}, /* kDataHSetDataRefSelect                     */
    {myDataHGetDataRef,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
}, /* kDataHGetDataRefSelect                     */
    {myDataHCompareDataRef,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean*)))
}, /* kDataHCompareDataRefSelect                 */
    {myDataHTask, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
}, /* kDataHTaskSelect                           */
    {myDataHScheduleData,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
            | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
}, /* kDataHScheduleDataSelect                   */
    {myDataHFinishData, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean)))
}, /* kDataHFinishDataSelect                     */
    {NULL, 0}, /* kDataHFlushCacheSelect       0x10              */
    {NULL, 0}, /* kDataHResolveDataRefSelect                 */
    {myDataHGetFileSize,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetFileSizeSelect                    */
    {myDataHCanUseDataRef,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long*)))
}, /* kDataHCanUseDataRefSelect                  */
    {NULL, 0}, /* kDataHGetVolumeListSelect                  */
    {NULL, 0}, /* kDataHWriteSelect                          */
    {NULL, 0}, /* kDataHPreextendSelect                      */
    {NULL, 0}, /* kDataHSetFileSizeSelect                    */
    {NULL, 0}, /* kDataHGetFreeSpaceSelect                   */
    {NULL, 0}, /* kDataHCreateFileSelect                     */
    {NULL, 0}, /* kDataHGetPreferredBlockSizeSelect          */
    {NULL, 0}, /* kDataHGetDeviceIndexSelect                 */
    {NULL, 0}, /* kDataHIsStreamingDataHandlerSelect         */
    {NULL, 0}, /* kDataHGetDataInBufferSelect                */
    {myDataHGetScheduleAheadTime,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetScheduleAheadTimeSelect           */
/* End of Required List */
    {NULL, 0}, /* kDataHSetCacheSizeLimitSelect              */
    {NULL, 0}, /* kDataHGetCacheSizeLimitSelect       0x20   */
    {NULL, 0}, /* kDataHGetMovieSelect                       */
    {NULL, 0}, /* kDataHAddMovieSelect                       */
    {NULL, 0}, /* kDataHUpdateMovieSelect                    */
    {NULL, 0}, /* kDataHDoesBufferSelect                     */
    {myDataHGetFileName,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Str255*)))
}, /* kDataHGetFileNameSelect                    */
    {myDataHGetAvailableFileSize,   kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetAvailableFileSizeSelect           */
    {NULL, 0}, /* kDataHGetMacOSFileTypeSelect               */
    {NULL, 0}, /* kDataHGetMIMETypeSelect                    */
    {NULL, 0}, /* kDataHSetDataRefWithAnchorSelect           */
    {NULL, 0}, /* kDataHGetDataRefWithAnchorSelect           */
    {NULL, 0}, /* kDataHSetMacOSFileTypeSelect               */
    {NULL, 0}, /* kDataHSetTimeBaseSelect                    */
    {myDataHGetInfoFlags,  kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(UInt32*)))
}, /* kDataHGetInfoFlagsSelect                   */
    {myDataHScheduleData64, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(wide*)))
            | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
            | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
}, /* kDataHScheduleData64Select                 */
    {NULL, 0}, /* kDataHWrite64Select                        */
    {myDataHGetFileSize64, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
}, /* kDataHGetFileSize64Select     0x30         */
    {NULL, 0}, /* kDataHPreextend64Select                    */
    {NULL, 0}, /* kDataHSetFileSize64Select                  */
    {NULL, 0}, /* kDataHGetFreeSpace64Select                 */
    {NULL, 0}, /* kDataHAppend64Select                       */
    {NULL, 0}, /* kDataHReadAsyncSelect                      */
    {NULL, 0}, /* kDataHPollReadSelect                       */
    {NULL, 0}, /* kDataHGetDataAvailabilitySelect            */
    {NULL, 0}, /* 0x0038 */
    {NULL, 0}, /* 0x0039 */
    {NULL, 0}, /* kDataHGetFileSizeAsyncSelect               */
    {NULL, 0}, /* kDataHGetDataRefAsTypeSelect               */
    {NULL, 0}, /* kDataHSetDataRefExtensionSelect            */
    {NULL, 0}, /* kDataHGetDataRefExtensionSelect            */
    {NULL, 0}, /* kDataHGetMovieWithFlagsSelect              */
    {NULL, 0}, /* 0x3F */
    {myDataHGetFileTypeOrdering, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DataHFileTypeOrderingHandle*)))
}, /* kDataHGetFileTypeOrderingSelect  0x40      */
    {NULL, 0}, /* kDataHCreateFileWithFlagsSelect            */
    {NULL, 0}, /* kDataHGetMIMETypeAsyncSelect               */
    {NULL, 0}, /* kDataHGetInfoSelect                        */
    {NULL, 0}, /* kDataHSetIdleManagerSelect                 */
    {NULL, 0}, /* kDataHDeleteFileSelect                     */
    {NULL, 0}, /* kDataHSetMovieUsageFlagsSelect             */
    {NULL, 0}, /* kDataHUseTemporaryDataRefSelect            */
    {NULL, 0}, /* kDataHGetTemporaryDataRefCapabilitiesSelect */
    {NULL, 0}, /* kDataHRenameFileSelect                     */
    {NULL, 0}, /* 0x4A */
    {NULL, 0}, /* 0x4B */
    {NULL, 0}, /* 0x4C */
    {NULL, 0}, /* 0x4D */
    {myDataHGetAvailableFileSize64, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
}, /* kDataHGetAvailableFileSize64Select         */
    {NULL, 0}, /* kDataHGetDataAvailability64Select          */
};

static const struct { LPVOID proc; ProcInfoType type;} componentFunctions_2[] =
{
    {myDataHPlaybackHints, kPascalStackBased
            | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
            | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
            | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))
            | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned long)))
            | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(unsigned long)))
            | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
}, /* kDataHPlaybackHintsSelect     0x103 */
    {NULL, 0}, /* kDataHPlaybackHints64Select   0x10E */
    {NULL, 0}, /* kDataHGetDataRateSelect       0x110 */
    {NULL, 0}, /* kDataHSetTimeHintsSelect      0x111 */
};

/* Component Functions */

static pascal ComponentResult myComponentOpen(ComponentInstance ci, ComponentInstance self)
{
    DHData myData;
    Handle storage;

    ZeroMemory(&myData,sizeof(DHData));
    PtrToHand( &myData, &storage, sizeof(DHData));
    SetComponentInstanceStorage(self,storage);

    return noErr;
}

static pascal ComponentResult myComponentClose(ComponentInstance ci, ComponentInstance self)
{
    Handle storage = GetComponentInstanceStorage(self);
    DHData *data;
    if (storage)
    {
        data = (DHData*)*storage;
        if (data && data->dataRef.pReader != NULL)
            IAsyncReader_Release(data->dataRef.pReader);
        DisposeHandle(storage);
        SetComponentInstanceStorage(self,NULL);
    }
    return noErr;
}

static pascal ComponentResult myComponentCanDo(ComponentInstance ci, SInt16 ftnNumber)
{
    TRACE("test 0x%x\n",ftnNumber);
    if (ftnNumber <= kComponentOpenSelect && ftnNumber >= kComponentCanDoSelect)
        return TRUE;
    if (ftnNumber == kDataHPlaybackHintsSelect)
        return TRUE;
    if (ftnNumber > kDataHGetDataAvailability64Select)
        return FALSE;
    TRACE("impl? %i\n",(componentFunctions[ftnNumber].proc != NULL));
    return (componentFunctions[ftnNumber].proc != NULL);
}

/* Main Proc */

static ComponentResult callOurFunction(LPVOID proc, ProcInfoType type, ComponentParameters * cp)
{
    ComponentRoutineUPP myUUP;
    ComponentResult result;

    myUUP = NewComponentFunctionUPP(proc, type);
    result = CallComponentFunction(cp, myUUP);
    DisposeComponentFunctionUPP(myUUP);
    return result;
}

static pascal ComponentResult myComponentRoutineProc ( ComponentParameters * cp,
                                         Handle componentStorage)
{
    switch (cp->what)
    {
        case kComponentOpenSelect:
            return callOurFunction(myComponentOpen, uppCallComponentOpenProcInfo,  cp);
        case kComponentCloseSelect:
            return callOurFunction(myComponentClose, uppCallComponentOpenProcInfo,  cp);
        case kComponentCanDoSelect:
            return callOurFunction(myComponentCanDo, uppCallComponentCanDoProcInfo,  cp);
        case kDataHPlaybackHintsSelect:
            return callOurFunction(componentFunctions_2[0].proc, componentFunctions_2[0].type, cp);
    }

    if (cp->what > 0 && cp->what <=kDataHGetDataAvailability64Select && componentFunctions[cp->what].proc)
        return callOurFunction(componentFunctions[cp->what].proc, componentFunctions[cp->what].type, cp);

    FIXME("unhandled select 0x%x\n",cp->what);
    return badComponentSelector;
}
