//	Album List for Winamp
//	Copyright (C) 1999-2001 Safai Ma
//
//	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., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include <shellapi.h>
#include <commctrl.h>
#include <mbstring.h>
#include "resource.h"
#include "frontend.h"
#include "wa_ipc.h"
#include "gen.h"
#include "Pages.h"
#include "Config.h"
#include "winampalbumlist.h"
#include "browseforfolder.h"

extern CWinampAlbumList winampAL;

/////////////////////////////////////////////////////////////////////////
// CHyperTextStatic
//

CHyperTextStatic::CHyperTextStatic()
{
}

LRESULT CALLBACK CHyperTextStatic::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT (CALLBACK *pOldWndProc)(HWND, UINT, WPARAM, LPARAM) = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetProp(hwnd, "OldWndProc");
	CHyperTextStatic *pWnd = (CHyperTextStatic*)GetProp(hwnd, "CHyperTextStatic");

	if (pWnd == NULL || pOldWndProc == NULL)
		return ::DefWindowProc(hwnd, uMsg, wParam, lParam);

	POINT point = { (short)LOWORD(lParam), (short)HIWORD(lParam) };

	switch (uMsg)
	{
	case WM_PAINT:
		pWnd->OnPaint(hwnd);
		return TRUE;

	case WM_DESTROY:
		pWnd->OnDestroy(hwnd);
		break;

	case WM_LBUTTONDOWN:
		pWnd->OnLButtonDown(hwnd, point);
		break;

	case WM_MOUSEMOVE:
		pWnd->OnMouseMove(hwnd, point);
		break;

	case WM_NCHITTEST:
		return HTCLIENT;
	}

	return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}

void CHyperTextStatic::OnPaint(HWND hWnd, int nMode /*=0*/, POINT *pt /*=NULL*/)
{
	PAINTSTRUCT ps;
	HDC hDC = NULL;

	if (nMode == 0)
		hDC = BeginPaint(hWnd, &ps);
	else
	{
		hDC = GetDC (hWnd);
	}

	char buffer[1024];
	GetWindowText(hWnd, buffer, 1024);

	NONCLIENTMETRICS ncm;
	ncm.cbSize = sizeof(NONCLIENTMETRICS);
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);

	LOGFONT lf;
	HFONT hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	if (GetObject(hDefFont, sizeof(LOGFONT), &lf))
	{
		memcpy(&ncm.lfMessageFont, &lf, sizeof(LOGFONT));
	}
	
	HFONT hFont = CreateFontIndirect(&ncm.lfMessageFont);

	ncm.lfMessageFont.lfUnderline = TRUE;
	HFONT hFontHyper = CreateFontIndirect(&ncm.lfMessageFont);

	ncm.lfMessageFont.lfWeight = FW_BOLD;
	ncm.lfMessageFont.lfUnderline = FALSE;
	HFONT hBoldFont = CreateFontIndirect(&ncm.lfMessageFont);

	ncm.lfMessageFont.lfWeight = FW_NORMAL;
	ncm.lfMessageFont.lfUnderline = TRUE;
	HFONT hUnderlineFont = CreateFontIndirect(&ncm.lfMessageFont);

	HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);
	int oldBkMode = SetBkMode(hDC, OPAQUE);
	COLORREF oldBkColor = SetBkColor(hDC, GetSysColor(COLOR_BTNFACE));
	COLORREF oldTextColor = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));

	TEXTMETRIC tm;
	GetTextMetrics(hDC, &tm);

	int nNumOfURLs = 0;

	int x = 0, y = 0;
	int len = lstrlen(buffer);
	char *p = buffer;
	for (int i=0; i<=len; i++)
	{
		if ((_strnicmp(&buffer[i], "<a>", 3) == 0) ||
			(_strnicmp(&buffer[i], "<e>", 3) == 0))	// start of hypertext
		{
			// flush previous stuff first
			buffer[i] = 0;
			TextOut(hDC, x, y, p, lstrlen(p));

			// update current position
			SIZE sz;
			GetTextExtentPoint(hDC, p, lstrlen(p), &sz);
 			x += sz.cx;
			p = buffer + i + 3;

			// find end character
			for (int j=i+3; j<=len; j++)
			{
				if ((_strnicmp(&buffer[j], "</a>", 4) == 0) ||
					(_strnicmp(&buffer[j], "</e>", 4) == 0))
				{
					BOOL bEmail = (BOOL)(_strnicmp(&buffer[j], "</e>", 4) == 0);
					buffer[j] = 0;

					HFONT hOldFont = (HFONT)SelectObject(hDC, hFontHyper);

					// update current position
					SIZE sz;
					GetTextExtentPoint(hDC, p, lstrlen(p), &sz);

					RECT rc = { x, y, x + sz.cx, y + tm.tmHeight };

					// add to our list if this is a "new" url
					if (++nNumOfURLs > m_URLs.GetSize())
					{
						LPLINK lpLink = new LINK;
						lpLink->rc = rc;
						lpLink->url[0] = 0;
						if (bEmail) lstrcpy(lpLink->url, "mailto:");
						lstrcat(lpLink->url, p);
						m_URLs.Add(lpLink);
					}

					COLORREF oldTextColor;
					if ((nMode == 1) && PtInRect(&rc, *pt))
						oldTextColor = SetTextColor(hDC, RGB(255, 0, 0));
					else
						oldTextColor = SetTextColor(hDC, RGB(0, 0, 255));

					// draw hypertext
					TextOut(hDC, x+2, y, p, lstrlen(p));

					SetTextColor(hDC, oldTextColor);
					SelectObject(hDC, hOldFont);
					
 					x += sz.cx + 4;
					p = buffer + j + 4;
					i = j;
					break;
				}
			}
		}
		else if ((_strnicmp(&buffer[i], "<b>", 3) == 0)	||	// start of bold
				 (_strnicmp(&buffer[i], "<u>", 3) == 0))	// start of underline
		{
			// flush previous stuff first
			buffer[i] = 0;
			TextOut(hDC, x, y, p, lstrlen(p));

			// update current position
			SIZE sz;
			GetTextExtentPoint(hDC, p, lstrlen(p), &sz);
 			x += sz.cx;
			p = buffer + i + 3;

			// find end character
			for (int j=i+3; j<=len; j++)
			{
				if ((_strnicmp(&buffer[j], "</b>", 4) == 0) ||
					(_strnicmp(&buffer[j], "</u>", 4) == 0))
				{
					BOOL bBold = (BOOL)(_strnicmp(&buffer[j], "</b>", 4) == 0);

					HFONT hOldFont = (HFONT)SelectObject(hDC, bBold ? hBoldFont : hUnderlineFont);

					// draw bold/underlined text
					buffer[j] = 0;
					TextOut(hDC, x, y, p, lstrlen(p));

					// update current position
					SIZE sz;
					GetTextExtentPoint(hDC, p, lstrlen(p), &sz);

					SelectObject(hDC, hOldFont);

 					x += sz.cx;
					p = buffer + j + 4;
					i = j;
					break;
				}
			}
		}
		else if (_strnicmp(&buffer[i], "<br>", 4) == 0)	// new lines
		{
			// flush previous stuff first
			buffer[i] = 0;
			TextOut(hDC, x, y, p, lstrlen(p));
			x = 0;
			y += tm.tmHeight;
			p = buffer + i + 4;
		}
		else if ((buffer[i] == 0) || (buffer[i] == '\n'))
		{
			// flush previous stuff first
			buffer[i] = 0;
			TextOut(hDC, x, y, p, lstrlen(p));
			x = 0;
			y += tm.tmHeight;
			p = buffer + i + 1;
		}
	}

	// clean up
	SetTextColor(hDC, oldTextColor);
	SetBkColor(hDC, oldBkColor);
	SetBkMode(hDC, oldBkMode);
	SelectObject(hDC, hOldFont);
	DeleteObject(hBoldFont);
	DeleteObject(hUnderlineFont);
	DeleteObject(hFontHyper);
	DeleteObject(hFont);

	if (nMode == 0)
		EndPaint(hWnd, &ps);
	else
		ReleaseDC (hWnd, hDC);
}

void CHyperTextStatic::OnDestroy(HWND hWnd)
{
	RemoveProp(hWnd, "OldWndProc");
	RemoveProp(hWnd, "CHyperTextStatic");

	for (int i=0; i<m_URLs.GetSize(); i++)
	{
		delete (LPLINK)m_URLs[i];
	}
	m_URLs.RemoveAll();
}

void CHyperTextStatic::OnMouseMove(HWND hWnd, POINT point)
{
	int size = m_URLs.GetSize();
	for (int i=0; i<size; i++)
	{
		LPLINK lpLink = (LPLINK)m_URLs[i];
		if (lpLink && PtInRect(&lpLink->rc, point))
		{
			SetCursor(LoadCursor(plugin.hDllInstance, MAKEINTRESOURCE(IDC_HAND)));
			OnPaint (hWnd, 1, &point);
			SetCapture (hWnd);
			return;
		}
	}

	if (GetCapture() == hWnd)
	{
		OnPaint (hWnd, 2);
		ReleaseCapture ();
		SetCursor(LoadCursor(NULL, IDC_ARROW));
	}
	else
		SetCursor(LoadCursor(NULL, IDC_ARROW));
}

void CHyperTextStatic::OnLButtonDown(HWND hWnd, POINT point)
{
	int size = m_URLs.GetSize();
	for (int i=0; i<size; i++)
	{
		LPLINK lpLink = (LPLINK)m_URLs[i];
		if (lpLink && PtInRect(&lpLink->rc, point))
		{
			GotoURL(lpLink->url, SW_SHOWNORMAL);
			return;
		}
	}
}

/////////////////////////////////////////////////////////////////////////
// CWPListBox
//

CWPListBox::CWPListBox()
{
}

LRESULT CALLBACK CWPListBox::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT (CALLBACK *pOldWndProc)(HWND, UINT, WPARAM, LPARAM) = (LRESULT(CALLBACK *)(HWND, UINT, WPARAM, LPARAM))GetProp(hwnd, "OldWndProc");
	CWPListBox *pWnd = (CWPListBox*)GetProp(hwnd, "CWPListBox");

	if (pWnd == NULL || pOldWndProc == NULL)
		return ::DefWindowProc(hwnd, uMsg, wParam, lParam);

	LRESULT lResult;
	switch (uMsg)
	{
	case WM_PAINT:
		lResult = CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
		pWnd->OnPaint(hwnd);
		return lResult;

	case WM_DESTROY:
		pWnd->OnDestroy(hwnd);
		break;
	}

	return CallWindowProc(pOldWndProc, hwnd, uMsg, wParam, lParam);
}

void CWPListBox::OnPaint(HWND hWnd)
{
	int nCount = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
	if (nCount == 0)
	{
		COLORREF clrText = GetSysColor(COLOR_WINDOWTEXT);
		COLORREF clrTextBk = GetSysColor(COLOR_WINDOW);

		HDC hDC = GetDC(hWnd);

		RECT rc;
		GetClientRect(hWnd, &rc);
		rc.top += 2;
		rc.left += 2;
		rc.right -= 2;

		int oldclrText = SetTextColor(hDC, clrText);
		int oldclrTextBk = SetBkColor(hDC, clrTextBk);
		HFONT hFont = (HFONT)SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
		DrawText(hDC, ALSTRING("Use the \"Add\" button to insert search path in the edit box above"), -1, &rc, 
					  DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);

		// Restore dc
		SetTextColor(hDC, oldclrText);
		SetBkColor(hDC, oldclrTextBk);
		SelectObject(hDC, hFont);
		ReleaseDC(hWnd, hDC);
	}			
}

void CWPListBox::OnDestroy(HWND hWnd)
{
	RemoveProp(hWnd, "OldWndProc");
	RemoveProp(hWnd, "CWPListBox");
}

/////////////////////////////////////////////////////////////////////////
// CAboutPage
//

CAboutPage::CAboutPage()
	: CTreePropertyPage(CAboutPage::IDD)
{
}

CAboutPage::CAboutPage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(CAboutPage::IDD, szName, nTree)
{
}

BOOL CAboutPage::OnInitDialog()
{
	SubclassDlgItem(IDC_VERSION_STATIC, CHyperTextStatic::DefWindowProc, "CHyperTextStatic", (DWORD)&m_htVersion);
	SubclassDlgItem(IDC_VERSION2_STATIC, CHyperTextStatic::DefWindowProc, "CHyperTextStatic", (DWORD)&m_htVersion2);
	SubclassDlgItem(IDC_ADDITIONAL_STATIC, CHyperTextStatic::DefWindowProc, "CHyperTextStatic", (DWORD)&m_htCode);
	SubclassDlgItem(IDC_LANG_STATIC, CHyperTextStatic::DefWindowProc, "CHyperTextStatic", (DWORD)&m_htTranslation);

	int major = 1, minor = 20, build = 1;
	GetVersionInformation(major, minor, build);

	char about[512], fmt[512];
	GetWindowText(GetDlgItem(m_hWnd, IDC_VERSION_STATIC), fmt, 512);

	wsprintf(about, fmt, major, minor, build);

	SetWindowText(GetDlgItem(m_hWnd, IDC_VERSION_STATIC), about);

	if (al_lang[0] != 0)
	{
		char name[MAX_PATH] = "";
		GetPrivateProfileString("Info", "Name", "", name, MAX_PATH, szLangINI);

		if (name[0] != 0)
		{
			char lang[MAX_PATH] = "";
			wsprintf(lang, "%s %s", ALSTRING("Translated by"), name);
			SetWindowText(GetDlgItem(m_hWnd, IDC_LANG_STATIC), lang);
		}
		else
		{
			SetWindowText(GetDlgItem(m_hWnd, IDC_LANG_STATIC), "");
		}
	}
	else
	{
		SetWindowText(GetDlgItem(m_hWnd, IDC_LANG_STATIC), "");
	}

	CheckDlgButton(m_hWnd, IDC_CHECKNEWVER, al_newverchk ? BST_CHECKED : BST_UNCHECKED);
	if (!bInternetReady) ShowWindow(GetDlgItem(m_hWnd, IDC_CHECKNEWVER), SW_HIDE);

	return TRUE;
}

void CAboutPage::OnOK()
{
	if (IsDlgButtonChecked(m_hWnd, IDC_CHECKNEWVER))
	{
		if (al_newverchk == 0) al_newverchk = 1;
	}
	else
	{
		al_newverchk = 0;
	}
}

/////////////////////////////////////////////////////////////////////////
// CReadmePage
//

CReadmePage::CReadmePage()
	: CTreePropertyPage(CReadmePage::IDD)
{
}

CReadmePage::CReadmePage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(CReadmePage::IDD, szName, nTree)
{
}

BOOL CReadmePage::OnInitDialog()
{
	HWND hWnd = GetDlgItem(m_hWnd, IDC_README_TEXT);

	char filename[512], *p;
	GetModuleFileName(plugin.hDllInstance, filename, sizeof(filename));
	p = (char *)_mbsrchr((unsigned char *)filename,'\\');
	if (p == NULL) p = filename-1;
	lstrcpy(p+1, "Album List\\history.txt");

	BOOL bTextLoaded = FALSE;

	HANDLE fp;
	if (INVALID_HANDLE_VALUE != (fp = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)))
	{
		DWORD dwSize = GetFileSize (fp, NULL);

		char *buffer = new char [dwSize+1];

		DWORD nBytesRead;
		BOOL bResult = ReadFile(fp, buffer, dwSize, &nBytesRead, NULL);
		if (bResult)
		{
			buffer[dwSize] = 0;
			SetWindowText(hWnd, buffer);

			bTextLoaded = TRUE;
		}

		delete [] buffer;

		CloseHandle(fp);
	}

	if (!bTextLoaded)
	{
		SetWindowText(hWnd, ALSTRING("history.txt not found"));
	}

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////
// CSkinsPage
//

CSkinsPage::CSkinsPage()
	: CTreePropertyPage(CSkinsPage::IDD)
{
	m_useplskin = 0;
	m_rmpltitle = 0;
}

CSkinsPage::CSkinsPage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(CSkinsPage::IDD, szName, nTree)
{
	m_useplskin = 0;
	m_rmpltitle = 0;
}

BOOL CALLBACK CSkinsPage::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_COMMAND:
		switch (HIWORD(wParam))	// wNotifyCode
		{
		case BN_CLICKED:
			switch (LOWORD(wParam))	// wID
			{
			case IDC_USEPLSKIN:
				OnUsePLSkin();
				return TRUE;

			case IDC_RMPLTITLE:
				OnRemovePLTitle();
				return TRUE;
			}
			break;
		}
		break;
	}
	return FALSE;
}

BOOL CSkinsPage::OnInitDialog()
{
	CheckDlgButton(m_hWnd, IDC_USEPLSKIN, al_useplskin ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_RMPLTITLE, al_rmpltitle ? BST_CHECKED : BST_UNCHECKED);
	EnableWindow(GetDlgItem(m_hWnd, IDC_RMPLTITLE), IsDlgButtonChecked(m_hWnd, IDC_USEPLSKIN));

	m_useplskin = al_useplskin;
	m_rmpltitle = al_rmpltitle;

	return TRUE;
}

void CSkinsPage::OnOK()
{
	al_useplskin = IsDlgButtonChecked(m_hWnd, IDC_USEPLSKIN);
	al_rmpltitle = IsDlgButtonChecked(m_hWnd, IDC_RMPLTITLE);

	winampAL.RefreshSkin();
	winampAL.Redraw();
}

void CSkinsPage::OnCancel()
{
	al_useplskin = m_useplskin;
	al_rmpltitle = m_rmpltitle;

	winampAL.RefreshSkin();
	winampAL.Redraw();
}

void CSkinsPage::OnUsePLSkin()
{
	EnableWindow(GetDlgItem(m_hWnd, IDC_RMPLTITLE), IsDlgButtonChecked(m_hWnd, IDC_USEPLSKIN));

	// fake a OnOK so that we get the new setting
	// and refresh the skin
	OnOK();
}

void CSkinsPage::OnRemovePLTitle()
{
	// fake a OnOK so that we get the new setting
	// and refresh the skin
	OnOK();
}

/////////////////////////////////////////////////////////////////////////
// COptionsPage
//

COptionsPage::COptionsPage()
	: CTreePropertyPage(COptionsPage::IDD)
{
}

COptionsPage::COptionsPage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(COptionsPage::IDD, szName, nTree)
{
}

BOOL CALLBACK COptionsPage::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_COMMAND:
		switch (HIWORD(wParam))	// wNotifyCode
		{
		case BN_CLICKED:
			break;
		}
		break;
	}
	return FALSE;
}

BOOL COptionsPage::OnInitDialog()
{
	CheckDlgButton(m_hWnd, IDC_SORT_FILENAME, al_sortname ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_SHOWCOVER, al_showcover ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_LOOP, al_loop ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_ENQUEUE, al_enqueue ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_KEEPSONGPLAYING, al_keepsp ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_AUTOADVANCE, al_autoadvance ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_RESUMEPLAY, al_resume_play ? BST_CHECKED : BST_UNCHECKED);

	return TRUE;
}

void COptionsPage::OnOK()
{
	al_enqueue		= IsDlgButtonChecked(m_hWnd, IDC_ENQUEUE);
	al_keepsp		= IsDlgButtonChecked(m_hWnd, IDC_KEEPSONGPLAYING);
	al_loop			= IsDlgButtonChecked(m_hWnd, IDC_LOOP);
	al_showcover	= IsDlgButtonChecked(m_hWnd, IDC_SHOWCOVER);
	al_sortname		= IsDlgButtonChecked(m_hWnd, IDC_SORT_FILENAME);
	al_autoadvance	= IsDlgButtonChecked(m_hWnd, IDC_AUTOADVANCE);
	al_resume_play	= IsDlgButtonChecked(m_hWnd, IDC_RESUMEPLAY);
}

/////////////////////////////////////////////////////////////////////////
// CAlbumNamingPage
//

CAlbumNamingPage::CAlbumNamingPage()
	: CTreePropertyPage(CAlbumNamingPage::IDD)
{
}

CAlbumNamingPage::CAlbumNamingPage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(CAlbumNamingPage::IDD, szName, nTree)
{
}

BOOL CALLBACK CAlbumNamingPage::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_COMMAND:
		switch (HIWORD(wParam))	// wNotifyCode
		{
		case BN_CLICKED:
			break;
		}
		break;
	}
	return FALSE;
}

BOOL CAlbumNamingPage::OnInitDialog()
{
	HWND hwnd = GetDlgItem(m_hWnd, IDC_STYLE);
	SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)ALSTRING("...\\Artist\\Album"));
	SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)ALSTRING("...\\Artist - Album"));
	SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)ALSTRING("...\\Artist - Album - Year"));
	SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)ALSTRING("...\\Artist\\Year - Album"));
	SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)ALSTRING("...\\Artist - Year - Album"));

	SendMessage(hwnd, CB_SETCURSEL, al_dirstyle, 0);
    
	CheckDlgButton(m_hWnd, IDC_FIXTITLES, al_fixtitles ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_MULTIDISCFIX, al_multidiscfix ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_USEID3, al_useid3 ? BST_CHECKED : BST_UNCHECKED);

	SetWindowText(GetDlgItem(m_hWnd, IDC_MULTIDISCNAMES), al_multidiscnames);

	return TRUE;
}

void CAlbumNamingPage::OnOK()
{
	int useid3		= IsDlgButtonChecked(m_hWnd, IDC_USEID3);
	int dirstyle	= SendMessage(GetDlgItem(m_hWnd, IDC_STYLE), CB_GETCURSEL, 0, 0);
	al_fixtitles	= IsDlgButtonChecked(m_hWnd, IDC_FIXTITLES);
	al_multidiscfix	= IsDlgButtonChecked(m_hWnd, IDC_MULTIDISCFIX);

	GetWindowText(GetDlgItem(m_hWnd, IDC_MULTIDISCNAMES), al_multidiscnames, MAX_PATH);

	if ((useid3 != al_useid3) ||
		(dirstyle != al_dirstyle))
	{
		winampAL.Redraw();
		winampAL.RefreshAlbums();
	}

	al_useid3 = useid3;
	al_dirstyle = dirstyle;
}

/////////////////////////////////////////////////////////////////////////
// CSearchPathPage
//

CSearchPathPage::CSearchPathPage()
	: CTreePropertyPage(CSearchPathPage::IDD)
{
	m_bRefresh = FALSE;
}

CSearchPathPage::CSearchPathPage(LPCTSTR szName, int nTree /*=0*/)
	: CTreePropertyPage(CSearchPathPage::IDD, szName, nTree)
{
	m_bRefresh = FALSE;
}

BOOL CALLBACK CSearchPathPage::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_COMMAND:
		switch (HIWORD(wParam))	// wNotifyCode
		{
		case BN_CLICKED:
			switch (LOWORD(wParam))	// wID
			{
			case IDC_ADD:
				OnAdd();
				return TRUE;

			case IDC_REMOVE:
				OnRemove();
				return TRUE;

			case IDC_REMOVEALL:
				OnRemoveAll();
				return TRUE;

			case IDC_IGNORE_M3U:
				OnIgnoreM3U();
				return TRUE;
			}
			break;
		}
		break;
	}
	return FALSE;
}

BOOL CSearchPathPage::OnInitDialog()
{
	m_bRefresh = FALSE;

	// subclass the list box to display empty listbox string
	SubclassDlgItem(IDC_PATHLIST, CWPListBox::DefWindowProc, "CWPListBox", (DWORD)&m_WPListBox);

	HWND hwnd = GetDlgItem(m_hWnd, IDC_PATHLIST);

	char paths[40] = "al_path";
	char al_path[MAX_PATH] = "";
	int i = 0;
	while (1)
	{
		DWORD dwRet = GetPrivateProfileString(szAppName, paths, "", al_path, MAX_PATH, szPluginINI);

		if (dwRet == 0 && i != 0)	break;

		if (lstrlen(al_path))
		{
			SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)_mbslwr((unsigned char *)al_path));
		}

		wsprintf(paths, "al_path_%ld", i++);
	}

	SetWindowText(GetDlgItem(m_hWnd, IDC_FILETYPEEDIT), al_extlist);

	CheckDlgButton(m_hWnd, IDC_SCAN_AT_STARTUP, al_startup_scan ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_SCANSUBDIR, al_searchsubdir ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_ADD_CDROM, al_add_cdroms ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_IGNOREPL, al_ignore_pl ? BST_CHECKED : BST_UNCHECKED);
	CheckDlgButton(m_hWnd, IDC_IGNORE_M3U, al_ignore_m3u ? BST_CHECKED : BST_UNCHECKED);

	if (al_ignore_m3u)
	{
		EnableWindow(GetDlgItem(m_hWnd, IDC_IGNOREPL), FALSE);
	}

	//ANDREAS:
	AdjustScrollWidth();

	return TRUE;
}

void CSearchPathPage::OnOK()
{
	// scan directories at startup
	al_startup_scan = IsDlgButtonChecked(m_hWnd, IDC_SCAN_AT_STARTUP);

	// scan sub-directories
	al_searchsubdir = IsDlgButtonChecked(m_hWnd, IDC_SCANSUBDIR);

	// search CD-ROMs automatically?
	if (al_add_cdroms != (int)IsDlgButtonChecked(m_hWnd, IDC_ADD_CDROM))
	{
		al_add_cdroms = IsDlgButtonChecked(m_hWnd, IDC_ADD_CDROM);
		m_bRefresh = TRUE;
	}

	// ignore playlist at root of search path
	if (al_ignore_pl != (int)IsDlgButtonChecked(m_hWnd, IDC_IGNOREPL))
	{
		al_ignore_pl = IsDlgButtonChecked(m_hWnd, IDC_IGNOREPL);
		m_bRefresh = TRUE;
	}

	// ignore all playlist
	BOOL bRefreshFull = FALSE;
	if (al_ignore_m3u != (int)IsDlgButtonChecked(m_hWnd, IDC_IGNORE_M3U))
	{
		al_ignore_m3u = IsDlgButtonChecked(m_hWnd, IDC_IGNORE_M3U);
		m_bRefresh = bRefreshFull = TRUE;
	}

	// file type
	GetWindowText(GetDlgItem(m_hWnd, IDC_FILETYPEEDIT), al_extlist, MAX_PATH);

	// search paths
	char paths[40] = "al_path";
	char al_path[MAX_PATH] = "";
	int i = 0;
	// delete them first
	while (1)
	{
		DWORD dwRet = GetPrivateProfileString(szAppName, paths, "", al_path, MAX_PATH, szPluginINI);
		if (dwRet == 0 && i != 0)	break;
		WritePrivateProfileString(szAppName, paths, NULL, szPluginINI);
		wsprintf(paths, "al_path_%ld", i++);
	}
	// write the new list
	HWND hWndPathList = GetDlgItem(m_hWnd, IDC_PATHLIST);
	int nCount = SendMessage(hWndPathList, LB_GETCOUNT, 0, 0);
	if (nCount && nCount != LB_ERR)
	{
		char szBuffer[MAX_PATH] = "";
		for (int i=0; i<nCount; i++)
		{
			SendMessage(hWndPathList, LB_GETTEXT, i, (LPARAM)szBuffer);
			wsprintf(paths, "al_path_%ld", i);
			WritePrivateProfileString(szAppName, paths, szBuffer, szPluginINI);
		}
	}

	if (m_bRefresh)	// changing search paths only
	{
		winampAL.Redraw();
		winampAL.RefreshAlbums(!bRefreshFull);
	}
}

void CSearchPathPage::OnAdd()
{
	HWND hWndPathList = GetDlgItem(m_hWnd, IDC_PATHLIST);

	char szBuffer[MAX_PATH] = "";

	CBrowseForFolder browser;

	browser.SetOwner(m_hWnd);
	browser.SetFlags(BIF_RETURNONLYFSDIRS);
	browser.SetTitle(ALSTRING("Select the folder where you want to include."));

	if (browser.SelectFolder())
	{
		CString szText = browser.GetSelectedFolder();
		char szBuffer[MAX_PATH] = "";
		lstrcpy(szBuffer, szText);

		SendMessage(hWndPathList, LB_ADDSTRING, 0, (LPARAM)szBuffer);
		m_bRefresh = TRUE;
	}

	AdjustScrollWidth();
}

void CSearchPathPage::OnRemove()
{
	HWND hWndPathList = GetDlgItem(m_hWnd, IDC_PATHLIST);

	int nSel = SendMessage(hWndPathList, LB_GETCURSEL, 0, 0);
	if (nSel == LB_ERR) return;

	SendMessage(hWndPathList, LB_DELETESTRING, nSel, 0);

	int nCount = SendMessage(hWndPathList, LB_GETCOUNT, 0, 0);
	if (nCount)
	{
		if (nCount <= nSel) nSel = nCount - 1;
		SendMessage(hWndPathList, LB_SETCURSEL, nSel, 0);
	}
	
	m_bRefresh = TRUE;

	AdjustScrollWidth();
}

void CSearchPathPage::OnRemoveAll()
{
	HWND hWndPathList = GetDlgItem(m_hWnd, IDC_PATHLIST);

	int nSel = SendMessage(hWndPathList, LB_RESETCONTENT, 0, 0);
	if (nSel == LB_ERR) return;

	m_bRefresh = TRUE;

	AdjustScrollWidth();
}

void CSearchPathPage::OnIgnoreM3U()
{
	EnableWindow(GetDlgItem(m_hWnd, IDC_IGNOREPL), !IsDlgButtonChecked(m_hWnd, IDC_IGNORE_M3U));
}

//ANDREAS: Find horizontal width of widest element and set scroll width.
void CSearchPathPage::AdjustScrollWidth()	
{
	HWND	hWndPathList = GetDlgItem(m_hWnd, IDC_PATHLIST);
	HDC		hDC = GetDC(hWndPathList);
	RECT	rc;
	HFONT	hFont = (HFONT)SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
	int		nWidest = 0;

	rc.left		= 0;
	rc.top		= 0;
	rc.right	= 1;
	rc.bottom	= 1;

	int nCount = SendMessage(hWndPathList, LB_GETCOUNT, 0, 0);
	if (nCount && nCount != LB_ERR)
	{
		char szBuffer[MAX_PATH] = "";
		for (int i=0; i<nCount; i++)
		{
			SendMessage(hWndPathList, LB_GETTEXT, i, (LPARAM)szBuffer);
			DrawText(hDC, szBuffer, -1, &rc, DT_CALCRECT);
			
			if(rc.right > nWidest) {
				nWidest = rc.right;
			}
		}
	}
	
	SendMessage(hWndPathList, LB_SETHORIZONTALEXTENT, nWidest + 8, 0);
	ReleaseDC(hWndPathList, hDC);
}
