/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
//                                                                          //
//  plOGGCodec - Plasma codec support for the OGG/Vorbis file format.       //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

#ifndef _plOGGCodec_h
#define _plOGGCodec_h

#include "plAudioFileReader.h"


//// Class Definition ////////////////////////////////////////////////////////

struct OggVorbis_File;

class plOGGCodec : public plAudioFileReader
{
public:

    plOGGCodec( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
    virtual ~plOGGCodec();

    enum DecodeFormat
    {
        k8bitUnsigned,
        k16bitSigned
    };

    enum DecodeFlags
    {
        kFastSeeking = 0x01
    };
    
    virtual plWAVHeader &GetHeader( void );

    virtual void    Close( void );

    virtual UInt32  GetDataSize( void ) { return fDataSize / fChannelAdjust; }
    virtual float   GetLengthInSecs( void );

    virtual hsBool  SetPosition( UInt32 numBytes );
    virtual hsBool  Read( UInt32 numBytes, void *buffer );
    virtual UInt32  NumBytesLeft( void );

    virtual hsBool  IsValid( void ) { return ( fOggFile != nil ) ? true : false; }

    static void     SetDecodeFormat( DecodeFormat f ) { fDecodeFormat = f; }
    static void     SetDecodeFlag( UInt8 flag, hsBool on ) { if( on ) fDecodeFlags |= flag; else fDecodeFlags &= ~flag; }
    static UInt8    GetDecodeFlags( void ) { return fDecodeFlags; }
    void            ResetWaveHeaderRef() { fCurHeaderPos = 0; }
    void            BuildActualWaveHeader();
    bool            ReadFromHeader(int numBytes, void *data); // read from Actual wave header

protected:

    enum
    {
        kPCMFormatTag = 1
    };

    char            fFilename[ 512 ];
    FILE            *fFileHandle;
    OggVorbis_File  *fOggFile;

    plWAVHeader     fHeader, fFakeHeader;
    UInt32          fDataStartPos, fCurrDataPos, fDataSize;

    plAudioCore::ChannelSelect  fWhichChannel;
    UInt32                      fChannelAdjust, fChannelOffset;

    static DecodeFormat fDecodeFormat;
    static UInt8        fDecodeFlags;
    UInt8 *             fHeadBuf;
    int                 fCurHeaderPos;

    void    IError( const char *msg );
    void    IOpen( const char *path, plAudioCore::ChannelSelect whichChan = plAudioCore::kAll );
};

#endif //_plOGGCodec_h