var MinedMapLayer = L.GridLayer.extend({
	initialize: function (mipmaps, layer) {
		this.mipmaps = mipmaps;
		this.layer = layer;

		this.zoomOffset = L.Browser.retina ? 1 : 0;

		this.options.attribution = 'Generated by <a href="http://git.universe-factory.net/MinedMap/">MinedMap</a>';

		if (!L.Browser.android) {
			this.on('tileunload', this._onTileRemove);
		}
	},

	createTile: function (coords, done) {
		var tile = document.createElement('img');

		tile.onload = L.bind(this._tileOnLoad, this, done, tile);
		tile.onerror = L.bind(this._tileOnError, this, done, tile);

		tile.alt = '';

		var z = -(coords.z + this.zoomOffset);
		if (z < 0)
			z = 0;

		var mipmap = this.mipmaps[z];

		if (coords.x >= mipmap.info.minX && coords.x <= mipmap.info.maxX &&
		    coords.y >= mipmap.info.minZ && coords.y <= mipmap.info.maxZ &&
		    mipmap.regions[coords.y-mipmap.info.minZ][coords.x-mipmap.info.minX])
			tile.src = 'data/'+this.layer+'/'+z+'/r.'+coords.x+'.'+coords.y+'.png';

		if (z == 0)
			L.DomUtil.addClass(tile, 'overzoomed');

		return tile;
	},

	_tileOnLoad: function (done, tile) {
		done(null, tile);
	},

	_tileOnError: function (done, tile, e) {
		done(e, tile);
	},

	_getTileSize: function () {
		var map = this._map, zoom = map.getZoom() + this.zoomOffset;

		var base = (L.Browser.retina ? 256 : 512);

		if (zoom > 0)
			return Math.round(map.getZoomScale(zoom, 0) * base);
		else
			return base;
	},

	_onTileRemove: function (e) {
		e.tile.onload = null;
		e.tile.src = L.Util.emptyImageUrl;
	},

	_abortLoading: function () {
		var i, tile;
		for (i in this._tiles) {
			tile = this._tiles[i].el;

			tile.onload = L.Util.falseFn;
			tile.onerror = L.Util.falseFn;

			if (!tile.complete) {
				tile.src = L.Util.emptyImageUrl;
				L.DomUtil.remove(tile);
			}
		}
	}
});


var CoordControl = L.Control.extend({
	initialize: function () {
		this.options.position = 'bottomleft';
	},

	onAdd: function (map) {
		this._container = L.DomUtil.create('div', 'leaflet-control-attribution');

		return this._container;
	},

	update: function (x, z) {
		if (!this._map) { return; }

		this._container.innerHTML = 'X: ' + x + '&nbsp;&nbsp;&nbsp;Z: ' + z;
	}
});


window.createMap = function () {
	var xhr = new XMLHttpRequest();
	xhr.onload = function () {
		var res = JSON.parse(this.responseText),
		    mipmaps = res.mipmaps,
		    spawn = res.spawn;

		var map = L.map('map', {
			center: [-spawn.z, spawn.x],
			zoom: 0,
			minZoom: -(mipmaps.length-1),
			maxZoom: 3,
			crs: L.CRS.Simple,
			maxBounds: [
				[-512*(mipmaps[0].info.maxZ+1), 512*mipmaps[0].info.minX],
				[-512*mipmaps[0].info.minZ, 512*(mipmaps[0].info.maxX+1)],
			],
		});

		var mapLayer = new MinedMapLayer(mipmaps, 'map');
		var lightLayer = new MinedMapLayer(mipmaps, 'light');

		mapLayer.addTo(map);

		var overlayMaps = {
			"Illumination": lightLayer,
		};

		L.control.layers({}, overlayMaps).addTo(map);

		var coordControl = new CoordControl();
		coordControl.addTo(map);

		map.on('mousemove', function(e) {
			coordControl.update(Math.round(e.latlng.lng), Math.round(-e.latlng.lat));
		});
	};

	xhr.open('GET', 'data/info.json', true);
	xhr.send();
}