//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


function Spawner()
{
	this.spawnArea = null;
	
	this.blockType = null;
	this.blockSubType = null;
	this.blockValues = new Array();
	this.switchPower = false;
	this.connected = false;
	this.fading = false;
	
	this.time = 0;
	this.timer = null;
	this.nextBlock = undefined;
	
	this.spawnIfValueExists = false;
	
	this.Registered = function()
	{
		this.PreSpawnBlock();
	}
	
	this.PreSpawnBlock = function()
	{
		var nextSpawnValue = this.GetSpawnBlockValue();
		this.nextBlock = gBlockSystem.CreateBlock(this.blockType, this.blockSubType, 0, nextSpawnValue, 0, 0, this.switchPower, this.connected, this.fading);
	}
	
	this.SetArea = function(spawnArea)
	{
		this.spawnArea = spawnArea;
	}
	
	this.SetBlockType = function(type, subType)
	{
		this.blockType = type;
		this.blockSubType = subType;
	}
	
	this.SetBlockRange = function(minValue, maxValue)
	{
		gConsole.Assert(maxValue - minValue > 0);
		for(var i = minValue; i <= maxValue; i++)
		{
			this.AddBlockValue(i);
		}
	}
	
	this.SpawnIfValueExists = function()
	{
		this.spawnIfValueExists = true;
	}
	
	this.SetBlockValue = function(value)
	{
		this.AddBlockValue(value);
	}
	
	this.AddBlockValue = function(value)
	{
		for(var i = 0; i < value; i++)
		{
			this.blockValues.push(value);
		}
	}
	
	this.ResetBlockValues = function()
	{
		this.blockValues = new Array();
	}
	
	this.SetSwitchPower = function(set)
	{
		this.switchPower = set;
	}
	
	this.SetFadingPower = function(set)
	{
		this.fading = set;
	}
	
	this.SetConnectedPower = function(set)
	{
		this.connected = set;
	}
	
	this.CanSpawnBlock = function()
	{
		if (this.spawnIfValueExists)
		{
			for(var i = 0; i < this.blockValues.length; i++)
			{
				if(gBlockSystem.CountBlocksOfValue(this.blockValues[i]) > 0)
				{
					return true;
				}
			}
			
			return false;
		}
		else
		{
			return true;
		}
	}
	
	this.GetSpawnBlockValue = function()
	{
		if (this.spawnIfValueExists)
		{
			var value = this.GetSpawnBlockValueInternal();
			while (gBlockSystem.CountBlocksOfValue(value) == 0)
			{
				value = this.GetSpawnBlockValueInternal();
			}
			
			return value;
		}
		else
		{
			return this.GetSpawnBlockValueInternal();
		}
	}
	
	this.GetSpawnBlockValueInternal = function()
	{
		var index = Math.floor((Math.random() * this.blockValues.length));
		index = Math.clamp(index, 0, this.blockValues.length - 1);
		return this.blockValues[index];
	}
	
	this.SetTimer = function(timer)
	{
		this.timer = timer;
	}
	
	this.IsValid = function()
	{
		return this.spawnArea && this.spawnArea.IsValid() && this.blockType && this.blockSubType && this.blockValues.length && this.timer;
	}
	
	this.CheckValid = function()
	{
		gConsole.AssertMsg(this.spawnArea, "Missing Spawn Area on Spawner");
		gConsole.AssertMsg(this.spawnArea.IsValid(), "Spawn Area is invaliud on Spawner");
		gConsole.AssertMsg(this.blockType && this.blockSubType && this.blockValues.length > 0, "Missing block type on spawner");
		gConsole.AssertMsg(this.timer, "Missing timer on Spawner");
		
		return this.IsValid();
	}
	
	this.Update = function()
	{
		if(this.timer)
		{
			if(this.timer <= this.time)
			{
				this.SpawnBlock();
				this.time = 0;
			}
			this.time++;
		}
	}
	
	this.SpawnBlock = function()
	{
		var vec2 = this.spawnArea.GetPoint(this.nextBlock);
		if(vec2)
		{
			if (this.CanSpawnBlock())
			{
				this.nextBlock.x = vec2.x;
				this.nextBlock.y = vec2.y;
				gBlockSystem.InsertBlock(this.nextBlock);
				
				this.PreSpawnBlock();
			}
		}
	}
	
	this.Debug = function()
	{
		if(this.timer)
		{
			gDraw.Watch("Spawner [ " + this.nextBlock.value + " ] " + this.time + "/" + this.timer);
			
			var breakdown = "";
			for(var i = 0; i < this.blockValues.length; i++)
			{
				breakdown += this.blockValues[i];
				if(i != this.blockValues.length - 1)
				{
					breakdown += ", "
				}
			}
			gDraw.Watch("Spawner [ " + breakdown + " ]");
		}
		
		var urlVars = getUrlVars();
		if(urlVars["spawnarea"])
		{
			this.spawnArea.Debug(this.nextBlock);
		}
	}
}