#include "stdafx.h"
#include "nlite_include.h"

namespace nlite{


	const static SIZE commentColorBoxSize = {35,0};								//色決定コンボボックスのサイズ
	const static LPCTSTR ANONYMOUS_MAILCOMMAND = TEXT("184");					//184定数文字列
	const static LPCTSTR ANONYMOUS_BOTTONSTRING = ANONYMOUS_MAILCOMMAND;		//184メールコマンド定数文字列
	const static LPCTSTR OWNERMODE_BOTTONSTRING = TEXT("主コメ");				//主コメ選択ボタン定数文字列
	const static LPCTSTR WRITE_BOTTONSTRING = TEXT("書き込み");					//書き込みボタン定数文字列					
	const static COLORREF OWNEREDITCOLOR = RGB(255,192,192);					//主コメ書き込みエディット色
	const static COLORREF NORMALEDITCOLOR = RGB(255,255,255);					//リスナー時の書き込みエディット色
	const static RECT COMMENTWRITEWINDOW_SEPARATEFSIZE = {0,5,0,5};				//コメント書き込みウィンドウの上下スペース
	const static UINT_PTR COMMENTWRITEWINDOW_SIDESEPARATESIZE = 5;				//横スペース幅
	const static UINT_PTR INIT_COMMENTWRITE_MAXLENGTH = 60;						//下記文字列最大長
	const static UINT_PTR CHECKBUTTON_SUBSCRIPT_HEIGHT = 10;					//選択ボタン文字列の高さ
	const static LPCTSTR DEFAULT_COMMENTCOLOR = TEXT("white");					//規定のコメント色
	const static LPCTSTR DEFAULT_COMMENTSIZE = TEXT("medium");					//規定のコメント文字列
	const static LPCTSTR DEFAULT_COMMENTPOS = TEXT("naka");						//規定のコメント表示位置



	namespace generalUser{
		const CommentColorInfo COMMENT_COLORLIST[] = {
			{DEFAULT_COMMENTCOLOR,PALETTERGB(0xFF,0xFF,0xFF)},	//白
			{TEXT("red"),PALETTERGB(0xFF,0x00,0x00)},			//赤
			{TEXT("pink"),PALETTERGB(0xFF,0x80,0x80)},			//ピンク
			{TEXT("orange"),PALETTERGB(0xFF,0xC0,0x00)},		//オレンジ
			{TEXT("yellow"),PALETTERGB(0xFF,0xFF,0x00)},		//黄色
			{TEXT("green"),PALETTERGB(0x00,0xFF,0x00)},			//緑
			{TEXT("cyan"),PALETTERGB(0x00,0xFF,0xFF)},			//寒色
			{TEXT("blue"),PALETTERGB(0x00,0x00,0xFF)},			//青
			{TEXT("purple"),PALETTERGB(0xC0,0x00,0xFF)},		//紫

		};

		const CommentSizeInfo COMMENT_SIZELIST[] = {
			{TEXT("普通　"),DEFAULT_COMMENTSIZE},				//普通サイズ
			{TEXT("小　"),TEXT("small")}						//小サイズ
		};


		const CommentPosInfo COMMENT_POSLIST[] = {
			{TEXT("通常　"),DEFAULT_COMMENTPOS}					//通常表示
		};
	}

	namespace premiumUser{

		const CommentColorInfo COMMENT_COLORLIST[] = {
			{TEXT("black"),PALETTERGB(0x00,0x00,0x00)},			//黒
			{TEXT("white2"),PALETTERGB(0xCC,0xCC,0x99)},		//白その２
			{TEXT("red2"),PALETTERGB(0xCC,0x00,0x33)},			//赤その２
			{TEXT("pink2"),PALETTERGB(0xFF,0x33,0xCC)},			//ピンクその２
			{TEXT("orange2"),PALETTERGB(0xFF,0x66,0x00)},		//オレンジその２
			{TEXT("yellow2"),PALETTERGB(0x99,0x99,0x00)},		//黄色その２
			{TEXT("green2"),PALETTERGB(0x00,0xCC,0x66)},		//緑その２
			{TEXT("cyan2"),PALETTERGB(0x00,0xCC,0xCC)},			//寒色その２
			{TEXT("blue2"),PALETTERGB(0x33,0x99,0xFF)},			//青その２
			{TEXT("purple2"),PALETTERGB(0x66,0x33,0xCC)}		//紫その２
			//	{TEXT("black2"),PALETTERGB(0x66,0x66,0x66)}			//黒その２はない？
		};

		const CommentSizeInfo COMMENT_SIZELIST[] = {
			{TEXT("大　"),TEXT("big")}							//大サイズ
		};



		const CommentPosInfo COMMENT_POSLIST[] = {
			{TEXT("下　"),TEXT("shita")},						//下に表示
			{TEXT("上　"),TEXT("ue")}							//上に表示
		};
	}





	template<typename T>
	static VOID addItemList(CComboBox &combo,T * colorList,UINT_PTR length){

		UINT_PTR startItemcount = combo.GetCount();
		length+= startItemcount;
		for(UINT_PTR index = startItemcount; index < length;index++){

			combo.AddString(colorList[index - startItemcount].name);
			combo.SetItemDataPtr(index,(LPVOID)&colorList[index - startItemcount]);

		}

		return;
	}



	template<typename T>
	static UINT_PTR CalcComboBoxWidth(CComboBox &combo){

		CPaintDC pdc(combo);
		SIZE size;
		UINT_PTR rslt = 0;
		UINT_PTR itemCount = combo.GetCount();
		LPCTSTR name;
		for(UINT_PTR index = 0;index < itemCount;index++){
			name = ((T*)combo.GetItemDataPtr(index))->name;
			::GetTextExtentPoint32(pdc,name,_tcslen(name),&size);
			rslt = rslt < (UINT_PTR)size.cx ? size.cx : rslt;
		}

		return rslt;
	}

	CCommentWriteWindow::CCommentWriteWindow(CNicoLiveStream &in_nicoLiveStream):
	commentWriteHeight(0),
		commentWriteInternalHeight(0),
		commentWriteMaxLength(INIT_COMMENTWRITE_MAXLENGTH),
		nicoLiveStream(in_nicoLiveStream),
		commentSubEdit(*this),
		streamTime(0)
	{}


	BOOL CCommentWriteWindow::IsWrighthing(){

		return this->commentSubEdit.untilConnectingFlag;

	}

	UINT_PTR CCommentWriteWindow::GetHeight(){

		return commentWriteHeight + infoDispHeight - COMMENTWRITEWINDOW_SEPARATEFSIZE.top;
	}


	LRESULT CCommentWriteWindow::OnCreate(LPCREATESTRUCT lpReateStruct){

		//ウィンドウ作成処理

		commentPosBox.Create(m_hWnd,0,WC_COMBOBOX,WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST ,0,COMMENTPOS_BOX);
		commentSizeBox.Create(m_hWnd,0,WC_COMBOBOX,WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST,0,COMMENTSIZE_BOX);
		commentColorBox.Create(m_hWnd,0,WC_COMBOBOX,WS_CHILD | WS_VISIBLE  | CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED ,0,COMMENTCOLOR_BOX);
		anonymousButton.Create(m_hWnd,0,WC_BUTTON,WS_CHILD | WS_VISIBLE |  BS_AUTOCHECKBOX | BS_PUSHLIKE,0,ANONYMOUS_BUTTON);
		ownerModeButton.Create(m_hWnd,0,WC_BUTTON,WS_CHILD |BS_AUTOCHECKBOX | BS_PUSHLIKE,0,OWNERMODE_BUTTON);
		commentSubEdit.Create(m_hWnd,0,WC_EDIT,WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,0,COMMENT_EDIT);
		commentWriteButton.Create(m_hWnd,0,WC_BUTTON,WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,0,COMMENTWRITE_BOTTON);
		commentPosBox.SetFont(AtlGetDefaultGuiFont());
		commentSizeBox.SetFont(AtlGetDefaultGuiFont());
		commentColorBox.SetFont(AtlGetDefaultGuiFont());

		//フォントの設定
		anonymousButton.SetFont(AtlGetDefaultGuiFont());
		commentSubEdit.SetFont(AtlGetDefaultGuiFont());
		commentSubEdit.SetLimitText(commentWriteMaxLength);
		commentWriteButton.SetWindowTextW(WRITE_BOTTONSTRING);
		commentWriteButton.SetFont(AtlGetDefaultGuiFont());

		commentSubEdit.SetWindowTextW(TEXT(""));

		addItemList(commentColorBox,generalUser::COMMENT_COLORLIST,ARRAY_LENGTH(generalUser::COMMENT_COLORLIST));
		addItemList(commentSizeBox,generalUser::COMMENT_SIZELIST,ARRAY_LENGTH(generalUser::COMMENT_SIZELIST));
		addItemList(commentPosBox,generalUser::COMMENT_POSLIST,ARRAY_LENGTH(generalUser::COMMENT_POSLIST));
		commentColorBox.SetCurSel(0);
		commentSizeBox.SetCurSel(0);
		commentPosBox.SetCurSel(0);
		CFontHandle font;
		font = AtlGetDefaultGuiFont();
		CPaintDC pdc(*this);
		SIZE thisSize;

		//ウィンドウの高さを求める
		LPCTSTR sample = TEXT(" ");
		GetTextExtentPoint32(pdc,sample,_tcslen(sample),&thisSize);
		commentWriteHeight = thisSize.cy  + COMMENTWRITEWINDOW_SEPARATEFSIZE.top + COMMENTWRITEWINDOW_SEPARATEFSIZE.bottom;
		infoDispHeight = commentWriteHeight;
		commentWriteInternalHeight = commentWriteHeight - (COMMENTWRITEWINDOW_SEPARATEFSIZE.top + COMMENTWRITEWINDOW_SEPARATEFSIZE.bottom);

		//プッシュライクボタンのフォントを決める
		LOGFONT anonymousLogFont = {0};
		anonymousLogFont.lfHeight = CHECKBUTTON_SUBSCRIPT_HEIGHT;
		anonymousLogFont.lfCharSet = SHIFTJIS_CHARSET;

		checkButtonFont.CreateFontIndirect(&anonymousLogFont);
		anonymousButton.SetFont(checkButtonFont);
		ownerModeButton.SetFont(checkButtonFont);
		CFontHandle f = AtlGetDefaultGuiFont();
		LOGFONT timeLogFont;
		f.GetLogFont(timeLogFont);

		timeLogFont.lfWeight = FW_BOLD;

		timeFont.CreateFontIndirectW(&timeLogFont);
		anonymousButton.SetWindowTextW(ANONYMOUS_MAILCOMMAND);
		ownerModeButton.SetWindowText(OWNERMODE_BOTTONSTRING);
		return 0;
	}

	VOID CCommentWriteWindow::OnDestroy(){
		commentPosBox.DestroyWindow();
		commentSizeBox.DestroyWindow();
		commentColorBox.DestroyWindow();
		anonymousButton.DestroyWindow();
		commentSubEdit.DestroyWindow();
		commentWriteButton.DestroyWindow();

	}



	LRESULT CCommentWriteWindow::OnSize(UINT wParam,SIZE lParam){
		ChangeSize(lParam);
		return 0;
	}
	VOID CCommentWriteWindow::OnPaint(HDC hdc){

		CPaintDC pdc(*this);
		RECT clientRect;
		this->GetClientRect(&clientRect);

		pdc.FillRect(&clientRect,COLOR_BTNFACE);




		pdc.SetBkColor(GetSysColor(COLOR_BTNFACE));
		if(streamTime != 0){

			RECT timeStringRect;

			TCHAR timeString[LENGTH_256];
			_tcscpy(timeString,TEXT("経過時間:"));
			LPTSTR timePtr = timeString + _tcslen(timeString);
			time_t dispTime = static_cast<time_t>(difftime(streamTime,nicoLiveStream.GetStartTime()));
			LPTSTR timeFormat;
			BOOL yetStartFlag = FALSE;
			if(dispTime < 0){
				yetStartFlag = TRUE;
				dispTime = abs(dispTime);
			}

			tm dispTimeStruct = *gmtime(&dispTime);

			if(dispTimeStruct.tm_hour > 0 && yetStartFlag == TRUE){

				timeFormat = TEXT("-%H:%M:%S");

			} else if(dispTimeStruct.tm_hour <= 0 && yetStartFlag == TRUE){

				timeFormat = TEXT("   -%M:%S");

			} else if(dispTimeStruct.tm_hour > 0){

				timeFormat = TEXT(" %H:%M:%S");

			}else {

				timeFormat = TEXT("    %M:%S");

			}

			_tcsftime(timePtr,ARRAY_LENGTH(timeString) - _tcslen(timeString),timeFormat,&dispTimeStruct);

			INT_PTR len = _tcslen(timeString);
			pdc.SelectFont(timeFont);


			timeStringRect.top = COMMENTWRITEWINDOW_SEPARATEFSIZE.top;
			timeStringRect.left = COMMENTWRITEWINDOW_SIDESEPARATESIZE;
			timeStringRect.bottom =timeStringRect.top;
			timeStringRect.right = timeStringRect.bottom;
			pdc.DrawTextW(timeString,len,&timeStringRect,DT_CALCRECT);
			pdc.DrawTextW(timeString,len,&timeStringRect,0);
		}




		return;
	}

	VOID CSubChatEdit::EnterChatBox(LPVOID userData){


		auto owner = ((CSubChatEdit*)userData)->self;
		auto &self = *((CSubChatEdit*)userData);
		CCommentMaker commentMaker;
		std::vector<TCHAR> chat(owner.commentSubEdit.GetWindowTextLengthW() + 1);


		owner.commentSubEdit.GetWindowTextW(&chat[0],chat.size());
		commentMaker.SetChatString(&chat[0]);
		if(owner.anonymousButton.GetCheck() == BST_CHECKED){

			commentMaker.AddMail(ANONYMOUS_MAILCOMMAND);
		}
		INT_PTR sizeIndex = owner.commentSizeBox.GetCurSel();
		if(sizeIndex == CB_ERR)sizeIndex = 0;
		auto &rCommentSizeInfo = *(CommentSizeInfo*)owner.commentSizeBox.GetItemDataPtr(sizeIndex);

		if(_tcscmp(rCommentSizeInfo.userData,DEFAULT_COMMENTSIZE) != 0){

			commentMaker.AddMail(rCommentSizeInfo.userData);

		}
		INT_PTR posIndex = owner.commentPosBox.GetCurSel();
		if(posIndex == CB_ERR)posIndex = 0;
		auto &rCommentPosInfo = *(CommentPosInfo*)owner.commentPosBox.GetItemDataPtr(posIndex);

		if(_tcscmp(rCommentPosInfo.userData,DEFAULT_COMMENTPOS) != 0){

			commentMaker.AddMail(rCommentPosInfo.userData);
		}

		INT_PTR colorIndex = owner.commentColorBox.GetCurSel();
		if(colorIndex == CB_ERR)colorIndex = 0;
		auto &rCommentColorInfo = *(CommentColorInfo*)owner.commentColorBox.GetItemDataPtr(colorIndex);

		if(_tcscmp(rCommentColorInfo.name,DEFAULT_COMMENTCOLOR) != 0){

			commentMaker.AddMail(rCommentColorInfo.name);
		}


		NLIB_RESULT code = NLIB_ERR_CODE_NOTSET;

		if(owner.nicoLiveStream.IsOwner() ==TRUE && owner.ownerModeButton.GetCheck() == BST_CHECKED){

			code = owner.nicoLiveStream.SendOwnerChat(commentMaker);

		} else {

			code = owner.nicoLiveStream.SendChat(commentMaker);

		}

		switch(code){

		case NLIB_ERR_OK:


			owner.commentSubEdit.SetWindowText(TEXT(""));
			goto end;

		case NLIB_ERR_NOT_LIVECONNECT:
		case NLIB_FAILED_CONNECT:	
			::MessageBox(owner,NLIB_GetErrorMessage(code),TEXT("コメント書き込みエラー"),MB_ICONERROR | MB_OK);
			owner.commentSubEdit.AgreeEnter();
			break;





		default:
			UnexpectedErrorMessageShow(TEXT("コメント書き込み中に"),NLIB_GetErrorMessage(code),__LINE__,TEXT(__FILE__),TEXT(__FUNCTION__));
			owner.commentSubEdit.AgreeEnter();
			break;

		}


end:




		self.AgreeEnter();

		_endthread();
		return;
	}

	BOOL CCommentWriteWindow::SendChat(){
		this->commentSubEdit.untilConnectingFlag = TRUE;
		this->commentSubEdit.SetReadOnly(TRUE);
		_beginthread(CSubChatEdit::EnterChatBox,0,&this->commentSubEdit);







		return TRUE;
	}


	BOOL CCommentWriteWindow::SetText(LPCTSTR lpStr){

		BOOL rslt = this->commentSubEdit.SetWindowText(lpStr);
		if(rslt == TRUE){
			commentSubEdit.SetFocus();
			int cursor = commentSubEdit.GetWindowTextLength();
			commentSubEdit.SetSel(cursor,cursor);
			//commentSubEdit.ShowCaret();
		}
		return rslt; 
	}

	VOID CCommentWriteWindow::OnChatReceveStart(CNicoLiveStream &nicoLiveStream,NicoLiveThreadComment_P threadComment){

		this->ShowWindow(SW_HIDE);
		this->commentColorBox.ResetContent();
		this->commentPosBox.ResetContent();
		this->commentSizeBox.ResetContent();

		addItemList(commentColorBox,generalUser::COMMENT_COLORLIST,ARRAY_LENGTH(generalUser::COMMENT_COLORLIST));
		addItemList(commentSizeBox,generalUser::COMMENT_SIZELIST,ARRAY_LENGTH(generalUser::COMMENT_SIZELIST));
		addItemList(commentPosBox,generalUser::COMMENT_POSLIST,ARRAY_LENGTH(generalUser::COMMENT_POSLIST));


		if(nicoLiveStream.IsPremium() == TRUE){

			addItemList(commentColorBox,premiumUser::COMMENT_COLORLIST,ARRAY_LENGTH(premiumUser::COMMENT_COLORLIST));
			addItemList(commentSizeBox,premiumUser::COMMENT_SIZELIST,ARRAY_LENGTH(premiumUser::COMMENT_SIZELIST));
			addItemList(commentPosBox,premiumUser::COMMENT_POSLIST,ARRAY_LENGTH(premiumUser::COMMENT_POSLIST));

		}
		this->commentColorBox.SetCurSel(0);
		this->commentPosBox.SetCurSel(0);
		this->commentSizeBox.SetCurSel(0);



		this->ShowWindow(SW_SHOW);
		this->streamTime = threadComment->server_time;
		this->SetTimer(TIMER_ID,1000,NULL);
		if(nicoLiveStream.IsOwner() == TRUE){

			this->ownerModeButton.ShowWindow(SW_SHOW);
			ownerModeButton.SetCheck(BST_CHECKED);
			editBkColor = OWNEREDITCOLOR;

		} else {

			this->ownerModeButton.ShowWindow(SW_HIDE);
			editBkColor = NORMALEDITCOLOR;

		}

		if(this->editBkBrush.IsNull() ==FALSE){
			editBkBrush.DeleteObject();
		}

		editBkBrush.CreateSolidBrush(editBkColor);
		SIZE size;
		RECT windowRect;
		this->GetClientRect(&windowRect);
		size.cx = windowRect.right - windowRect.left;
		size.cy = windowRect.bottom - windowRect.top;
		ChangeSize(size);

		return;
	}

	VOID CCommentWriteWindow::ChangeSize(SIZE &size){

		SIZE commentAnonymousButtonSize;
		SIZE commentWriteButtonSize;
		commentWriteButton.GetIdealSize(&commentWriteButtonSize);
		anonymousButton.GetIdealSize(&commentAnonymousButtonSize);
		UINT_PTR defwindowCount = 0;
		RECT commentPosBoxRect;
		RECT commentSizeBoxRect;
		RECT commentColorBoxRect;
		RECT anonymousButtonRect;
		RECT commentEditRect;
		RECT commentWriteButtonRect;
		RECT ownerModeButtonRect;
		RECT thisWindowRect;

		UINT_PTR writeSpaceHeight = COMMENTWRITEWINDOW_SEPARATEFSIZE.top * 2 + commentWriteInternalHeight;
		this->GetWindowRect(&thisWindowRect);

		commentPosBoxRect.left = COMMENTWRITEWINDOW_SIDESEPARATESIZE;
		this->commentPosBoxCS.Lock();
		commentPosBoxRect.right = commentPosBoxRect.left + CalcComboBoxWidth<CommentPosInfo>(commentPosBox);
		this->commentPosBoxCS.Unlock();

		commentSizeBoxRect.left = commentPosBoxRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
		this->commentSizeBoxCS.Lock();
		commentSizeBoxRect.right = commentSizeBoxRect.left + CalcComboBoxWidth<CommentSizeInfo>(commentSizeBox);
		this->commentSizeBoxCS.Unlock();

		commentColorBoxRect.left = commentSizeBoxRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
		commentColorBoxRect.right = commentColorBoxRect.left + commentColorBoxSize.cx;



		anonymousButtonRect.left = commentColorBoxRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
		anonymousButtonRect.right = anonymousButtonRect.left + commentAnonymousButtonSize.cx;

		if(ownerModeButton.IsWindowVisible() == TRUE){


			SIZE ownerModeButtonSize;
			ownerModeButton.GetIdealSize(&ownerModeButtonSize);
			ownerModeButtonRect.left = anonymousButtonRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
			ownerModeButtonRect.right = ownerModeButtonRect.left + ownerModeButtonSize.cx;
			commentEditRect.left = ownerModeButtonRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
			defwindowCount = 7;
		} else {

			commentEditRect.left = anonymousButtonRect.right + COMMENTWRITEWINDOW_SIDESEPARATESIZE;
			defwindowCount = 6;
		}

		commentWriteButtonRect.right = size.cx - COMMENTWRITEWINDOW_SIDESEPARATESIZE;
		commentWriteButtonRect.left = commentWriteButtonRect.right - commentWriteButtonSize.cx;

		commentEditRect.right = commentWriteButtonRect.left - COMMENTWRITEWINDOW_SIDESEPARATESIZE;



		//移動処理
		HDWP hDwp = BeginDeferWindowPos(defwindowCount);

		commentPosBox.DeferWindowPos(hDwp,*this,
			commentPosBoxRect.left,writeSpaceHeight,commentPosBoxRect.right - commentPosBoxRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		commentSizeBox.DeferWindowPos(hDwp,*this,
			commentSizeBoxRect.left,writeSpaceHeight,commentSizeBoxRect.right - commentSizeBoxRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		commentColorBox.DeferWindowPos(hDwp,*this,
			commentColorBoxRect.left,writeSpaceHeight,commentColorBoxRect.right - commentColorBoxRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		anonymousButton.DeferWindowPos(hDwp,*this,
			anonymousButtonRect.left,writeSpaceHeight,anonymousButtonRect.right - anonymousButtonRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		if(ownerModeButton.IsWindowVisible() == TRUE){
			ownerModeButton.DeferWindowPos(hDwp,*this,
				ownerModeButtonRect.left,writeSpaceHeight,ownerModeButtonRect.right - ownerModeButtonRect.left,commentWriteInternalHeight,
				SWP_NOZORDER);

		}
		commentSubEdit.DeferWindowPos(hDwp,*this,
			commentEditRect.left,writeSpaceHeight,commentEditRect.right - commentEditRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		commentWriteButton.DeferWindowPos(hDwp,*this,
			commentWriteButtonRect.left,writeSpaceHeight,commentWriteButtonRect.right - commentWriteButtonRect.left,commentWriteInternalHeight,
			SWP_NOZORDER);

		EndDeferWindowPos(hDwp);

		return;
	}

	VOID CCommentWriteWindow::OnDrawItem(UINT wParam,LPDRAWITEMSTRUCT lParam){



		if(lParam->hwndItem == commentColorBox.m_hWnd && commentColorBox.GetCount() > 0){



			RECT drawRect = lParam->rcItem;
			UINT_PTR itemNo = 0;
			INT_PTR curselNo = commentColorBox.GetCurSel();
			CDCHandle dcHandle = lParam->hDC;
			CBrush bkBrush;
			const UINT_PTR width = 1;
			drawRect.left += width;
			drawRect.top += width;
			drawRect.right -= width;
			drawRect.bottom -= width;

			if(lParam->itemID == ((UINT)-1)){
				itemNo = curselNo == CB_ERR ? 0 : curselNo;
			} else {
				itemNo = lParam->itemID;
			}

			CommentInfo<COLORREF> &commentColor = *(CommentInfo<COLORREF> *)commentColorBox.GetItemDataPtr(itemNo);


			if(lParam->itemState & (ODS_FOCUS | ODS_COMBOBOXEDIT)){



				bkBrush.CreateSolidBrush(PALETTERGB(160,160,160));

			} else {

				bkBrush.CreateSolidBrush(PALETTERGB(255,255,255));

			}




			CBrush brush;
			CPen cpen;

			brush.CreateSolidBrush(commentColor.userData);
			dcHandle.SelectBrush(brush);
			dcHandle.FillRect(&lParam->rcItem,bkBrush);
			dcHandle.SelectBrush(brush);
			dcHandle.SelectPen((HPEN)::GetStockObject(BLACK_PEN));
			dcHandle.Rectangle(&drawRect);

		}

		return;
	}

	LRESULT CCommentWriteWindow::OnEraseBkGnd(HDC wParam){

		return TRUE;
	}


	LRESULT CCommentWriteWindow::OnCtlolorEdit(HDC hdc,HWND hWnd){

		if(hWnd == this->commentSubEdit){


			SetBkMode(hdc, TRANSPARENT);	// 背景を透過
			SetBkColor(hdc,this->editBkColor);	// テキストが書かれている部分のテキストの背景の色

			return (LRESULT)editBkBrush.m_hBrush;
		}

		return 0;
	}

	LRESULT CCommentWriteWindow::OnButton(UINT hiWparam,INT_PTR loWparam,HWND lParam){

		if(lParam == commentWriteButton){

			this->SendChat();

		} else if(lParam == this->ownerModeButton){

			if(this->ownerModeButton.GetCheck() == BST_CHECKED){

				this->editBkColor = OWNEREDITCOLOR;

			} else {

				this->editBkColor = NORMALEDITCOLOR;
			}

			if(this->editBkBrush.IsNull() == FALSE){

				this->editBkBrush.DeleteObject();

			}

			this->editBkBrush.CreateSolidBrush(editBkColor);
			commentSubEdit.Invalidate();

		}

		return TRUE;
	}

	VOID CCommentWriteWindow::OnTimer(UINT id){
		streamTime++;
		this->Invalidate();

		return;
	}

	VOID CCommentWriteWindow::OnMeasureItem(UINT wParam,LPMEASUREITEMSTRUCT lParam){

		switch(lParam->CtlID){

		case COMMENTCOLOR_BOX:
			{
				SIZE itemSize;
				CPaintDC pdc(*this);
				pdc.SelectFont(AtlGetDefaultGuiFont());
				LPCTSTR sample = TEXT(" ");
				::GetTextExtentPoint32(pdc,sample,_tcslen(sample),&itemSize);
				lParam->itemHeight = itemSize.cy;

			}
			break;

		}



		return;
	}




	VOID CCommentWriteWindow::OnSendChatResult(){

		commentSubEdit.AgreeEnter();
		return;
	}



	VOID CCommentWriteWindow::OnHeartBeat(NicoLiveHeartBeat_P heartBeat){

		if(heartBeat->status == NLIB_ERR_OK){
			streamTime = heartBeat->time;

		}

		return;
	}

	VOID CCommentWriteWindow::OnDisConnect(){

		this->KillTimer(TIMER_ID);

		return;
	}


	//
	//CSubChatEditクラス
	//////////////////////////////////////////////////////////////////////////////////////

	void CSubChatEdit::OnKeyDown(TCHAR wParam, UINT upLParam,UINT loLParam){
		if(wParam == VK_RETURN){

			cs.Lock();

			if(untilConnectingFlag == FALSE){



				self.SendChat();
			}

			cs.Unlock();


		} else {

			this->DefWindowProc();

		}
		return;
	}


	VOID CSubChatEdit::AgreeEnter(){
		cs.Lock();
		this->SetReadOnly(FALSE);
		untilConnectingFlag = FALSE;
		cs.Unlock();
	}

}