/*
** Copyright (C) 1999 Albert L. Faber
**  
** 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 2 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, write to the Free Software 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifndef ID3TAGINCLUDED
#define ID3TAGINCLUDED

#include "Config.h"

#pragma pack(push,1)

#define FORMAT_LEN 512
#define STD_BUF_LEN 2048
#define PLAY_BUF_LEN 4096
#define DECODER "l3dec"
#define DECODEOPTS "-sti","-sto","-sa"
#define AUDIO "/dev/dsp"
#define FILENAME_LEN 256

/* MPEG Header Definitions - Mode Values */

#define         MPG_MD_STEREO           0
#define         MPG_MD_JOINT_STEREO     1
#define         MPG_MD_DUAL_CHANNEL     2
#define         MPG_MD_MONO             3

#define         MPG_MD_LR_LR             0
#define         MPG_MD_LR_I              1
#define         MPG_MD_MS_LR             2
#define         MPG_MD_MS_I              3



// ID3 TAG Format, as it is stored in the MP3 files
// Warning: No zero terminiated strings!, they are just fixed
typedef struct 
{
    char	tag[3];
    char	title[30];
    char	artist[30];
    char	album[30];
    char	year[4];
    char	comment[30];
    BYTE	genre;

} ID3FILETAG;


class CID3Tag 
{
public:

	// CONSTRUCTOR
	CID3Tag(CString& strFileName);
	CID3Tag() {};

	// MUTATORS
	BOOL	LoadTag();
	BOOL	SaveTag_v1();
	BOOL	SaveTag_v2();
	BOOL	SaveTag( );
	static FILE* SaveInitialV2Tag( const CString& strFileName, DWORD dwPadSize );
	static BOOL  CopyTags( const CString& strSrc,const CString& strDst );

	BOOL	OpenFile();
	BOOL	OpenFile( CString strFileName );
	void	CloseFile();

	CString GetTitle() const { return m_strTitle; }
	CString GetArtist() const { return m_strArtist; }
	CString GetAlbum() const { return m_strAlbum; }
	CString GetYear() const { return m_strYear; }
	BYTE	GetTrackNumber() const { return m_nTrackNumber; }
	BYTE	GetTotalTracks() const { return m_nTotalTracks; }
	size_t	GetTagSize() const { return m_nTagSize; }

	CString	GetComment() const		{ return m_strComment; }
	CString	GetGenre() const		{ return m_strGenre; }
	CString	GetEncodedBy() const	{ return m_strEncodedBy; }
	CString	GetCommentDescr() const { return m_strCommentDescr; }
	CString	GetMCDI() const			{ return m_strMCDI; }
	CString	GetLengthInMs() const	{ return m_strLengthInMs;}
	BYTE*	GetRawToc() const		{ return (BYTE*)m_btaRawToc; }
	
	void Init( );

	void SetTitle( const CString& strNew )			{ m_strTitle = strNew; }
	void SetArtist( const CString& strNew )			{ m_strArtist = strNew;}
	void SetAlbum( const CString& strNew )			{ m_strAlbum = strNew; }
	void SetYear( const CString& strNew ) 			{ m_strYear = strNew; }
	void SetComment( const CString& strNew )		{ m_strComment = strNew; }
	void SetGenre( const CString& strNew )			{ m_strGenre = strNew; }
	void SetEncodedBy( const CString& strNew )		{ m_strEncodedBy = strNew; }
	void SetTrackNumber( BYTE nValue )				{ m_nTrackNumber=nValue; }
	void SetTotalTracks( BYTE nValue )				{ m_nTotalTracks=nValue; }
	void SetTagSize( size_t nValue )				{ m_nTagSize = nValue; }
	void SetCommentDescr( const CString& strNew )	{ m_strCommentDescr = strNew; }
	void SetMCDI( const CString& strNew )			{ m_strMCDI = strNew; }
	void SetLengthInMs( const CString& strNew )		{ m_strLengthInMs = strNew; } 
	void SetRawToc( BYTE* btaRawToc )				{ memcpy( m_btaRawToc, btaRawToc, sizeof( RAW_TOC_TYPE ) ); }

	bool IsV2Tag() { return m_bIsV2; }
	bool IsV1Tag() { return m_bIsV1; }

	void IsV1Tag( bool bValue ) { m_bIsV1 = bValue; }
	void IsV2Tag( bool bValue ) { m_bIsV2 = bValue; }

private:
	CString	m_strTitle;
	CString m_strArtist;
	CString m_strAlbum;
	CString m_strYear;
	CString m_strComment;
	CString m_strEncodedBy;
	CString m_strMCDI;
	CString	m_strFileName;
	CString m_strGenre;
	BYTE	m_nTrackNumber;
	BYTE	m_nTotalTracks;
	FILE*	m_pFile;
	size_t	m_nTagSize;
	CString	m_strCommentDescr;
	bool	m_bIsV2;
	bool	m_bIsV1;
	CString	m_strLengthInMs;
	RAW_TOC_TYPE	m_btaRawToc;
};



#if 0
class Layer 
{
public:
	char *mode_name();
	char *layer_name();
	char *version_name();
	char *version_num();
	unsigned int bitrate();
	unsigned int sfreq();
	BOOL get(FILE * file);
	int version;
	int lay;
	int error_protection;
	int bitrate_index;
	int sampling_frequency;
	int padding;
	int extension;
	int mode;
	int mode_ext;
	int copyright;
	int original;
	int emphasis;
	int stereo;
};


class Mpfile {
    public:
    Mpfile();
    ~Mpfile();
    BOOL mpopen(char *name, BOOL write);
    void mpclose();
    BOOL initfile(BOOL gettag);
    void calc();
    BOOL mpformat(char *dest, char *format, size_t maxlen, int canslash);
    BOOL frename(char *format);
    BOOL execute(char *format);
    BOOL writetag();
    BOOL wipetag();
#ifdef PLAYER
    BOOL play(int threads);
#endif
    void tagcopy(Tag * from);

    Tag *tag;
    Layer *layer;
    BOOL hastag;
    BOOL haslayer;

    protected:
    BOOL openwrite;
    BOOL parseif(char what);
    FILE *file;
    size_t filelen;
    char filename[FILENAME_LEN];
    unsigned long length;
};

#endif

/* From tag.c */
//extern char *genres[];
//extern int genre_largest;

#pragma pack(pop)

#endif