/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include "CDPlayer.h"
#include "AudioFilePlayer.h"
#include "SDLOSXCAGuard.h"

/* we're exporting these functions into C land for SDL_syscdrom.c */
/*extern "C" {*/

/*///////////////////////////////////////////////////////////////////////////
    Constants
  //////////////////////////////////////////////////////////////////////////*/

#define kAudioCDFilesystemID   (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */

/* XML PList keys */
#define kRawTOCDataString           "Format 0x02 TOC Data"
#define kSessionsString             "Sessions"
#define kSessionTypeString          "Session Type"
#define kTrackArrayString           "Track Array"
#define kFirstTrackInSessionString      "First Track"
#define kLastTrackInSessionString       "Last Track"
#define kLeadoutBlockString         "Leadout Block"
#define kDataKeyString              "Data"
#define kPointKeyString             "Point"
#define kSessionNumberKeyString         "Session Number"
#define kStartBlockKeyString            "Start Block"   
    
/*///////////////////////////////////////////////////////////////////////////
    Globals
  //////////////////////////////////////////////////////////////////////////*/

#pragma mark -- Globals --

static int             playBackWasInit = 0;
static AudioUnit        theUnit;
static AudioFilePlayer* thePlayer = NULL;
static CDPlayerCompletionProc   completionProc = NULL;
static SDL_mutex       *apiMutex = NULL;
static SDL_sem         *callbackSem;
static SDL_CD*          theCDROM;

/*///////////////////////////////////////////////////////////////////////////
    Prototypes
  //////////////////////////////////////////////////////////////////////////*/

#pragma mark -- Prototypes --

static OSStatus CheckInit ();

static void     FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus);

static int      RunCallBackThread (void* inRefCon);


#pragma mark -- Public Functions --

void     Lock ()
{
    if (!apiMutex) {
        apiMutex = SDL_CreateMutex();
    }
    SDL_mutexP(apiMutex);
}

void     Unlock ()
{
    SDL_mutexV(apiMutex);
}

int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes)
{
    int volumeIndex;
    int cdVolumeCount = 0;
    OSStatus result = noErr;
    
    for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++)
    {
        FSVolumeRefNum  actualVolume;
        FSVolumeInfo    volumeInfo;
        
        memset (&volumeInfo, 0, sizeof(volumeInfo));
        
        result = FSGetVolumeInfo (kFSInvalidVolumeRefNum,
                                  volumeIndex,
                                  &actualVolume,
                                  kFSVolInfoFSInfo,
                                  &volumeInfo,
                                  NULL,
                                  NULL); 
         
        if (result == noErr)
        {
            if (volumeInfo.filesystemID == kAudioCDFilesystemID) /* It's an audio CD */
            {
                if (volumes != NULL && cdVolumeCount < numVolumes)
                    volumes[cdVolumeCount] = actualVolume;
            
                cdVolumeCount++;
            }
        }
        else 
        {
            /* I'm commenting this out because it seems to be harmless */
            /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result);*/
        }
    }
        
    return cdVolumeCount;
}

int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD)
{
    HFSUniStr255      dataForkName;
    OSStatus          theErr;
    FSIORefNum        forkRefNum;
    SInt64            forkSize;
    Ptr               forkData = 0;
    ByteCount         actualRead;
    CFDataRef         dataRef = 0;
    CFPropertyListRef propertyListRef = 0;
    int               i;
    FSRefParam      fsRefPB;
    FSRef           tocPlistFSRef;
    FSRef           rootRef;
    const char* error = "Unspecified Error";
    const UniChar uniName[] = { '.','T','O','C','.','p','l','i','s','t' };

    theErr = FSGetVolumeInfo(theVolume, 0, 0, kFSVolInfoNone, 0, 0, &rootRef);
    if(theErr != noErr) {
        error = "FSGetVolumeInfo";
        goto bail;
    }

    SDL_memset(&fsRefPB, '\0', sizeof (fsRefPB));

    /* get stuff from .TOC.plist */
    fsRefPB.ref = &rootRef;
    fsRefPB.newRef = &tocPlistFSRef;
    fsRefPB.nameLength = sizeof (uniName) / sizeof (uniName[0]);
    fsRefPB.name = uniName;
    fsRefPB.textEncodingHint = kTextEncodingUnknown;

    theErr = PBMakeFSRefUnicodeSync (&fsRefPB);
    if(theErr != noErr) {
        error = "PBMakeFSRefUnicodeSync";
        goto bail;
    }
    
    /* Load and parse the TOC XML data */

    theErr = FSGetDataForkName (&dataForkName);
    if (theErr != noErr) {
        error = "FSGetDataForkName";
        goto bail;
    }
    
    theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum);
    if (theErr != noErr) {
        error = "FSOpenFork";
        goto bail;
    }
    
    theErr = FSGetForkSize (forkRefNum, &forkSize);
    if (theErr != noErr) {
        error = "FSGetForkSize";
        goto bail;
    }
    
    /* Allocate some memory for the XML data */
    forkData = NewPtr (forkSize);
    if(forkData == NULL) {
        error = "NewPtr";
        goto bail;
    }
    
    theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */, forkSize, forkData, &actualRead);
    if(theErr != noErr) {
        error = "FSReadFork";
        goto bail;
    }
    
    dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize);
    if(dataRef == 0) {
        error = "CFDataCreate";
        goto bail;
    }

    propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault,
                                                       dataRef,
                                                       kCFPropertyListImmutable,
                                                       NULL);
    if (propertyListRef == NULL) {
        error = "CFPropertyListCreateFromXMLData";
        goto bail;
    }

    /* Now we got the Property List in memory. Parse it. */
    
    /* First, make sure the root item is a CFDictionary. If not, release and bail. */
    if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID())
    {
        CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef;
        
        CFDataRef   theRawTOCDataRef;
        CFArrayRef  theSessionArrayRef;
        CFIndex     numSessions;
        CFIndex     index;
        
        /* This is how we get the Raw TOC Data */
        theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString));
        
        /* Get the session array info. */
        theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString));
        
        /* Find out how many sessions there are. */
        numSessions = CFArrayGetCount (theSessionArrayRef);
        
        /* Initialize the total number of tracks to 0 */
        theCD->numtracks = 0;
        
        /* Iterate over all sessions, collecting the track data */
        for(index = 0; index < numSessions; index++)
        {
            CFDictionaryRef theSessionDict;
            CFNumberRef     leadoutBlock;
            CFArrayRef      trackArray;
            CFIndex         numTracks;
            CFIndex         trackIndex;
            UInt32          value = 0;
            
            theSessionDict      = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index);
            leadoutBlock        = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString));
            
            trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString));
            
            numTracks = CFArrayGetCount (trackArray);

            for(trackIndex = 0; trackIndex < numTracks; trackIndex++) {
                    
                CFDictionaryRef theTrackDict;
                CFNumberRef     trackNumber;
                CFNumberRef     sessionNumber;
                CFNumberRef     startBlock;
                CFBooleanRef    isDataTrack;
                UInt32          value;
                
                theTrackDict  = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex);
                
                trackNumber   = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString));
                sessionNumber = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString));
                startBlock    = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString));
                isDataTrack   = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString));
                                                        
                /* Fill in the SDL_CD struct */
                int idx = theCD->numtracks++;

                CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value);
                theCD->track[idx].id = value;
                
                CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value);
                theCD->track[idx].offset = value;

                theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK;

                /* Since the track lengths are not stored in .TOC.plist we compute them. */
                if (trackIndex > 0) {
                    theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset;
                }
            }
            
            /* Compute the length of the last track */
            CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value);
            
            theCD->track[theCD->numtracks-1].length = 
                value - theCD->track[theCD->numtracks-1].offset;

            /* Set offset to leadout track */
            theCD->track[theCD->numtracks].offset = value;
        }
    
    }

    theErr = 0;
    goto cleanup;
bail:
    SDL_SetError ("ReadTOCData: %s returned %d", error, theErr);
    theErr = -1;
cleanup:

    if (propertyListRef != NULL)
        CFRelease(propertyListRef);
    if (dataRef != NULL)
        CFRelease(dataRef);
    if (forkData != NULL)
        DisposePtr(forkData);
        
    FSCloseFork (forkRefNum);

    return theErr;
}

int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks)
{
    OSStatus        result = -1;
    FSIterator      iterator;
    ItemCount       actualObjects;
    FSRef           rootDirectory;
    FSRef           ref;
    HFSUniStr255    nameStr;
    
    result = FSGetVolumeInfo (theVolume,
                              0,
                              NULL,
                              kFSVolInfoFSInfo,
                              NULL,
                              NULL,
                              &rootDirectory); 
                                 
    if (result != noErr) {
        SDL_SetError ("ListTrackFiles: FSGetVolumeInfo returned %d", result);
        return result;
    }

    result = FSOpenIterator (&rootDirectory, kFSIterateFlat, &iterator);
    if (result == noErr) {
        do
        {
            result = FSGetCatalogInfoBulk (iterator, 1, &actualObjects,
                                           NULL, kFSCatInfoNone, NULL, &ref, NULL, &nameStr);
            if (result == noErr) {
                
                CFStringRef  name;
                name = CFStringCreateWithCharacters (NULL, nameStr.unicode, nameStr.length);
                
                /* Look for .aiff extension */
                if (CFStringHasSuffix (name, CFSTR(".aiff")) ||
                    CFStringHasSuffix (name, CFSTR(".cdda"))) {
                    
                    /* Extract the track id from the filename */
                    int trackID = 0, i = 0;
                    while (i < nameStr.length && !isdigit(nameStr.unicode[i])) {
                        ++i;
                    }
                    while (i < nameStr.length && isdigit(nameStr.unicode[i])) {
                        trackID = 10 * trackID +(nameStr.unicode[i] - '0');
                        ++i;
                    }

                    #if DEBUG_CDROM
                    printf("Found AIFF for track %d: '%s'\n", trackID, 
                    CFStringGetCStringPtr (name, CFStringGetSystemEncoding()));
                    #endif
                    
                    /* Track ID's start at 1, but we want to start at 0 */
                    trackID--;
                    
                    assert(0 <= trackID && trackID <= SDL_MAX_TRACKS);
                    
                    if (trackID < numTracks)
                        memcpy (&trackFiles[trackID], &ref, sizeof(FSRef));
                }
                CFRelease (name);
            }
        } while(noErr == result);
        FSCloseIterator (iterator);
    }
    
    return 0;
}

int LoadFile (const FSRef *ref, int startFrame, int stopFrame)
{
    int error = -1;
    
    if (CheckInit () < 0)
        goto bail;
    
    /* release any currently playing file */
    if (ReleaseFile () < 0)
        goto bail;
    
    #if DEBUG_CDROM
    printf ("LoadFile: %d %d\n", startFrame, stopFrame);
    #endif
    
    /*try {*/
    
        /* create a new player, and attach to the audio unit */
        
        thePlayer = new_AudioFilePlayer(ref);
        if (thePlayer == NULL) {
            SDL_SetError ("LoadFile: Could not create player");
            return -3; /*throw (-3);*/
        }
            
        if (!thePlayer->SetDestination(thePlayer, &theUnit))
            goto bail;
        
        if (startFrame >= 0)
            thePlayer->SetStartFrame (thePlayer, startFrame);
        
        if (stopFrame >= 0 && stopFrame > startFrame)
            thePlayer->SetStopFrame (thePlayer, stopFrame);
        
        /* we set the notifier later */
        /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL);*/
            
        if (!thePlayer->Connect(thePlayer))
            goto bail;
    
        #if DEBUG_CDROM
        thePlayer->Print(thePlayer);
        fflush (stdout);
        #endif
    /*}
      catch (...)
      {
          goto bail;
      }*/
        
    error = 0;

    bail:
    return error;
}

int ReleaseFile ()
{
    int error = -1;
        
    /* (Don't see any way that the original C++ code could throw here.) --ryan. */
    /*try {*/
        if (thePlayer != NULL) {
            
            thePlayer->Disconnect(thePlayer);
            
            delete_AudioFilePlayer(thePlayer);
            
            thePlayer = NULL;
        }
    /*}
      catch (...)
      {
          goto bail;
      }*/
    
    error = 0;
    
/*  bail: */
    return error;
}

int PlayFile ()
{
    OSStatus result = -1;
    
    if (CheckInit () < 0)
        goto bail;
        
    /*try {*/
    
        // start processing of the audio unit
        result = AudioOutputUnitStart (theUnit);
            if (result) goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart")
        
    /*}
    catch (...)
    {
        goto bail;
    }*/
    
    result = 0;
    
bail:
    return result;
}

int PauseFile ()
{
    OSStatus result = -1;
    
    if (CheckInit () < 0)
        goto bail;
            
    /*try {*/
    
        /* stop processing the audio unit */
        result = AudioOutputUnitStop (theUnit);
            if (result) goto bail;  /*THROW_RESULT("PauseFile: AudioOutputUnitStop")*/
    /*}
      catch (...)
      {
          goto bail;
      }*/
    
    result = 0;
bail:
    return result;
}

void SetCompletionProc (CDPlayerCompletionProc proc, SDL_CD *cdrom)
{
    assert(thePlayer != NULL);

    theCDROM = cdrom;
    completionProc = proc;
    thePlayer->SetNotifier (thePlayer, FilePlayNotificationHandler, cdrom);
}

int GetCurrentFrame ()
{    
    int frame;
    
    if (thePlayer == NULL)
        frame = 0;
    else
        frame = thePlayer->GetCurrentFrame (thePlayer);
        
    return frame; 
}


#pragma mark -- Private Functions --

static OSStatus CheckInit ()
{    
    if (playBackWasInit)
        return 0;
    
    OSStatus result = noErr;
    
    /* Create the callback semaphore */
    callbackSem = SDL_CreateSemaphore(0);

    /* Start callback thread */
    SDL_CreateThread(RunCallBackThread, NULL);

    { /*try {*/
        ComponentDescription desc;
    
        desc.componentType = kAudioUnitType_Output;
        desc.componentSubType = kAudioUnitSubType_DefaultOutput;
        desc.componentManufacturer = kAudioUnitManufacturer_Apple;
        desc.componentFlags = 0;
        desc.componentFlagsMask = 0;
        
        Component comp = FindNextComponent (NULL, &desc);
        if (comp == NULL) {
            SDL_SetError ("CheckInit: FindNextComponent returned NULL");
            if (result) return -1; //throw(internalComponentErr);
        }
        
        result = OpenAComponent (comp, &theUnit);
            if (result) return -1; //THROW_RESULT("CheckInit: OpenAComponent")
                    
        // you need to initialize the output unit before you set it as a destination
        result = AudioUnitInitialize (theUnit);
            if (result) return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize")
        
                    
        playBackWasInit = true;
    }
    /*catch (...)
      {
          return -1;
      }*/
    
    return 0;
}

static void FilePlayNotificationHandler(void * inRefCon, OSStatus inStatus)
{
    if (inStatus == kAudioFilePlay_FileIsFinished) {
    
        /* notify non-CA thread to perform the callback */
        SDL_SemPost(callbackSem);
        
    } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) {
    
        SDL_SetError ("CDPlayer Notification: buffer underrun");
    } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) {
    
        SDL_SetError ("CDPlayer Notification: player is uninitialized");
    } else {
        
        SDL_SetError ("CDPlayer Notification: unknown error %ld", inStatus);
    }
}

static int RunCallBackThread (void *param)
{
    for (;;) {
    
	SDL_SemWait(callbackSem);

        if (completionProc && theCDROM) {
            #if DEBUG_CDROM
            printf ("callback!\n");
            #endif
            (*completionProc)(theCDROM);
        } else {
            #if DEBUG_CDROM
            printf ("callback?\n");
            #endif
        }
    }
    
    #if DEBUG_CDROM
    printf ("thread dying now...\n");
    #endif
    
    return 0;
}

/*}; // extern "C" */
