#include "StdAfx.h"
#include "Xcell.h"
#include "XTable.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

XCell::XCell(XTable* parent)
{
	rowSpan = 0;
	colSpan = 0;

	backColor = RGB (255,255,255);
	borderColor = RGB (0xDC,0xDC,0xDC);

	borderStyle = 0;

	text = "";
	textFontSize = 14;
	textFontFace = "Arial";
	textFont = NULL;
	textColor = RGB (0,0,0);

	label = "";
	labelFontSize = 14;
	labelFontFace = "Arial";
	labelFont =  NULL;
	labelColor = RGB (0,0,0);
	backMode = TRANSPARENT;
	format = 0;
	overlap = false;

	leftMargin = 4;
	rightMargin = 4;
}

XCell::~XCell()
{
	delete textFont;
	delete labelFont;
}

XCell& XCell::operator = (XCell& cell)
{
	if (&cell == this) return *this;

	rowSpan = cell.rowSpan;
	colSpan = cell.colSpan;

	text = cell.text; 
	textColor = cell.textColor;

	delete textFont;
	textFont = NULL;
	if (cell.textFont)
	{
		LOGFONT logFont;
		cell.textFont->GetLogFont (&logFont);

		textFont = new CFont;
		textFont->CreateFontIndirect (&logFont);
	}

	textFontSize = cell.textFontSize;
	textFontFace = cell.textFontFace;

	label = cell.label;
	labelColor = cell.labelColor;

	delete labelFont;
	labelFont = NULL;
	if (cell.labelFont)
	{
		LOGFONT logFont;
		cell.labelFont->GetLogFont (&logFont);

		labelFont = new CFont;
		labelFont->CreateFontIndirect (&logFont);
	}

	labelFontSize = cell.labelFontSize;
	labelFontFace = cell.labelFontFace;

	format = cell.format;
	leftMargin = cell.leftMargin;
	rightMargin = cell.rightMargin;

	backMode = cell.backMode;
	backColor = cell.backColor;

	borderColor = cell.borderColor;
	borderStyle = cell.borderStyle;

	overlap = cell.overlap;

	table = cell.table;

	return *this;
}


int XCell::ToXML (CMarkup& markup)
{
	TCHAR buf[32];

	if (colSpan > 1)
		markup.AddChildAttr ("colSpan", colSpan);
	if (rowSpan > 1)
		markup.AddChildAttr ("rowSpan", rowSpan);

	if (backColor != table->defaultCell.backColor)
	{
		sprintf (buf, "#%.2x%.2x%.2x", GetRValue(backColor), GetGValue(backColor), GetBValue(backColor));
		markup.AddChildAttr ("backColor", buf);
	}
	if (textColor != table->defaultCell.textColor)
	{
		sprintf (buf, "#%.2x%.2x%.2x", GetRValue(textColor), GetGValue(textColor), GetBValue(textColor));
		markup.AddChildAttr ("textColor", textColor);
	}
	if (backMode != table->defaultCell.backMode)
	{
		if (backMode == TRANSPARENT)
			markup.AddChildAttr ("backMode", "transparent");
		else
			markup.AddChildAttr ("backMode", "opaque");
	}

	if (textFontSize != table->defaultCell.textFontSize)
		markup.AddChildAttr ("fontSize", textFontSize);
	if (textFontFace != table->defaultCell.textFontFace)
		markup.AddChildAttr ("fontFace", textFontFace);
	if (textFontSize != table->defaultCell.textFontSize)
		markup.AddChildAttr ("fontWeight", textFontSize);

	int align = GetAlignment();
	if (align != table->defaultCell.GetAlignment())
	{
		if (align & ALIGN_CENTER)
			markup.AddChildAttr("align", "center");
		else if (align & ALIGN_RIGHT)
			markup.AddChildAttr("align", "right");

		if (align & ALIGN_MIDDLE)
			markup.AddChildAttr("vlign", "middle");
		else if (align & ALIGN_BOTTOM)
			markup.AddChildAttr("valign", "bottom");
	}

	bool ellipsis = GetEllipsis ();
	if (ellipsis != table->defaultCell.GetEllipsis())
	{
		if (ellipsis)
			markup.AddChildAttr ("ellipsis", "true");
		else
			markup.AddChildAttr ("ellipsis", "false");
	}

	bool singleLine = GetSingleLine();
	if (singleLine != table->defaultCell.GetSingleLine ())
	{
		if (overlap)
			markup.AddChildAttr ("singleline", "true");
		else
			markup.AddChildAttr ("singleline", "false");
	}

	bool wordBreak = GetWordbreak();
	if (wordBreak != table->defaultCell.GetWordbreak ())
	{
		if (wordBreak)
			markup.AddChildAttr ("wordbreak", "true");
		else
			markup.AddChildAttr ("wordbreak", "false");
	}

	if (leftMargin != table->defaultCell.leftMargin)
		markup.AddChildAttr ("leftMargin", leftMargin);
	if (rightMargin != table->defaultCell.rightMargin)
		markup.AddChildAttr ("rightMargin", rightMargin);

	bool overlap = GetOverlap ();
	if (overlap != table->defaultCell.GetOverlap ())
	{
		if (overlap)
			markup.AddChildAttr ("overlap", "true");
		else
			markup.AddChildAttr ("overlap", "false");
	}

	if (label != table->defaultCell.label)
		markup.AddChildAttr ("label", label);

	if (text != "")
		markup.SetChildData(text);

	return 0;
}

int XCell::FromXML (CMarkup& markup)
{
	CString value;

	*this = table->defaultCell;

	colSpan = 1;
	rowSpan = 1;

	value = markup.GetChildAttr("colSpan");
	if (value != "")
		colSpan = atoi (value);

	value = markup.GetChildAttr("rowSpan");
	if (value != "")
		rowSpan = atoi (value);

	value = markup.GetChildAttr("backColor");
	if (value != "")
	{
		if (*value == '#')
			sscanf(value, "#%x", &backColor);
		else
			backColor = atoi (value);

		backColor = RGB (GetBValue(backColor), GetGValue(backColor), GetRValue(backColor)); 
	}

	value = markup.GetChildAttr("textColor");
	if (value != "")
	{
		if (*value == '#')
			sscanf(value, "#%x", &textColor);
		else
			textColor = atoi (value);
		
		textColor = RGB (GetBValue(textColor), GetGValue(textColor), GetRValue(textColor));
	}

	value = markup.GetChildAttr("fontWeight");
	if (value != "")
		textFontSize = atoi (value);

	value = markup.GetChildAttr("fontFace");
	if (value != "")
		textFontFace = value;

	value = markup.GetChildAttr("backMode");
	if (value != "opaque")
		backMode = TRANSPARENT;
	else
		backMode = OPAQUE;

	value = markup.GetChildAttr("align");
	if (value == "center")
		SetAlignment(ALIGN_CENTER);
	else if (value == "right")
		SetAlignment(ALIGN_RIGHT);

	value = markup.GetChildAttr("valign");
	if (value == "middle")
		SetAlignment(ALIGN_MIDDLE);
	else if (value == "bottom")
		SetAlignment(ALIGN_BOTTOM);

	value = markup.GetChildAttr("ellipsis");
	if (value == "true")
		SetEllipsis(true);
	else
		SetEllipsis(false);

	value = markup.GetChildAttr("singleline");
	if (value == "true")
		SetSingleLine(true);
	else
		SetSingleLine(false);

	value = markup.GetChildAttr("wordbreak");
	if (value == "true")
		SetWordbreak(true);
	else
		SetWordbreak(false);

	value = markup.GetChildAttr("leftMargin");
	if (value != "")
		leftMargin = atoi (value);

	value = markup.GetChildAttr("rightMargin");
	if (value != "")
		rightMargin = atoi (value);

	value = markup.GetChildAttr("overlap");
	if (value == "true")
		overlap = true;
	else
		overlap = false;

	label = markup.GetChildAttr("label");
	text = markup.GetChildData();

	if (text != "")
		text = markup.GetChildData();

 	return 0;
}

int XCell::SetSpan(int rows, int cols)
{
	rowSpan = rows;
	colSpan = cols;

	return 0;
}

int XCell::SetText(CString str)
{
	text = str;

	return 0;
}

CString XCell::GetText()
{
	return text;
}

int XCell::SetTextColor(COLORREF color)
{
	textColor = color;

	return 0;
}

COLORREF XCell::GetTextColor()
{
	return textColor;
}

int XCell::SetAlignment (int align)
{
	if ( (align & ~ALIGN_MASK) != 0) return -1;

	format = (format & ~ALIGN_MASK) | align;

	return 0;
}

int XCell::GetAlignment ()
{
	return format & ALIGN_MASK;
}

int XCell::SetFormat (int format)
{
	this->format = format;

	return 0;
}

int XCell::GetFormat ()
{
	return format;
}

int XCell::SetSingleLine (bool enable)
{
	if (enable)
		format |= DT_SINGLELINE;
	else
		format &= ~DT_SINGLELINE;

	return 0;
}

bool XCell::GetSingleLine ()
{
	return (format & DT_SINGLELINE) != 0;
}

int XCell::SetWordbreak (bool enable)
{
	if (enable)
	{
		format |= DT_WORDBREAK;
     	format |= DT_EDITCONTROL;
	}
	else
	{
		format &= ~DT_WORDBREAK;
	 	format &= ~DT_EDITCONTROL;
	}

	return 0;
}

bool XCell::GetWordbreak ()
{
	return (format & DT_WORDBREAK) != 0;
}

int XCell::SetEllipsis (bool enable)
{
	if (enable)
		format |= DT_END_ELLIPSIS;
	else
		format &= ~DT_END_ELLIPSIS;

	return 0;
}

bool XCell::GetEllipsis ()
{
	return (format & DT_END_ELLIPSIS) != 0;
}

int XCell::SetLeftMargin (int pixels)
{
	leftMargin = pixels;

	return 0;
}

int XCell::GetLeftMargin ()
{
	return leftMargin;
}

int XCell::SetRightMargin (int pixels)
{
	rightMargin = pixels;

	return 0;
}

int XCell::GetRightMargin ()
{
	return rightMargin;
}



int XCell::SetLabel (CString str)
{
	label = str;

	return 0;
}

CString XCell::GetLabel ()
{
	return label;
}

int XCell::SetOverlap (bool enable)
{
	overlap = enable;

	return 0;
}

bool XCell::GetOverlap ()
{
	return overlap;
}

int XCell::SetTextFont(CFont* font)
{
	LOGFONT longfont;

	if (!font->GetLogFont(&longfont))
		return -1;

	if (textFont)
	{
		delete textFont;
		textFont = NULL;
	}
	
	textFont = new CFont;
	textFont->CreateFontIndirect(&longfont);

	return 0;
}

CFont* XCell::GetTextFont()
{
	return textFont;
}

int XCell::SetTextFontSize(int size)
{
	textFontSize = size;

	return 0;
}

int XCell::GetTextFontSize()
{
	return textFontSize;
}

int XCell::SetLabelColor(COLORREF color)
{
	labelColor = color;

	return 0;
}

COLORREF XCell::GetLabelColor()
{
	return labelColor;
}

int XCell::SetLabelFont(CFont* font)
{
	LOGFONT logfont;

	if (!font->GetLogFont(&logfont))
		return -1;

	if (labelFont)
	{
		labelFont->DeleteObject();
		labelFont = NULL;
	}

	labelFont = new CFont;
	labelFont->CreateFontIndirect(&logfont);

	return 0;
}

CFont* XCell::GetLabelFont()
{
	return labelFont;
}

int XCell::SetLabelFontSize(int size)
{
	labelFontSize = size;

	return 0;
}

int XCell::GetLabelFontSize()
{
	return labelFontSize;
}

int XCell::SetBackMode(int mode)
{
	backMode = mode;

	return 0;
}

int XCell::GetBackMode()
{
	return backMode;
}

int XCell::SetBackColor(COLORREF color)
{
	backColor = color;

	return 0;
}

COLORREF XCell::GetBackColor()
{
	return backColor;
}

int XCell::SetBorderSyle(int syle)
{
	borderStyle = syle;

	return 0;
}

int XCell::GetBorderSyle()
{
	return borderStyle;
}

int XCell::DrawText(CDC* pDC, RECT rect)
{
	if (text.IsEmpty()) return 0;

	COLORREF oldTextColor = pDC->SetTextColor (textColor);
	int oldBkMode = pDC->SetBkMode (backMode);
	CFont* oldFont;
	CFont tempFont;

	if (textFont)
		oldFont = pDC->SelectObject (textFont);
	else
	{
		tempFont.CreateFont (textFontSize,0,0, 0, FW_NORMAL, FALSE, FALSE, 0,
				ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
				DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,  textFontFace);
		oldFont = pDC->SelectObject (&tempFont);
	}

	if (leftMargin)
		rect.left += leftMargin;
	if (rightMargin)
		rect.right -= rightMargin;

	pDC->DrawText (text, &rect, format);
//	pDC->DrawText (text, &rect, DT_VCENTER|DT_SINGLELINE);	
	pDC->SetTextColor(oldTextColor);
	pDC->SetBkMode (oldBkMode);
	pDC->SelectObject (oldFont);

	tempFont.DeleteObject ();

	return 0;
}

int XCell::DrawLabel(CDC* pDC, RECT rect)
{
	return 0;
}

int XCell::Draw(CDC* pDC, RECT rect)
{
	DrawBorder (pDC, rect);

	RECT rect1;

	rect1.left = rect.left+1;
	rect1.top = rect.top+1;
	rect1.right = rect.right;
	rect1.bottom = rect.bottom;

	DrawBackground (pDC, rect1);

	DrawText (pDC, rect1);

	return 0;
}

int XCell::DrawBorder(CDC* pDC, RECT rect)
{
	CPen linePen (PS_SOLID, 1, borderColor);

	CPen* pOldPen = pDC->SelectObject(&linePen);

	pDC->MoveTo (rect.left, rect.top);
	pDC->LineTo (rect.right, rect.top);
	pDC->LineTo (rect.right, rect.bottom);
	pDC->LineTo (rect.left, rect.bottom);
	pDC->LineTo (rect.left, rect.top);

	pDC->SelectObject(pOldPen);

	return 0;
}

int XCell::DrawHitBorder (CDC* pDC, RECT rect, COLORREF color) 
{
	CPen pen (PS_SOLID, 3, color);

	CPen* oldPen = pDC->SelectObject(&pen);

	pDC->MoveTo (rect.left, rect.top);
	pDC->LineTo (rect.right, rect.top);
	pDC->LineTo (rect.right, rect.bottom);
	pDC->LineTo (rect.left, rect.bottom);
	pDC->LineTo (rect.left, rect.top);

	pDC->SelectObject(oldPen);
	
	return 0;
}

int XCell::DrawBackground (CDC* pDC, RECT rect)
{
	CBrush bkBrush (backColor);

	pDC->FillRect (&rect, &bkBrush);

	return 0;
}

int XCell::CalcTextRect (CDC* pDC, RECT* rect)
{
	CFont* oldFont;
	CFont tempFont;

	if (textFont)
		oldFont = pDC->SelectObject (textFont);
	else
	{
		tempFont.CreateFont (textFontSize,0,0, 0, FW_NORMAL, FALSE, FALSE, 0,
				ANSI_CHARSET,OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
				DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,  textFontFace);
		oldFont = pDC->SelectObject (&tempFont);
	}

	if (leftMargin)
		rect->left += leftMargin;

	pDC->DrawText (text, rect, format | DT_CALCRECT);
//	pDC->DrawText ("eee3333ttt tt2ww wwddddffffffffvvvvgg2 33 44", rect, format | DT_CALCRECT);	
//	pDC->DrawText (text, rect, DT_EDITCONTROL | DT_WORDBREAK | DT_CALCRECT);	
 
	pDC->SelectObject (oldFont);

	tempFont.DeleteObject ();

	return 0;
}