function Board(divName, theNumberOfPlayers)
{
    this.init(divName, theNumberOfPlayers);
}


Board.prototype.init = function(divName, theNumberOfPlayers)
{
    this.divName = divName;
    this.numberOfPlayers = theNumberOfPlayers;
    this.initialMoves = this.numberOfPlayers;
    this.fixedSpaces = new Array();

    this.grid = Utility.layoutGrid(divName, 8, 15, this);

    // layout the preplaced 'fixed' Symbols on the board
	this.grid[2][2].fixedSpace = true;
	this.fixedSpaces.push(this.grid[2][2]);
	this.grid[2][7].fixedSpace = true;
	this.fixedSpaces.push(this.grid[2][7]);
	this.grid[7][2].fixedSpace = true;
	this.fixedSpaces.push(this.grid[7][2]);
	this.grid[7][12].fixedSpace = true;
	this.fixedSpaces.push(this.grid[7][12]);
	this.grid[12][2].fixedSpace = true;
	this.fixedSpaces.push(this.grid[12][2]);
	this.grid[12][7].fixedSpace = true;
	this.fixedSpaces.push(this.grid[12][7]);


    this.placeSymbol(Symbol.GREEN, 	this.grid[2][2]);
    this.placeSymbol(Symbol.RED, 	this.grid[2][7]);
    this.placeSymbol(Symbol.BLUE, 	this.grid[7][2]);
    this.placeSymbol(Symbol.PURPLE, this.grid[7][12]);
    this.placeSymbol(Symbol.ORANGE, this.grid[12][2]);
    this.placeSymbol(Symbol.YELLOW, this.grid[12][7]);

    // make some grid spots off limits due to the number of players
    for (var i=0; i<this.grid.length; i++)
    {
		for (var j=0; j<this.grid[i].length; j++)
		{
			if ((i == 0) || (i == 14) ||
				(j == 0) || ((j+1) == this.grid[i].length))
			{
				if (this.numberOfPlayers < 4)
				{
					this.placeSymbol(Symbol.RESTRICTED_DARK, this.grid[i][j]);
				}
			}
			else if ((i == 1) || (i == 13) ||
				(j == 1) || ((j+2) == this.grid[i].length))
			{
				if (this.numberOfPlayers < 3)
				{
					this.placeSymbol(Symbol.RESTRICTED_LIGHT, this.grid[i][j]);
				}
			}
		}
	}

	// place sundials
	var anchor = getElementPosition('anchor');
	Utility.moveTo(document.getElementById('sundial1'), 10+anchor.left, 0+anchor.top);
	Utility.moveTo(document.getElementById('sundial2'), 10+anchor.left, 380+anchor.top);
	Utility.moveTo(document.getElementById('sundial3'), 315+anchor.left, 0+anchor.top);
	Utility.moveTo(document.getElementById('sundial4'), 315+anchor.left, 380+anchor.top);
}

Board.prototype.renderHex = function(controlDiv, space, col, row, colHeight)
{
    var div = document.createElement('div');
    div.className = 'positionable';

    // must handle shading of hexes in the outter rows
    var hexImage = 'smallPlain.gif';
    if ((col == 0) || (col == 14) ||
        (row == 0) || ((row+1) == colHeight))
    {
		hexImage = 'smallPlainDarkGray.gif';
	}
    else if ((col == 1) || (col == 13) ||
        (row == 1) || ((row+2) == colHeight))
    {
		hexImage = 'smallPlainLightGray.gif';
	}

    var html = '<img src="/ingenious/images/' + hexImage + '" width="' + Symbol.WIDTH + '" height="' + Symbol.HEIGHT + '" border="0" onkeypress="onKeyPress(event,' +
        space.getRow() + ',' + space.getCol() + ')" />';

    div.innerHTML = html;
    hideDiv(div);
    controlDiv.appendChild(div);

    div.style.left = space.left + 'px';
    div.style.top = space.top + 'px';

    div.id = this.getSpaceDiv(space);


    showDiv(div);


}

Board.prototype.getSpaceDiv = function(space)
{
    return 'Board_' + space.getRow() + '_' + space.getCol();
}


Board.prototype.getSpaceByCoordinates = function(x,y)
{
    var pos = getElementPosition(this.divName);

    x -= pos.left;
    y -= pos.top;

    for (var i=0; i<this.grid.length; i++)
    {
        for (var j=0; j<this.grid[i].length; j++)
        {
            var space = this.grid[i][j];

            if ((space.left < x) && ((space.left + Symbol.WIDTH) > x) &&
                (space.top < y) && ((space.top + Symbol.HEIGHT) > y))
            {
                return space;
            }
        }
    }

    return null;
}

Board.prototype.verifyPlacement = function(tile, space)
{
    if (space.symbol != null)
    {
        return false;
    }

    var floater = space.navigate(tile.getOrientation());
    if ((floater == null) || (floater.symbol != null))
    {
        return false;
    }

    if (this.initialMoves > 0)
    {
		return this.verifyInitialMove(tile, space);
	}

    return true;
}

Board.prototype.verifyInitialMove = function(tile, space)
{
	// must find fixed space as a neighbor to one of the symbols in the tile
	var fixedSpace = space.findFixedNeighbor();
	if (fixedSpace == null)
	{
		fixedSpace = space.navigate(tile.getOrientation()).findFixedNeighbor();
	}
	if (fixedSpace == null)
	{
		return false;
	}

	return !fixedSpace.hasNeighbors();
}



Board.prototype.placeTile = function(tile, space)
{
    this.placeSymbol(tile.pivot, space);
    this.placeSymbol(tile.floater, space.navigate(tile.getOrientation()));
    tile.setPlaced(true);

	this.initialMoves--;

    this.deemphasize();
}


Board.prototype.placeSymbol = function(symbol, space)
{
    var html = '<img id="' + space.getId() + '" src="' + symbol.getImage() + '" width="' + Symbol.WIDTH + '" height="' + Symbol.HEIGHT + '" border="0" />';
    var div = document.getElementById(this.getSpaceDiv(space));
    div.innerHTML = html;
    space.symbol = symbol;
}

Board.prototype.scoreTile = function(tile, space, emphasize)
{
    // go out in all directions BUT the orientation direction
    var pivotScore = this.scoreSymbol(tile.pivot, tile.orientation, space, emphasize);

    // go out in all directions BUT the orientation direction
    var floatScore = this.scoreSymbol(tile.floater, (tile.orientation + 3) % 6, space.navigate(tile.orientation), emphasize);

    return { tile: tile, pivotScore: pivotScore, floatScore: floatScore };
}


Board.prototype.scoreSymbol = function(symbol, orientation, space, emphasize)
{
	if (emphasize == null)
	{
		emphasize = false;
	}

    var score = 0;
    for (var i=0; i<6; i++)
    {
        var currentSpace = space;
        if (i != orientation)
        {
            currentSpace = currentSpace.navigate(i);
            while (currentSpace != null)
            {
                if (currentSpace.getSymbol() == symbol)
                {
                    score++;

                    if (emphasize)
                    {
						currentSpace.emphasize();
					}

                    currentSpace = currentSpace.navigate(i);
                }
                else
                {
                    currentSpace = null;
                }
            }
        }
    }
    return score;
}

Board.prototype.emphasize = function(tile, space)
{
	this.scoreTile(tile, space, true);
}

Board.prototype.deemphasize = function()
{
	for (var i=0; i<this.grid.length; i++)
	{
		var row = this.grid[i];
		for (var j=0; j<row.length; j++)
		{
			var space = row[j];
			if (space != null)
			{
				space.deemphasize();
			}
		}
	}
}

Board.prototype.getEdges = function()
{
	var spaces = new Array();

	if (this.initialMoves > 0)
	{
		for (var i=0; i<this.fixedSpaces.length; i++)
		{
			var space = this.fixedSpaces[i];
			if (!space.hasNeighbors())
			{
				space.loadEmptyEdges(spaces);
			}
		}
	}
	else
	{
		for (var i=0; i<this.grid.length; i++)
		{
			var col = this.grid[i];
			for (var j=0; j<col.length; j++)
			{
				var space = col[j];
				if (!space.isOccupied() && space.hasCloseNeighbors())
				{
					spaces.push(space);
				}
			}
		}
	}

	return spaces;
}

Board.prototype.hasPlayableSpace = function()
{
	for (var i=0; i<this.grid.length; i++)
	{
		var col = this.grid[i];
		for (var j=0; j<col.length; j++)
		{
			var space = col[j];
			if (!space.isOccupied() && space.hasAnOpenNeighbor())
			{
				return true;
			}
		}
	}
	return false;
}