#include "StdAfx.h"
#include "SpacialHashing.h"
#include "PriorQueue.h"
#include <set>
#include <algorithm>

CSpacialHashing::CSpacialHashing(int nScreenX, int nScreenY) 
	: m_nScreenX(nScreenX), m_nScreenY(nScreenY)
{
/*	m_aHItems = new CHashItem*[m_nScreenX];
	m_aVItems = new CHashItem*[m_nScreenY];

	for(int i=0; i<nScreenX; i++){
		m_aHItems[i] = NULL;
	}
	for(int i=0; i<nScreenY; i++){
		m_aVItems[i] = NULL;
	}*/
	m_lHItems = new set<CHashItem>*[m_nScreenX];
	m_lVItems = new set<CHashItem>*[m_nScreenY];

	for(int i=0; i<nScreenX; i++){
		m_lHItems[i] = NULL;
	}
	for(int i=0; i<nScreenY; i++){
		m_lVItems[i] = NULL;
	}
}

CSpacialHashing::~CSpacialHashing()
{
	SAFE_DELETE_ARRAY(*m_lHItems);
	SAFE_DELETE_ARRAY(*m_lVItems);
}

void CSpacialHashing::RegisterCObject(CCommonObject *pObject, int l, int t, int r, int b)
{
	if(l<0 || t<0 || r<0 || b<0)
		return;
	
	RegisterCObjectH(pObject, l, r, -1, -1);
	RegisterCObjectV(pObject, t, b, -1, -1);
}

void CSpacialHashing::RegisterWire(CCommonObject *pObject, Point *points, int nPointCount)
{	
	if(pObject == NULL || points == NULL || nPointCount < 0)
		return;
	int nKeyH;
	int nKeyV;
	for(int i=0; i<nPointCount; i++){
		nKeyH = points[i].Y / 10;
		nKeyV = points[i].X / 10;
		RegisterCObjectH(pObject, points[i].X, points[i].X, 2, i);
		RegisterCObjectV(pObject, points[i].Y, points[i].Y, 2, i);
		int x1, y1, x2, y2;
		if(i != nPointCount - 1)
		{
			if(points[i].X == points[i+1].X)
			{
				if(points[i].Y < points[i+1].Y)
				{
					y1 = points[i].Y;
					y2 = points[i+1].Y;
				}else{
					y2 = points[i].Y;
					y1 = points[i+1].Y;
				}
				RegisterCObjectH(pObject, points[i].X, points[i].X, 0, i);
				RegisterCObjectV(pObject, y1 + 10, y2 - 10, 0, i);
			}
			else if(points[i].Y == points[i+1].Y)
			{
				if(points[i].X < points[i+1].X)
				{
					x1 = points[i].X;
					x2 = points[i+1].X;
				}else{
					x2 = points[i].X;
					x1 = points[i+1].X;
				}
				RegisterCObjectH(pObject, x1 + 10, x2 - 10, 1, i);
				RegisterCObjectV(pObject, points[i].Y, points[i].Y, 1, i);
			}
		}
	}
}

void CSpacialHashing::RegisterCObjectH(CCommonObject *pObject, int l, int r, int nID, int nKey)
{
	if(l<0 || r<0)
		return;
	int nLeft = l / 10;
	if(l % 10)
		nLeft++;
	int nRight = r / 10;	
	/*CHashItem *pNext = NULL;
	CHashItem *pCurrent;
	CHashItem *pPrev = NULL;
*
	for(int i=nLeft; i<=nRight; i++){
		pCurrent = m_aHItems[i];
		if(pCurrent == NULL){
			m_aHItems[i] = new CHashItem(pObject, NULL, nID, nKey);
		}
		else{
			while(pCurrent && (pNext = pCurrent->GetNext()) && pNext->GetKey() < nKey){
				pPrev = pCurrent;
				pCurrent = pNext;
			}

			if(pCurrent->GetKey() > nKey){
				if(pPrev){
					pPrev->SetNext(new CHashItem(pObject, pCurrent, nID, nKey));
				}
				else{
					m_aHItems[i] = new CHashItem(pObject, pCurrent, nID, nKey);
				}
			} else {
				if(pCurrent->HasNext()){
					pCurrent->SetNext(new CHashItem(pObject, pCurrent->GetNext(), nID, nKey));
				} else {
					pCurrent->SetNext(new CHashItem(pObject, NULL, nID, nKey));
				}
			}
		}
	}*/
	for(int i = nLeft; i <= nRight; i++)
	{
		set<CHashItem> *curSet = m_lHItems[i];
		if(curSet == NULL)
		{
			curSet = m_lHItems[i] = new set<CHashItem>;
		}
		CHashItem item(pObject, nID, nKey);
		curSet->insert(item);
	}
}

void CSpacialHashing::RegisterCObjectV(CCommonObject *pObject, int t, int b, int nID, int nKey)
{
	if(t<0 || b<0)
		return;
	int nTop = t / 10;
	if(t % 10)
		nTop++;
	int nBottom = b / 10;
	/*CHashItem *pNext = NULL;
	CHashItem *pCurrent;
	CHashItem *pPrev = NULL;
	for(int i=nTop; i<=nBottom; i++){
		pCurrent = m_aVItems[i];
		if(pCurrent == NULL){
			m_aVItems[i] = new CHashItem(pObject, NULL, nID, nKey);
		}
		else{
			while(pCurrent && (pNext = pCurrent->GetNext()) && pNext->GetKey() < nKey){
				pPrev = pCurrent;
				pCurrent = pNext;
			}

			if(pCurrent->GetKey() > nKey){
				if(pPrev){
					pPrev->SetNext(new CHashItem(pObject, pCurrent, nID, nKey));
				}
				else{
					m_aVItems[i] = new CHashItem(pObject, pCurrent, nID, nKey);
				}
			} else {
				if(pCurrent->HasNext()){
					pCurrent->SetNext(new CHashItem(pObject, pCurrent->GetNext(), nID, nKey));
				} else {
					pCurrent->SetNext(new CHashItem(pObject, NULL, nID, nKey));
				}
			}
		}
	}*/
	for(int i = nTop; i <= nBottom; i++)
	{
		set<CHashItem> *curSet = m_lVItems[i];
		if(curSet == NULL)
		{
			curSet = m_lVItems[i] = new set<CHashItem>;
		}
		CHashItem item(pObject, nID, nKey);
		curSet->insert(item);
	}
}

void CSpacialHashing::DeRegisterCObject(CCommonObject *pObject, int l, int t, int r, int b)
{
	if(l<0 || t<0 || r<0 || b<0 || pObject == NULL)
		return;
	if(pObject->m_nObjType == 4){ // wire
		this->DeRegisterWire(pObject, ((CWire*)pObject)->m_Points, (int)((CWire*)pObject)->m_Anchors.GetSize());
	}
	if(l != r)
		DeRegisterCObjectH(pObject, l, r, -1);
	if(t != b)
		DeRegisterCObjectV(pObject, t, b, -1);
}

void CSpacialHashing::DeRegisterWire(CCommonObject *pObject, Point *points, int nPointCount)
{
	/*if(pObject == NULL || points == NULL || nPointCount < 0)
		return;
	for(int i=0; i<nPointCount; i++){
		DeRegisterCObjectH(pObject, points[i].X, points[i].X+10, i+1);
		DeRegisterCObjectV(pObject, points[i].Y, points[i].Y+10, i+1);
	}*/
	DeRegisterWire(pObject);
}

void CSpacialHashing::DeRegisterWire(CCommonObject *pObject)
{
	DeRegisterCObject(pObject);
}

void CSpacialHashing::DeRegisterCObject(CCommonObject *pObject)
{
	vector<set<CHashItem>::iterator> toDelete;
	for(int x = 0; x < m_nScreenX; x++)
	{
		set<CHashItem> *curSet = m_lHItems[x];
		if(curSet == NULL)
		{
			continue;
		}
		for(set<CHashItem>::iterator i = curSet->begin(); i != curSet->end(); i++)
		{
			if(*i == pObject)
			{
				toDelete.push_back(i);
			}
		}
		for(vector<set<CHashItem>::iterator>::iterator i = toDelete.begin(); i != toDelete.end(); i++)
		{
			curSet->erase(*i);
		}
		toDelete.clear();
	}
	for(int y = 0; y < m_nScreenY; y++)
	{
		set<CHashItem> *curSet = m_lVItems[y];
		if(curSet == NULL)
		{
			continue;
		}
		for(set<CHashItem>::iterator i = curSet->begin(); i != curSet->end(); i++)
		{
			if(*i == pObject)
			{
				toDelete.push_back(i);
			}
		}
		for(vector<set<CHashItem>::iterator>::iterator i = toDelete.begin(); i != toDelete.end(); i++)
		{
			curSet->erase(*i);
		}
		toDelete.clear();
	}
}

void CSpacialHashing::DeRegisterCObjectH(CCommonObject *pObject, int l, int r, int nID)
{
	if(l<0 || r<0)
		return;
	int nLeft = l / 10;
	if(l % 10)
		nLeft++;
	int nRight = r / 10;
/*	CHashItem *pTemp = NULL;
	CHashItem *pPrevItem = NULL;
	int nPos = 0;
	for(int i=nLeft; i<=nRight; i++){
		if(nLeft >= 0 && nRight <=1000){
			pTemp = m_aHItems[i];
			pPrevItem = NULL;
			while(pTemp){
				if(*pTemp == pObject && pTemp->GetID() == nID){
					if(pPrevItem){
						pPrevItem->SetNext(pTemp->GetNext());
					}
					else{
						m_aHItems[i] = pTemp->GetNext();
					}
					SAFE_DELETE(pTemp);
					break;
				}
				pPrevItem = pTemp;
				pTemp = pTemp->GetNext();
			}
		}
	}*/
	for(int x=nLeft; x<=nRight; x++){
		set<CHashItem> *curSet = m_lHItems[x];
		ASSERT(curSet != NULL);
		for(set<CHashItem>::iterator i = curSet->begin(); i != curSet->end(); i++)
		{
			if((*i) == pObject && (*i).GetID() == nID)
			{
				curSet->erase(i);
				if(curSet->empty())
				{
					delete curSet;
					m_lHItems[x] = NULL;
				}
				break;
			}
		}
	}
}

void CSpacialHashing::DeRegisterCObjectV(CCommonObject *pObject, int t, int b, int nID)
{
	if(t<0 || t<0)
		return;
	int nTop = t / 10;
	if(t % 10)
		nTop++;
	int nBottom = b / 10;
	/*CHashItem *pTemp = NULL;
	CHashItem *pPrevItem = NULL;
	for(int i=nTop; i<=nBottom; i++){
		pTemp = m_aVItems[i];
		pPrevItem = NULL;
		while(pTemp){
			if(*pTemp == pObject && pTemp->GetID() == nID){
				if(pPrevItem){
					pPrevItem->SetNext(pTemp->GetNext());
				}
				else{
					m_aVItems[i] = pTemp->GetNext();
				}
				SAFE_DELETE(pTemp);
				break;
			}
			pPrevItem = pTemp;
			pTemp = pTemp->GetNext();
		}
	}*/
	for(int y=nTop; y<=nBottom; y++){
		set<CHashItem> *curSet = m_lVItems[y];
		ASSERT(curSet != NULL);
		for(set<CHashItem>::iterator i = curSet->begin(); i != curSet->end(); i++)
		{
			if((*i) == pObject && (*i).GetID() == nID)
			{
				curSet->erase(i);
				if(curSet->empty())
				{
					delete curSet;
					m_lVItems[y] = NULL;
				}
				break;
			}
		}
	}
}

bool CSpacialHashing::CanMoveCObject(GraphicsPath *newGP)
{
	return true;
}

void CSpacialHashing::MoveCObject(CCommonObject *pObject, CPoint oldTL)
{
	if(pObject == NULL)
		return;
	Rect *newBound;
	newBound = pObject->GetBounds();
	//int nWidth = newBound->Width;
	// dowiththissomething!
	//nWidth -= (nWidth%10);
	//int nHeight = newBound->Height;
	//nHeight -= (nHeight%10);
	CPoint newTL(newBound->GetLeft(), newBound->GetTop());
	DeRegisterCObject(pObject);
	RegisterCObject(pObject, newBound->GetLeft(), newBound->GetTop(), newBound->GetRight(), newBound->GetBottom());
	/*CSize delta = oldTL - newTL;
	if(abs(delta.cx) > nWidth){
		DeRegisterCObjectH(pObject, oldTL.x, oldTL.x+nWidth, -1);
		RegisterCObjectH(pObject, newTL.x, newTL.x+nWidth);
	}
	else{
		if(delta.cx > 0){ // moving object to left
			DeRegisterCObjectH(pObject, newTL.x+nWidth, oldTL.x+nWidth);
			RegisterCObjectH(pObject, newTL.x, oldTL.x);
		}
		else if(delta.cx < 0){ // moving object to right
			DeRegisterCObjectH(pObject, oldTL.x, newTL.x);
			RegisterCObjectH(pObject, oldTL.x+nWidth, newTL.x+nWidth);
		}
	}
	if(abs(delta.cy) > nHeight){
		DeRegisterCObjectV(pObject, oldTL.y, oldTL.y+nHeight);
		RegisterCObjectV(pObject, newTL.y, newTL.y+nHeight);
	}
	else{
		if(delta.cy > 0){ // moving object up
			DeRegisterCObjectV(pObject, newTL.y+nHeight, oldTL.y+nHeight);
			RegisterCObjectV(pObject, newTL.y, oldTL.y);
		}
		else if(delta.cy < 0){ // moving object down
			DeRegisterCObjectV(pObject, oldTL.y, newTL.y);
			RegisterCObjectV(pObject, oldTL.y+nHeight, newTL.y+nHeight);
		}
	}*/
}

void CSpacialHashing::MoveWire(CCommonObject *pObject, Point *oldPoints, int nOldPointCount, Point *newPoints, int nNewPointCount)
{
	if(pObject == NULL || oldPoints == NULL || newPoints == NULL || nNewPointCount<0)
		return;
	DeRegisterWire(pObject, oldPoints, nOldPointCount);
	RegisterWire(pObject, newPoints, nNewPointCount);
}

CCommonObject *CSpacialHashing::HashTest(CPoint point, int objType)
{
	int nXPos = point.x/10;
	int nYPos = point.y/10;
	if(nYPos < 0 || nXPos < 0)
		return NULL;
	set<CHashItem> *xSet = m_lHItems[nXPos];
	set<CHashItem> *ySet = m_lVItems[nYPos];
	if(xSet == NULL || ySet == NULL)
	{
		return NULL;
	}
	vector<CHashItem> intersect;
	set_intersection(xSet->begin(), xSet->end(), ySet->begin(), ySet->end(), insert_iterator<vector<CHashItem>>(intersect, intersect.begin()));
	for(vector<CHashItem>::iterator i = intersect.begin(); i != intersect.end(); i++)
	{
		if(objType == -1 || (*i).GetCurrentCO()->GetType() == objType)
		{
			return (*i).GetCurrentCO();
		}
	}
	if(objType != -1 && objType != 4)
	{
		return NULL;
	}
	/*
	// there can be line on this point too...check it
	CHashItem *pFirstItem = m_aHItems[nXPos];
	CHashItem *pSecondItem = NULL;
	while(pFirstItem){
		if(pFirstItem->GetID() > 0){
			pSecondItem = pFirstItem->GetNext();
			while(pSecondItem){
				if(pFirstItem->GetID() > 0){
					if(pFirstItem->GetCurrentCO() == pSecondItem->GetCurrentCO()){
						if(abs(pSecondItem->GetID() - pFirstItem->GetID()) == 1)
							if((nYPos > pFirstItem->GetKey() && nYPos < pSecondItem->GetKey()) || (nYPos > pSecondItem->GetKey() && nYPos < pFirstItem->GetKey()))
								return pFirstItem->GetCurrentCO();
					}
				}
				pSecondItem = pSecondItem->GetNext();
			}
		}
		pFirstItem = pFirstItem->GetNext();
	}


	pFirstItem = m_aVItems[nYPos];
	pSecondItem = NULL;
	while(pFirstItem){
		if(pFirstItem->GetID() > 0){
			pSecondItem = pFirstItem->GetNext();
			while(pSecondItem){
				if(pFirstItem->GetID() > 0){
					if(pFirstItem->GetCurrentCO() == pSecondItem->GetCurrentCO()){
						if(abs(pSecondItem->GetID() - pFirstItem->GetID()) == 1){
							if((nXPos > pFirstItem->GetKey() && nXPos < pSecondItem->GetKey()) || (nXPos > pSecondItem->GetKey() && nXPos < pFirstItem->GetKey()))
								return pFirstItem->GetCurrentCO();
						}
					}
				}
				pSecondItem = pSecondItem->GetNext();
			}
		}
		pFirstItem = pFirstItem->GetNext();
	}*/
	return NULL;
}

CCommonObject* CSpacialHashing::HashTestWireEdge(CPoint point, CCommonObject *pObjExclude)
{
/*	int nXPos = point.x/10;
	int nYPos = point.y/10;
	if(nYPos < 0 || nXPos < 0)
		return NULL;
	CHashItem *pFirstItem = m_aHItems[nXPos];
	CHashItem *pSecondItem = NULL;
	while(pFirstItem){
		if(pFirstItem->GetID() > 0){
			pSecondItem = pFirstItem->GetNext();
			while(pSecondItem){
				if(pFirstItem->GetID() > 0){
					if(pFirstItem->GetCurrentCO() == pSecondItem->GetCurrentCO()){
						if(abs(pSecondItem->GetID() - pFirstItem->GetID()) == 1)
							if((nYPos > pFirstItem->GetKey() && nYPos < pSecondItem->GetKey()) || (nYPos > pSecondItem->GetKey() && nYPos < pFirstItem->GetKey())){
								while(pFirstItem->GetCurrentCO() == pObjExclude && pFirstItem->HasNext())
									pFirstItem = pFirstItem->GetNext();
								if(pFirstItem->GetCurrentCO() != pObjExclude)
									return pFirstItem->GetCurrentCO();
								else return NULL;
							}
					}
				}
				pSecondItem = pSecondItem->GetNext();
			}
		}
		pFirstItem = pFirstItem->GetNext();
	}


	pFirstItem = m_aVItems[nYPos];
	pSecondItem = NULL;
	while(pFirstItem){
		if(pFirstItem->GetID() > 0){
			pSecondItem = pFirstItem->GetNext();
			while(pSecondItem){
				if(pFirstItem->GetID() > 0){
					if(pFirstItem->GetCurrentCO() == pSecondItem->GetCurrentCO()){
						if(abs(pSecondItem->GetID() - pFirstItem->GetID()) == 1){
							if((nXPos > pFirstItem->GetKey() && nXPos < pSecondItem->GetKey()) || (nXPos > pSecondItem->GetKey() && nXPos < pFirstItem->GetKey()))
								while(pFirstItem->GetCurrentCO() == pObjExclude && pFirstItem->HasNext())
									pFirstItem = pFirstItem->GetNext();
								if(pFirstItem->GetCurrentCO() != pObjExclude)
									return pFirstItem->GetCurrentCO();
								else return NULL;
						}
					}
				}
				pSecondItem = pSecondItem->GetNext();
			}
		}
		pFirstItem = pFirstItem->GetNext();
	}*/
	return NULL;
}

bool CSpacialHashing::HashAreaTest(CPoint point, int width, int height)
{
/*	int from = point.y/10;
	int to = (point.y+height)/10;

	for(int i = from; i < to; i++){
		if(GetHLine(i*10,point.x,point.x+width) < width)
			return false;
	}*/
	return true;
}

int CSpacialHashing::GetHLine(int Vpos, int start, int end)
{
/*	if(Vpos < 0 || start<0 || end<0)
		return 0;
	int nStart, nEnd, nWidth, nTLX, nTRX;
	int nRet;
	CHashItem *pTemp = m_aVItems[Vpos/10];
	if(start > end){ // right to left
		nEnd = start - 10;
		nStart = end + 10;
		nRet = start - end;

		while(pTemp){
			nTLX = pTemp->GetCurrentCO()->m_pointTopLeft.x;
			nWidth = pTemp->GetCurrentCO()->m_rectBounding.Width;
			nTRX = nTLX+nWidth;
			if(!(nTRX < nStart || nTLX > nEnd)){ // line crosses this object for sure
				TRACE(_T("Line crosses object H (RtoL)\n"));
				if(nTRX < nEnd){
					if(nEnd - nTRX+10 < nRet)
						nRet = nEnd - nTRX+10;
				}
				else
					return 0;
			}
			pTemp = pTemp->GetNext();
		}
		return -nRet;
	}
	else{ // left to right
		nStart = start + 10;
		nEnd = end - 10;
		nRet = end - start;

		while(pTemp){
			nTLX = pTemp->GetCurrentCO()->m_pointTopLeft.x;
			nWidth = pTemp->GetCurrentCO()->m_rectBounding.Width;
			nTRX = nTLX+nWidth;
			
			if(!(nTRX <= nStart || nTLX > nEnd)){ // line crosses this object for sure
				TRACE(_T("Line crosses object H (LtoR)\n"));
				if(nTLX > nStart){
					if(nTLX - nStart+10 < nRet)
						nRet = nTLX - nStart+10;
				}
				else
					return 0;
			}
			pTemp = pTemp->GetNext();
		}
		return nRet;
	}*/
	return 0;
}

int CSpacialHashing::GetVLine(int Hpos, int start, int end)
{
/*	if(Hpos < 0 || start<0 || end<0)
		return 0;
	int nStart, nEnd, nHeight, nTLX, nBLX;
	int nRet;
	CHashItem *pTemp = m_aHItems[Hpos/10];
	if(start > end){ // bottom to top
		nEnd = start - 10;
		nStart = end + 10;
		nRet = start - end;

		while(pTemp){
			nTLX = pTemp->GetCurrentCO()->m_pointTopLeft.y;
			//nTLX = pTemp->GetCurrentCO()->GetBounds()->Y;
			nHeight = pTemp->GetCurrentCO()->m_rectBounding.Height;
			//nHeight = pTemp->GetCurrentCO()->GetBounds()->Height;
			nBLX = nTLX+nHeight;
			
			if(!(nBLX < nStart || nTLX > nEnd)){ // line crosses this object for sure
				TRACE(_T("Line crosses object V (BtoT)\n"));
				if(nBLX < nEnd){
					if(nEnd - nBLX+10 < nRet)
						nRet = nEnd - nBLX+10;
				}
				else
					return 0;
			}
			pTemp = pTemp->GetNext();
		}
		return -nRet;
	}
	else{ // top to bottom
		nStart = start + 10;
		nEnd = end - 10;
		nRet = end - start;

		while(pTemp){
			nTLX = pTemp->GetCurrentCO()->m_pointTopLeft.y;
			nHeight = pTemp->GetCurrentCO()->m_rectBounding.Height;
			nBLX = nTLX+nHeight;
			
			if(!(nBLX < nStart || nTLX > nEnd)){ // line crosses this object for sure
				TRACE(_T("Line crosses object V (TtoB)\n"));
				if(nTLX > nStart){
					if(nTLX - nStart+10 < nRet)
						nRet = nTLX - nStart+10;
				}
				else
					return 0;
			}
			pTemp = pTemp->GetNext();
		}
		return nRet;
	}*/
	return 0;
}

void CSpacialHashing::OutVH(stringstream &ss)
{
/*	ss << "HORIZONTAL: \n";
	CHashItem *pTemp;
	CStringA text;
	for(int i=0; i<100; i++){
		pTemp = m_aHItems[i];
		ss << "i" << i << " ";
		while(pTemp){
			//text = pTemp->m_pCObj->m_strUniqueName
			ss << (CStringA)pTemp->GetCurrentCO()->m_strUniqueName << " ";
			pTemp = pTemp->GetNext();
		}
		ss << "\n";
		
	}
	ss << "\n\n\nVERTICAL: \n";
	for(int i=0; i<100; i++){
		pTemp = m_aVItems[i];
		ss << "i" << i << " ";
		while(pTemp){
			//text = pTemp->m_pCObj->m_strUniqueName
			ss << (CStringA)pTemp->GetCurrentCO()->m_strUniqueName << " ";
			pTemp = pTemp->GetNext();
		}
		ss << "\n";
		
	}*/
}

void CSpacialHashing::OutLine(stringstream &ss)
{
/*	CHashItem *pTemp;
	ss << "HORIZONTAL: \n";
	for(int i=0; i<100; i++){
		pTemp = m_aHItems[i];
		ss << "i" << i << " ";
		while(pTemp){
			if(pTemp->GetCurrentCO()->GetType() == 4){
				ss << "[" << pTemp->GetID() << ";" << pTemp->GetKey() << "]  ";
			}
			pTemp = pTemp->GetNext();
		}
		ss << "\n";
		
	}
	ss << "\n\n\nVERTICAL: \n";
	for(int i=0; i<100; i++){
		pTemp = m_aVItems[i];
		ss << "i" << i << " ";
		while(pTemp){
			if(pTemp->GetCurrentCO()->GetType() == 4){
				ss << "[" << pTemp->GetID() << "'" << pTemp->GetKey() << "]  ";
			}
			pTemp = pTemp->GetNext();
		}
		ss << "\n";
		
	}*/
}

std::vector<CCommonObject *> CSpacialHashing::GetObjectsAtRegion(int l, int t, int r, int b)
{
	set<CCommonObject *> v;
	set<CCommonObject *> c;
	vector<CCommonObject *> ret;
	for(int x = l / 10; x <= r / 10; x++)
	{
		set<CHashItem> *xSet = m_lHItems[x];
		if(xSet == NULL)
		{
			continue;
		}
		for(set<CHashItem>::iterator i = xSet->begin(); i != xSet->end(); i++)
		{
			v.insert((*i).GetCurrentCO());
		}
	}
	for(int y = t / 10; y <= b / 10; y++)
	{
		set<CHashItem> *ySet = m_lVItems[y];
		if(ySet == NULL)
		{
			continue;
		}
		for(set<CHashItem>::iterator i = ySet->begin(); i != ySet->end(); i++)
		{
			if(v.find((*i).GetCurrentCO()) != v.end())
			{
				c.insert((*i).GetCurrentCO());
			}
		}
	}
	for(set<CCommonObject *>::iterator i = c.begin(); i != c.end(); i++)
	{
		ret.push_back((*i));
	}
	return ret;
}

void CSpacialHashing::GetMaxXY(int *x, int *y)
{
	*x = m_nScreenX;
	*y = m_nScreenY;
}

int CSpacialHashing::GetWireDirAtPoint(CCommonObject *obj, CPoint point)
{
	int nXPos = point.x/10;
	int nYPos = point.y/10;
	if(nYPos < 0 || nXPos < 0)
		return NULL;
	set<CHashItem> *xSet = m_lHItems[nXPos];
	set<CHashItem> *ySet = m_lVItems[nYPos];
	if(xSet == NULL || ySet == NULL)
	{
		return -1;
	}
	vector<CHashItem> intersect;
	set_intersection(xSet->begin(), xSet->end(), ySet->begin(), ySet->end(), insert_iterator<vector<CHashItem>>(intersect, intersect.begin()));
	for(vector<CHashItem>::iterator i = intersect.begin(); i != intersect.end(); i++)
	{
		if((*i) == obj)
		{
			return (*i).GetID();
		}
	}
	return -1;
}

CHashItem::CHashItem(CCommonObject *pObject, int nID)
	: m_pCObj(pObject), m_nID(nID), m_nKey(-1)
{

}

CHashItem::CHashItem(CCommonObject *pObject, int nID, int nKey) 
	: m_pCObj(pObject), m_nID(nID), m_nKey(nKey)
{
}

bool CHashItem::operator ==(const CCommonObject *CObj) const
{
	if(CObj == NULL || m_pCObj == NULL)
		return false;
	if(CObj == this->m_pCObj)
		return true;
	return false;
}

