//------------------------------------------------------------
// Tony Hyun Kim
// Spring 2007
// 18.354 Project: Lattice gas
// Some pre-configured node geometries IMPLEMENTATION
//------------------------------------------------------------

#include "NodeGeometry.h"

void CreateBox(D3DXVECTOR2& pos, int width, int height)
{
	for(int i=0; i<=height; i++)
	{
		CreateLine(pos,0,width);
		pos += (i%2)?g_dir[4]:g_dir[5];
	}
}

void CreateLine(D3DXVECTOR2& pos, int dir, int n)
{
	for(int i=0; i<=n; i++)
		myNodes.AddNode(NODE(pos+i*g_dir[dir]));
}

void CreateHexagonFilled(D3DXVECTOR2 &pos, int n)
{
	CreateHexagonRing(pos,0,n);
}

void CreateHexagonRing(D3DXVECTOR2& pos, int inner, int outer)
{
	for(int i=inner; i<=outer; i++)
		CreateHexagon(pos,i);
}

void CreateHexagon(D3DXVECTOR2& pos, int n)
{
	if(n<0)
		return;
	else if(n == 0)
	{
		myNodes.AddNode(NODE(pos));
		return;
	}

	D3DXVECTOR2 anchor;
	int i, j;

	for(i=0; i<6; i++)
	{
		anchor = pos+n*g_dir[i];
		for(j=0; j<n; j++)
		{
			myNodes.AddNode(NODE(anchor+j*g_dir[(i+2)%6]));
		}
	}
}


// The way I wrote the Demo* procedures is very hackish! 

void Demo1()
{
	CreateHexagonFilled(15*g_dir[3],10);
	for(float i=-25*g_spacing; i<-10*g_spacing; i+= 0.5f*g_spacing)
	{
		for(float j = -10*g_spacing; j<10*g_spacing; j+= 0.5f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
				test->current.occ = g_PosFlags[rand()%6];
		}
	}
	CreateHexagonFilled(15*g_dir[0],10);

	CreateLine(4*g_dir[3],0,8);
	CreateLine(5*g_dir[3]+g_dir[1],0,9);
	CreateLine(5*g_dir[3]+g_dir[5],0,9);
}

void Demo2()
{
	CreateHexagonFilled(15*g_dir[3],10);
	for(float i=-25*g_spacing; i<-10*g_spacing; i+= 0.5f*g_spacing)
	{
		for(float j = -10*g_spacing; j<10*g_spacing; j+= 0.5f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
				test->current.occ = g_PosFlags[rand()%6];
		}
	}
	CreateHexagonFilled(15*g_dir[0],10);
	
	for(float i=10*g_spacing; i<25*g_spacing; i+= 0.5f*g_spacing)
	{
		for(float j = -10*g_spacing; j<10*g_spacing; j+= 0.5f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
			{
				test->current.occ = g_PosFlags[rand()%6];
				test->current.type = test->current.occ;
			}
		}
	}


	CreateLine(4*g_dir[3],0,8);
	CreateLine(5*g_dir[3]+g_dir[1],0,9);
	CreateLine(5*g_dir[3]+g_dir[5],0,9);
}

void Demo3()
{
	CreateBox(g_origin,50,10);
	CreateBox(8*g_dir[1]+8*g_dir[2],50,10);
	CreateLine(g_dir[1],0,25);
	CreateLine(g_dir[1]+g_dir[2],0,23);
	CreateLine(2*g_dir[1]+g_dir[2],0,16);
	CreateLine(2*g_dir[1]+2*g_dir[2],0,23);
	CreateLine(3*g_dir[1]+2*g_dir[2],0,25);
	for(float i=0; i<15*g_spacing; i+= 0.25f*g_spacing)
	{
		for(float j = -10*g_spacing; j<20*g_spacing; j+= 0.25f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
			{
				switch(rand()%6)
				{
				case 0:
					test->current.occ = g_PosFlags[1];
					break;
				case 1:
					test->current.occ = g_PosFlags[5];
					break;
				default:
					test->current.occ = g_PosFlags[0];
					break;
				}
			}
		}
	}
}

void Demo4()
{
	CreateBox(2*g_dir[1]+2*g_dir[2],30,8);
	for(float i=0*g_spacing; i<8*g_spacing; i+= 0.25f*g_spacing)
	{
		for(float j = -5*g_spacing; j<5*g_spacing; j+= 0.25f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
			{
				test->current.occ = g_PosFlags[0];
			}
		}
	}

	for(float i=15*g_spacing; i<20*g_spacing; i+= 0.25f*g_spacing)
	{
		for(float j = -5*g_spacing; j<5*g_spacing; j+= 0.25f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
			{
				test->current.occ = g_PosFlags[rand()%6];
				test->current.type = test->current.occ;
			}
		}
	}
}

void Demo5()
{
	CreateBox(3*g_dir[1]+3*g_dir[2],30,12);

	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+3*g_dir[1]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+g_dir[4]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+3*g_dir[5]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+4*g_dir[2]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+5*g_dir[2]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+5*g_dir[2]+g_dir[1]));
	myNodes.DelNode(myNodes.GetNodeByPos(18*g_dir[0]+2*g_dir[4]));
	myNodes.DelNode(myNodes.GetNodeByPos(16*g_dir[0]+4*g_dir[4]));
	myNodes.DelNode(myNodes.GetNodeByPos(16*g_dir[0]+2*g_dir[2]));
	myNodes.DelNode(myNodes.GetNodeByPos(16*g_dir[0]+g_dir[2]));
	myNodes.DelNode(myNodes.GetNodeByPos(16*g_dir[0]+4*g_dir[4]+g_dir[5]));
	myNodes.DelNode(myNodes.GetNodeByPos(16*g_dir[0]+4*g_dir[4]+2*g_dir[5]));

	for(float i=0*g_spacing; i<8*g_spacing; i+= 0.25f*g_spacing)
	{
		for(float j = -6*g_spacing; j<6*g_spacing; j+= 0.25f*g_spacing)
		{
			NODE* test = myNodes.GetNodeByPos(D3DXVECTOR2(i,j));
			if( test )
				test->current.occ = g_PosFlags[0];
		}
	}
}