//Copyright (C) Ben Parbury - All Rights Reserved. Unauthorized copying of this file, via any medium is strictly prohibited. Written by Ben Parbury <ben@gridlockinteractive.com> 2014
var gBlockRenderer = new BlockRenderer();

function ArcCommand(x, y, radius, startAngle, endAngle, clockwise)
{
	this.x = x;
	this.y = y;
	this.radius = radius;
	this.startAngle = startAngle;
	this.endAngle = endAngle;
	this.clockwise = clockwise;
	
	this.Draw = function(x, y)
	{
		var alignX = Math.round(this.x + x);
		var alignY = Math.round(this.y + y);
		alignX = alignX > kTileSizeD2 ? alignX-0.5 : alignX+0.5;
		alignY = alignY > kTileSizeD2 ? alignY-0.5 : alignY+0.5;
		gBlockRenderer.context.arc(alignX, alignY, this.radius, this.startAngle, this.endAngle, this.clockwise);
	}
}

function BlockRenderer()
{
	this.arcCommands = new Array();
	this.preRenders = new Array();
	
	this.Init = function()
	{
		this.context = gDraw.context;
	}
	
	this.BuildArcCommands = function(block)
	{
		if(!(block.type in this.arcCommands))
		{
			this.arcCommands[block.type] = new Array();
		}

		if(!(block.subType in this.arcCommands[block.type]))
		{
			this.arcCommands[block.type][block.subType] = new Array();
		}
		
		if(block.rotation in this.arcCommands[block.type][block.subType])
		{
			//already built this one
			return;
		}
		
		this.arcCommands[block.type][block.subType][block.rotation] = new Array();
		var arrayRef = this.arcCommands[block.type][block.subType][block.rotation];

		var PId2 = Math.PI/2;
		var PI3d2 = Math.PI + PId2;

		var rounding = block.GetBlockRounding();
		
		//Build chain code that has traced the edge of the polyomino
		
		//Chain code
		//   3
		// 2 + 0
		//   1

		var chainArray = new Array();
		
		//find first subblock...
		var x = 0;
		while(!block.HasSubBlockAt(x, 0))
		{
			x++;
		}
		
		var position = new Vec2(x, 0);
		var lastCode = 0;
		
		var startCode = lastCode;
		var startPosition = new Vec2(position.x, position.y);
		
		do
		{
			chainArray.push(lastCode);
			//Get new position
			position = this.AdjustPositionForChainCode(position, lastCode);
			lastCode = this.GetNextChainCode(block, position, lastCode);
		}
		while(lastCode != startCode || (startPosition.x != position.x || startPosition.y != position.y))
		
		gConsole.Assert(lastCode == startCode);
		gConsole.Assert(startPosition.x == position.x && startPosition.y == position.y);
		
		gConsole.Assert(chainArray.length <= (block.subBlocks.length * 2) + 2);
		
		gConsole.Log(3, "[BR] Arc " + block.type + ", " + block.subType + ", " + block.rotation + " - " + chainArray);
		
		//Build arcs from chain code
		for(var i = 0; i < chainArray.length; i++)
		{
			var currentCode = chainArray[i];
			var nextCode = chainArray[(i + 1) % chainArray.length];
			position = this.AdjustPositionForChainCode(position, currentCode);
			if(currentCode != nextCode)
			{
				var startAngle = this.GetAngle(currentCode);
				var endAngle = this.GetAngle(nextCode);
				var width = (position.x * kTileSize);
				var height = (position.y * kTileSize);
				var clockwise = (currentCode + 1) % 4 != nextCode;
				if(clockwise)
				{
					startAngle = (startAngle + Math.PI) % (Math.PI * 2);
					endAngle = (endAngle + Math.PI) % (Math.PI * 2);
					width += startAngle == 0 || startAngle == PId2 ? -rounding : rounding;
					height += startAngle == PId2 || startAngle == Math.PI ? -rounding : rounding;
				}
				else
				{
					width += startAngle == 0 || startAngle == PI3d2 ? -rounding : rounding;
					height += startAngle == 0 || startAngle == PId2 ? -rounding : rounding;
				}
				//Width and height need to be adjusted by rounds to keep the block inside the tile
				arrayRef.push(new ArcCommand(width, height, rounding, startAngle, endAngle, clockwise));
			}
		}
		
	}
	
	this.BuildPreRender = function(block)
	{
		if(!(block.type in this.preRenders))
		{
			this.preRenders[block.type] = new Array();
		}

		if(!(block.subType in this.preRenders[block.type]))
		{
			this.preRenders[block.type][block.subType] = new Array();
		}
		
		if(!(block.rotation in this.preRenders[block.type][block.subType]))
		{
			this.preRenders[block.type][block.subType][block.rotation] = new Array();
		}

		if(block.value in this.preRenders[block.type][block.subType][block.rotation])
		{
			//already rendered this one
			return;
		}

		gConsole.Log(3, "[BR] Pre " + block.type + ", " + block.subType + ", " + block.rotation + " - " + block.value);
		
		var preRenders = 1
		if(block.switchPower)
		{
			preRenders = gTweenSteps;
		}
		else if(block.fading)
		{
			preRenders = gBlockDeleteTime;
		}
		
		var previousX = block.x;
		var previousY = block.y;
		var previousTween = block.tween;
		var previousDeleting = block.deleting;
		var previousDeleteTime = block.deleteTime;
		var previousContext = gBlockRenderer.context;
		
		if(block.switchPower)
		{
			this.preRenders[block.type][block.subType][block.rotation][block.value] = new Array(preRenders);
			block.tween = new Tween(block, block.x, block.y, block.x + 1, block.y + 1, gTweenSteps);
		}
		else if(block.fading)
		{
			this.preRenders[block.type][block.subType][block.rotation][block.value] = new Array(preRenders);
		}

		for(var i = 0; i < preRenders; i++)
		{
			//Pre Render the blocks
			var canvas = document.createElement('canvas');
			this.PreRenderPadding = Math.round(kTileSize * 0.05);
			canvas.width = block.GetBlockWidth() + (this.PreRenderPadding * 2);
			canvas.height = block.GetBlockHeight() + (this.PreRenderPadding * 2);
			var context = canvas.getContext('2d');
			
			gBlockRenderer.context = context;
			block.x = (this.PreRenderPadding/kTileSize);
			block.y = (this.PreRenderPadding/kTileSize);
			
			if(block.switchPower)
			{
				block.tween.step = i;
			}
			else if(block.fading)
			{
				block.deleting = (i != 0);
				block.deleteTime = i;
			}

			gBlockRenderer.Draw(block);
			gBlockRenderer.DrawOverlay(block);
			
			if(block.switchPower)
			{
				this.preRenders[block.type][block.subType][block.rotation][block.value][i] = canvas;
			}
			else if(block.fading)
			{
				this.preRenders[block.type][block.subType][block.rotation][block.value][i] = canvas;
			}
			else
			{
				this.preRenders[block.type][block.subType][block.rotation][block.value] = canvas;
			}
		}
		
		block.x = previousX;
		block.y = previousY;
		block.tween = previousTween;
		block.deleting = previousDeleting;
		block.deleteTime = previousDeleteTime;
		gBlockRenderer.context = previousContext;
		
	}
	
	this.GetAngle = function(code)
	{
		var PId2 = Math.PI/2;
		return PId2 * ((code + 3)%4);
	}
	
	this.GetNextChainCode = function(block, position, chainCode)
	{
		for(var i = 0; i < 4; i++)
		{
			//Chain code
			//   3
			// 2 + 0
			//   1
				
			//Check clockwise from back 90 degrees
			var code = Math.abs((chainCode + 3 + i) % 4);
			var x = position.x;
			var y = position.y;
			switch(code)
			{
				case 0:
					break;
				case 1:
					x--;
					break;
				case 2:
					x--;
					y--;
					break;
				case 3:
					y--;
					break;
				default:
					gConsole.Assert(0);
					break;
			}
			
			if(block.HasSubBlockAt(x, y))
			{
				return code;
			}
		}
		
		gConsole.Assert(0);
		return (chainCode + 1 % 4);
	}
	
	this.AdjustPositionForChainCode = function(position, chainCode)
	{
		switch(chainCode)
		{
			case 0:
				position.x++;
				return position;
			case 1:
				position.y++;
				return position;
			case 2:
				position.x--;
				return position;
			case 3:
				position.y--;
				return position;
		}
		
		gConsole.Assert(0);
		return position;
	}
	
	this.DrawClear = function(block)
	{
		if(block.x != block.px || block.y != block.py || block.palpha != block.GetAlphaFraction() || block.redraw)
		{
			for(var i = 0; i < block.subBlocks.length; i++)
			{
				var subBlock = block.subBlocks[i];
				var x = (block.px * kTileSize);
				var y = (block.py * kTileSize);

				this.context.clearRect(x + (subBlock.x * kTileSize), y + (subBlock.y * kTileSize), kTileSize, kTileSize);
				//TODO add unique point for all clearRects so can easily debug redrawing...
				//this.context.rect(x + (subBlock.x * kTileSize), y + (subBlock.y * kTileSize), kTileSize, kTileSize);
				//this.context.fillStyle = "rgb(255, 0, 0)";
				//this.context.fill();
			}
			block.redraw = true;
		}
	}
	
	this.GetRender = function(block)
	{
		if(block.switchPower)
		{
			return this.preRenders[block.type][block.subType][block.rotation][block.value][block.tween ? block.tween.step : 0];
		}
		else if(block.fading)
		{
			return this.preRenders[block.type][block.subType][block.rotation][block.value][block.deleteTime];
		}
		else
		{
			return this.preRenders[block.type][block.subType][block.rotation][block.value];
		}

		return null;
	}
	
	this.Draw = function(block)
	{
		//if(block.redraw)
		{
			var x = (block.x * kTileSize);
			var y = (block.y * kTileSize);
			
			var render = this.GetRender(block);
			if(render)
			{
				this.context.drawImage(render, x - this.PreRenderPadding, y - this.PreRenderPadding);
				return;
			}

			this.context.strokeStyle = gStyles.GetBlockRGB(block.type, block.value, block.IsDeleting() && block.fading).GetAdjusted(-64).GetColor();
			this.context.fillStyle = block.GetBlockFillStyle();
			this.context.beginPath();
			this.context.lineWidth = 0.5;
			var arrayRef = this.arcCommands[block.type][block.subType][block.rotation];
			var arrayRefLength = arrayRef.length;
			for(var i = 0; i < arrayRefLength; i++)
			{
				arrayRef[i].Draw(x, y);
			}
			this.context.fill();
			if(block.type == EBlockType.Normal && !block.IsDeleting())
			{
				this.context.closePath();
				this.context.stroke();
			}
			
			
			if(block.fading && block.IsDeleting() && block.type == EBlockType.Normal)
			{
				this.context.save();
				this.context.beginPath();
				var ox = (block.x * kTileSize) + (kTileSizeD2) + block.ox;
				var oy = (block.y * kTileSize) + (kTileSizeD2) + block.oy;
				this.context.moveTo(ox, oy);
				var startAngle = -Math.PI * 0.5;
				var circle = Math.PI * 2;
				var fraction = (block.deleteTime - gBlockDeleteTime)/gBlockDeleteTime
				this.context.arc(ox, oy, kTileSize * 3, startAngle, startAngle + (fraction * circle), true);
				this.context.clip();

				this.context.beginPath();
				for(var i = 0; i < arrayRefLength; i++)
				{
					arrayRef[i].Draw(x, y);
				}
				this.context.closePath();
				
				this.context.strokeStyle = block.GetBlockOutlineStrokeStyle();
				this.context.stroke();
				this.context.restore();
			}
			
			block.px = block.x;
			block.py = block.y;
			block.palpha = block.GetAlphaFraction();
		}
	}
	
	this.DrawOverlay = function(block)
	{
		var render = this.GetRender(block);
		if(render)
		{
			return;
		}
		
		//if(block.redraw)
		{
			var x = (block.x * kTileSize) + (kTileSizeD2) + block.ox;
			var y = (block.y * kTileSize) + (kTileSizeD2) + block.oy;

			if(block.switchPower)
			{
				this.DrawSwitchOverlay(block, x, y);
			}
			
			if(block.fading)
			{
				this.DrawFadingOverlay(block, x, y);
			}
			
			switch(block.type)
			{
				case EBlockType.Sliding:
					this.DrawSlidingOverlay(block, x, y);
					break;
				case EBlockType.Static:
					this.DrawStaticOverlay(block, x, y);
					break;
			}
			
			if (this.overlay)
			{
				this.context.shadowOffsetX = kTileSize * 0.02;
				this.context.shadowOffsetY = kTileSize * 0.02;
				this.context.shadowBlur = kTileSize * 0.04;
				this.context.shadowColor = block.GetTextShadowFillStyle();
				this.context.strokeStyle = block.GetTextFillStyle();
				this.context.fillStyle = block.GetTextFillStyle();
				this.context.font	 = GetFont(GetFontScale(32));
				this.context.textAlign	 = 'center';
				this.context.textBaseline	 = 'middle';
				
				if(block.value == 1)
				{
					this.DrawOverlayDetailText(block.value, x, y);
				}
				else
				{
					this.overlay(block.value, x, y);
				}
			}
			block.redraw = false;
		}
	}
	
	this.DrawSwitchOverlay = function(block, x, y)
	{
		var radius = kTileSize * 0.39;

		this.context.shadowOffsetX = 0;
		this.context.shadowOffsetY = 0;
		this.context.shadowBlur = 0;
		this.context.shadowColor = "rgb(0, 0, 0)";

		var strokeStyle = block.GetBlockStrokeStyle();
		this.context.fillStyle = strokeStyle;
		this.context.strokeStyle = strokeStyle;
		this.context.lineWidth = kTileSize * 0.1;//5;
		this.context.lineCap = "butt";
		
		this.context.beginPath();
		this.context.arc(x, y, radius - (kTileSize * 0.048), 0, Math.PI * 2);
		this.context.fill();
		
		var teeth = 6;
		for(i = 0; i < teeth; i++)
		{
			var extra = block.tween ? (block.tween.step/block.tween.steps) * Math.PI * (2/3) : 0;
			var startAngle = (Math.PI * 2 * (i/teeth)) + (Math.PI * 0.3) + extra;
			var rotation = Math.PI * (1/teeth);
			this.context.beginPath();
			this.context.arc(x, y, radius, startAngle, startAngle + rotation);
			this.context.stroke();
		}
	}
	
	this.DrawFadingOverlay = function(block, x, y)
	{
		var radius = ((kTileSize - 10)/2)

		this.context.shadowOffsetX = 0;
		this.context.shadowOffsetY = 0;
		this.context.shadowBlur = 0;
		this.context.shadowColor = "rgb(0, 0, 0)";

		var strokeStyle = block.GetBlockStrokeStyle();
		this.context.fillStyle = strokeStyle;
		
		this.context.beginPath();
		var fraction = 1 - (block.deleteTime/gBlockDeleteTime);
		this.context.moveTo(x, y)
		var startAngle = -Math.PI/2
		this.context.arc(x, y, radius, startAngle, startAngle + (Math.PI * 2 * -fraction), true);
		this.context.lineTo(x, y)
		this.context.fill();
	}
	
	this.DrawSlidingOverlay = function(block, x, y)
	{
		this.context.shadowOffsetX = 0;
		this.context.shadowOffsetY = 0;
		this.context.shadowBlur = 0;
		this.context.shadowColor = "rgb(0, 0, 0)";
		
		this.context.strokeStyle = block.GetBlockStrokeStyle();
		
		this.context.lineWidth = kTileSize * 0.06;
		this.context.lineJoin = "round";
		this.context.lineCap = "round";
		
		var radius = (kTileSizeD2) - (kTileSize * 0.1);
		var pronglength = kTileSize * 0.18;
		var prongAngle = Math.PI * 0.25;

		this.context.beginPath();
		var startAngle = 0;
		if(block.switchPower)
		{
			startAngle = block.tween ? (block.tween.step/block.tween.steps) * Math.PI * (2/3) : 0;
		}
		for(var angle = startAngle; angle < (Math.PI * 2) + startAngle; angle += Math.PI * 0.333)
		{
			this.DrawProng(x, y, radius, angle, pronglength, prongAngle);
		}
		
		this.context.stroke();
	}
	
	this.DrawProng = function(x, y, radius, angle, prongLength, prongAngle)
	{
		this.context.moveTo(x, y);
		this.context.lineTo(x + (Math.cos(angle) * radius), y + (Math.sin(angle) * radius));
		
		var prongStartLength = radius - prongLength;
		var prongX = x + (Math.cos(angle) * prongStartLength);
		var prongY = y + (Math.sin(angle) * prongStartLength);
		
		this.context.moveTo(prongX, prongY);
		this.context.lineTo(prongX + (Math.cos(angle + prongAngle) * prongLength), prongY + (Math.sin(angle + prongAngle) * prongLength));
		this.context.moveTo(prongX, prongY);
		this.context.lineTo(prongX + (Math.cos(angle - prongAngle) * prongLength), prongY + (Math.sin(angle - prongAngle) * prongLength));
	}

	
	this.DrawStaticOverlay = function(block, x, y)
	{
		var padding = kTileSize * 0.24;

		this.context.shadowOffsetX = 0;
		this.context.shadowOffsetY = 0;
		this.context.shadowBlur = 0;
		this.context.shadowColor = "rgb(0, 0, 0)";

		this.context.strokeStyle = block.GetBlockStrokeStyle();
		this.context.lineWidth = kTileSize * 0.1;
		this.context.lineJoin = "round";
		this.context.lineCap = "round";

		this.context.beginPath();
		this.context.arc(x, y, ((kTileSize - padding)/2), (Math.PI * 2), 0);
		
		this.context.moveTo(x + kTileSizeD2 - padding, y + padding - kTileSizeD2);
		this.context.lineTo(x + padding - kTileSizeD2, y + kTileSizeD2 - padding);
		this.context.stroke();

	}
	
	this.DrawOverlayDetailText = function(value, x, y)
	{
		this.context.fillText(value == 1 ? "?" : value, x, y);
	}
	
	this.DrawOverlayDetailArc = function(value, x, y)
	{
		var startAngle = -Math.PI*0.5
		this.ValueToAngle = function(value)
		{
			return startAngle + (((value)/9) * Math.PI * 2)
		}
		var radius = kTileSize*2/5;
		this.context.beginPath();
		this.context.moveTo(x, y);
		this.context.arc(x, y, radius, startAngle, this.ValueToAngle(value), false);
		this.context.fill();
		
		this.context.save();
		this.context.beginPath();
		this.context.shadowOffsetX = 0;
		this.context.shadowOffsetY = 0;
		this.context.shadowBlur = 0;

		this.context.lineWidth = 1;
		this.context.strokeStyle = "rgba(0, 0, 0, 0.5)";
		for(var i = 1; i <= value - 1; i++)
		{
			this.context.moveTo(x, y);
			var angle = this.ValueToAngle(i);
			this.context.lineTo(x + (Math.cos(angle) * radius), y + (Math.sin(angle) * radius));
		}
		this.context.stroke();
		this.context.restore();
	}

	this.DrawOverlayDetailLatin = function(value, x, y)
	{
		var text;
		switch(value)
		{
			case 1:
				text = "I";
				break;
			case 2:
				text = "II";
				break;
			case 3:
				text = "III";
				break;
			case 4:
				text = "IV";
				break;
			case 5:
				text = "V";
				break;
			case 6:
				text = "VI";
				break;
			case 7:
				text = "VII";
				break;
			case 8:
				text = "VIII";
				break;
			case 9:
				text = "IX";
				break;
			default:
				text = "X";
				break;
		}
		this.context.fillText(text, x, y);
	}

	this.circleCoords = new Array();
	this.circleCoords[1] = new Array(new Vec2(4, 4));
	this.circleCoords[2] = new Array(new Vec2(2, 6), new Vec2(6, 2));
	this.circleCoords[3] = new Array(new Vec2(2, 2), new Vec2(6, 2), new Vec2(4, 6));
	this.circleCoords[4] = new Array(new Vec2(4, 2), new Vec2(6, 4), new Vec2(4, 6), new Vec2(2, 4));
	this.circleCoords[5] = new Array(new Vec2(4, 2), new Vec2(6, 4), new Vec2(4, 6), new Vec2(2, 4), new Vec2(4, 4));
	this.circleCoords[6] = new Array(new Vec2(4, 2), new Vec2(6, 3), new Vec2(6, 5), new Vec2(4, 6), new Vec2(2, 3), new Vec2(2, 5));
	this.circleCoords[7] = new Array(new Vec2(4, 2), new Vec2(6, 3), new Vec2(6, 5), new Vec2(4, 6), new Vec2(2, 3), new Vec2(2, 5), new Vec2(4, 4));
	this.circleCoords[8] = new Array(new Vec2(2, 2), new Vec2(4, 2), new Vec2(6, 2), new Vec2(2, 4), new Vec2(6, 4),new Vec2(2, 6), new Vec2(4, 6), new Vec2(6, 6));
	this.circleCoords[9] = new Array(new Vec2(2, 2), new Vec2(4, 2), new Vec2(6, 2), new Vec2(2, 4), new Vec2(4, 4), new Vec2(6, 4),new Vec2(2, 6), new Vec2(4, 6), new Vec2(6, 6));
	this.DrawOverlayDetailCircles = function(value, x, y)
	{
		x -= kTileSizeD2;
		y -= kTileSizeD2;
		var spacing = kTileSize/8;
		var radius = kTileSize/10;
		var array = this.circleCoords[value];
		var length = array.length;
		for(var i = 0; i < length; i++)
		{
			this.context.beginPath();
			var coord = array[i];
			this.context.arc(x + (coord.x * spacing), y + (coord.y * spacing), radius, 0, Math.PI * 2);
			this.context.fill();
		}
	}
	
	this.diamondRadius = kTileSize * 0.7;
	this.diamondPositions = new Array(new Vec2(this.diamondRadius * 0, this.diamondRadius * -1),
	new Vec2(this.diamondRadius * 0.5, this.diamondRadius * -0.5),
	new Vec2(this.diamondRadius * 1, this.diamondRadius * 0),
	new Vec2(this.diamondRadius * 0.5, this.diamondRadius * 0.5),
	new Vec2(this.diamondRadius * 0, this.diamondRadius * 1),
	new Vec2(this.diamondRadius * -0.5, this.diamondRadius * 0.5),
	new Vec2(this.diamondRadius * -1, this.diamondRadius * 0),
	new Vec2(this.diamondRadius * -0.5, this.diamondRadius * -0.5))
	
	this.diamondStartOffset = new Array(7, 0, 2, 5, 1, 6, 4, 0);
	
	this.DrawOverlayDiamond = function(value, x, y)
	{
		var offset = this.diamondStartOffset[value - 1];
		if(value == 9)
		{
			offset = this.diamondStartOffset[7];
		}
		
		this.context.beginPath();
		this.context.moveTo(x, y);
		for(var i = 0; i <= value ; i++)
		{
			var index = (offset + i) % 8
			var pos = this.diamondPositions[index];
			this.context.lineTo(x + pos.x, y + pos.y);
		}
		this.context.closePath();
		this.context.fill();
		
		if(value == 9)
		{
			var radius = this.diamondRadius * 0.5;
			this.context.beginPath();
			this.context.moveTo(x, y - radius);
			this.context.lineTo(x + radius, y);
			this.context.lineTo(x, y + radius);
			this.context.lineTo(x - radius, y);
			this.context.closePath();
			this.context.stroke();
			this.context.fill();
		}
	}
	
	this.DrawOverlayDetailAztec = function(value, x, y)
	{
		this.context.lineCap = "butt";
		x -= kTileSizeD2;
		y -= kTileSizeD2;
		var spacing = kTileSize/8;
		var radius = kTileSize/12;
		var dotsOffsetY = kTileSizeD2 - spacing;
		var dots = value >= 5 ? value - 5 : value;
		var dotsStepX = kTileSize/(dots + 1);
		for(var i = 0; i < dots; i++)
		{
			this.context.beginPath();
			this.context.arc(x + (dotsStepX * (i + 1)), y + dotsOffsetY, radius, 0, Math.PI * 2);
			this.context.fill();
		}
		var lineOffsetY = kTileSizeD2 + spacing;
		if(value >= 5)
		{
			this.context.beginPath();
			this.context.lineWidth = radius * 2;
			this.context.moveTo(x + spacing, y + lineOffsetY);
			this.context.lineTo(x + kTileSize - spacing, y + lineOffsetY);
			this.context.stroke();
		}
	}
	
	this.DrawOverlayDetailSides = function(value, x, y)
	{
		this.context.lineJoin = "round";
		this.context.beginPath();
		var step = (Math.PI * 2)/value;
		var size = kTileSize/3;
		for(var i = 0; i < value; i++)
		{
			var angle = (step * i) + Math.PI;
			this.context.lineTo(x + (Math.sin(angle) * size), y + (Math.cos(angle) * size));
		}
		this.context.closePath();
		this.context.fill();
	}

	this.DrawOverlayDetailLines = function(value, x, y)
	{
		this.context.beginPath();
		var step = Math.PI/value;
		var size = kTileSize/3;
		for(var i = 0; i < value; i++)
		{
			var angle = (step * i);
			var xOffset = (Math.sin(angle) * size);
			var yOffset = (Math.cos(angle) * size);
			this.context.moveTo(x - xOffset, y - yOffset);
			this.context.lineTo(x + xOffset, y + yOffset);
		}
		this.context.closePath();
		this.context.stroke();
	}
	
	this.SetOverlay = function(index)
	{
		var currentIndex = this.overlays.indexOf(this.overlay);
		if(currentIndex != index)
		{
			gStorage.setItem("options", "block", "overlay", index);
			this.overlay = this.overlays[index];
			return true;
		}
		else
		{
			return false;
		}
	}

	this.overlayNames = new Array(
		"blockdesign_numbers",
		"blockdesign_shapes",
		"blockdesign_dots",
		"blockdesign_aztec",
		"blockdesign_blank"
		)
	
	this.overlays = new Array(
		this.DrawOverlayDetailText,
		this.DrawOverlayDetailSides,
		this.DrawOverlayDetailCircles,
		this.DrawOverlayDetailAztec,
		//this.DrawOverlayDetailLatin,
		null)
	
	this.overlay = this.DrawOverlayDetailText;
	this.GetOverlayName = function(index)
	{
		return this.overlayNames[index];
	}
	
	var prevOverlay = gStorage.getItem("options", "block", "overlay");
	if(prevOverlay)
	{
		var index = parseInt(prevOverlay);
		if(index < this.overlays.length)
		{
			this.overlay = this.overlays[index];
		}
	}
}

