#include "StdAfx.h"
#include "settingview.h"
#include "ServerController.h"
#include "Mmsystem.h"
#include "UserDialog.h"
#include "BandWidthDialog.h"
#include "FileIconDialog.h"

#include "ServerPage1.h"
#include "ServerPage2.h"
#include "ServerPage3.h"
#include "ServerPage4.h"
#include "ServerPage5.h"
#include "SIICGIPage1.h"
#include "SSICGIPage2.h"
#include "SSICGIPage3.h"

#define ITEM_WIDTH	400
#define ITEM_HEIGHT	50

CSettingView::CSettingView(void)
{
	m_tracking = -1;

	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_TOOL),"サーバ基本設定","最大接続数、タイムアウトなどサーバの基本的な設定を行います。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_USER),"ユーザー設定","ユーザー名、パスワードなどの設定を行います。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_SCRIPT),"CGI、SSIの設定","CGIやSSIの設定を行います。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_SINWAVE),"帯域幅制限","サーバのデータ転送速度を制限します。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_IE),"各種表示のカスタマイズ","エラー表示やインデックス表示のカスタマイズを行います。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_INDEX),"ファイル・アイコンの設定","インデックス・リストに表示するアイコンを設定します。"));
	m_settingItem.Add(CSettingItem(GET_APP()->LoadIcon(IDI_UNKNOWN),"MIMEタイプの設定","拡張子とMIMEタイプの関連付けを設定します。"));
}

CSettingView::~CSettingView(void)
{
}
BEGIN_MESSAGE_MAP(CSettingView, CMainViewBase)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_MOUSEWHEEL()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

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

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

//	アイテム描画
void CSettingView::DrawListItem(CDC *pDC,int index,int fover,int fill)
{
	//	現在の表示位置
	int pos = GetScrollPos(SB_VERT);
	if(index + pos >= m_settingItem.GetSize())
		return;

	CSettingItem info = m_settingItem[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.m_selected)
	{
		textColor = TEXT_COLOR_WHITE;
		bkColor = TEXT_COLOR_BLUE;
	}
	else if(fover)
	{
		textColor = TEXT_COLOR_BLUE;
	}
	
	//	枠線の描画
	if(fill == 1 || info.m_selected && 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);

	//	アイコン描画
	CImageList	icon;
	CPoint		pt;
	pt.x = itemRect.left + 5;
	pt.y = itemRect.top + 7;
	icon.Create(32,32,ILC_COLOR24,1,1);
	icon.SetBkColor(bkColor);
	icon.Add(info.m_icon);

	if(!info.m_selected)
	{
		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 + 10,info.m_label);

	CFontSelector normal(pDC,GET_GDI().m_fNormal);
	pDC->TextOut(itemRect.left + 51,itemRect.top + 25,info.m_info);
}

//	スクロールの設定
void CSettingView::SetupScroll()
{
	CRect	client;
	GetClientRect(client);

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

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

	SetScrollInfo(SB_VERT,&info);

	if(canDraw >= m_settingItem.GetSize())
		ShowScrollBar(SB_VERT,FALSE);
	else
		ShowScrollBar(SB_VERT,TRUE);

}

//	サイズ変更
void CSettingView::OnSize(UINT nType, int cx, int cy)
{
	CMainViewBase::OnSize(nType, cx, cy);

	SetupScroll();
}

//	スクロール
void CSettingView::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();

	CMainViewBase::OnVScroll(nSBCode, nPos, pScrollBar);
}

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

	int canDraw = client.Height() / ITEM_HEIGHT;
	if(canDraw == 0)
		canDraw = 1;
   
	if(canDraw < m_settingItem.GetSize())
	{
		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 CMainViewBase::OnMouseWheel(nFlags, zDelta, pt);
}

//	マウス移動
void CSettingView::OnMouseMove(UINT nFlags, CPoint point)
{
	if(m_tracking == -1)
	{
		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);
				if(::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_HAND)))
					::SetCursor(::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_HAND)));
			}
			else
			{
				::SetCursor(::LoadCursor(NULL ,MAKEINTRESOURCE(IDC_ARROW)));
			}

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

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


//	マウスから位置を取得
int CSettingView::GetPointItem(CPoint pt)
{
	//	現在の表示位置取得
	int pos = GetScrollPos(SB_VERT);

	int sel = pt.y / ITEM_HEIGHT;

	if(sel < 0 || sel + pos >= m_settingItem.GetSize())
		return(-1);

	return(sel + pos);
}

//	マウスダウン
void CSettingView::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_tracking = GetPointItem(point);

	CMainViewBase::OnLButtonDown(nFlags, point);
}

//	マウスアップ
void CSettingView::OnLButtonUp(UINT nFlags, CPoint point)
{
	int index = GetPointItem(point);
	if(m_tracking != -1)
	{
		ReleaseCapture();

		CClientDC 	dc(this);

		DrawListItem(&dc,m_tracking,0,0);

		if(m_tracking == index)
		{
			GET_APP()->ClickSound();
			DoCommand(index);
		}
	}

	m_tracking = -1;

	CMainViewBase::OnLButtonUp(nFlags, point);
}


//	選択コマンドを処理
void CSettingView::DoCommand(int command)
{
	switch(command)
	{
		//	サーバ基本設定
		case 0:
			DoServerSetting();
			break;

		//	ユーザー設定
		case 1:
			{
				CUserDialog	user(this);
				user.DoModal();
			}
			break;

		//	CGI/CCI
		case 2:
			DoSSICGISetting();
			break;

		//	帯域幅制限
		case 3:
			{
				CBandWidthDialog	band(this);
				band.DoModal();
			}
			break;

		//	各種表示のカスタマイズ
		case 4:
			if(MessageBox("表示のカスタマイズを行う為には、表示に使用するHTMLファイルを編集する必要があります。\n詳細はドキュメントを参照してください。\nHTMLフォルダを開きますか？","各種表示のカスタマイズ",MB_ICONQUESTION | MB_YESNO) == IDYES)
			{
				CString path = GET_APP()->m_setting.GetConfig("Html::HtmlFileDirectory","%ServerRoot%Html\\");
				path = GET_APP()->GetPathSwap(path);
				::ShellExecute(0, _T("open"), path.GetBuffer(0), 0, 0, SW_SHOWNORMAL);
			}	
			break;

		//	ファイル・アイコンの設定
		case 5:
			{
				CFileIconDialog	file(0,this);
				file.DoModal();
			}
			break;

		//	MIMEタイプの設定
		case 6:
			{
				CFileIconDialog	file(1,this);
				file.DoModal();
			}
			break;
	}

}

//	サーバー設定を実行
void CSettingView::DoServerSetting()
{
	CServerPage1	page1;
	CServerPage2	page2;
	CServerPage3	page3;
	CServerPage4	page4;
	CServerPage5	page5;
	CPropertySheet	sheet("サーバ基本設定",this,0);

	sheet.AddPage(&page1);
	sheet.AddPage(&page2);
	sheet.AddPage(&page3);
	sheet.AddPage(&page4);
	sheet.AddPage(&page5);

	GET_APP()->PushSetting();
	if(sheet.DoModal() != IDOK)
		GET_APP()->PopSetting();
	else
		GET_APP()->SaveSetting();

}


//	SSICGI設定を実行
void CSettingView::DoSSICGISetting()
{
	CSIICGIPage1	page1;
	CSSICGIPage2	page2;
	CSSICGIPage3	page3;
	CPropertySheet	sheet("SSI/CGIの設定",this,0);

	sheet.AddPage(&page1);
	sheet.AddPage(&page2);
	sheet.AddPage(&page3);
	GET_APP()->PushSetting();
	if(sheet.DoModal() != IDOK)
		GET_APP()->PopSetting();
	else
		GET_APP()->SaveSetting();
}
