/**
 * The output map presents an on-screen visual representation of
 * a data source as markers over a map implementation
 */
HYSMaps.OutputMap = function (factory, input, element) {
	this.factory = factory; // map factory
	this.input = input; // path to XML data

	this.sizer = new HYSMaps.AutoPanelSizer(this);
	this.sizer._waitingPanels = [];
	// See note in HYSMaps.InputParser.prototype.onload, bbc-news-map.js line 240

	this.showTypedSeriesTotals = true;
	
	if (HYSMaps.browserType == "FireFoxMac") {
		glow.dom.get("body").addClass("browser-type-firefox-mac");
	}

	this.dom = {
		
		base: element,
		header: document.createElement('h2'),
		controls: {
			top: document.createElement('ul'),
			base: document.createElement('ul'),
			commentBase: document.createElement('div'),
			commentList: document.createElement('ul'),
			commentClear: document.createElement('div')
		},
		types: {
			base: document.createElement('ul'),
			wrapper: document.createElement('div'),
			header: document.createElement('div')
		},
		overlay: {
			base: document.createElement('div'),
			wrapper: element.getElementsByTagName('div')[0],
			bg: document.createElement('div'),
			close: document.createElement('a'),
			content: document.createElement('div')
		},
		nextPrevPanelControl: {
			base: document.createElement('div'),
			inner: document.createElement('div'),
			nextButton: document.createElement('a'),
			prevButton: document.createElement('a'),
			buttonHolder: document.createElement("div"),
			numButtonHolder: document.createElement("div")
		},
		commentLimiter: {
			base: document.createElement('div'),
			height: 0
		}
	};
	this.dom.nextPrevPanelControl.base.setAttribute('id', 'map-next-prev-panel-control-holder');
	this.dom.nextPrevPanelControl.inner.className = "mnpp-inner";
	this.dom.nextPrevPanelControl.base.appendChild(this.dom.nextPrevPanelControl.inner);
	this.dom.nextPrevPanelControl.buttonHolder.className = "mnpp-button-holder";
	this.dom.nextPrevPanelControl.inner.appendChild(this.dom.nextPrevPanelControl.buttonHolder);
	this.dom.nextPrevPanelControl.numButtonHolder.className = "mnpp-num-button-holder";
	this.dom.nextPrevPanelControl.buttonHolder.appendChild(this.dom.nextPrevPanelControl.numButtonHolder);

	this.dom.nextPrevPanelControl.nextButton.className = "mnpp-next-prev-button mnpp-next-button";
	this.dom.nextPrevPanelControl.prevButton.className = "mnpp-next-prev-button mnpp-prev-button";
	this.dom.nextPrevPanelControl.nextButton.setAttribute('href', '#');
	this.dom.nextPrevPanelControl.prevButton.setAttribute('href', '#');

	this.dom.nextPrevPanelControl.buttonHolder.appendChild(this.dom.nextPrevPanelControl.nextButton);
	this.dom.nextPrevPanelControl.buttonHolder.appendChild(this.dom.nextPrevPanelControl.prevButton);

	this.dom.nextPrevPanelControl.base.style.width = HYSMaps.mapDimensions.width+"px";
	this.dom.base.parentNode.insertBefore(this.dom.nextPrevPanelControl.base, this.dom.base.nextSibling );


	this.dom.base.style.position="relative";
	
	this.dom.controls.base.className = 'controls';
	this.dom.base.insertBefore(this.dom.controls.base, this.dom.base.firstChild);
	
	/* Comment Limiter Stuff */
	this.dom.commentLimiter.base.setAttribute('id', 'mnpp-comment-limiter');
	var clHTML = '<div class="cl-holder selected cl-hide-extra-comments">';
	clHTML += '<input type="checkbox" checked="checked" />';
	clHTML += '<label>Most recent '+HYSMaps.showCommentLimit+' comments</label>';
	clHTML += '</div>';
	
	clHTML += '<div class="cl-holder cl-show-extra-comments">';
	clHTML += '<input type="checkbox" />';
	clHTML += '<label>Most recent '+HYSMaps.totalCommentLimit+' comments <span>(May slow your computer down)</span></label>';
	clHTML += '</div>';
	clHTML += '<div class="cl-clear"></div>';
	this.dom.commentLimiter.base.innerHTML = clHTML;
	this.dom.base.insertBefore(this.dom.commentLimiter.base, this.dom.base.firstChild);
		
	// This does not seem to be used anymore
	/*this.dom.controls.top.className = 'controls date';
	this.dom.base.insertBefore(this.dom.controls.top, this.dom.controls.base);*/
	
	this.dom.types.base.className = 'types';
	this.dom.types.header.className = 'header';
	
	this.dom.types.wrapper.className = 'types';
	this.dom.types.wrapper.appendChild(this.dom.types.header);
	this.dom.types.wrapper.appendChild(this.dom.types.base);
	this.dom.base.appendChild(this.dom.types.wrapper);
	
	this.dom.header.className = 'header';
	this.dom.base.insertBefore(this.dom.header, this.dom.base.firstChild);
	
	this.dom.overlay.close.setAttribute('href', '#');
	this.dom.overlay.close.className = 'close';
	this.dom.overlay.close.innerHTML = 'Close';
	this.dom.overlay.content.className = 'content';
	this.dom.overlay.bg.className = 'bg';
	
	var clickEvent = new HYSMaps.CloseClick(this.dom.overlay.base);
	this.dom.overlay.close.onclick = clickEvent.action;
	
	this.dom.overlay.base.setAttribute('id', 'map-overlay');
	this.dom.overlay.base.appendChild(this.dom.overlay.close);
	this.dom.overlay.base.appendChild(this.dom.overlay.content);
	this.dom.overlay.base.appendChild(this.dom.overlay.bg);
	this.dom.overlay.wrapper.insertBefore(this.dom.overlay.base, this.dom.overlay.wrapper.firstChild);

	// Comment controls stuff	
	this.dom.controls.commentBase.className = 'map-comment-controls';
	this.dom.controls.commentClear.className = 'map-comment-controls-clear';
	this.dom.controls.commentBase.style.width = HYSMaps.mapDimensions.width+"px";
	this.dom.controls.commentBase.appendChild(this.dom.controls.commentList);
	this.dom.controls.commentBase.appendChild(this.dom.controls.commentClear);
	// Insert commentControls Ul after the map el
	this.dom.base.parentNode.insertBefore(this.dom.controls.commentBase, this.dom.base.nextSibling )

};
/**
 * Start parsing XML input data
 */
HYSMaps.OutputMap.prototype.initialise = function () {
	
	var parser = new HYSMaps.InputParser;
	parser.parse(this.input, this);
};

/**
 * This function is called when data is received and parsed
 */
HYSMaps.OutputMap.prototype.onData = function (data) {
	var params = data.map || {};
	
	this.series  = data.series || {};
	//this.density = parseInt(params.density, 10) || 0;
	
	this.initMap(params);
};

/**
 * Initialise the map
 */
HYSMaps.OutputMap.prototype.initMap = function (params) {
	
	if (params.displayCommentTotals == false) {
		this.showTypedSeriesTotals = false;
	}
	
	// Dealing with comment type icons
	// Firstly, we go through all the typeicons and find any colours that have not been allocated
	var spareColourArray = HYSMaps.helperFunctions.cloneArray({ anArray: HYSMaps.defaults.typeIconColours });
	for (var anObj in HYSMaps.commentTypeIcons) {
		spareColourArray = HYSMaps.helperFunctions.removeItemFromArray({
			anArray: spareColourArray,
			item: HYSMaps.commentTypeIcons[anObj]
		});
	}
	// We now have in spareColourArray an array of colours that have not been allocated 
	// We now go through the HYSMaps.commentTypeIcons array, and allocate a colour to any item that does not have a colour
	var spareColourIndex = 0;
	for (var anObj in HYSMaps.commentTypeIcons) {
		if (!HYSMaps.commentTypeIcons[anObj]) { // no colur set
			spareColourIndex = ((spareColourIndex+1)>=spareColourArray.length) ? 0 : spareColourIndex+1;
			HYSMaps.commentTypeIcons[anObj] = spareColourArray[spareColourIndex];
		}
	}
		
	var that = this;
	
	// select map implementation
	this.map = this.factory.createMap(params.provider, params.type, params.plotter, true, params.ugc);
	if (!this.map) return false;
	
	// set title
	this.dom.header.innerHTML = params.title;
	
	// initialise series specific functionality
	for (var i in this.series) {
		this.series[i].initMap(this);
	}
	
	// initialise points on map (don't do redraw yet)
	this.initPoints(false);

	// Calculate the map's dimensions at outermost zoom level
	this.map.setZoom(this.map.OUTERMOST_ZOOM_LEVEL);
	this.sizer.getZoomRatio();

	// Add panels now that map is initialised
	// See note in HYSMaps.InputParser.prototype.onload, bbc-news-map.js line 240
	for (var i = 0; i < this.sizer._waitingPanels.length; ++i) {
		this.sizer.addPanel(
			this.sizer._waitingPanels[  i],
			this.sizer._waitingPanels[++i],
			this.sizer._waitingPanels[++i],
			this.sizer._waitingPanels[++i],
			this);
	}

	delete this.sizer._waitingPanels;

	// set the map centre
	if (params.override) {
		if ((!params.override.latitude || !params.override.latitude) && params.override.zoom && this.sizer.sequencedPanels.length > 0) { // Only zoom set
			this.map.setCentre(new HYSMaps.GeoCoords(this.sizer.sequencedPanels[0].latitude, this.sizer.sequencedPanels[0].longitude), params.override.zoom);
		}
		else {
			this.map.setCentre(new HYSMaps.GeoCoords(params.override.latitude, params.override.longitude), params.override.zoom);
		}
	}
	else {
		this.map.setCentre();
	}
	this.map.redraw();

	this.map.addZoomListener(this.sizer.update, this.sizer);
	this.sizer.update(this.sizer.output.map.zoomLevel);

	// Nxt prev panel controls stuff
	this.initNextPrevPanelControls({
		override: params.override
	});
	
  	// loaded OK
  	this.dom.base.className += ' loaded';
  	
  	if (params.displayMapControls) {
  		// Display the controls for toggling media type if this setting is set
  		this.dom.controls.base.style.display = "block";	
  	}

	// Display the controls for toggling media type if this setting is set
	this.dom.controls.commentBase.style.display = "block";	
	
	if (HYSMaps.commentsArray.length > HYSMaps.showCommentLimit) {
		// There are more than 250 comments, so we show the commentLimiter panel
		this.initialiseCommentLimiter();
		this.dom.commentLimiter.base.style.display = "block";
		this.dom.commentLimiter.height = this.dom.commentLimiter.base.offsetHeight;
	}

  	return true;
};

/**
 * Inititalise comment limiter
 */
HYSMaps.OutputMap.prototype.initialiseCommentLimiter = function() {
		
	var that = this;
	var extraCommentsVisible = false;
	var hideExtraCommentsHolder = glow.dom.get(this.dom.commentLimiter.base).get(".cl-hide-extra-comments")[0];
	var showExtraCommentsHolder = glow.dom.get(this.dom.commentLimiter.base).get(".cl-show-extra-comments")[0];
	var hideExtraCheckBox = glow.dom.get(hideExtraCommentsHolder).get("input")[0];
	var showExtraCheckBox = glow.dom.get(showExtraCommentsHolder).get("input")[0];
	
	if (HYSMaps.commentsArray.length < HYSMaps.totalCommentLimit) {
		glow.dom.get(showExtraCommentsHolder).get("label")[0].innerHTML = "Show all comments <span>(May slow your computer down)</span>";
	}

	glow.events.addListener(
		hideExtraCheckBox,
		'click',
		function () {
			if (!extraCommentsVisible) {
				return false;
			}
			else {
				// Call the function that hides the comments
				showExtraCheckBox.checked=false;
				glow.dom.get(showExtraCommentsHolder).removeClass("selected");
				glow.dom.get(hideExtraCommentsHolder).addClass("selected");
				extraCommentsVisible = false;
				that.hideExtraComments();
			}
		}
	);

	glow.events.addListener(
		showExtraCheckBox,
		'click',
		function () {
			if (extraCommentsVisible) {
				return false;
			}
			else {
				// Call the function that show the comments
				hideExtraCheckBox.checked=false;
				glow.dom.get(showExtraCommentsHolder).addClass("selected");
				glow.dom.get(hideExtraCommentsHolder).removeClass("selected");
				extraCommentsVisible = true;
				that.showExtraComments();
			}
		}
	);


}

HYSMaps.OutputMap.prototype.showExtraComments = function() {
	var numExtraComments = HYSMaps.limitedCommentsPanelArray.length;
	for (var counter = 0; counter < numExtraComments; counter++) {
		HYSMaps.limitedCommentsPanelArray[counter].data.shouldBeShownDespiteLimited = true;
		HYSMaps.limitedCommentsPanelArray[counter].addPanelToMap();
		HYSMaps.limitedCommentsPanelArray[counter].update();
	}
}

HYSMaps.OutputMap.prototype.hideExtraComments = function() {
	var numExtraComments = HYSMaps.limitedCommentsPanelArray.length;
	for (var counter = 0; counter < numExtraComments; counter++) {
		HYSMaps.limitedCommentsPanelArray[counter].data.shouldBeShownDespiteLimited = false;
		HYSMaps.limitedCommentsPanelArray[counter].removePanelFromMap();
	}
}

/**
 * Inititalises the enabling and disabling nextprev control
 */
HYSMaps.OutputMap.prototype.disableNextPrevPanelControls = function() {
	glow.dom.get(this.dom.nextPrevPanelControl.inner).addClass("next-prev-disabled");
}

HYSMaps.OutputMap.prototype.enableNextPrevPanelControls = function() {
	glow.dom.get(this.dom.nextPrevPanelControl.inner).removeClass("next-prev-disabled");
}

/**
 * Inititalises the NextPrevPanelControl
 */
HYSMaps.OutputMap.prototype.initNextPrevPanelControls = function(dataObj) {
	var that = this;
	var override = dataObj.override;

	var numOfPanels = this.sizer.sequencedPanels.length;
	
	if (numOfPanels < 1) {
		return;
	}
	var numButtonsList = new Array();
	
	// Lets create the buttons for the panels
	for (var counter = 0; counter <numOfPanels; counter++) {
		var aNumButton = document.createElement("a");	
		aNumButton.setAttribute('href', '#');
		aNumButton.innerHTML = ""+(counter+1);
		numButtonsList.push(aNumButton);
		this.dom.nextPrevPanelControl.numButtonHolder.appendChild(aNumButton);
	}
	this.dom.nextPrevPanelControl.buttonHolder.style.width = (numOfPanels * HYSMaps.defaults.nextPrevPanelControls.numButtonWidth)+"px";

	var selectedPanel = 0; // Zero means none selected, else is the num of the panel (1 = 1st, 2 = 2nd etc)
	
	var previouslySelectedButton = numButtonsList[0];
	//glow.dom.get(numButtonsList[0]).addClass("num-button-selected"); // The first panel is auto selected

	var updateSelectedPanel = function() {
		if (selectedPanel != 0) { 
			glow.dom.get(previouslySelectedButton).removeClass("num-button-selected");
			glow.dom.get(numButtonsList[selectedPanel-1]).addClass("num-button-selected");
			previouslySelectedButton = numButtonsList[selectedPanel-1];
		}
		if (selectedPanel <= 1) {
			glow.dom.get(that.dom.nextPrevPanelControl.prevButton).addClass("mnpp-next-prev-button-disabled");
		}
		else {
			glow.dom.get(that.dom.nextPrevPanelControl.prevButton).removeClass("mnpp-next-prev-button-disabled");
		}
		if (selectedPanel == numOfPanels) {
			glow.dom.get(that.dom.nextPrevPanelControl.nextButton).addClass("mnpp-next-prev-button-disabled");
		}
		else {
			glow.dom.get(that.dom.nextPrevPanelControl.nextButton).removeClass("mnpp-next-prev-button-disabled");
		}
	}
	
	updateSelectedPanel();
	
	// Initialise the click event on th numbered buttons
	for (var counter = 0; counter < numOfPanels; counter++) {
		(function() {
			var thisNumButton = numButtonsList[counter];
			var thisPanelNumber = counter+1;

			glow.events.addListener(
				thisNumButton,
				'click',
				function () {
					if (!HYSMaps.infoPanelStatus.isAPanelOpen) {
						selectedPanel = thisPanelNumber;
						updateSelectedPanel();
						that.sizer.focusNextPanel.call(that.sizer, selectedPanel-1);
					}
					return false;
				}
			);

		})();
	}
	
	// We initialise the panel next prev controls here
	glow.events.addListener(
		this.dom.nextPrevPanelControl.nextButton,
		'click',
		function () {
			if (HYSMaps.infoPanelStatus.isAPanelOpen) { // Next prev disabled if an info panel is open
				return false;	
			}
			if (selectedPanel+1 <= numOfPanels) {
				selectedPanel++;
				that.sizer.focusNextPanel.call(that.sizer, selectedPanel-1);
				updateSelectedPanel();
			}
			return false;
		}
	);

	glow.events.addListener(
		this.dom.nextPrevPanelControl.prevButton,
		'click',
		function () {
			if (HYSMaps.infoPanelStatus.isAPanelOpen) { // Next prev disabled if an info panel is open
				return false;	
			}
			if (selectedPanel-1 > 0) {
				selectedPanel--;
				that.sizer.focusPreviousPanel.apply(that.sizer);
				updateSelectedPanel();
			}
			return false;
		}
	);
	
	// Now that everything is initialised, we can display the controls
	this.dom.nextPrevPanelControl.base.style.display="block";

	if (!override || ((!override.latitude || !override.latitude) && override.zoom)) {
		glow.events.fire(that.dom.nextPrevPanelControl.nextButton, 'click');
	}
	

}


/**
 * Ask series to plot their points
 */
HYSMaps.OutputMap.prototype.initPoints = function (redraw) {
	
	this.map.clearMarkers();

	for (var i in this.series) {
		this.series[i].updatePoints(this); // add points to map
	}
	
	if (redraw !== false) this.map.redraw();
};



/**
 * Add controls for each series (checkboxes for toggling each series)
 */
HYSMaps.OutputMap.prototype.addControl = function (series, name, icon) {	
	
	var that = this;
	if (name == "Comments") {
		HYSMaps.commentsArray = series.points;
	}
	
	// Helper function for creating a control
	var createAndInitialiseControlHTML = function(dataObj) {

		var aSeries = dataObj.series;
		var name = dataObj.name;
		var icon = dataObj.icon;
		var numOfItems = dataObj.numOfItems;
		var isType = dataObj.isType;
		
		var input = document.createElement('input');
		input.setAttribute('type', 'checkbox');
		input.checked = true;
		input.setAttribute('defaultChecked', 'defaultChecked');
		input.onclick = that.toggleSeries.bind(that, aSeries, isType);

		var label = document.createElement('label');
		numOfItems = (isType && !that.showTypedSeriesTotals || !numOfItems) ? '' : ' ('+numOfItems+')';
		var text = document.createTextNode(' ' + name + numOfItems);
		label.appendChild(input);
		label.appendChild(text);
		if (HYSMaps.browserType == "IE6" && icon.indexOf(".png") != -1) {
			label.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+icon+'", sizingMethod="crop")';
		}
		else {
			label.style.backgroundImage = "url('" + icon + "')";
		}
		var control = document.createElement('li');
		control.appendChild(label);
		return control;	
	}

	// firstly check if it is a comment,
	// If so, we need to break into categories and display at the bottom
	
	var totalNumOfTypedComments = 0;
	if (name == "Comments") {
		var commentSeries = {}; 
		for (var anObj in HYSMaps.commentTypeIcons) {
			var category = anObj;
			commentSeries[category] = new HYSMaps.Series();
			commentSeries[category].category=category;
			for (counter = 0; counter < series.points.length; counter++) {
				if (category == series.points[counter].type) {
					commentSeries[category].addPoint(series.points[counter]);
				}
			}
			commentSeries[category].isCommentCategory = true;
			// Make sure the comment block is visible
			// This creates the comment category controls at the bottom of the map
			this.dom.controls.commentList.appendChild(createAndInitialiseControlHTML({
					series: commentSeries[category],
					name: category,
					icon: HYSMaps.assets+HYSMaps.commentIconUrlTemplate.replace("????",HYSMaps.commentTypeIcons[category]),
					numOfItems: HYSMaps.commentTypeCounts[category],
					isType: true
				})
			);
			totalNumOfTypedComments+=parseInt(HYSMaps.commentTypeCounts[category]);
		}
		// This creates the controls at the top of the map
		this.dom.controls.base.appendChild(createAndInitialiseControlHTML({
				series: series,
				name: name,
				icon: icon.image,
				numOfItems:totalNumOfTypedComments,
				isType: false
			})
		);
	}
	else {
	
	
		// This creates the controls at the top of the map
		this.dom.controls.base.appendChild(createAndInitialiseControlHTML({
				series: series,
				name: name,
				icon: icon.image,
				numOfItems:series.points.length,
				isType: false
			})
		);
	}
	
	var anEl = this;
};

/**
 * Add controls for toggling the types within each series
 */
HYSMaps.OutputMap.prototype.addType = function (series, type, icon) {
		
	// types control
	var span = document.createElement('span');
	var text = document.createTextNode(' ' + type + ' ');
	span.appendChild(text);

	var input = document.createElement('input');
	input.setAttribute('type', 'checkbox');
	input.checked = true;
	input.setAttribute('defaultChecked', 'defaultChecked');
	input.onclick = this.toggleType.bind(this, series, type);

	var label = document.createElement('label');
	label.appendChild(input);
	label.appendChild(span);
	label.style.backgroundImage = "url('" + icon.image + "')";

	var control = document.createElement('li');
	control.appendChild(label);

	if (this.showTypedSeriesTotals) {
		var total = series.points.length;
		total += (total === 1) ? ' item' : ' items';
		control.appendChild(document.createElement('span')).appendChild(document.createTextNode(total));
	}

	this.dom.types.base.appendChild(control);
	this.dom.types.header.innerHTML = "Users selected from the following options: ";
};

/*
 * Add a date-filter control
 */
 
HYSMaps.OutputMap.prototype.addDateFilter = function (series, limit, byline, headline, active) 
{
	var div = document.createElement('div');
	
	var oHeadline = document.createElement('span');
	oHeadline.innerHTML = headline || 'Most recent ' + limit + ' comments';
	div.appendChild(oHeadline);
	
	if (byline) {
		var oByline = document.createElement('span');
		oByline.innerHTML = "<br />(" + byline + ")";
		div.appendChild(oByline);
	}
	
	var input = document.createElement('input');
	input.setAttribute('type', 'checkbox');
	input.onclick = this.onDateFilter.bind(this, series, input, oHeadline, limit);
	
	var label = document.createElement('label');
	label.appendChild(input);
	label.appendChild(div);
	
	if (active) {
		oHeadline.className += " active";
		input.setAttribute('checked', 'checked');
		series.toggleFiltering(limit);
	}
	
	var control = document.createElement("li");
	control.appendChild(label);
	
	this.dom.controls.top.appendChild(control);
};

HYSMaps.OutputMap.prototype.addPoint = function (point, coords, icon, date, grouped) 
{
	var marker = this.map.addMarker(coords, icon, date, grouped);
	if (marker) {
		var clickEvent = point.makeClickEvent(this.dom.overlay.base, this.dom.overlay.content);
		this.map.bind(marker, 'mouseup', clickEvent, clickEvent.action);
	}
};

HYSMaps.OutputMap.prototype.toggleSeries = function (series, isType) {
	series.toggle();
	this.initPoints();
	this.sizer.filterBySeries(series, isType);
};

HYSMaps.OutputMap.prototype.toggleType = function (series, type) {
	series.toggleType(type);
	this.initPoints();

	this.sizer.filterByType(type);
};

/*
 * Respond to date-filter changes
 */

HYSMaps.OutputMap.prototype.onDateFilter = function (series, object, headline, limit) 
{
	var headlines = this.dom.controls.top.getElementsByTagName('span');
	for (var i = 0; i < headlines.length; ++i) headlines[i].className = '';
	
	var inputs = this.dom.controls.top.getElementsByTagName('input');
	for (var i = 0; i < inputs.length; ++i) inputs[i].checked = '';
	
	headline.className = "active";
	object.checked="checked";
	series.toggleFiltering(limit);
	this.initPoints();
}


HYSMaps.OutputMap.prototype.unload = function () {
	
	var inputs = this.dom.controls.base.getElementsByTagName('input');
	for (var i = 0; i < inputs.length; ++i) {
		inputs[i].onclick(Function.prototype.unbind);
	}
	var inputs = this.dom.types.base.getElementsByTagName('input');
	for (var i = 0; i < inputs.length; ++i) {
		inputs[i].onclick(Function.prototype.unbind);
	}
	this.dom.overlay.close.onclick = null;
	
	if (this.map) this.map.unload();
};