// DirectoryListCtrl.cpp : 幚憰僼傽僀儖
//

#include "stdafx.h"
#include "ServerController.h"
#include "DirectoryListCtrl.h"

#define ITEM_WIDTH	400
#define ITEM_HEIGHT	68


// CDirectoryListCtrl

IMPLEMENT_DYNAMIC(CDirectoryListCtrl, CWnd)
CDirectoryListCtrl::CDirectoryListCtrl()
{
	m_pathSetting = GET_APP()->m_setting.GetAccess("Path");
}

CDirectoryListCtrl::~CDirectoryListCtrl()
{
	DestroyWindow();
}


BEGIN_MESSAGE_MAP(CDirectoryListCtrl, CWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_VSCROLL()
	ON_WM_SIZE()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()



// CDirectoryListCtrl 儊僢僙乕僕 僴儞僪儔


BOOL CDirectoryListCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

//	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_ARROW), GET_GDI().m_bWhite, NULL);

	return TRUE;
}

int CDirectoryListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	return 0;
}

void CDirectoryListCtrl::OnPaint()
{
	CPaintDC dc(this); // device context for painting

	for(int i=0;i<GetItemCount();i++)
	{
		DrawListItem(&dc,i,0);
	}
}

//	傾僀僥儉悢庢摼
int	CDirectoryListCtrl::GetItemCount()
{
	return(m_pathSetting.GetSubNodeCount());
}

//	傾僀僥儉昤夋
void CDirectoryListCtrl::DrawListItem(CDC *pDC,int index,int fover,int fill)
{
	//	尰嵼偺昞帵埵抲
	int pos = GetScrollPos(SB_VERT);
	CStringArray	list;
	m_pathSetting.GetAllSubNode(list);
	
	if(index + pos >= list.GetSize())
		return;

	CWorkspaceAccess	info = m_pathSetting.GetAccess(list[index+pos]);

	CRect	client;
	GetClientRect(client);

	int	width;
	if(client.Width() < ITEM_WIDTH)
		width = ITEM_WIDTH;
	else
		width = client.Width() - LINE_PADDING;

	CRect	itemRect(0,0,width,ITEM_HEIGHT);
	itemRect.OffsetRect(0,ITEM_HEIGHT * index);

	DWORD	textColor = TEXT_COLOR_GRAY;
	DWORD	bkColor = TEXT_COLOR_WHITE;

	if(info.GetConfig("Selected",0))
	{
		textColor = TEXT_COLOR_WHITE;
		bkColor = TEXT_COLOR_BLUE;
	}
	else if(fover)
	{
		textColor = TEXT_COLOR_BLUE;
	}
	
	//	榞慄偺昤夋
	if((fill == 1 || info.GetConfig("Selected",0)) && fover==0)
		pDC->FillSolidRect(itemRect,bkColor);

	CPenSelector	gray(pDC,GET_GDI().m_pGray);
	
	pDC->MoveTo(itemRect.left,itemRect.bottom-1);
	pDC->LineTo(itemRect.right,itemRect.bottom-1);
	pDC->MoveTo(itemRect.left+51,itemRect.top + 48);
	pDC->LineTo(itemRect.right,itemRect.top + 48);

	//	傾僀僐儞昤夋
	CImageList	icon;
	CPoint		pt;
	pt.x = itemRect.left + 5;
	pt.y = itemRect.top + 5;
	icon.Create(32,32,ILC_COLOR24,1,1);
	icon.SetBkColor(bkColor);
	icon.Add(GET_APP()->LoadIcon(IDI_FOLDER));

	if(!info.GetConfig("Selected",0))
	{
		icon.Draw(pDC,0,pt,ILD_TRANSPARENT);
	}
	else
	{
		ImageList_DrawEx(icon.m_hImageList,0,pDC->m_hDC,pt.x,pt.y,0,0,CLR_NONE,bkColor,ILD_BLEND50 | ILD_TRANSPARENT);
	}

	//	暥帤偺昤夋
	CFontSelector bold(pDC,GET_GDI().m_fBold);
	pDC->SetBkMode(TRANSPARENT);
	pDC->SetTextColor(textColor);
	pDC->TextOut(itemRect.left + 51,itemRect.top + 5,info.GetConfig("Info",""));

	CFontSelector normal(pDC,GET_GDI().m_fNormal);
	if(info.GetConfig("VirtualHost","*") != "*")
		pDC->TextOut(itemRect.left + 51,itemRect.top + 20,"Server : <" + info.GetConfig("VirtualHost","*") + "> " + info.GetConfig("ServerPath",""));
	else
		pDC->TextOut(itemRect.left + 51,itemRect.top + 20,"Server : " + info.GetConfig("ServerPath",""));

	if(info.GetConfig("Forward","").IsEmpty())
		pDC->TextOut(itemRect.left + 51,itemRect.top + 34,"Local : " + info.GetConfig("LocalPath",""));
	else
		pDC->TextOut(itemRect.left + 51,itemRect.top + 34,"Forward : " + info.GetConfig("Forward",""));
	pDC->TextOut(itemRect.left + 51,itemRect.top + 52,GetSettingString(info.GetAccess("Options")));

}

//	徻嵶忣曬偺庢摼
CString CDirectoryListCtrl::GetSettingString(CWorkspaceAccess info)
{
	CString	draw;

	if(info.GetConfig("EnableAuthenticate",0))
		draw += "擣徹 : 仜    ";
	else
		draw += "擣徹 : 亊    ";

	if(info.GetConfig("EnableIndex",0))
		draw += "Index : 仜    ";
	else
		draw += "Index : 亊    ";

	if(info.GetConfig("EnableSSICGI",0))
		draw += "SSI/CGI : 仜    ";
	else
		draw += "SSI/CGI : 亊    ";

	if(info.GetConfig("EnableWebDAV",0))
		draw += "WebDAV : 仜    ";
	else
		draw += "WebDAV : 亊    ";

	if(info.GetConfig("EnableWrite",0))
		draw += "彂偒崬傒 : 仜    ";
	else
		draw += "彂偒崬傒 : 亊    ";

	if(info.GetConfig("EnableHiddenFile",0))
		draw += "塀偟僼傽僀儖 : 仜    ";
	else
		draw += "塀偟僼傽僀儖 : 亊    ";

	if(info.GetConfig("EnableBandWidthLimit",0))
		draw += "懷堟惂尷 : 仜    ";
	else
		draw += "懷堟惂尷 : 亊    ";

	if(info.GetConfig("AcceptHTTP",1))
		draw += "HTTP : 仜    ";
	else
		draw += "HTTP : 亊    ";

	if(info.GetConfig("AcceptHTTPS",1))
		draw += "HTTPS : 仜    ";
	else
		draw += "HTTPS : 亊    ";


	return(draw);
}


//	僗僋儘乕儖偺愝掕
void CDirectoryListCtrl::SetupScroll()
{
	CRect	client;
	GetClientRect(client);

	int canDraw = client.Height() / ITEM_HEIGHT;
	if(canDraw == 0)
		canDraw = 1;
    
	int cur = GetScrollPos(SB_VERT);
	if(cur >= GetItemCount())
		cur = GetItemCount()-1;

	SCROLLINFO	info;
	info.cbSize = sizeof(SCROLLINFO);
	info.fMask = SIF_ALL;
	info.nMax = GetItemCount()-1;
	info.nMin = 0;
	info.nPage = canDraw;
	info.nPos = cur;
	info.nTrackPos = 0;

	SetScrollInfo(SB_VERT,&info);

	if(canDraw >= GetItemCount())
		ShowScrollBar(SB_VERT,FALSE);
	else
		ShowScrollBar(SB_VERT,TRUE);

}


void CDirectoryListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	int y = GetScrollPos(SB_VERT);
	SCROLLINFO info;
	GetScrollInfo(SB_VERT, &info, SIF_PAGE|SIF_RANGE);

	int	update=1;
	switch (LOBYTE(nSBCode))
	{
	case SB_TOP:
		y = 0;
		break;
	case SB_BOTTOM:
		y = INT_MAX;
		break;
	case SB_LINEUP:
		y -= 1;
		break;
	case SB_LINEDOWN:
		y += 1;
		break;
	case SB_PAGEUP:
		y -= info.nPage;
		break;
	case SB_PAGEDOWN:
		y += info.nPage;
		break;
	case SB_THUMBTRACK:
		y = nPos;
		update = 0;
		break;
	}
	SetScrollPos(SB_VERT, y);

	Invalidate();
}

void CDirectoryListCtrl::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	SetupScroll();
}

//	儅僂僗偐傜埵抲傪庢摼
int CDirectoryListCtrl::GetPointItem(CPoint pt)
{
	//	尰嵼偺昞帵埵抲庢摼
	int pos = GetScrollPos(SB_VERT);

	int sel = pt.y / ITEM_HEIGHT;

	if(sel < 0 || sel + pos >= GetItemCount())
		return(-1);

	return(sel);
}

void CDirectoryListCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	CClientDC 	dc(this);

	static int oldSel = -1;
	CRect	client;

	GetClientRect(client);
	if(client.PtInRect(point))
	{
		int sel = GetPointItem(point);
		if(oldSel!=-1 && oldSel != sel)
		{
			DrawListItem(&dc,oldSel,0,0);
		}

		if(sel!=-1)
		{
			DrawListItem(&dc,sel,1,0);
		}

		oldSel = sel;
		SetCapture();
		SetFocus();
	}
	else
	{
		ReleaseCapture();

		if(oldSel!=-1)
		{
			DrawListItem(&dc,oldSel,0,0);
		}
	}
		
	CWnd::OnMouseMove(nFlags, point);
}

void CDirectoryListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	static int oldSelect = -1;

	CStringArray	list;
	m_pathSetting.GetAllSubNode(list);
	int	click = GetPointItem(point);
	int	index = GetScrollPos(SB_VERT) + click;

	//	慖戰夝彍	
	if(click == -1)
	{
		for(int i=0;i<list.GetSize();i++)
			m_pathSetting.GetAccess(list[i]).SetConfig("Selected",0);
	}
	else
	{
		if(GetAsyncKeyState(VK_SHIFT) & 0x8000 && oldSelect != -1)
		{
			for(int i=0;i<list.GetSize();i++)
				m_pathSetting.GetAccess(list[i]).SetConfig("Selected",0);

			if(index > oldSelect)
			{
				for(int i=oldSelect;i<=index;i++)
				{
					m_pathSetting.GetAccess(list[i]).SetConfig("Selected",1);
				}
			}
			else
			{
				for(int i=index;i<=oldSelect;i++)
				{
					m_pathSetting.GetAccess(list[i]).SetConfig("Selected",1);
				}
			}
		}
		else if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
		{
			m_pathSetting.GetAccess(list[index]).SetConfig("Selected",1 - m_pathSetting.GetAccess(list[index]).GetConfig("Selected",0));
			oldSelect = index;
		}
		else
		{
			for(int i=0;i<list.GetSize();i++)
				m_pathSetting.GetAccess(list[i]).SetConfig("Selected",0);

			m_pathSetting.GetAccess(list[index]).SetConfig("Selected",1);
			oldSelect = index;
		}
	}

	RedrawItem();
	CWnd::OnLButtonDown(nFlags, point);
}

//	傾僀僥儉嵞昤夋
void CDirectoryListCtrl::RedrawItem()
{
	CClientDC 	dc(this);

	for(int i=0;i<GetItemCount();i++)
	{
		DrawListItem(&dc,i,0,1);
	}
}

void CDirectoryListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	ReleaseCapture();
	GetParent()->SendMessage(USER_MESG_TOOL_CLICK,TOOL_BUTTON_COMMAND_START + 1,0);

	CWnd::OnLButtonDblClk(nFlags, point);
}

//	慡偰峏怴
void CDirectoryListCtrl::UpdateAll()
{
	SetupScroll();
	Invalidate();
}

//	Wheel
BOOL CDirectoryListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	CRect	client;
	GetClientRect(client);

	int canDraw = client.Height() / ITEM_HEIGHT;
	if(canDraw == 0)
		canDraw = 1;
   
	if(canDraw < GetItemCount())
	{
		SCROLLINFO info;
		GetScrollInfo(SB_VERT, &info, SIF_PAGE|SIF_RANGE);
		int y = GetScrollPos(SB_VERT);

		if(zDelta < 0)
		{
			if(y <= (int)(info.nMax - info.nPage))
			{
				y += 1;
				SetScrollPos(SB_VERT, y);
				Invalidate();
			}
		}
		else
		{
			if(y > info.nMin)
			{
				y -= 1;
				SetScrollPos(SB_VERT, y);
				Invalidate();
			}
		}

	}

	return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}
