/*
* Copyright (C) 2009 Joel Sutherland.
* Liscenced under the MIT liscense
* TODO:
* 1. Create API
* 2. Address accesibility automatically
* 3. Make object oriented
*/
(function($) {
	$.fn.zoommap = function(settings) {
		settings = $.extend({
			zoomDuration: 1000,
			zoomClass: 'zoomable',
			popupSelector: 'div.popup',
			popupCloseSelector: 'a.close',
			bulletWidthOffset: '10px',
			bulletHeightOffset: '10px',
			showReturnLink: true,
			returnId: 'returnlink',
			returnText: 'Return to Previous Map'
		}, settings);
		var intervals = [];
		var zoomSettings = null;
		var that = this;
		$(this).each(function(){
			var map = $(this);
			$(this).data('currentId', '');
			
			function showMapById(id){
				var region = findRegion(settings.map, id);
				if(region != -1){
					displayMap(region);
				}
			}

			// recursive id find
			function findRegion(root, id){
				if(root.id == id){
					return root;
				}else{
					if(root.maps != undefined){
						for(var i=0; i<root.maps.length; i++){
							var possible = findRegion(root.maps[i], id);
							if(possible != -1)
								return possible;
						}
					}
				}
				return -1;
			}
			// region is a map
			// This gets called every time we zoom
			function displayMap(region){
				//Set Current Region Id
				$(this).data('currentId', region.id);
				
				for (var i=0;i<intervals.length;i++)
					clearTimeout(intervals[i]);
				intervals = [];
				//Clear the Map and Set the Background Image
				map.empty().css({
					backgroundImage: 'url(' + region.image + ')',
					width: settings.width,
					height: settings.height
				});
				var check = map.css('background-image');
				
				//Load RegionData
				loadRegionData(region);
			}
			/************************************************************************************/

			
			//Show Return Link
			function showReturnLink(region){
				map.append('<a href="javascript:void(0);" id="' + settings.returnId + '">' + /*settings.returnText +*/ '</a>');
				var returnMap = function(){
					if (!!zoomSettings){
						$(that).append(zoomSettings.elem);
						$(that).css('background-image', zoomSettings.map);
						$('a,div',that).remove();
						for (var i=0;i<intervals.length;i++)
							clearTimeout(intervals[i]);
						intervals = [];
						$(zoomSettings.elem).animate({
							width: zoomSettings.width,
							height: zoomSettings.height,
							top: zoomSettings.top,
							left: zoomSettings.left
						}, settings.zoomDuration, '', function(){
							showMapById(region.parent);
						});
					}else
						showMapById(region.parent);
				}
				$('#' + settings.returnId).hide().fadeIn().click(returnMap);//.hover(returnMap);
			}
			function startAnim(atag, isbig){
				var canvasSize = isbig ? 46 : 24;
				var maxWidth = isbig ? 6 : 4;
				var maxSize = isbig ? 40 : 20;
				var stages = 60;
				var stage=0;
				var newCanvas = document.createElement('canvas');
				var isexcanvas = false;
				if (!newCanvas.getContext){
					newCanvas = G_vmlCanvasManager.initElement(newCanvas);
					isexcanvas = true;
				}
				newCanvas.width = canvasSize;
				newCanvas.height = canvasSize;
				$(atag).empty().append(newCanvas);
				var ctx = newCanvas.getContext('2d');
				var draw2 = false, draw3 = false;
				var draw = function(stage) {
					var size = (stage * maxSize) / stages;
					var width = 1 + (stage * (maxWidth-1)) / stages;
					var alpha = 1.0-(stage/stages);
					ctx.lineWidth = width;
					ctx.beginPath();
					//ctx.strokeStyle = "rgba(233,106,71,"+alpha+")";
					ctx.strokeStyle = "rgba(54,54,54,"+alpha+")";
					ctx.arc(canvasSize/2, canvasSize/2,size/2,0,Math.PI*2,true);;
					ctx.stroke();
				}
				return setInterval(function (){
					if (isexcanvas)
						$('shape', atag).remove();
					ctx.clearRect(0,0,canvasSize,canvasSize);
					draw(stage)
					if (isbig){
						draw2 = draw2 || stage >= stages/3;
						draw3 = draw3 || stage >= (stages/3)*2;
						if (draw2)
							draw((stage+(2*stages/3))%stages)
						if (draw3)
							draw((stage+stages/3)%stages)
					} else{
						draw2 = draw2 || stage >= stages/2;
						if (draw2)
							draw((stage+stages/2)%stages)
					}
					stage = ++stage % stages;
				}, 100);
			}
			//Load the Bullets 
			function loadRegionData(region){
				var url = region.data;
				map.load(url, {}, function(){
					//place bullets
					var count = $(this).children('a.bullet').length;
					var i = 0;
					$(this).children('a.bullet').each(function(){
						//var div = $(this).wrap('<div class="bullet"></div>').parent();
						var coords = $(this).attr('rel').split('-');
						var regId = $(this).attr('id');
						var isbig = regId == 'europebullet' || regId == 'africabullet' || regId == 'saudiarabiabullet';
						var offsetHeight = parseInt(settings.bulletHeightOffset) - (isbig?0:10);
						var offsetWidth = parseInt(settings.bulletWidthOffset) - (isbig?0:10);
						$(this).css({left: addpx(Number(coords[0]) - offsetWidth), top: addpx(Number(coords[1]) - offsetHeight)});
						$(this).mouseenter(function(){showPopup($(this).attr('id'));})
						intervals.push(startAnim(this, isbig));
					});
					//Set up each submap as an item to click
					if(region.maps != undefined){
						for(var i=0; i<region.maps.length; i++){
							//addZoom(region.maps[i]);
						}
					}
					//Create Return Link
					if(settings.showReturnLink && region.parent != undefined){
						showReturnLink(region);
					}
					Cufon.replace('#map .MapPopup, #map .Legend', { fontFamily: 'dax-medium' });
				});
			}
			
			function showPopup(id, leftbul, topbul){
				map.find(settings.popupSelector).fadeOut(); 
				var boxid = '#' + id + '-box';
				
				var p = $("#"+id);
                var offset = p.offset();
                var m = $("#map");
                var moffset = m.offset();
				var toppx = offset.top - moffset.top - ($(boxid).height()/2);
				var lpx =  offset.left - moffset.left - ($(boxid).width()/2);
				if (toppx < 0)
					toppx = 10;
				else if (toppx + $(boxid).height() + 10> $("#map").height())
					toppx = $("#map").height() - $(boxid).height() - 10;
				if (lpx < 0)
					lpx = 10;
				else if (lpx + $(boxid).width() + 16> $("#map").width())
					lpx = $("#map").width() - $(boxid).width() - 16;
				$(boxid).css({'top': toppx + 'px', 'left': lpx + 'px'});
				$('td:last-child,th:last-child',boxid).addClass('Last');
				$('td:first-child,th:first-child',boxid).addClass('First');
				$(boxid).fadeIn();
				$(boxid).mouseleave(function(){map.find(settings.popupSelector).fadeOut();});
				$(settings.popupCloseSelector).click(function(){
					$(this).parent().fadeOut();
				});
			}
			
			function closePopup (id, leftbul, topbul){
			    //map.find(settings.popupSelector).fadeOut(); 
				var boxid = '#' + id + '-box';
				map.find(settings.popupSelector).fadeOut();
				/*if ($(boxid).mouseout())
				{
				    
				}*/
				
			}
			
			//add a clickable image for a region on the current map
			var zooming = false;
			function addZoom(region){
				var zoomclick = function(){
					if (zooming)
						return;
					zooming = true;
					//hide neighboring bullets and zoomables
					var width = settings.width;
					var height = settings.height;
					if(region.scan){
						width = region.scanwidth;
						height = region.scanheight;
					}
					$(this).siblings().remove();
					$(this).hide()
							.attr('src', region.image).load(function(){
								zoomSettings = {
									width: $(this).width(),
									height: $(this).height(),
									top: $(this).css('top'),
									left: $(this).css('left'),
									map: $(that).css('background-image')
								};
								$(this).fadeIn('slow')
										.animate({
											width: width,
											height: height,
											top: '0px',
											left: '0px'
										}, settings.zoomDuration, '', function(){
											zoomSettings.elem = $(this).clone();
											displayMap(region);
											zooming = false;
										});
							});
					return false;
				};
				var mapimg = $('<img />').addClass(settings.zoomClass)
					.attr({
						src: settings.blankImage,
						id: region.id
					}).css({
						position: 'absolute',
						width: region.width,
						height: region.height,
						top: region.top,
						left: region.left
					}).appendTo(map).click(zoomclick);
				var f = function(){
					mapimg.click();
					return false;
				}
				$('#'+region.id+'bullet-zoom').click(f)//.hover(f);
			}
			
			function rempx(string){
				return Number(string.substring(0, (string.length - 2)));
			}
			
			function addpx(string){
				return string + 'px';
			}
			
			function showHash(string){
				string = string.replace('#', '');
				showMapById(string);
			}
			
			//initialize map
			var hash = self.document.location.hash;
			if(hash.length > 0)
				showHash(hash);
			else{
				displayMap(settings.map);
			}
			
			return this;
		});
	}
})(jQuery);
