var N_STATE_INACTIVE	= -1;
var N_STATE_WAITING		= 0;
var N_STATE_QUEUED		= 1;
var N_STATE_LOADING		= 2;
var N_STATE_COMPLETE	= 3;

var N_DIR_LEFT		= 0;
var N_DIR_TOP			= 1;
var N_DIR_RIGHT		= 2;
var N_DIR_BOTTOM	= 3;

var N_MAX_REQUESTS			= 5;
var N_MAX_LOADING_TILES	= 5;

var A_TILESIZE_METER = [40, 50, 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 
												204800, 409600, 819200, 1638400]; /* 3276800, 6553600];*/

/********************************************************************************/

function iwTile(oTileset, 
								nIndexX, nIndexY, 
								nPositionX, nPositionY, 
								nCenterMeterX, nCenterMeterY)
{
	// class variables
	this.nIndexX = nIndexX;
	this.nIndexY = nIndexY;
	this.nPositionX = 0;
	this.nPositionY = 0;
	this.nCenterMeterX = nCenterMeterX;
	this.nCenterMeterY = nCenterMeterY;
	this.nState = N_STATE_WAITING;
	this.nWeight = 0;
	this.nTimestamp = 0;
	this.nTilesizeMeter = A_TILESIZE_METER[2];
	this.sSource = "";
	this.oTileset = oTileset;
	this.oTimeout = null;
	this.oDiv = document.getElementById('divTile_' + nIndexX + '_' + nIndexY);
	this.oImg = document.getElementById('imgTile_' + nIndexX + '_' + nIndexY);
	
	// class methods
	this.ComputeWeight = iwComputeWeight;
	this.Move = iwMoveTile;
	this.MoveTo = iwMoveTileTo;
	this.LoadTile = iwLoadTile;
	this.TileComplete = iwTileComplete;
	this.LoadingTimeout = iwLoadingTimeout;
	
	// constructor implementation
	this.MoveTo(nPositionX, nPositionY);
}

function iwComputeWeight(nCenterX, nCenterY)
{
	var nTileCenterX = this.nPositionX + this.oTileset.nTilesize / 2;
	var nTileCenterY = this.nPositionY + this.oTileset.nTilesize / 2;
	
	this.nWeight = Math.sqrt(		Math.pow(nCenterX - nTileCenterX, 2)
														+ Math.pow(nCenterY - nTileCenterY, 2));
}

function iwMoveTile(nOffsetX, nOffsetY)
{
	this.nPositionX += nOffsetX;
	this.nPositionY += nOffsetY;
	
	if (bDebugMode)
	{
		/****************** DEBUGGING ONLY **********************/
		this.oDiv.style.left = this.nPositionX + nMainMapOffsetPixelX;
		this.oDiv.style.top  = this.nPositionY + nMainMapOffsetPixelY;
		/********************************************************/
	}
	else
	{
		this.oDiv.style.left = this.nPositionX;
		this.oDiv.style.top  = this.nPositionY;
	}
}

function iwMoveTileTo(nPositionX, nPositionY)
{
	this.nPositionX = nPositionX;
	this.nPositionY = nPositionY;
	
	if (bDebugMode)
	{
		/****************** DEBUGGING ONLY **********************/
		this.oDiv.style.left = this.nPositionX + nMainMapOffsetPixelX;
		this.oDiv.style.top  = this.nPositionY + nMainMapOffsetPixelY;
		/********************************************************/
	}
	else
	{
		this.oDiv.style.left = this.nPositionX;
		this.oDiv.style.top  = this.nPositionY;
	}
}

function iwLoadTile()
{
	this.oDiv.style.visibility = "hidden";
	
	var nIndex = this.nIndexY * this.oTileset.nTotalTilesX + this.nIndexX;
	var sFail = 'oTileset.aTiles[' + nIndex + '].LoadingTimeout();';
	this.oTimeout = window.setTimeout(sFail, 20000);
	
	this.oImg.onload = this.TileComplete;
	
	var sURL =		this.oTileset.sMapServerURL 
							+ "GetTileMap.jsp?cmd=GetTile&file="
							+ this.sSource;	
	this.oImg.src =	configurator.getMapServerUrl(sURL);
	
	this.nState = N_STATE_LOADING;
}

function iwLoadingTimeout()
{
	// try again to load the image and reset the timeout
	this.oImg.src = this.oImg.src;
	var nIndex = this.nIndexY * this.oTileset.nTotalTilesX + this.nIndexX;
	var sFail = 'oTileset.aTiles[' + nIndex + '].LoadingTimeout();';
	this.oTimeout = window.setTimeout(sFail, 20000);
}

function iwTileComplete()
{
	// find the tile for the loaded image
	var aParts = this.id.split('_');
	var nIndexX = parseInt(aParts[1]);
	var nIndexY = parseInt(aParts[2]);
	var nIndex = nIndexY * oTileset.nTotalTilesX + nIndexX;
	var oTile = oTileset.aTiles[nIndex];

	if (oTile.oTimeout)
	{
		window.clearTimeout(oTile.oTimeout);
		oTile.oTimeout = null;
	}
	
	// ignore tiles which have been discarded and should be reloaded (marked as queued)
	if (oTile.nState == N_STATE_LOADING)
	{
		oTile.oDiv.style.visibility = "visible";
		oTile.nState = N_STATE_COMPLETE;
	}
	oTile.oTileset.nLoadingTiles--;
	
	var nTileLeft		= oTile.nPositionX;
	var nTileRight	= nTileLeft + oTile.oTileset.nTilesize;
	var nTileTop		= oTile.nPositionY;
	var nTileBottom	= nTileTop + oTile.oTileset.nTilesize;
	
	if (		(		(nTileLeft >= 0 && nTileLeft < oTile.oTileset.nVisibleWidth)
						||(nTileRight >= 0 && nTileRight < oTile.oTileset.nVisibleWidth))
			&&	(		(nTileTop >= 0 && nTileTop < oTile.oTileset.nVisibleHeight)
						||(nTileBottom >= 0 && nTileBottom < oTile.oTileset.nVisibleHeight)))
	{
		//console.log(oTile.nTimestamp, ++nTest);
		new LockCounter().syncDecrease();
	}
	
	oTile.oTileset.LoadNext();
}