// Copyright, T. Pavlidis 2006
// Caution: This is a simplified version of the one used in
// the examples. It has not been tested on its own.

#include "StdAfx.h"
#include "Bead.h"
#include <math.h>

CBead::CBead(void)
{
}

CBead::~CBead(void)
{
}

BOOL CBead::InitBead(COLORREF color, CSize size, CPoint point)
{
	// a lot of the code assumes circular beads, so
	ASSERT(size.cx == size.cy);
	m_color = color;
	m_size  = size;
	if(point.x >=0 && point.y >=0) MoveTo(point);
	m_broken = FALSE;
	return TRUE;
}

void CBead::MoveTo(CPoint point)
{
	if(m_broken == TRUE) return;
	m_pos.SetRect(point.x-GetWidth()/2, point.y-GetHeight()/2,
			point.x+GetWidth()/2, point.y+GetHeight()/2);
}

void CBead::MoveBy(int dx, int dy)
{
	if(m_broken == TRUE) return;
	m_pos.left	+= dx;
	m_pos.right += dx;
	m_pos.top	+= dy;
	m_pos.bottom+= dy;
}

BOOL CBead::PointInBead(CPoint point)
{
	return m_pos.PtInRect(point);
}

BOOL CBead::TooClose(CBead *bp)
{
	int dx = m_pos.CenterPoint().x - bp->m_pos.CenterPoint().x;
	int dy = m_pos.CenterPoint().y - bp->m_pos.CenterPoint().y;
	double d = dx*dx + dy*dy;
	d = sqrt(d);
	if( 2*d < m_pos.Width() + bp->m_pos.Width() ) return TRUE;
	else return FALSE;
}

BOOL CBead::InsideRect(CRect *rp)
{
	CRect runion;
	runion.UnionRect(&m_pos, rp);
	return *rp == runion;
}

void CBead::Display(CDC *pDC)
{
	CBrush brush(m_color);
	CBrush *oldbrush = pDC->SelectObject(&brush);
	pDC->Ellipse(&m_pos);
	pDC->SelectObject(oldbrush);

	if(m_broken==TRUE) {	// Draw an X over the bead
		CPen *oldPen = (CPen *)pDC->SelectStockObject(BLACK_PEN);
		pDC->MoveTo(m_pos.left, m_pos.top);
		pDC->LineTo(m_pos.right, m_pos.bottom);
		pDC->MoveTo(m_pos.right, m_pos.top);
		pDC->LineTo(m_pos.left, m_pos.bottom);
		pDC->SelectObject(oldPen);
	}
}

