/**************************************************************************
 * Copyright (C) 2008 Cocha                                               *
 * http://sourceforge.jp/projects/ecodecotool/                            *
 *                                                                        *
 *  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, 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 GNU Make; see the file COPYING.  If not, write to          *
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *
 *                                                                        *
 **************************************************************************/

#include "EcoDecoTooL.h"

#define DW 248 
#define DH 128 

#define TIMERID_DROPFILE 1
#define TIMERID_CONVERT  2


struct RESOURCEDATA
{
   int nResourceID;
   WCHAR *pwCaption[sizeof_LANGUAGE];
};

struct ERRORMESSAGE
{
   WCHAR *pwCaption[sizeof_LANGUAGE];
};

struct LOCALEDATA
{
   RESOURCEDATA resourceData[21];
};


static ERRORMESSAGE g_localMessage[3] =
{
   L"Failed to Initialize",
   L"初期化に失敗しました",

   L"Failed to Convert",
   L"変換できませんでした",

   L"Same as Input",
   L"入力と同じ"
};

static LOCALEDATA g_localeData =
{
   IDC_CONVERT_STATIC_TITLE,
   L"%s Converting",
   L"%s 変換中",

   IDC_CONVERT_STATIC_TITLE,
   L"%s Analyzing Volume",
   L"%s 音量調査中",

   IDC_CONVERT_COMBO_CPU,
   L"CPU Usage : Lowest;CPU Usage : Low;CPU Usage : Middle;CPU Usage : High;CPU Usage : Highest",
   L"CPU使用率 : 最低;CPU使用率 : 低い;CPU使用率 : 普通;CPU使用率 : 高い;CPU使用率 : 最高",

   IDC_CONVERT_STATIC_SUCCESS,
   L"Success : %d",
   L"成功 : %d",

   IDC_CONVERT_STATIC_FAILURE,
   L"Failure : %d",
   L"失敗 : %d",

   IDC_CONVERT_STATIC_INPUT_FILENAME,
   L"Input File : %s",
   L"入力ファイル : %s",

   IDC_CONVERT_STATIC_INPUT_FORMAT,
   L"Input Format : %s",
   L"入力音質 : %s",

   IDC_CONVERT_STATIC_OUTPUT_FOLDER,
   L"Output Folder : %s",
   L"出力フォルダ : %s",

   IDC_CONVERT_STATIC_OUTPUT_FORMAT,
   L"Output Format : %s",
   L"出力音質 : %s",
};

static const POINT g_apRgn[] =
{
               {   1,   7},{   1,   5},{   2,   4},{   2,   3},{   3,   2},{   4,   2},{   5,   1},{   7,   1},{   8,   0},
   {DW-8,   0},{DW-7,   1},{DW-5,   1},{DW-4,   2},{DW-3,   2},{DW-2,   3},{DW-2,   4},{DW-1,   5},{DW-1,   7},{  DW,   8},
   {  DW,DH-9},{DW-1,DH-8},{DW-1,DH-6},{DW-2,DH-5},{DW-2,DH-4},{DW-4,DH-2},{DW-5,DH-2},{DW-6,DH-1},{DW-8,DH-1},{DW-9,  DH},
   {   9,DH  },{   8,DH-1},{   6,DH-1},{   5,DH-2},{   4,DH-2},{   2,DH-4},{   2,DH-5},{   1,DH-6},{   1,DH-8},{   0,DH-9},
   {   0,   8}
};

static const POINT g_apFrame1[] =
{
               {   1,   7},{   1,   5},{   2,   4},{   2,   3},{   3,   2},{   4,   2},{   5,   1},{   7,   1},{   8,   0},
   {DW-9,   0},{DW-8,   1},{DW-6,   1},{DW-5,   2},{DW-4,   2},{DW-3,   3},{DW-3,   4},{DW-2,   5},{DW-2,   7},{DW-1,   8},
   {DW-1,DH-9},{DW-2,DH-8},{DW-2,DH-6},{DW-3,DH-5},{DW-3,DH-4},{DW-4,DH-3},{DW-5,DH-3},{DW-6,DH-2},{DW-8,DH-2},{DW-9,DH-1},
   {   8,DH-1},{   7,DH-2},{   5,DH-2},{   4,DH-3},{   3,DH-3},{   2,DH-4},{   2,DH-5},{   1,DH-6},{   1,DH-8},{   0,DH-9},
   {   0,   7}
};

static const POINT g_apFrame2[] =
{
               {   2,   7},{   2,   5},{   3,   4},{   3,   3},{   4,   3},{   5,   2},{   7,   2},{   8,   1},
   {DW-9,   1},{DW-8,   2},{DW-6,   2},{DW-5,   3},{DW-4,   3},{DW-4,   4},{DW-3,   5},{DW-3,   7},{DW-2,   8},
   {DW-2,DH-9},{DW-3,DH-8},{DW-3,DH-6},{DW-4,DH-5},{DW-4,DH-4},{DW-5,DH-4},{DW-6,DH-3},{DW-8,DH-3},{DW-9,DH-2},
   {   8,DH-2},{   7,DH-3},{   5,DH-3},{   4,DH-4},{   3,DH-4},{   3,DH-5},{   2,DH-6},{   2,DH-8},{   1,DH-9},
   {   1,   7}
};

static const POINT g_apFrame3[] =
{
               {   3,   7},{   3,   5},{   5,   3},{   7,   3},{   8,   2},
   {DW-9,   2},{DW-8,   3},{DW-6,   3},{DW-4,   5},{DW-4,   7},{DW-3,   8},
   {DW-3,DH-9},{DW-4,DH-8},{DW-4,DH-6},{DW-6,DH-4},{DW-8,DH-4},{DW-9,DH-3},
   {   8,DH-3},{   7,DH-4},{   5,DH-4},{   3,DH-6},{   3,DH-8},{   2,DH-9},
   {   2,   7}
};

static CConvertDialog *g_pMyClass = NULL; 

CConvertDialog::CConvertDialog()
{
   
   g_pMyClass = this;
   m_pConvert = NULL;
   m_pInputLinkedList = NULL;

   m_hRgn = NULL;
   m_nMinResourceID = IDB_BITMAP_MIN1;
   m_nCloseResourceID = IDB_BITMAP_CLOSE1;

   m_nCurrentPercent = 0;
   m_nAnimationCount = 0;
   m_nSuccessCount = 0;
   m_nErrorCount = 0;

   m_nCurrentCpuUsage = 4;
   m_nNewCpuUsage = 4;
 
   m_bGraphNotify = false;

   ::ZeroMemory(&m_convertData, sizeof(m_convertData));
}

CConvertDialog::~CConvertDialog()
{
   SAFE_DELETEOBJECT(m_hRgn);

   SAFE_DELETE(m_pInputLinkedList);
   SAFE_DELETE(m_pConvert);
}






void CConvertDialog::GetSubString(WCHAR *pwItem, WCHAR *pwLine, int nCount)
{  

   int i, n, nStartPos, nEndPos, nLength;

   n = 1;
   nStartPos = 0;
   nEndPos = 0;
   nLength = ::lstrlen(pwLine);

   for(i=0;i<nLength;i++)
   {
      if(pwLine[i] == ';')
      {
         n++;

         if(n == nCount)
            nStartPos = i + 1;

         if(n == (nCount + 1))
         {
            nEndPos = i - 1;
            break;
         }
      }
   }

   if(nStartPos == 0 && nEndPos == 0)
   {
      pwItem[0] = '\0';
      return;
   }

   if(i == nLength)
      nEndPos = i;

   for(i=0;i<=(nEndPos - nStartPos);i++)
      pwItem[i] = pwLine[nStartPos + i];

   pwItem[i] = '\0';
}

void CConvertDialog::AddListFromFolder(HWND hWnd, WCHAR *pwFilePath)
{  

   HANDLE handle = NULL;
   WIN32_FIND_DATA find_data;
   WCHAR szSearch[MAX_PATH], awInputFileName[MAX_PATH];
   WCHAR awPath[MAX_PATH];

   
   ::lstrcpy(awPath, pwFilePath);

   
   if(awPath[::lstrlen(awPath)-1] != '\\')
      ::lstrcat(awPath, L"\\");

   
   ::lstrcpy(szSearch, awPath);
   ::lstrcat(szSearch, L"*.*");

   
   handle = ::FindFirstFile(szSearch, &find_data);

   if (handle == INVALID_HANDLE_VALUE)
   {
      if(handle != NULL)
         ::FindClose(handle);

      return;
   }

   do
   {
      
      if(m_bExit == true)
      {
         ::FindClose(handle);
         return;
      }

      if(::lstrcmp(find_data.cFileName, L".") == 0 ||
         ::lstrcmp(find_data.cFileName, L"..") == 0)
      {  
      }
      else if( (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) !=0)
      {  

         WCHAR awNextFolder[MAX_PATH];
         ::wsprintf(awNextFolder, L"%s%s", awPath, find_data.cFileName);

         if(::PathIsSystemFolder(awNextFolder, 0) == FALSE)
            AddListFromFolder(hWnd, awNextFolder);
      }
      else
      {  

         ::lstrcpy(awInputFileName, awPath);
         ::lstrcat(awInputFileName, find_data.cFileName);

         
         m_pInputLinkedList->AddList(awInputFileName);

         if(m_pInputLinkedList->GetCount() % 100 == 0)
         {  
            WCHAR awText[32];
            ::wsprintf(awText, L"[0/%d]", m_pInputLinkedList->GetCount());
            ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText);
            ::InvalidateRect(hWnd, NULL, TRUE);

         }
      }
   } while (::FindNextFile(handle, &find_data));

   ::FindClose(handle);
}

void CConvertDialog::DropFiles(HWND hWnd)
{  

   WCHAR awText[32];
   WCHAR *pwText = NULL;

   
   m_pDropLinkedList->SetFirstList();
   m_pInputLinkedList->SetFirstList();

   
   while(true)
   {
      pwText = m_pDropLinkedList->GetNextText();
      if(pwText == NULL)
         break;

      if(::PathIsDirectory(pwText) == FALSE)
      {  

         
         m_pInputLinkedList->AddList(pwText);

         if(m_pInputLinkedList->GetCount() % 100 == 0)
         {  
            ::wsprintf(awText, L"[0/%d]", m_pInputLinkedList->GetCount());
            ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText);
            ::InvalidateRect(hWnd, NULL, TRUE);

         }
      }
      else
      {  
         AddListFromFolder(hWnd, pwText);
      }

      
      if(m_bExit == true)
         return;
   }

   
   ::wsprintf(awText, L"[0/%d]", m_pInputLinkedList->GetCount());
   ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText);
   ::InvalidateRect(hWnd, NULL, TRUE);

}

void CConvertDialog::ConvertExit(HWND hWnd)
{  

   m_bExit = true;

   
   ::KillTimer(hWnd, TIMERID_DROPFILE);
   ::KillTimer(hWnd, TIMERID_CONVERT);

   
   ::Sleep(200);

   
   m_pConvert->ConvertExit();
}

void CConvertDialog::ConvertStart(HWND hWnd)
{  

   WCHAR *pwInputFileName = NULL;
   int nStartState = m_nConvertState;

   
   if(m_nConvertState == STATE_START_NEXTFILE)
   {
      pwInputFileName = m_pInputLinkedList->GetNextText();

      
      WCHAR awText1[MAX_PATH];
      ::wsprintf(awText1, g_localeData.resourceData[5].pwCaption[m_nLanguage], ::PathFindFileName(pwInputFileName));
      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_INPUT_FILENAME, awText1);
   }
   else 
      pwInputFileName = m_pInputLinkedList->GetCurrentText();

   
   m_nCurrentPercent = -1;

   
   WCHAR awOutputFolder[MAX_PATH];

   if(m_settingData.nOutputFolder == 0)
   {
      ::lstrcpy(awOutputFolder, pwInputFileName);
      ::PathRemoveFileSpec(awOutputFolder);
   }
   else  
      ::lstrcpy(awOutputFolder, m_settingData.awOutputFolder);

   m_nConvertState = m_pConvert->ConvertStart(hWnd, pwInputFileName, awOutputFolder, &m_convertData, m_nCurrentCpuUsage);



   if(m_nConvertState == STATE_CONVERTING)
   {  

      WCHAR awText1[MAX_PATH];

      if(nStartState == STATE_START_NEXTFILE)
      {  

         
         WCHAR awInputFormat[32], awOutputFormat[32];
         m_pConvert->GetFormat(awInputFormat, awOutputFormat);

         
         ::wsprintf(awText1, g_localeData.resourceData[6].pwCaption[m_nLanguage], awInputFormat);
         ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_INPUT_FORMAT, awText1);

         
         ::wsprintf(awText1, g_localeData.resourceData[8].pwCaption[m_nLanguage], awOutputFormat);
         ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_OUTPUT_FORMAT, awText1);
      }

      
      WCHAR awText2[64];

      if(m_settingData.nContainerType == CONTAINER_AAC && m_convertData.bUseFrontEnd == true)
      {
         ::wsprintf(awText1, L"[%d/%d] NecoAacEnc", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());
         ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 
      }
      else
      {
         if(m_settingData.nContainerType == CONTAINER_RAW)
            ::wsprintf(awText1, L"[%d/%d]", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());
         else
         {
            ::wsprintf(awText1, L"[%d/%d]   0%%", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());
            m_nCurrentPercent = 0;
         }

         if(m_convertData.bNormalize == true)
            ::wsprintf(awText2, g_localeData.resourceData[1].pwCaption[m_nLanguage], awText1); 
         else
            ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 
      }

      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText2);
      ::SetWindowText(hWnd, awText2);
   }
   else
   {  
      WCHAR awText1[32];
      ::wsprintf(awText1, L"[%d/%d]", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());
      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText1);
      ::SetWindowText(hWnd, awText1);

      
      ::wsprintf(awText1, g_localeData.resourceData[6].pwCaption[m_nLanguage], L"-");
      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_INPUT_FORMAT, awText1);

      
      ::wsprintf(awText1, g_localeData.resourceData[8].pwCaption[m_nLanguage], L"-");
      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_OUTPUT_FORMAT, awText1);
   }
}

void CConvertDialog::Converting(HWND hWnd)
{  

   if(m_nNewCpuUsage != m_nCurrentCpuUsage)
   {  
      m_pConvert->SetWait(m_nNewCpuUsage);
      m_nCurrentCpuUsage = m_nNewCpuUsage;
   }

   int nPercent = -1;

   
   m_nConvertState = m_pConvert->Converting(&nPercent);

   if(0 < nPercent)
   {  
      if(nPercent != m_nCurrentPercent)
      {  
         WCHAR awText1[64], awText2[64];
         ::wsprintf(awText1, L"[%d/%d] %3d%%", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount(), nPercent);

         if(m_convertData.bNormalize == true)
            ::wsprintf(awText2, g_localeData.resourceData[1].pwCaption[m_nLanguage], awText1); 
         else
            ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 

         ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText2);
         ::SetWindowText(hWnd, awText2);
   
         m_nCurrentPercent = nPercent;
      }
   }
   else
   {  
      

      m_nAnimationCount++;
      if(8 <= m_nAnimationCount)
         m_nAnimationCount = 0;

      if((m_nAnimationCount % 2) == 1)
      {
         WCHAR awText1[64], awText2[64];

         if(m_settingData.nContainerType == CONTAINER_AAC && m_convertData.bUseFrontEnd == true)
         {
            ::wsprintf(awText1, L"[%d/%d] NecoAacEnc", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());
            ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 

            for(int i=0;i<m_nAnimationCount/2;i++)
               ::lstrcat(awText2, L".");

            ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText2);
            ::SetWindowText(hWnd, awText2);
         }
         else
         {
            WCHAR awText1[64], awText2[64];
            ::wsprintf(awText1, L"[%d/%d]", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount(), nPercent);

            if(m_convertData.bNormalize == true)
               ::wsprintf(awText2, g_localeData.resourceData[1].pwCaption[m_nLanguage], awText1); 
            else
               ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 

            for(int i=0;i<m_nAnimationCount/2;i++)
               ::lstrcat(awText2, L".");

            ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText2);
            ::SetWindowText(hWnd, awText2);
         }
      }
   }
}

void CConvertDialog::ConvertEnd(HWND hWnd)
{  

   if(m_nConvertState == STATE_END_SUCCESS)
   {  

      if(0 <= m_nCurrentPercent)
      {  
         WCHAR awText1[64], awText2[64];

         ::wsprintf(awText1, L"[%d/%d] 100%%", m_nSuccessCount + m_nErrorCount + 1, m_pInputLinkedList->GetCount());

         if(m_convertData.bNormalize == true)
            ::wsprintf(awText2, g_localeData.resourceData[1].pwCaption[m_nLanguage], awText1); 
         else
            ::wsprintf(awText2, g_localeData.resourceData[0].pwCaption[m_nLanguage], awText1); 

         ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, awText2);
         ::SetWindowText(hWnd, awText2);
      }
      else
      {
         m_nAnimationCount = 0;
      }

      
      m_nConvertState = m_pConvert->ConvertEnd(&m_convertData);

      if(m_nConvertState == STATE_START_NEXTFILE)
      {
         m_nSuccessCount++;

         if(m_convertData.nGainMode == GAIN_TRACK_NORMALIZE)
            m_convertData.bNormalize = true;

         if(m_convertData.nGainMode != GAIN_ALBUM_NORMALIZE)
            m_convertData.nPass = 1;

         
         WCHAR awText[32];
         ::wsprintf(awText, g_localeData.resourceData[3].pwCaption[m_nLanguage], m_nSuccessCount);
         ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_SUCCESS, awText);
      }
      else 
      {
         if(m_convertData.nGainMode == GAIN_TRACK_NORMALIZE)
            m_convertData.bNormalize = false;

         if(m_convertData.nGainMode != GAIN_ALBUM_NORMALIZE)
            m_convertData.nPass++;
      }
   }

   if(m_nConvertState == STATE_END_ERROR)
   {  
      
      m_pConvert->ConvertExit();
      m_nErrorCount++;

      
      WCHAR awText[32];
      ::wsprintf(awText, g_localeData.resourceData[4].pwCaption[m_nLanguage], m_nErrorCount);
      ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_FAILURE, awText);

      
      m_nConvertState = STATE_START_NEXTFILE;
      m_convertData.nPass = 1;

      if(m_convertData.nGainMode == GAIN_TRACK_NORMALIZE)
         m_convertData.bNormalize = true;
   }

   if( (m_nSuccessCount + m_nErrorCount) == m_pInputLinkedList->GetCount() )
   {  

      if(m_nSuccessCount == 0)
      {  

         m_bExit = true;
         ::KillTimer(hWnd, TIMERID_CONVERT);

         ::MessageBox(hWnd, g_localMessage[1].pwCaption[m_nLanguage], L"EcoDecoTooL error", MB_OK);

         
         OnClose(hWnd);
         ::EndDialog(hWnd, IDOK);
      }
      else if(m_convertData.nGainMode == GAIN_ALBUM_NORMALIZE && m_convertData.bNormalize == true)
      {  

         
         m_pInputLinkedList->SetFirstList();
         m_nConvertState = STATE_START_NEXTFILE;
         m_convertData.nPass = 2;
         m_convertData.bNormalize = false;
         m_convertData.dNormalize = ::pow(10.0, m_convertData.dAlbumGain / 20.0);

         
         m_nSuccessCount = 0;
         m_nErrorCount = 0;
      }
      else
      {
         if(m_convertData.nGainMode == GAIN_ALBUM_GAIN)
         {  

            WCHAR *pwInputFileName = NULL;

            m_pInputLinkedList->SetFirstList();

            for(int i=0;i<m_pInputLinkedList->GetCount();i++)
            {
               pwInputFileName = m_pInputLinkedList->GetNextText();

               if(pwInputFileName != NULL)
               {
                  WCHAR awOutputFolder[MAX_PATH];

                  if(m_settingData.nOutputFolder == 0)
                  {
                     ::lstrcpy(awOutputFolder, pwInputFileName);
                     ::PathRemoveFileSpec(awOutputFolder);
                  }
                  else  
                     ::lstrcpy(awOutputFolder, m_settingData.awOutputFolder);

                  m_pConvert->WriteAlbumGain(pwInputFileName, awOutputFolder, m_convertData.dAlbumPeak, m_convertData.dAlbumGain);

               }
            }
         }

         m_bExit = true;
         ::KillTimer(hWnd, TIMERID_CONVERT);

         


         
         BOOL bSoundPlay = FALSE;
         WCHAR awFileName[MAX_PATH];
         ::GetModuleFileName(NULL, awFileName, MAX_PATH);
         ::PathRemoveFileSpec(awFileName);
         ::lstrcat(awFileName, L"\\end.wav");

         if(::PathFileExists(awFileName) != FALSE)
         {
            bSoundPlay = ::PlaySound(awFileName, NULL, SND_FILENAME | SND_ASYNC);
         }

         
         for(int i=0;i<4;i++)
         {
            ::FlashWindow(hWnd, TRUE);
            ::Sleep(500);
            ::FlashWindow(hWnd, FALSE);
         }

         
         if(bSoundPlay != FALSE)
         {
            ::PlaySound(NULL, NULL, 0);
            ::Sleep(100);
         }

         
         OnClose(hWnd);
         ::EndDialog(hWnd, IDOK);
      }
   }
}

void CConvertDialog::DrawCustomRoundRect(HDC hDC, RECT *pRect)
{
   RECT r;
   HPEN hPen;

   ::SetRect(&r, pRect->left+1, pRect->top+5, pRect->right-1, pRect->bottom-4);
   ::FillRect(hDC, &r, (HBRUSH)::GetStockObject(WHITE_BRUSH));

   hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
   ::SelectObject(hDC, hPen);
   ::MoveToEx(hDC, pRect->left+5, pRect->top+1, NULL); ::LineTo(hDC, pRect->right-5, pRect->top+1);
   ::MoveToEx(hDC, pRect->left+3, pRect->top+2, NULL); ::LineTo(hDC, pRect->right-3, pRect->top+2);
   ::MoveToEx(hDC, pRect->left+2, pRect->top+3, NULL); ::LineTo(hDC, pRect->right-2, pRect->top+3);
   ::MoveToEx(hDC, pRect->left+2, pRect->top+4, NULL); ::LineTo(hDC, pRect->right-2, pRect->top+4);
   ::MoveToEx(hDC, pRect->left+2, pRect->bottom-4, NULL); ::LineTo(hDC, pRect->right-2, pRect->bottom-4);
   ::MoveToEx(hDC, pRect->left+2, pRect->bottom-3, NULL); ::LineTo(hDC, pRect->right-2, pRect->bottom-3);
   ::MoveToEx(hDC, pRect->left+3, pRect->bottom-2, NULL); ::LineTo(hDC, pRect->right-3, pRect->bottom-2);
   ::MoveToEx(hDC, pRect->left+5, pRect->bottom-1, NULL); ::LineTo(hDC, pRect->right-5, pRect->bottom-1);
   ::DeleteObject(hPen);

   hPen = CreatePen(PS_SOLID, 1, RGB(235, 235, 235));
   ::SelectObject(hDC, hPen);
   ::MoveToEx(hDC, pRect->left+5, pRect->top, NULL);

   ::LineTo(hDC, pRect->right-5, pRect->top);
   ::LineTo(hDC, pRect->right-4, pRect->top+1);
   ::LineTo(hDC, pRect->right-3, pRect->top+1);
   ::LineTo(hDC, pRect->right-1, pRect->top+3);
   ::LineTo(hDC, pRect->right-1, pRect->top+4);
   ::LineTo(hDC, pRect->right,   pRect->top+5);
   ::LineTo(hDC, pRect->right,   pRect->bottom-5);
   ::LineTo(hDC, pRect->right-1, pRect->bottom-4);
   ::LineTo(hDC, pRect->right-1, pRect->bottom-3);
   ::LineTo(hDC, pRect->right-3, pRect->bottom-1);
   ::LineTo(hDC, pRect->right-4, pRect->bottom-1);
   ::LineTo(hDC, pRect->right-5, pRect->bottom);
   ::LineTo(hDC, pRect->left+5,  pRect->bottom);
   ::LineTo(hDC, pRect->left+4,  pRect->bottom-1);
   ::LineTo(hDC, pRect->left+3,  pRect->bottom-1);
   ::LineTo(hDC, pRect->left+1,  pRect->bottom-3);
   ::LineTo(hDC, pRect->left+1,  pRect->bottom-4);
   ::LineTo(hDC, pRect->left,    pRect->bottom-5);
   ::LineTo(hDC, pRect->left,    pRect->top+5);
   ::LineTo(hDC, pRect->left+1,  pRect->top+4);
   ::LineTo(hDC, pRect->left+1,  pRect->top+3);
   ::LineTo(hDC, pRect->left+3,  pRect->top+1);
   ::LineTo(hDC, pRect->left+4,  pRect->top+1);
   ::LineTo(hDC, pRect->left+5,  pRect->top);

   ::DeleteObject(hPen); 
}

void CConvertDialog::DrawItem(DRAWITEMSTRUCT *pDrawItem)
{
   if(pDrawItem->CtlType == ODT_COMBOBOX)
   {
      if(pDrawItem->itemState & ODS_SELECTED)
      {
         RECT r;
         int i, color;
         HBRUSH hBrush = NULL;

         double dx = (pDrawItem->rcItem.right - pDrawItem->rcItem.left - 4) / 30.0;
         double dc = (255.0-220.0) / 30.0;

         for(i=0;i<=30;i++)
         {
            color = 220 + (int)(i*dc);

            ::SetRect(&r, 2+int(i*dx), pDrawItem->rcItem.top, 2+int((i+1)*dx), pDrawItem->rcItem.bottom);

            hBrush = ::CreateSolidBrush(RGB(color,color,color));
            ::FillRect(pDrawItem->hDC, &r, hBrush);
            SAFE_DELETEOBJECT(hBrush);
         }

         HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
         ::SelectObject(pDrawItem->hDC, hPen);

         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.top, NULL);
         ::LineTo(pDrawItem->hDC, 6, pDrawItem->rcItem.top);
         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.top+1, NULL);
         ::LineTo(pDrawItem->hDC, 4, pDrawItem->rcItem.top+1);
         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.top+2, NULL);
         ::LineTo(pDrawItem->hDC, 2, pDrawItem->rcItem.top+4);

         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.bottom-4, NULL);
         ::LineTo(pDrawItem->hDC, 2, pDrawItem->rcItem.bottom-2);
         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.bottom-2, NULL);
         ::LineTo(pDrawItem->hDC, 4, pDrawItem->rcItem.bottom-2);
         ::MoveToEx(pDrawItem->hDC, 2, pDrawItem->rcItem.bottom-1, NULL);
         ::LineTo(pDrawItem->hDC, 6, pDrawItem->rcItem.bottom-1);

         SAFE_DELETEOBJECT(hPen);
      }
      else
      {
         ::FillRect(pDrawItem->hDC, &pDrawItem->rcItem, (HBRUSH)GetStockObject(WHITE_BRUSH));
      }

      ::SetBkMode(pDrawItem->hDC, TRANSPARENT);
      ::SetTextColor(pDrawItem->hDC, RGB(0,0,0));

      RECT r;
      ::SetRect(&r, pDrawItem->rcItem.left+4, pDrawItem->rcItem.top, pDrawItem->rcItem.right-2, pDrawItem->rcItem.bottom);

      WCHAR awItem[256];
      ::SendMessage(pDrawItem->hwndItem, CB_GETLBTEXT, pDrawItem->itemID, (LPARAM)awItem);
      ::DrawText(pDrawItem->hDC, awItem, -1, &r, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
   }
}

void CConvertDialog::DrawHoverButton(DRAWITEMSTRUCT *pDrawItem, int nResourceID)
{
   HDC hmDC;
   HBITMAP hBitmap = NULL;

   hBitmap = ::LoadBitmap(::GetModuleHandle(NULL), MAKEINTRESOURCE(nResourceID));

   if(hBitmap != NULL)
   {
      hmDC = ::CreateCompatibleDC(pDrawItem->hDC);
      ::SelectObject(hmDC, hBitmap);
      ::BitBlt(pDrawItem->hDC, 0, 0, 16, 14, hmDC, 0, 0, SRCCOPY);
      ::DeleteDC(hmDC);
      ::DeleteObject(hBitmap);
   }
}

void CConvertDialog::OnPaint(HDC hDC)
{
   RECT r;

   int i, color;

   double dx = DW / 50.0;
   double dc = (240.0-210.0) / 50.0;

   HBRUSH hBrush;

   for(i=0;i<=50;i++)
   {
      color = 210 + (int)(i*dc);

      ::SetRect(&r, int(i*dx), 0, int((i+1)*dx), DH);
      hBrush = ::CreateSolidBrush(RGB(color,color,color));
      ::FillRect(hDC, &r, hBrush);
      ::DeleteObject(hBrush); 
   }

   ::SetRect(&r, 0, 0, DW, 20);
   hBrush = ::CreateSolidBrush(RGB(255,255,255));
   ::FillRect(hDC, &r, hBrush);
   ::DeleteObject(hBrush); 

   HPEN hPen;

   hPen = CreatePen(PS_SOLID, 1, RGB(206, 206, 206));
   ::SelectObject(hDC, hPen);
   ::Polyline(hDC, g_apFrame1, 40);
   ::Polyline(hDC, g_apFrame2, 40);
   ::DeleteObject(hPen); 

   hPen = CreatePen(PS_SOLID, 1, RGB(230, 230, 230));
   ::SelectObject(hDC, hPen);
   ::Polyline(hDC, g_apFrame3, 24);

   ::MoveToEx(hDC, 5, 4, NULL);
   ::LineTo(hDC, DW-5, 4);

   ::MoveToEx(hDC, 4, 19, NULL);
   ::LineTo(hDC, DW-4, 19);

   ::DeleteObject(hPen); 

   hPen = CreatePen(PS_SOLID, 1, RGB(239, 239, 239));
   ::SelectObject(hDC, hPen);
   ::MoveToEx(hDC, 8, 3, NULL);
   ::LineTo(hDC, DW-8, 3);

   ::MoveToEx(hDC, 3, 21, NULL);
   ::LineTo(hDC, 3, DH-9);

   ::DeleteObject(hPen); 

   hPen = CreatePen(PS_SOLID, 1, RGB(235, 235, 235));
   ::SelectObject(hDC, hPen);
   ::MoveToEx(hDC, 4, 5, NULL);
   ::LineTo(hDC, DW-4, 5);
   ::DeleteObject(hPen); 

   hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
   ::SelectObject(hDC, hPen);
   ::MoveToEx(hDC, 3, 20, NULL);
   ::LineTo(hDC, DW-3, 20);
   ::DeleteObject(hPen); 

   ::SetRect(&r, 155, 26, 240, 52);
   DrawCustomRoundRect(hDC, &r);

   ::SetRect(&r, 18, 56, 240, 86);
   DrawCustomRoundRect(hDC, &r);

   ::SetRect(&r, 18, 90, 240, 120);
   DrawCustomRoundRect(hDC, &r);
}

void CConvertDialog::OnCreate(HWND hWnd)
{  

   WCHAR awText[64];

   
   m_nConvertState = STATE_START_NEXTFILE;

   
   WCHAR awIniFileName[MAX_PATH];
   ::GetModuleFileName(NULL, awIniFileName, MAX_PATH);
   ::PathRemoveFileSpec(awIniFileName);
   ::lstrcat(awIniFileName, TEXT("\\EcoDecoTooL.ini"));

   int nMinimize;
   POINT p;
   RECT r1, r2;

   p.x = (int)::GetPrivateProfileInt(L"ConvertDialog", L"WindowLeft", -10, awIniFileName);
   p.y = (int)::GetPrivateProfileInt(L"ConvertDialog", L"WindowTop", -10, awIniFileName);
   nMinimize = (int)::GetPrivateProfileInt(L"ConvertDialog", L"WindowMinimize", 0, awIniFileName);



   
   ::SystemParametersInfo(SPI_GETWORKAREA, 0, &r1, 0);
   ::GetWindowRect(hWnd, &r2);

   if(p.x < 0)
      p.x = 0;
   else if( ((r1.right- r1.left) - (r2.right - r2.left)) < p.x)
      p.x = (r1.right- r1.left) - (r2.right - r2.left);

   if(p.y < 0)
      p.y = 0;
   else if( ((r1.bottom- r1.top) - (r2.bottom - r2.top)) < p.y)
      p.y = (r1.bottom- r1.top) - (r2.bottom - r2.top);

   
   ::SendMessage(::GetDlgItem(hWnd, IDC_CONVERT_COMBO_CPU), CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)13);

   for(int i=0;i<5;i++)
   {
      GetSubString(awText, g_localeData.resourceData[2].pwCaption[m_nLanguage], i+1);
      ::SendMessage(::GetDlgItem(hWnd, g_localeData.resourceData[2].nResourceID), CB_ADDSTRING, 0, (LPARAM)awText);
   }

   m_nCurrentCpuUsage = (int)::GetPrivateProfileInt(L"ConvertDialog", L"CpuUsage", 4, awIniFileName);
   if(m_nCurrentCpuUsage < 0 || 5 < m_nCurrentCpuUsage) m_nCurrentCpuUsage = 4;
   m_nNewCpuUsage = m_nCurrentCpuUsage;
   ::SendMessage(::GetDlgItem(hWnd, IDC_CONVERT_COMBO_CPU), CB_SETCURSEL, (WPARAM)m_nCurrentCpuUsage, (LPARAM)0);

   ::SystemParametersInfo(SPI_GETWORKAREA, 0, &r1, 0);
   ::GetWindowRect(hWnd, &r2);

   if(p.x < 0)
      p.x = 0;
   else if( ((r1.right- r1.left) - (r2.right - r2.left)) < p.x)
      p.x = (r1.right- r1.left) - (r2.right - r2.left);

   if(p.y < 0)
      p.y = 0;
   else if( ((r1.bottom- r1.top) - (r2.bottom - r2.top)) < p.y)
      p.y = (r1.bottom- r1.top) - (r2.bottom - r2.top);

   
   if(nMinimize == 1)
   {  
      ::SetWindowPos(hWnd, HWND_TOP, p.x, p.y, 0, 0, SWP_NOSIZE);
      ::ShowWindow(hWnd, SW_MINIMIZE);
      ::UpdateWindow(hWnd);
   }
   else
   {
      ::SetWindowPos(hWnd, HWND_TOPMOST, p.x, p.y, 0, 0, SWP_NOSIZE);
      ::SetForegroundWindow(hWnd);
      ::ShowWindow(hWnd, SW_SHOW);
      ::UpdateWindow(hWnd);
   }








   











   ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_TITLE, L"[0/0]");

   ::wsprintf(awText, g_localeData.resourceData[3].pwCaption[m_nLanguage], 0);
   ::SetDlgItemText(hWnd, g_localeData.resourceData[3].nResourceID, awText);

   ::wsprintf(awText, g_localeData.resourceData[4].pwCaption[m_nLanguage], 0);
   ::SetDlgItemText(hWnd, g_localeData.resourceData[4].nResourceID, awText);

   ::wsprintf(awText, g_localeData.resourceData[5].pwCaption[m_nLanguage], L"-");
   ::SetDlgItemText(hWnd, g_localeData.resourceData[5].nResourceID, awText);

   ::wsprintf(awText, g_localeData.resourceData[6].pwCaption[m_nLanguage], L"-");
   ::SetDlgItemText(hWnd, g_localeData.resourceData[6].nResourceID, awText);

   ::wsprintf(awText, g_localeData.resourceData[7].pwCaption[m_nLanguage], L"-");
   ::SetDlgItemText(hWnd, g_localeData.resourceData[7].nResourceID, awText);

   ::wsprintf(awText, g_localeData.resourceData[8].pwCaption[m_nLanguage], L"-");
   ::SetDlgItemText(hWnd, g_localeData.resourceData[8].nResourceID, awText);

   
   m_myProc[0] = (WNDPROC)::GetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_MIN), GWL_WNDPROC);
   ::SetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_MIN), GWL_WNDPROC, (LONG)CustomProc);

   m_myProc[1] = (WNDPROC)::GetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_CLOSE), GWL_WNDPROC);
   ::SetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_CLOSE), GWL_WNDPROC, (LONG)CustomProc);


   
   ::SetWindowPos(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_MIN),   NULL, 215,   7,  11, 11, SWP_NOZORDER);
   ::SetWindowPos(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_CLOSE), NULL, 229,   7,  11, 11, SWP_NOZORDER);

   ::SetWindowPos(::GetDlgItem(hWnd, IDC_CONVERT_STATIC_TITLE), NULL, 28, 6,  0, 0, SWP_NOSIZE | SWP_NOZORDER);

   
   WCHAR awFolder[MAX_PATH];

   if(m_settingData.nOutputFolder == 1)
      ::wsprintf(awFolder, g_localeData.resourceData[7].pwCaption[m_nLanguage], m_settingData.awOutputFolder);
   else
      ::wsprintf(awFolder, g_localeData.resourceData[7].pwCaption[m_nLanguage], g_localMessage[2].pwCaption[m_nLanguage]);

   ::SetDlgItemText(hWnd, IDC_CONVERT_STATIC_OUTPUT_FOLDER, awFolder);

   
   m_hRgn = ::CreatePolygonRgn(g_apRgn, 40, WINDING);

   ::SetWindowRgn(hWnd, m_hRgn, TRUE);
   ::SetWindowPos(hWnd, HWND_TOPMOST, p.x, p.y, DW, DH, SWP_NOZORDER);

   
   m_bRunningConvert = false;
   ::SetTimer(hWnd, TIMERID_DROPFILE, 10, NULL);
}

void CConvertDialog::OnClose(HWND hWnd)
{  

   
   POINT p;
   WCHAR awText[MAX_PATH], awIniFileName[MAX_PATH];

   ::GetModuleFileName(NULL, awIniFileName, MAX_PATH);
   ::PathRemoveFileSpec(awIniFileName);
   ::lstrcat(awIniFileName, TEXT("\\EcoDecoTooL.ini"));

   p.x = (int)::GetPrivateProfileInt(L"ConvertDialog", L"WindowLeft", -10, awIniFileName);
   p.y = (int)::GetPrivateProfileInt(L"ConvertDialog", L"WindowTop", -10, awIniFileName);

   WINDOWPLACEMENT wndpl;
   ::GetWindowPlacement(hWnd, &wndpl);
   ::wsprintf(awText, L"%d", wndpl.rcNormalPosition.left);
   ::WritePrivateProfileString(L"ConvertDialog", L"WindowLeft", awText, awIniFileName);
   ::wsprintf(awText, L"%d", wndpl.rcNormalPosition.top);
   ::WritePrivateProfileString(L"ConvertDialog", L"WindowTop", awText, awIniFileName);

   if(wndpl.showCmd & SW_MINIMIZE)
      ::WritePrivateProfileString(L"ConvertDialog", L"WindowMinimize", L"1", awIniFileName);
   else
      ::WritePrivateProfileString(L"ConvertDialog", L"WindowMinimize", L"0", awIniFileName);


   
   int nCpuUsage = ::SendMessage(::GetDlgItem(hWnd, IDC_CONVERT_COMBO_CPU), CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
   ::wsprintf(awText, L"%d", nCpuUsage);
   ::WritePrivateProfileString(L"ConvertDialog", L"CpuUsage", awText, awIniFileName);
}

void CConvertDialog::ShowDialog(SETTINGDATA *pData, int nLanguage, CLinkedList *pList)
{
   m_bExit = false;
   m_nLanguage = nLanguage;
   m_pDropLinkedList = pList;

   
   ::CopyMemory(&m_settingData, pData, sizeof(m_settingData));

   m_convertData.dAlbumGain = 100.0;
   m_convertData.dAlbumPeak = 0.0;
   m_convertData.dTargetGain = m_settingData.dGain;
   m_convertData.bUseFrontEnd = false;
   m_convertData.dNormalize = 1.0;
   m_convertData.nGainMode = m_settingData.nGainMode;
   m_convertData.fVBR = m_settingData.fVBR;
   m_convertData.nABRCBR = m_settingData.nABRCBR;
   m_convertData.nAdvancedMode = m_settingData.nAdvancedMode;
   m_convertData.nEncodeMode = m_settingData.nEncodeMode;
   m_convertData.nPass = 1;
   m_convertData.nVBR = m_settingData.nVBR;
   ::CopyMemory(&m_convertData.wf, &m_settingData.wf, sizeof(m_settingData.wf));

   if(m_convertData.nGainMode == GAIN_TRACK_NORMALIZE || m_convertData.nGainMode == GAIN_ALBUM_NORMALIZE)
      m_convertData.bNormalize = true;
   else
      m_convertData.bNormalize = false;

   try
   {
      
      m_pInputLinkedList = new CLinkedList();

      
      HRESULT hr;
      m_pConvert = new CConvert(pData->nContainerType, &hr);

      if(FAILED(hr))
         throw bad_alloc();
   }
   catch(std::bad_alloc & e)
   {
      MessageBox(NULL, g_localMessage[0].pwCaption[m_nLanguage], L"EcoDecoTooL error", MB_OK);
      return;
   }

   
   ::DialogBox(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_CONVERT), NULL, (DLGPROC)DialogProc);

   
   SAFE_DELETE(m_pInputLinkedList);
}

LRESULT CALLBACK CConvertDialog::CustomProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{  

   int nResourceID;

   nResourceID = ::GetDlgCtrlID(hWnd);

   switch(msg)
   {
   case WM_SETCURSOR:
      
      ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(32649)));
      return 0;
   case WM_MOUSEMOVE:

      if(wParam != MK_LBUTTON)
      {
         TRACKMOUSEEVENT tme;
         tme.cbSize = sizeof(tme);
         tme.dwFlags = TME_LEAVE;
         tme.hwndTrack = hWnd;
         ::TrackMouseEvent(&tme);

         if(nResourceID == IDC_CONVERT_BUTTON_MIN)
         {
            if(g_pMyClass->m_nMinResourceID != IDB_BITMAP_MIN2)
            {
               g_pMyClass->m_nMinResourceID = IDB_BITMAP_MIN2;
               ::InvalidateRect(hWnd, NULL, FALSE);
               ::UpdateWindow(hWnd);
            }
         }
         else 
         {
            if(g_pMyClass->m_nCloseResourceID != IDB_BITMAP_CLOSE2)
            {
               g_pMyClass->m_nCloseResourceID = IDB_BITMAP_CLOSE2;
               ::InvalidateRect(hWnd, NULL, FALSE);
               ::UpdateWindow(hWnd);
            }
         }
      }

      break;

   case WM_MOUSELEAVE:

      if(nResourceID == IDC_CONVERT_BUTTON_MIN)
      {
         if(g_pMyClass->m_nMinResourceID != IDB_BITMAP_MIN1)
         {
            g_pMyClass->m_nMinResourceID = IDB_BITMAP_MIN1;
            ::InvalidateRect(hWnd, NULL, FALSE);
            ::UpdateWindow(hWnd);
         }
      }
      else 
      {
         if(g_pMyClass->m_nCloseResourceID != IDB_BITMAP_CLOSE1)
         {
            g_pMyClass->m_nCloseResourceID = IDB_BITMAP_CLOSE1;
            ::InvalidateRect(hWnd, NULL, FALSE);
            ::UpdateWindow(hWnd);
         }
      }

      break;

   case WM_LBUTTONDOWN:

      if(nResourceID == IDC_CONVERT_BUTTON_MIN)
      {
         if(g_pMyClass->m_nMinResourceID != IDB_BITMAP_MIN3)
         {
            g_pMyClass->m_nMinResourceID = IDB_BITMAP_MIN3;
            ::InvalidateRect(hWnd, NULL, FALSE);
            ::UpdateWindow(hWnd);
         }
      }
      else 
      {
         if(g_pMyClass->m_nCloseResourceID != IDB_BITMAP_CLOSE3)
         {
            g_pMyClass->m_nCloseResourceID = IDB_BITMAP_CLOSE3;
            ::InvalidateRect(hWnd, NULL, FALSE);
            ::UpdateWindow(hWnd);
         }
      }

      break;

   case WM_LBUTTONUP:

      if(nResourceID == IDC_CONVERT_BUTTON_MIN)
      {
         if(0 <= LOWORD(lParam) && LOWORD(lParam) < 11 && 0 <= HIWORD(lParam) && HIWORD(lParam) < 11)
            ::ShowWindow(::GetParent(hWnd), SW_MINIMIZE);
      }
      else 
      {
         if(0 <= LOWORD(lParam) && LOWORD(lParam) < 11 && 0 <= HIWORD(lParam) && HIWORD(lParam) < 11)
         {
            g_pMyClass->OnClose(::GetParent(hWnd));
            ::EndDialog(::GetParent(hWnd), IDCANCEL);
            return 0;
         }
      }

      break;
   }

   if(nResourceID == IDC_CONVERT_BUTTON_MIN)
      return ::CallWindowProc(g_pMyClass->m_myProc[0], hWnd , msg , wParam , lParam);
   else 
      return ::CallWindowProc(g_pMyClass->m_myProc[1], hWnd , msg , wParam , lParam);
}

LRESULT CALLBACK CConvertDialog::DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch (msg)
   {
   case WM_INITDIALOG:
      g_pMyClass->OnCreate(hWnd);
      return TRUE;

   case WM_PAINT:

      HDC hDC;
      PAINTSTRUCT ps;

      hDC = ::BeginPaint(hWnd , &ps);
      g_pMyClass->OnPaint(hDC);
      ::EndPaint(hWnd , &ps);

      return TRUE;

   case WM_ERASEBKGND:
      
      return 0;

   case WM_DRAWITEM:

      

      if(wParam == IDC_CONVERT_BUTTON_MIN)
         g_pMyClass->DrawHoverButton((DRAWITEMSTRUCT *)lParam, g_pMyClass->m_nMinResourceID);
      else if(wParam == IDC_CONVERT_BUTTON_CLOSE)
         g_pMyClass->DrawHoverButton((DRAWITEMSTRUCT *)lParam, g_pMyClass->m_nCloseResourceID);
      else
         g_pMyClass->DrawItem((DRAWITEMSTRUCT *)lParam);

      return TRUE;

   case WM_CTLCOLORSTATIC:

      
      if(::GetDlgCtrlID((HWND)lParam) == IDC_CONVERT_STATIC_TITLE)
         ::SetTextColor((HDC)wParam, RGB(0x50, 0x50, 0x50)) ;

      ::SetBkMode((HDC)wParam, TRANSPARENT);

return (BOOL)(HBRUSH)GetStockObject(WHITE_BRUSH);



   case WM_LBUTTONDOWN:

      if(LOWORD(lParam) < 214 && HIWORD(lParam) <= 20)
      {  

         
         ::PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lParam);
      }

      return TRUE;

   case WM_TIMER:

      
      if(g_pMyClass->m_bRunningConvert == true)
         return FALSE;

      if(g_pMyClass->m_bExit == true)
         return FALSE;

      g_pMyClass->m_bRunningConvert = true;

      switch(wParam)
      {
      case TIMERID_DROPFILE:
         ::KillTimer(hWnd, TIMERID_DROPFILE);
         g_pMyClass->DropFiles(hWnd);

         ::SetTimer(hWnd, TIMERID_CONVERT, 100, NULL);
         break;

      case TIMERID_CONVERT:

         if(g_pMyClass->m_bGraphNotify == true)
         {  

            
            int nState = g_pMyClass->m_pConvert->GraphNotify();

            if(nState == EC_COMPLETE)
               g_pMyClass->m_nConvertState = STATE_END_SUCCESS;
            else if(nState == EC_ERRORABORT)
               g_pMyClass->m_nConvertState = STATE_END_ERROR;

            g_pMyClass->m_bGraphNotify = false;
         }
         else if(g_pMyClass->m_nConvertState <= STATE_START_NEXT_FRONTEND)
            g_pMyClass->ConvertStart(hWnd);
         else if(g_pMyClass->m_nConvertState <= STATE_CONVERTING_FRONTEND)
            g_pMyClass->Converting(hWnd);
         else
            g_pMyClass->ConvertEnd(hWnd);

         break;
      }

      g_pMyClass->m_bRunningConvert = false;

      return TRUE;

   case WM_GRAPHNOTIFY:
      g_pMyClass->m_bGraphNotify = true;
       return TRUE;

   case WM_COMMAND:
      switch(LOWORD(wParam))
      {
      case IDC_CONVERT_COMBO_CPU:
         
         g_pMyClass->m_nNewCpuUsage = ::SendMessage(::GetDlgItem(hWnd, IDC_CONVERT_COMBO_CPU), CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
         return TRUE;

      case IDC_CONVERT_BUTTON_MIN:
         
         ::ShowWindow(hWnd, SW_MINIMIZE);
         return TRUE;

      case IDC_CONVERT_BUTTON_CLOSE:
         
         g_pMyClass->ConvertExit(hWnd);
         g_pMyClass->OnClose(hWnd);
         ::EndDialog(hWnd ,IDCANCEL);
         return TRUE;
      }

      break;

   case WM_DESTROY:

      
      if(g_pMyClass->m_myProc[0] != NULL)
      {
         ::SetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_MIN), GWL_WNDPROC, (LONG)g_pMyClass->m_myProc[0]);
         g_pMyClass->m_myProc[0] = NULL;
      }

      if(g_pMyClass->m_myProc[1] != NULL)
      {
         ::SetWindowLong(::GetDlgItem(hWnd, IDC_CONVERT_BUTTON_CLOSE), GWL_WNDPROC, (LONG)g_pMyClass->m_myProc[1]);
         g_pMyClass->m_myProc[1] = NULL;
      }

      ::PostQuitMessage(0); 
      return TRUE;

   case WM_CLOSE:
      g_pMyClass->ConvertExit(hWnd);
      g_pMyClass->OnClose(hWnd);
      ::EndDialog(hWnd ,IDCANCEL);
      return TRUE;

   }

	return FALSE;
}

