/////////////////////////////////////////////////////////////////////////////
// Name:        sound.cpp
// Purpose:     wxSound class implementation: optional
// Author:      Stefan Csomor
// Modified by:
// Created:     1998-01-01
// RCS-ID:      $Id: sound.cpp,v 1.3 2004/05/23 20:52:41 JS Exp $
// Copyright:   (c) Stefan Csomor
// Licence:       wxWindows licence
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
#pragma implementation "sound.h"
#endif

#include "wx/object.h"
#include "wx/string.h"
#include "wx/sound.h"

#if wxUSE_SOUND

#ifdef __WXMAC__
#include "wx/mac/private.h"
#ifndef __DARWIN__
#include <Sound.h>
#endif
#endif

wxSound::wxSound()
  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
{
}

wxSound::wxSound(const wxString& sFileName, bool isResource)
  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
{
    Create(sFileName, isResource);
}


wxSound::~wxSound()
{
    FreeData();
}

wxSound::wxSound(int size, const wxByte* data)
  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false)
{
    //TODO convert data
}

bool wxSound::Create(const wxString& fileName, bool isResource)
{
    bool ret = false;
    m_sndname = fileName;
    m_isResource = isResource;

    if (m_isResource)
        ret = true;
    else
    { /*
        if (sndChan)
        {                                                                    // we're playing
            FSClose(SndRefNum);
            SndRefNum = 0;
            SndDisposeChannel(sndChan, TRUE);
            free(sndChan);
            sndChan = 0;
            KillTimer(0,timerID);
        }

        if (!lpSnd)
            return true;

        if (_access(lpSnd,0))                            // no file, no service
            return false;

        // Allocate SndChannel
        sndChan = (SndChannelPtr) malloc (sizeof(SndChannel));

        if (!sndChan)
            return false;

        sndChan->qLength = 128;

        if (noErr != SndNewChannel (&sndChan, sampledSynth, initMono | initNoInterp, 0))
        {
            free(sndChan);
            sndChan = 0;
            return false;
        }

        if (!(SndRefNum = MacOpenSndFile ((char *)lpSnd)))
        {
            SndDisposeChannel(sndChan, TRUE);
            free(sndChan);
            sndChan = 0;

            return false;
        }

        bool async = false;

        if (fdwSound & SND_ASYNC)
            async = true;

        if (SndStartFilePlay(sndChan, SndRefNum, 0, 81920, 0, 0, 0, async) != noErr)
        {
            FSClose (SndRefNum);
            SndRefNum = 0;
            SndDisposeChannel (sndChan, TRUE);
            free (sndChan);
            sndChan = 0;
            return false;
        }

        if (async)
        {  // haven't finish yet
            timerID = SetTimer(0, 0, 250, TimerCallBack);
        }
        else
        {
            FSClose (SndRefNum);
            SndRefNum = 0;
            SndDisposeChannel (sndChan, TRUE);
            free (sndChan);
            sndChan = 0;
        }*/
    }

    return ret;
}


//don't know what to do with looped, wth
bool wxSound::DoPlay(unsigned flags) const
{
    bool ret = false;

    if (m_isResource)
    {
    	Str255 snd ;
    	wxMacStringToPascal( m_sndname , snd ) ;
      	SndListHandle hSnd;

      	hSnd = (SndListHandle) GetNamedResource('snd ', snd);

      	if ((hSnd != NULL) && (SndPlay((SndChannelPtr)m_sndChan, (SndListHandle) hSnd, (flags & wxSOUND_ASYNC)) == noErr))
        	ret = true;
    }

    return ret;
}


bool wxSound::FreeData()
{
    bool ret = false;

    if (m_isResource)
    {
        m_sndname.Empty();
        ret = true;
    }
    else
    {
        //TODO,
    }

    return ret;
}


//code below is from an old implementation used for telinfo with MSVC crossplatform support
//technology proceeds, so it would be the wisest to drop this code, but it's left here just
//for the sake of a reference. BTW: Wave files can now be played with QT, starting from V3

/*static short MacOpenSndFile (char * path)
{
    VolumeParam vp;
    FSSpec fspec;
    Str255 name;
    char *c;

    // first, get the volume reference number for the file.  Start by
    // making a Pstring with just the volume name
    strcpy ((char *) name, path);
    if (c = strchr ((char *) name, ':'))
    {
        c++;
        *c = '\0';
    }

    c2pstr ((char *) name);
    vp.ioCompletion = 0;
    vp.ioVolIndex    = -1;
    vp.ioNamePtr    = name;
    vp.ioVRefNum    = 0;

    if (PBGetVInfo((ParamBlockRec *)&vp, 0) != noErr)
        return 0;

    // next, buld an FSSpec for the file
    strcpy ((char *) name, path);
    c2pstr ((char *) name);
    if (FSMakeFSSpec (vp.ioVRefNum, 0, name, &fspec) != noErr)
        return 0;

    short frefnum;
    // now open the file, and return it's reference number
    if (FSpOpenDF(&fspec, fsRdPerm, &frefnum) != noErr)
        return 0;

    return frefnum;
}


void TimerCallBack(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
    if(!sndChan)
    {
        KillTimer(0,timerID);
        return;
    }

    SCStatus    scstat;

    if (noErr == SndChannelStatus (sndChan, sizeof (SCStatus), &scstat)) {
        if (scstat.scChannelPaused || scstat.scChannelBusy)
            return;                            // not done yet
    }

    // either error or done.
    FSClose (SndRefNum);
    SndRefNum = 0;
    SndDisposeChannel (sndChan, TRUE);
    free (sndChan);
    sndChan = 0;
    KillTimer(0,timerID);
}*/


#endif
