// XBMDraw.cpp: implementation of the XBMDraw class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XBMDraw.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

XBMDraw::XBMDraw()
{
	m_nWidth = m_nHeight = 0;
	m_pImage = NULL;
}

XBMDraw::~XBMDraw()
{
	try
	{
		if(m_pImage)
			delete[] m_pImage;
	}
	catch(...)
	{
	}
}

bool XBMDraw::CreateImage(CString sName, int nWidth, int nHeight, BYTE bBackground)
{
	try
	{
		m_sName = sName;
		m_nWidth = nWidth;
		m_nHeight = nHeight;

		if(m_pImage)
			delete[] m_pImage;

		m_pImage = new BYTE[m_nWidth * m_nHeight];
		memset(m_pImage, bBackground, m_nWidth * m_nHeight);

		return true;
	}
	catch(...)
	{
	}
	return false;
}

bool XBMDraw::GetImage(CString &sImage)
{
	try
	{
		if(m_pImage)
		{
			int nRealWidth = m_nWidth / 8;
			if(m_nWidth % 8 != 0)
				nRealWidth++;
			long nSize = nRealWidth * m_nHeight * 6 + 1;
			BYTE *sBits = new BYTE[nSize];
			memset(sBits, 0, nSize);
			int nCount = 0;
			for(int i = 0; i < nRealWidth * m_nHeight; i++)
			{
				TCHAR sBit[20];
				sprintf(sBit, "0x%x", m_pImage[i]);
				if(i < (nRealWidth * m_nHeight - 1))
					strcat(sBit, ", ");

				for(unsigned int j = 0; j < strlen(sBit) + 1; j++)
					sBits[nCount + j] = sBit[j];

				nCount += strlen(sBit);
			}

			sImage.Format("\n<script language=\"javascript\">\n%s = \'#define _width %d\\n#define _height %d\\nstatic unsigned char _bits[] = { %s }\'\n</script>\n",
				m_sName.GetBuffer(0), m_nWidth, m_nHeight, sBits);

			delete[] sBits;

			return true;
		}
	}
	catch(...)
	{
	}
	return false;
}

bool XBMDraw::Plot(int x, int y, bool bXOR)
{
	try
	{
		if(m_pImage)
		{
			if(x >= 0 && x < m_nWidth && y >= 0 && y < m_nHeight)
			{
				int nRealWidth = m_nWidth / 8;
				if(m_nWidth % 8 != 0)
					nRealWidth++;
				int nPos = nRealWidth * (m_nHeight - y - 1) + (x / 8);
				BYTE nVal = 1 << (x % 8);
				if(m_pImage[nPos] & nVal && bXOR)
					m_pImage[nPos] &= (0xff & ~nVal);
				else
					m_pImage[nPos] |= nVal;
				
				return true;
			}
		}
	}
	catch(...)
	{
	}
	return false;
}

CString XBMDraw::GetImageTag()
{
	try
	{
		CString sRet;
		sRet.Format("<img src=\"javascript:%s\" width=\"%d\" height=\"%d\">", m_sName.GetBuffer(0), m_nWidth, m_nHeight);
		return sRet;
	}
	catch(...)
	{
	}
	return "";
}

bool XBMDraw::Line(int x1, int y1, int x2, int y2, bool bXOR)
{
	try
	{
		if(m_pImage)
		{
			int dX = abs(x2 - x1);
			int dY = abs(y2 - y1);
			int Xincr, Yincr;
			if (x1 > x2) { Xincr=-1; } else { Xincr=1; }
			if (y1 > y2) { Yincr=-1; } else { Yincr=1; }
			
			if (dX >= dY)
			{           
				int dPr 	= dY << 1;
				int dPru 	= dPr - (dX << 1);
				int P 		= dPr - dX;

				for (; dX >= 0; dX--)
				{
					Plot(x1, y1, bXOR);
					if (P > 0)
					{ 
						x1 += Xincr;
						y1 += Yincr;
						P += dPru;
					}
					else
					{
						x1 += Xincr;
						P += dPr;
					}
				}		
			}
			else
			{
				int dPr 	= dX << 1;
				int dPru 	= dPr - (dY << 1);
				int P 		= dPr - dY;

				for (; dY >= 0; dY--)
				{
					Plot(x1, y1, bXOR);
					if (P > 0)
					{ 
						x1 += Xincr;
						y1 += Yincr;
						P += dPru;
					}
					else
					{
						y1 += Yincr;
						P += dPr;
					}
				}		
			}		
				
			return true;
		}
	}
	catch(...)
	{
	}
	return false;
}
