/*
** 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 CDINFO_INCLUDED
#define CDINFO_INCLUDED

#define TRACKSPERSEC 75
#define CB_CDDASECTORSIZE 2352


#include "config.h"

#pragma pack(push,1)


enum CDTEXT_PACK_TYPE
{
	CDT_TRACK_TITLE	=0x80, // Title of Album name(ID2=00h) or Track Titles (ID2=01h...63h)
	CDT_PERFORMER	=0x81, // Name(s) of the performer(s) (in ASCII)
	CDT_SONGWRITER	=0x82, // Name(s) of the songwriter(s) (in ASCII)
	CDT_COMPOSER	=0x83, // Name(s) of the composer(s) (in ASCII)
	CDT_ARRANGER	=0x84, // Name(s) of the arranger(s) (in ASCII)
	CDT_MESSAGE		=0x85, // Message(s) from content provider and/or artist (in ASCII)
	CDT_DISC_ID		=0x86, // Disc Identification information
	CDT_GENRE		=0x87, // Genre Identification and Genre information
	CDT_TOC_INFO	=0x88, // Table of Content information
	CDT_SEC_TOC_INFO=0x89, // Second Table of Content information
	CDT_RESERVED_1	=0x8A, // Reserved
	CDT_RESERVED_2	=0x8B, // Reserved
	CDT_RESERVED_3	=0x8C, // Reserved
	CDT_RESERVED_4	=0x8D, // Reserved for content provider only
	CDT_UPC_EAN		=0x8E, // UPC/EAN code of the album and ISRC code of each track
	CDT_SIZE_BLOCK	=0x8F  // Size information of the Block
};

typedef struct CDTEXTPACK_TAG
{
  BYTE packType;
  BYTE trackNumber;
  BYTE sequenceNumber;

  BYTE characterPosition:4;		// character position
  BYTE block			:3;		// block number 0..7
  BYTE bDBC				:1;		// double byte character

  BYTE data[12];
  BYTE crc0;
  BYTE crc1;
} CDTEXTPACK;

#pragma pack(pop)


class PlayList:public CObject
{
private:
	CString m_strFileName;
	CString m_strOutDir;
	CString m_strPlayListDir;
	CString m_strFileDir;

public:
	PlayList( CString strPlayListFileName );
	void AddEntry( CString Entry );
	void AddM3UEntry( CString Entry );
	void AddPLSEntry( CString Entry );

private:
	CString MakeEntry(	const CString& strListName, 
						const CString& strEntry );

};


class CCDTrackInfo: public CObject
{
//private:
public:
	BYTE	m_reserved1;
	BYTE	m_btFlags;
	BYTE	m_btTrack;
	BYTE	m_reserved2;
	DWORD	m_dwStartSector;
	CString	m_strTrackName;
	CString	m_strExtTrackName;
	int		m_nCDDBType;
public:
	CCDTrackInfo();
	DWORD	GetStartSector()	const {return m_dwStartSector;}
	BYTE	GetFlags()			const {return m_btFlags;}
	BYTE	GetTrack()			const {return m_btTrack;}

	CString	GetTrackName()		const {return m_strTrackName;}
	CString	GetExtTrackName()	const {return m_strExtTrackName;}

	void	SetTrack(BYTE btTrack)				{m_btTrack=btTrack;}
	void	SetTrackName(CString strValue)		{m_strTrackName=strValue;}
	void	SetExtTrackName(CString strValue)	{m_strExtTrackName=strValue;}
	void	SetStartSector(DWORD dwStartSector)	{m_dwStartSector=dwStartSector;}
};


class CDInfo: public CObject
{
private:
	INT				m_nNumTracks;
	CCDTrackInfo	m_TrackInfo[MAXTRK];
	CString			m_strArtist;
	CString			m_strTitle;
	CString			m_strExtTitle;
	BYTE			m_btCategory;
	DWORD			m_dwVolID;
	DWORD			m_dwDiscID;
	CString			m_strYear;
	CString			m_strGenre;
	DWORD			m_dwTotalSecs;
	INT				m_nRevision;
	CString			m_strSubmission;
	CString			m_strVolID;
	CString			m_strCDDBCat;
	CString			m_strMCDI;
	RAW_TOC_TYPE	m_btaRawToc;
public:
	// CONSTRUCTORS
	CDInfo();
	// DESTRUCTOR
	~CDInfo();

	CString			GetCDDBCat();
	void			SetCDDBCat( const CString& strCDDBCat );

	INT				GetNumTracks() const {return m_nNumTracks;}
	VOID			SetNumTracks(WORD wValue) {m_nNumTracks=wValue;}
	void			DumpToc(LPBYTE pbtBuffer,int nSize);
	LONG			GetEndSector(int p_track);
	LONG			GetStartSector(int p_track);
	CString			GetTrackDuration(int nTrack);
	CString			GetStartTime(int nTrack);
	DWORD			GetSize(int nTrack);
	BOOL			IsAudioTrack(int p_track);
	DWORD			CalculateDiscID();

	WORD			GetTrack(int iTrackIndex) const {return m_TrackInfo[iTrackIndex].GetTrack();}
	void			SetTrack(int iTrackIndex, BYTE btTrack) { m_TrackInfo[iTrackIndex].SetTrack(btTrack);}


	CString			GetTrackName(int iTrackIndex) const {return m_TrackInfo[iTrackIndex].GetTrackName();}
	void 			SetTrackName( const CString& strValue, int iTrackIndex);

	CString			GetExtTrackName(int iExtTrackIndex) const {return m_TrackInfo[iExtTrackIndex].GetExtTrackName();}
	void 			SetExtTrackName( const CString& strValue,int iExtTrackIndex );

	CString			GetArtist() const {return m_strArtist;}
	void			SetArtist( const CString& strValue );
	
	CString			GetTitle() const {return m_strTitle;}
	void			SetTitle( const CString& strValue);

	CString			GetExtTitle() const {return m_strExtTitle;}
	void			SetExtTitle( const CString& strValue )	  {m_strExtTitle=strValue;}

	CString			GetYear()	const {return m_strYear;}
	void			SetYear(CString strValue) { m_strYear = strValue; }

	CString			GetGenre()	const {return m_strGenre;}
	void			SetGenre(CString strValue);

	int				GetRevision()	const {return m_nRevision;}
	void			SetRevision(int nValue)	  {m_nRevision=nValue;}

	CString			GetSubmission()	const {return m_strSubmission;}
	void			SetSubmission(CString strValue)	  {m_strSubmission=strValue;}

	void			SetStartSector(	int p_track, DWORD dwOffset);

	void			SetTotalSecs( DWORD dwSecs) {m_dwTotalSecs=dwSecs;}

	int				FirstTrack();

	void			ReadCDInfo();
	void			SaveCDInfo();

	DWORD			GetDiscID() const {return m_dwDiscID;}
	void			SetDiscID(DWORD dwID) {m_dwDiscID=dwID;}
	DWORD			GetVolID() const {return m_dwVolID;}

	CString			GetMCDI() const { return m_strMCDI; }

	BYTE*			GetRawToc() const { return (BYTE*)m_btaRawToc; }
	void			SetRawToc( BYTE* btaRawToc ) { memcpy( m_btaRawToc, btaRawToc, sizeof( RAW_TOC_TYPE ) ); }

	BOOL			IsLastAudioTrack( int p_track );
	LONG			GetSaveEndSector(int p_track);

	void			Init();
	BOOL			ReadCDPlayerIni();
	BOOL			ReadCDText();
	void			SaveCDPlayerIni();
	BOOL			ReadLocalCDDB( );
	BOOL			ReadRemoteCDDB( CWnd* pWnd, volatile BOOL& bAbort  );
	BOOL			SubmitRemoteCDDB( CWnd* pWnd, volatile BOOL& bAbort  );
	BOOL			ReadRemoteCDDBBatch( CWnd* pWnd, volatile BOOL& bAbort );
	DWORD			GetTotalSecs() const {return m_dwTotalSecs;}
	CDEX_ERR		ReadToc();
	BOOL			ReadFromWinampDB();

private:
	BOOL			ReadWinampDBString( CFile& cFile, CString& strRead );


};

UINT ReadRemoteCDDBThreadFunc( void* pParam, CWnd* pWnd, volatile BOOL& bAbort );
UINT SubmitRemoteCDDBThreadFunc( void* pParam, CWnd* pWnd, volatile BOOL& bAbort );
UINT BatchRemoteCDDBThreadFunc( void* pParam, CWnd* pWnd, volatile BOOL& bAbort );


#endif
