#ifndef ___ECODECOTOOL_H_INCLUDED___
#define ___ECODECOTOOL_H_INCLUDED___

#include <windows.h>
#include <shlobj.h>
#include <Shlwapi.h>
#include <process.h>
#include <streams.h>
#include <dmoreg.h>
#include <dmodshow.h>

#include<vector>
using namespace std;

#include "DShowTool.h"
#include "resource.h"

#define WM_CONVERT     WM_USER+1
#define WM_GRAPHNOTIFY WM_USER+2
#define WAVE_FORMAT_IEEE_FLOAT 0x0003


#define SAFE_RELEASE(p) { if(p!=NULL) { (p)->Release(); (p)=NULL; } }
#define SAFE_FREEMEDIATYPE(p) { if(p!=NULL) { FreeMediaType(*(p)); (p)=NULL; } }

#define FILTER_SOURCE      0
#define FILTER_SPLITTER    0
#define FILTER_DECODEAUDIO 1
#define FILTER_CONVERTWAV  2
#define FILTER_WRITER      3

#define CONTAINER_WAV_SAME_FORMAT     0
#define CONTAINER_WAV_CHANGE_FORMAT   1
#define CONTAINER_MP3_FRAUNHOFER_CBR 10
#define CONTAINER_MP3_LAME_CBR       20
#define CONTAINER_MP3_LAME_VBR       21
#define CONTAINER_OGG_AOTUV_CBR      30
#define CONTAINER_OGG_AOTUV_VBR      31
#define CONTAINER_OGG_LANCER_CBR     40
#define CONTAINER_OGG_LANCER_VBR     41
#define CONTAINER_RAW               100
#define CONTAINER_RAW_AAC           101
#define CONTAINER_RAW_MP2           102
#define CONTAINER_RAW_MP3           103
#define CONTAINER_RAW_OGG           104
#define CONTAINER_RAW_WAV           105


#define OUTPUT_SAME_FOLDER 0
#define OUTPUT_DIFF_FOLDER 1
typedef struct tagVORBISFORMAT
{
	WORD  nChannels;
	long  nSamplesPerSec;
	long  nMinBitsPerSec;
	long  nAvgBitsPerSec;
	long  nMaxBitsPerSec;
	float fQuality;
} VORBISFORMAT;
typedef struct
{
   int nMode;
   int nQuality;

   struct
   {
      DWORD dwBitrate;
   } abr;

   struct
   {
      DWORD dwBitrate;
   } cbr;

   struct
   {
      int nVBRQuality;
      DWORD dwMinBitrate;
      DWORD dwMaxBitrate;
   } vbr;
} LAME_CONFIG, *PLAME_CONFIG;
__interface IEcoDecoInterface : public IUnknown
{
public:
   HRESULT SetWait(int);
   HRESULT GetInFormat(WAVEFORMATEX *);
   HRESULT GetTransformedBytes(LONGLONG *);
};
__interface
IDecodeInterface : public IUnknown
{
public:
   HRESULT GetOutFormat(void *);
   HRESULT SetOutFormat(void *);
};
__interface
IEncodeLameInterface: public IUnknown
{
public:
   HRESULT GetOutFormat(void *);
   HRESULT SetOutFormat(void *);
   HRESULT CheckOutFormat(WAVEFORMATEX *, LAME_CONFIG *);
};
__interface
IConvertWavInterface : public IUnknown
{
public:
   HRESULT GetInFormat(WAVEFORMATEX *);
   HRESULT GetOutFormat(WAVEFORMATEX *);
   HRESULT SetOutFormat(WAVEFORMATEX *);
};
__interface
IEncodeFraunhoferInterface: public IUnknown
{
public:
   HRESULT SetOutFormat(void *);
   HRESULT CheckOutFormat(WAVEFORMATEX *, int *);
};
__interface IEcoDecoWriterInterface : public IUnknown
{
public:
   int GetOutputMode(void);
   void SetOutputMode(int);
};
struct FilterData
{
   HMODULE hDLL;
   CLSID clsid;
};
struct CONVERTDATA
{
   int nContainerFormat;
   int nOutputFolder;
   WCHAR awOutputFolder[MAX_PATH];

   WAVEFORMATEX wf;
   int nCBRVBR;
   float fVBR;
};
class CDirectShow
{
private:
   HRESULT RenderWma(IGraphBuilder *, WCHAR *, IBaseFilter *, bool);
   HRESULT RenderByAllFilter(IGraphBuilder *, WCHAR *, IBaseFilter *, bool);
   HRESULT RenderByFileExt(IGraphBuilder *, WCHAR *, IBaseFilter *, bool);
   HRESULT RenderAudio(IGraphBuilder *, IBaseFilter *, IBaseFilter *, bool);
   IBaseFilter *AddSourceFilter(FilterData *, IGraphBuilder *, WCHAR *, CLSID, WCHAR *);
   IBaseFilter *AddFilter(FilterData *, IGraphBuilder *, WCHAR *, CLSID);

   IGraphBuilder *m_pGraphBuilder;
   IMediaEventEx *m_pMediaEventEx;
   IMediaControl *m_pMediaControl;
   IEcoDecoInterface *m_pEcoDecoInterface;
   LONGLONG m_llTotalBytes;
   WAVEFORMATEX m_InputFormat;
   WAVEFORMATEX m_OutputFormat;

   CDShowTool dshowTool;
   FilterData m_filterData[4];

   int m_nRawFileType;

public:
   CDirectShow();
   ~CDirectShow();

   void Release();
   int PlayEnd(void);
   int GetRawFileType(void);
   int GetPercent(void);
   void SetWait(int);
   void GetFormat(WAVEFORMATEX *, WAVEFORMATEX *);
   bool ConvertToWav(HWND, WCHAR *, WCHAR *, WAVEFORMATEX *, int);
   bool ConvertToFraunhoferMP3(HWND, WCHAR *, WCHAR *, int, int);
   bool ConvertToLameMP3(HWND, WCHAR *, WCHAR *, int, int, int);
   bool ConvertToOgg(HWND, WCHAR *, WCHAR *, int, int, float, int);
   bool ConvertRaw(HWND, WCHAR *, WCHAR *, int);
};
class CConvertDialog
{
private:

   void AddListFromFolder(HWND, WCHAR *);
   void GetInputFileName(HWND);
   void DoEvents(HWND);
   void Convert(HWND);
   void GetOutputFileName(WCHAR *, CONVERTDATA *, WCHAR *);
   bool ConvertStart(HWND, CONVERTDATA *, WCHAR *, WCHAR *, int);
   void ConvertGetPercent(HWND);
   void ConvertExit(HWND);
   void ConvertEnd(HWND, int);

   void InitDialog(HWND);
   void EndDialog(HWND);
   static LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);

   bool m_bExit;
   int m_nCurrentCpuUsage;
   int m_nNewCpuUsage;
   int m_nCurrentNumber;
   int m_nErrorCount;
   int m_nCurrentPercent;
   int m_nConvertState;
   WCHAR m_awCurrentOutputFileName[MAX_PATH];
   vector<std::wstring> m_dropFileList;
   vector<std::wstring> m_inputFileList;
   CONVERTDATA m_convertData;
   CDirectShow *m_pDirectShow;

public:
   CConvertDialog();
   ~CConvertDialog();
   void Show(CONVERTDATA *, vector<std::wstring>);
};
class CCustomMainDialog
{
private:
   HRGN m_hRgn;

public:
   CCustomMainDialog();
   void Paint(HDC);
   void DrawCustomRoundRect(HDC, RECT *);
   void CreateRgnWindow(HWND);
   void DeleteRgnWindow(void);
   void MeasureItem(HWND, MEASUREITEMSTRUCT *);
   void DrawHoverButton(DRAWITEMSTRUCT *, int);
   void DrawItem(DRAWITEMSTRUCT *);
};
class CMainDialog
{
   friend class CCustomMainDialog;

private:
   bool ExistsFraunhoferPro(void);
   bool ExistsLameEnc(void);
   void SelectComboBox(HWND, int);
   void SelectFolder(HWND);
   void LoadSetting(HWND);
   void SaveSetting(HWND);
   bool DropFiles(HWND, HDROP);
   static int CALLBACK SHBrowseProc(HWND, UINT, LPARAM, LPARAM);
   static LRESULT CALLBACK LinkLabelProc(HWND, UINT, WPARAM, LPARAM);
   static LRESULT CALLBACK ButtonProc(HWND, UINT, WPARAM, LPARAM);
   static LRESULT CALLBACK DialogWaveFormatProc(HWND, UINT, WPARAM, LPARAM);
   static LRESULT CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
   void InitDialog(HWND);
   void EndDialog(HWND);

   WNDPROC m_defButtonMinProc;
   WNDPROC m_defButtonCloseProc;
   WNDPROC m_defButtonHelpProc;
   WNDPROC m_defLinkLabelFraunhoferProc;
   WNDPROC m_defLinkLabelLameProc;
   WNDPROC m_defButtonDropFileHelpProc;
   int m_nMinResourceID;
   int m_nCloseResourceID;
   int m_nAlpha;
   WAVEFORMATEX m_waveFormat;
   CONVERTDATA m_convertData;
   vector<std::wstring> m_dropList;
   bool m_bExistsFraunhoferPro;
   bool m_bExistsLameEnc;
   CCustomMainDialog customMainDialog;

public:
   CMainDialog();
   ~CMainDialog();
   bool Show(CONVERTDATA *, vector<std::wstring> *);
};


#endif ___ECODECOTOOL_H_INCLUDED___
