#include "StdAfx.h"
#include "Node.h"

#define NODE_SIZE 4

CNode::CNode(CPoint position)
{
	m_nObjType = 7;
	m_Position = position;
	m_pLeft = NULL;
	m_pTop = NULL;
	m_pRight = NULL;
	m_pBottom = NULL;
	m_pAttachedObject = NULL;
	m_pBrush = new SolidBrush((ARGB)Color::Black);
	MakeBoundingRect();
	m_gPath = new Gdiplus::GraphicsPath();
}

CNode::~CNode(void)
{
}

void CNode::MakeBoundingRect(void)
{
	m_rectBounding.X = m_Position.x - NODE_SIZE;
	m_rectBounding.Y = m_Position.y - NODE_SIZE;
	m_rectBounding.Width = NODE_SIZE*2;
	m_rectBounding.Height = NODE_SIZE*2;
}

void CNode::OutScreen(Gdiplus::Graphics &g)
{
	g.FillEllipse(m_pBrush, m_Position.x - NODE_SIZE, m_Position.y - NODE_SIZE, NODE_SIZE*2, NODE_SIZE*2);
}

void CNode::AttachObject(CCommonObject *obj, int freeDir)
{
	m_pAttachedObject = obj;
	this->m_pLeft = (CCommonObject*)-1;
	this->m_pTop = (CCommonObject*)-1;
	this->m_pRight = (CCommonObject*)-1;
	this->m_pBottom = (CCommonObject*)-1;

	Gdiplus::Rect *bounds = obj->GetBounds();
	if(freeDir == 2)
	{
		this->m_pRight = NULL;
	}
	if(freeDir == 3)
	{
		this->m_pBottom = NULL;
	}
	if(freeDir == 0)
	{
		this->m_pLeft = NULL;
	}
	if(freeDir == 1)
	{
		this->m_pTop = NULL;
	}

}

Gdiplus::Rect * CNode::GetBounds()
{
	return &m_rectBounding;
}

CCommonObject* CNode::ConnectHitTest(CPoint point, int &nNumber)
{
	if(m_rectBounding.Contains(point.x, point.y) == TRUE)
	{	
		if(m_pLeft == NULL || m_pTop == NULL || m_pRight == NULL || m_pBottom == NULL)
		{
			nNumber = 1;
			return this;
		}
	}
	nNumber = 0;
	return NULL;
}

bool CNode::IsDirectionFree(int dir)
{
	switch(dir)
	{
	case 0:
		return (m_pLeft == NULL);
	case 1:
		return (m_pTop == NULL);
	case 2:
		return (m_pRight == NULL);
	case 3:
		return (m_pBottom == NULL);
	}
	return false;
}

void CNode::ConnectWire(CWire *wire, int dir)
{
	switch(dir)
	{
	case 0:
		if (m_pLeft == NULL)
		{
			m_pLeft = wire;
			return;
		}
		break;
	case 1:
		if (m_pTop == NULL)
		{
			m_pTop = wire;
			return;
		}
		break;
	case 2:
		if (m_pRight == NULL)
		{
			m_pRight = wire;
			return;
		}
		break;
	case 3:
		if (m_pBottom == NULL)
		{
			m_pBottom = wire;
			return;
		}
		break;
	}
	m_NonRectObjects.AddTail(wire);
}

void CNode::DisconnectWire(CWire *wire)
{
	if(m_pLeft == wire)
	{
		m_pLeft = NULL;
	}else if(m_pTop == wire)
	{
		m_pTop = NULL;
	}else if(m_pRight == wire)
	{
		m_pRight = NULL;
	}else if(m_pBottom == wire)
	{
		m_pBottom = NULL;
	}else
	{
		POSITION pos = m_NonRectObjects.Find(wire);	
		if(pos != NULL)
		{
			m_NonRectObjects.RemoveAt(pos);
		}
	}
}

void CNode::MoveDelta(int dx, int dy)
{
	m_Position.x += dx;
	m_Position.y += dy;
	MakeBoundingRect();
}

vector<CWire *> CNode::GetWires()
{
	vector<CWire *> wires;
	if(m_pLeft != NULL && m_pLeft != (CCommonObject*)-1)
	{
		if(m_pLeft->GetType() == 4)
		{
			wires.push_back(dynamic_cast<CWire *>(m_pLeft));
		}
	}
	if(m_pTop != NULL && m_pTop != (CCommonObject*)-1)
	{
		if(m_pTop->GetType() == 4)
		{
			wires.push_back(dynamic_cast<CWire *>(m_pTop));
		}
	}
	if(m_pRight != NULL && m_pRight != (CCommonObject*)-1)
	{
		if(m_pRight->GetType() == 4)
		{
			wires.push_back(dynamic_cast<CWire *>(m_pRight));
		}
	}
	if(m_pBottom != NULL && m_pBottom != (CCommonObject*)-1)
	{
		if(m_pBottom->GetType() == 4)
		{
			wires.push_back(dynamic_cast<CWire *>(m_pBottom));
		}
	}
	POSITION pos = m_NonRectObjects.GetHeadPosition();
	while(pos)
	{
		CCommonObject *pObj = m_NonRectObjects.GetNext(pos);
		if(pObj->GetType() == 4)
		{
			wires.push_back(dynamic_cast<CWire *>(pObj));
		}
	}
	return wires;
}