// CAsGenericTextCell.cpp
//

#include "stdafx.h"
#include "AsGenericTextCell.h"
#include "DrawUtils.h"
#include <assert.h>

CAsGenericTextCell::CAsGenericTextCell():
	editBox_(NULL)
{
	fontInfo_.SetFontName(_T("courier"));
	fontInfo_.SetFontBold(false);
	fontInfo_.SetFontSize(10);
}

CAsGenericTextCell::~CAsGenericTextCell()
{
	KillFocus(false, false);
}

void CAsGenericTextCell::SetDrawArea(const CRect& drawArea)
{
	CAsBaseCell::SetDrawArea(drawArea);

	if (HasFocus()) {
		CRect textArea;

		textArea = GetTextBoxArea();
		editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
	}
}

CSize CAsGenericTextCell::GetMinSize()
{
	return drawArea_.Size();
}

void CAsGenericTextCell::Draw(CDC* pDC)
{
	if (visible_ && !IsHidden()) {
		CAsBaseCell::Draw(pDC);

		if (HasFocus()) {
			if (editBox_)
				editBox_->RedrawWindow();
		}
	}
}

bool CAsGenericTextCell::HitTest(const CPoint& pt)
{
	BOOL ret;

	ret = drawArea_.PtInRect(pt);

	return ret == TRUE;
}

void CAsGenericTextCell::SetText(const cmString& text, bool redraw)
{
	CAsBaseCell::SetText(text, false);

	if (HasFocus() && editBox_)
		editBox_->SetWindowText(text);

	if (parentWnd_ && redraw)
		parentWnd_->RedrawWindow();
}

bool CAsGenericTextCell::ProcessMessage(DWORD msg, DWORD lParam, DWORD wParam, const CPoint& pt, const CRect& parentRect, bool& needRedraw)
{
	bool processed;
	bool selected;
	
	selected = IsSelected();

	processed = CAsBaseCell::ProcessMessage(msg, lParam, wParam, pt, parentRect, needRedraw);
	
	// if selection changed after a WM_LBUTTOMDOWON SetFocus
	//
	if (!selected && IsSelected())
		SetFocus(false);

	switch (msg) {
				
		case WM_KEYDOWN:
		{
			if (HasFocus()) {
				switch (wParam) {
					case VK_ESCAPE:
						KillFocus(false, false);
						processed = true;
						needRedraw = true;
						break;

					case VK_RETURN:
						KillFocus(true, false);
						processed = true;
						needRedraw = true;
						break;
				}
			} else if (IsSelected()) {
				//CString tmp;

				//tmp = _TCHAR(wParam);
				
				//if (!GetAsyncKeyState(VK_LSHIFT) || !GetAsyncKeyState(VK_RSHIFT))
				//	tmp.MakeLower();
				/*SetFocus();
				text_ = (const char*) "";
				editBox_->SetWindowText(_T(""));
				editBox_->SendMessage(msg, wParam, lParam);
				processed = true;
				*/
				//editBox_->SetSel((int)text_.length(), text_.length());

				// TODO !!!
			}
			break;
		}
	}

	return processed;
}

void CAsGenericTextCell::SetFocus(bool redraw)
{
	//TRACE1(_T("Text Set Focus %s\n"), text_.c_str());

	if (HasFocus())
		return;
	
	CAsBaseCell::SetFocus(false);
	
	CRect textArea;

	textArea = GetTextBoxArea();
	
	assert(editBox_ == NULL);
	
	editBox_ = new CEdit;
	editBox_->Create(WS_CHILD | WS_VISIBLE, textArea, parentWnd_, -1);
	font_.CreateFont(-fontInfo_.GetFontSize(), 
					 0,										/* width */ 
					 0,										/* escapement */
					 0,										/* orientation */
					 fontInfo_.GetFontBold() ? FW_BOLD : FW_NORMAL,		/* weight*/
					 0,										/* italic*/
					 0,										/* underline */
					 0,										/* strikeout */
					 ANSI_CHARSET,							/* charset */
					 OUT_DEFAULT_PRECIS,					/* out precision */
					 CLIP_DEFAULT_PRECIS,					/* clip precision */
					 DEFAULT_QUALITY,						/* quality */
					 DEFAULT_PITCH,							/* pitch family */
					 fontInfo_.GetFontName());
	
	editBox_->SetFont(&font_);
	editBox_->SetWindowText(text_);
	editBox_->SetFocus();
	editBox_->SetSel((int)text_.GetLength(), text_.GetLength());
	editBox_->SetWindowPos(&CWnd::wndTop, textArea.left, textArea.top, textArea.Width(), textArea.Height(), SWP_SHOWWINDOW);
	editBox_->ModifyStyleEx(0, WS_EX_CONTROLPARENT);

	if (redraw && parentWnd_)
		parentWnd_->RedrawWindow(drawArea_);
}

void CAsGenericTextCell::SetFontInfo(const CAsFontInfo& fontInfo)
{
	fontInfo_ = fontInfo;

	if (HasFocus() && editBox_) {
		
		fontInfo_.CreateFont();
	
		editBox_->SetFont(fontInfo_.GetFont());
	}
}

void CAsGenericTextCell::KillFocus(bool storeData, bool redraw)
{	
//	TRACE1(_T("Text Kill Focus %s\n"), text_.c_str());

	if (!HasFocus())
		return;

	if (storeData)
		StoreData();

	CAsBaseCell::KillFocus(storeData, false);
	
	if (editBox_ == NULL || !editBox_->GetSafeHwnd())
		return;
	
	delete editBox_;
	editBox_ = NULL;
		
	if (font_.GetSafeHandle())
		font_.DeleteObject();

	if (redraw && parentWnd_)
		parentWnd_->RedrawWindow(drawArea_);
}

void CAsGenericTextCell::SetVisible(bool visible)
{
	CAsBaseCell::SetVisible(visible);

	if (HasFocus() && !visible)
		editBox_->ShowWindow(SW_HIDE);
}

CRect CAsGenericTextCell::GetTextBoxArea()
{
	CRect tmp;

	tmp = drawArea_;
	//tmp.DeflateRect(6, 3, 5, 1);
	tmp.DeflateRect(7, 4, 5, 1);
	return tmp;
}

void CAsGenericTextCell::StoreData()
{
	if (HasFocus()) {
		CString tmp;
		cmString oldValue;

		oldValue = text_;
		editBox_->GetWindowText(tmp);
		
		text_ = (const TCHAR*)tmp;

		if (text_ != oldValue && cellListener_) {
			bool ret;

			ret = cellListener_->OnValueChanged(name_, oldValue, text_);
			if (!ret) {
				editBox_->SetWindowText(oldValue);
				text_ = oldValue;
			}
		}
	}
}

cmString CAsGenericTextCell::GetText()
{
	if (HasFocus())
		StoreData();

	return text_;
}
