function Tile() {
	this.imageObject = document.createElement('img');
//	this.imageObject.style.border = 'solid 1px black';
}

function Layer(imageWidth, imageHeight) {
//	this.parent = Parent;

	this.Viewer;
	this.minCoords = new Point();
	var TileSize = new Point();
	this.Scale = new Point();
	var mapSize = new Point(imageWidth, imageHeight);

	this.tilePadding = 0;

	var Tiles = new Array();

	var MinImageCoords = new Point(0,0);

	this.initialize = function() {
		var nW = roundUp(imageWidth / TileSize.x)+this.tilePadding*2;
		var nH = roundUp(imageHeight / TileSize.y)+this.tilePadding*2;
		for(var x = 0; x < nW; x++) {
			Tiles[x] = new Array();
			for(var y = 0; y < nH; y++) {
				Tiles[x][y] = new Tile();
			}
		}
		MinImageCoords = new Point(-1*this.tilePadding*TileSize.x, -1*this.tilePadding*TileSize.y);
		this.minCoords.x = this.minCoords.x - this.Scale.x * TileSize.x * this.tilePadding;
		this.minCoords.y = this.minCoords.y - this.Scale.y * TileSize.y * this.tilePadding;
	}	


	// This is meant to be replaced by the viewers native scaling function.
	this.getScale = function () {
		return 1;
	}

	this.setMapSize = function(size) {
		mapSize = size;
	}

	this.getTileSize = function() {
		return TileSize;
	}

	this.setTileSize = function(size) {
		TileSize = size;
	}

	this.resetTiles = function (w, h) {
		Tiles = new Array();
		for(var x = 0; x < w; x++) {
			Tiles[x] = new Array();
			for(var y = 0; y < h; y++) {
				Tiles[x][y] = new Tile();
			}
		}
	}

	this.reloadTiles = function () {
		for(var x = 0; x < Tiles.length; x++) {
			for(var y = 0; y < Tiles[0].length; y++) {
				Tiles[x][y].imageObject.src = 'null';
			}
		}
		this.populateEmptyTiles();
	}

	this.emptyTiles = function() {
		var length = Tiles.length;
		for(var i = 0; i < length; i++) {
			removeRow(0);
			Tiles.shift();
		}
		Tiles = new Array();
	}

	this.populateEmptyTiles = function () {
		var ImageScale = new Point(this.Scale.x * TileSize.x, this.Scale.y * TileSize.y);
		//alert(ImageScale.toString(','));
		this.Viewer.imageSize = TileSize;
		var test = true;
		for(var x = 0; x < Tiles.length; x++) {
			for(var y = 0; y < Tiles[0].length; y++) {
				if(Tiles[x][y] == null) { Tiles[x][y] = new Tile(); }
				if(Tiles[x][y].imageObject.src == null || Tiles[x][y].imageObject.src == '' || Tiles[x][y].imageObject.src.match('null')) {
					var TileMinCoords = new Point(parseFloat(this.minCoords.x)+(ImageScale.x*x), parseFloat(this.minCoords.y)+(ImageScale.y*(Tiles[0].length - (y+1))));
					var TileMaxCoords = new Point(parseFloat(TileMinCoords.x)+parseFloat(ImageScale.x), parseFloat(TileMinCoords.y)+parseFloat(ImageScale.y));
					if(test) {
						//alert(TileMaxCoords.toString(',')); test = false;
					}
					this.Viewer.coords = new LineSegment(TileMinCoords, TileMaxCoords);
					Tiles[x][y].imageObject.src = this.Viewer.buildMapServerString('map');
				}
			}
		}
	}	

	this.getImageObjects = function() {
		var imageObjects = new Array();
		var c = 0;
		for(var x = 0; x < Tiles.length; x++) {
			for(var y = 0; y < Tiles[0].length; y++) {
				if(Tiles[x][y].imageObject.parentNode == null) {
					Tiles[x][y].imageObject.style.position = 'absolute';
					Tiles[x][y].imageObject.style.left = parseInt(MinImageCoords.x) + x * TileSize.x +'px';
					Tiles[x][y].imageObject.style.top = parseInt(MinImageCoords.y) + y * TileSize.y + 'px';
				}
				imageObjects[c] = Tiles[x][y].imageObject;
				c++;
			}
		}
		return imageObjects;
	}

	this.setMinImageCoords = function (newPoint) {
		MinImageCoords = newPoint;
	}

	this.getMinImageCoords = function () {
		return MinImageCoords;
	}

	this.shift = function(shiftx, shifty) {
		MinImageCoords.x = parseInt(MinImageCoords.x) + shiftx;
		MinImageCoords.y = parseInt(MinImageCoords.y) + shifty;
		for(var x = 0; x < Tiles.length; x++) {
			for(var y = 0; y < Tiles[0].length; y++) {
				Tiles[x][y].imageObject.style.left = parseInt(MinImageCoords.x) + x * TileSize.x + 'px';
				Tiles[x][y].imageObject.style.top = parseInt(MinImageCoords.y) + y * TileSize.y + 'px';
			}
		}
	}

	function removeRow(x) {
		for(var y = 0; y < Tiles[x].length; y++) {
			var p = Tiles[x][y].imageObject.parentNode;
			p.removeChild(Tiles[x][y].imageObject);
		}
	}

	function removeColumn(y) {
		for(var x = 0; x < Tiles.length; x++) {
			var p = Tiles[x][y].imageObject.parentNode;
			p.removeChild(Tiles[x][y].imageObject);
		}
	}

	this.fallOffTiles = function() {
		// Clean up on the Left
		var FarLeft = Tiles[0][0].imageObject.offsetLeft;
		var nLeft = parseInt(FarLeft / TileSize.x) * -1;
		nLeft-=this.tilePadding;

		var FarRight = Tiles[Tiles.length-1][0].imageObject.offsetLeft+Tiles[Tiles.length-1][0].imageObject.offsetWidth - mapSize.x;
		var nRight = parseInt(FarRight / TileSize.x);
		nRight-=this.tilePadding;

		var TopGap = Tiles[0][0].imageObject.offsetTop;
		var nTop = parseInt(TopGap / TileSize.y) * -1;
		nTop-=this.tilePadding;

		var BottomGap = (Tiles[0][Tiles[0].length-1].imageObject.offsetTop+Tiles[0][Tiles[0].length-1].imageObject.offsetHeight) - mapSize.y;
		var nBottom = parseInt(BottomGap / TileSize.y);
		nBottom-=this.tilePadding;

		if(nLeft > 0) {
			for(var x = 0; x < nLeft; x++) {
				removeRow(0);
				MinImageCoords.x = parseInt(MinImageCoords.x) + parseInt(TileSize.x);
				this.minCoords.x = this.minCoords.x + (TileSize.x * this.Scale.x);
				Tiles.shift();
			}
		}

		if(nRight > 0) {
			for(var x = 0; x < nRight; x++) {
				removeRow(Tiles.length - 1);
				Tiles.pop();
			}
		}

		if(nTop > 0) {
			//this.minCoords.y = parseFloat(this.minCoords.y)+parseFloat(this.Scale.y)*nBottom*TileSize.y;
			for(var i = 0; i < nTop; i++) {
				removeColumn(0);
				//MinImageCoords.y = parseInt(MinImageCoords.y) + parseInt(TileSize.y);
				for(var x = 0; x < Tiles.length; x++) {
					Tiles[x].shift();
				}
			}
		}

		if(nBottom > 0) {
			this.minCoords.y = parseFloat(this.minCoords.y)+parseFloat(this.Scale.y)*nBottom*TileSize.y;

			for(var i = 0; i < nBottom; i++) {
				removeColumn(Tiles[0].length - 1);

				for(var x = 0; x < Tiles.length; x++) {
					Tiles[x].pop();
				}
			}

		}

	}

	this.pan = function(panx, pany) {
//		this.fallOffTiles();

		var LeftGap = Tiles[0][0].imageObject.offsetLeft;
		var RightGap = Tiles[Tiles.length-1][0].imageObject.offsetLeft+Tiles[Tiles.length-1][0].imageObject.offsetWidth - mapSize.x;
		var TopGap = Tiles[0][0].imageObject.offsetTop;
		var BottomGap = (Tiles[0][Tiles[0].length-1].imageObject.offsetTop+Tiles[0][Tiles[0].length-1].imageObject.offsetHeight) - mapSize.y;
		var newTiles = new Array();


		if(LeftGap > 0) {
			var n = roundUp(LeftGap / TileSize.x);
			if(n > 0 && LeftGap >= 0) { MinImageCoords.x = MinImageCoords.x - (TileSize.x*n); }

			for(var x = 0; x < Tiles.length; x++) {
				newTiles[x+n] = Tiles[x];
			}

			for(var x = 0; x < n; x++) {
				newTiles[x] = new Array();
				for(var y = 0; y < Tiles[0].length; y++) {
					newTiles[x][y] = new Tile();
				}
			} 
			this.minCoords = new Point(parseFloat(this.minCoords.x)-parseFloat(this.Scale.x)*n*TileSize.x, this.minCoords.y);
			Tiles = newTiles;
		} 

		if(RightGap < 0) {
			var n = roundUp(-1*RightGap / TileSize.x);
			var maxX = Tiles.length;
			for(var x = maxX; x < maxX + n; x++) {
				Tiles[x] = new Array();
				for(var y = 0; y < Tiles[0].length; y++) {
					Tiles[x][y] = new Tile();
				}
			}
		}

		if(TopGap > 0) {
			newTiles = new Array();
			var n = roundUp(TopGap / TileSize.y);
			if(n > 0) { MinImageCoords.y = MinImageCoords.y - (TileSize.y*n); }
			for(var x = 0; x < Tiles.length; x++) {
				newTiles[x] = new Array();
				for(var y = 0; y < Tiles[0].length; y++) {
					newTiles[x][y+n] = Tiles[x][y];
				}
			}

			for(var x = 0; x < Tiles.length; x++) {
				for(var y = 0; y < n; y++) {
					newTiles[x][y] = new Tile();
				}
			}
			Tiles = newTiles;
		}

		if(BottomGap < 0) {
			var n = roundUp(-1 * BottomGap / TileSize.x);
			var maxY = Tiles[0].length;
			for(var x = 0; x < Tiles.length; x++) {
				for(var y = maxY; y < maxY+n; y++) {
					Tiles[x][y] = new Tile();
				}
			}
			this.minCoords = new Point(this.minCoords.x, parseFloat(this.minCoords.y)-parseFloat(this.Scale.y)*n*TileSize.y);
		}

		this.populateEmptyTiles();
	}
		

	this.clone = function() {
		var newLayer = new Layer(imageWidth, imageHeight);
	
		newLayer.Viewer = this.Viewer;
		newLayer.minCoords = this.minCoords;
		newLayer.setTileSize(TileSize);
		newLayer.Scale = this.Scale;
		newLayer.setMapSize(mapSize);
		newLayer.setMinImageCoords(this.getMinImageCoords());
		newLayer.tilePadding = this.tilePadding;
		newLayer.resetTiles(Tiles.length, Tiles[0].length);

		return newLayer;
	}

}
