//if(typeof(console)!='undefined'){window.alert=console.log;}
var $htmlmap=(function($){

	$config={
		'hasVML':document.namespaces,
		'hasCanvas':!!document.createElement('canvas').getContext,
		'isSupported':document.namespaces||!!document.createElement('canvas').getContext,
		'canvasStyle':{
			'position':'absolute',
			'left':0,
			'top':0,
			'padding':0,
			'border':0
		},
		'initialized':false
	}

	if(!$config.isSupported){
		$.fn.htmlmap=function(){
			return this;
		};
		return;
	}

fader=function(element, opacity, interval) {
	if(opacity <= 1) {
		element.style.opacity=opacity;
		window.setTimeout(fader, 10, element, opacity + 0.1, 10);
	}
};

	var $cache={},
		$active=false,
		$lib={
			'addShape':function(canvas, shape, coords, options, name){
				if($config.hasCanvas){
					var i, context=canvas.getContext('2d');
					context.beginPath();
					if(shape=='rect') {
						context.rect(coords[0], coords[1], coords[2] - coords[0], coords[3] - coords[1]);
					}else if(shape=='poly') {
						for(i=0; i < coords.length; i+=2) {
							context.lineTo(coords[i], coords[i+1]);
						}
					}else if(shape=='circ' || shape=='circle') {
						context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2, false);
					}
					context.closePath();
					if(options.fill){this.fillShape(context,options.fill.color,options.fill.opacity);}
					if(options.stroke){this.strokeShape(context,options.stroke.color,options.stroke.opacity,options.stroke.width);}
					if(options.fade){fader(canvas,0);}
				}else{
					name='highlighted';
					var fill, stroke, opacity, e;
					fill='<v:fill color="#'+options.fill.color+'" opacity="'+(options.fill ? options.fill.opacity : 0)+'" />';
					stroke=(options.stroke ? 'strokeweight="'+options.stroke.width+'" stroked="t" strokecolor="#'+options.stroke.color+'"' : 'stroked="f"');
					opacity='<v:stroke opacity="'+(options.stroke ? options.stroke.opacity : 0)+'"/>';
					if(shape=='rect'){
						e=$('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
					}else if(shape=='poly'){
						e=$('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
					} else if(shape=='circ' || shape=='circle'){
						e=$('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
					}
					e.get(0).innerHTML=fill+opacity;
					$(canvas).append(e);
				}
			},
			'clearCanvas':function(canvas,e,options){
				var td=$.data(e.target);
				var group=options.group && td['htmlmap.group'].name && (options.group instanceof Array?$.inArray(td['htmlmap.group'].name,options.group)<0:true);
				if(group){
					if(e.relatedTarget && e.relatedTarget.nodeName=='AREA'){
						if($.data(e.relatedTarget,'htmlmap.group').name==td['htmlmap.group'].name){return false;}
					}
				}
				if($config.hasCanvas){
					canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
				}else{
					$(canvas).empty();
				}
				return true;
			},
			'createCanvas':function(width,height){
				if($config.hasCanvas){
					var c=$('<canvas style="width:'+width+'px;height:'+height+'px;"></canvas>').get(0);
					c.getContext("2d").clearRect(0, 0, c.width, c.height);
				}else{
					c=$('<var style="zoom:1;overflow:hidden;display:block;width:'+Math.round(width)+'px;height:'+Math.round(height)+'px;"></var>').get(0);
				}
					c.width=width;
					c.height=height;
				return c;
			},
			'createMap':function(object,name,options){
				object.attr('usemap','#'+name);
				var scale={'width':object.innerWidth()/options.base.width,'height':object.innerHeight()/options.base.height};
				var map='<map name="'+name+'">';
				$.each($cache[options.scheme].canvas,function(k,v){
					if(v.exclude){var el=$.extend(true,{},v);}
					$.each(v.coords,function(i,c){
						var coords=[];
						$.each(c,function(n,p){
							if(v.shape=='rect' || v.shape=='poly'){
								coords[coords.length]=(n%2==0)?Math.round(p*scale.width):Math.round(p*scale.height);
								return true;
							}
							coords[coords.length]=(n!=2)?((n%2==0)?Math.round(p*scale.width):Math.round(p*scale.height)):Number(p);
						});
						if(!v.exclude){
							if(options.overlay){
								map += '<area coords="' + coords.join(', ') + '" shape="'+(v.shape?v.shape:'poly')+'" title="' + k + '" />'
							}else{
								map += '<area coords="' + coords.join(', ') + '" shape="'+(v.shape?v.shape:'poly')+'" title="' + k + '" href="'+ (v['url']?v.url:'') +'" />'
							}
						}else{
							el.coords[i]=coords;
							$cache[options.scheme].exclude[k]=el;
						}
					});
				});
				map += '</map>';
				return $(map).find('area').each(function(){
					var g=false;
					var obj=$(this);
					var k=obj.attr('title');
					$.each($cache[options.scheme].groups,function(i,v){
						if($.inArray(k,v.keys)>=0){g={'name':i,'url':v.url};return false;}
					});
					obj.data({'htmlmap.key':k,'htmlmap.group':g}).addClass([k,g.name].join(' '));

					if($cache[options.scheme].canvas[k].overlay){
						obj.data('htmlmap.overlay',$cache[options.scheme].canvas[k].overlay);
					}

					var item=$cache[options.scheme].canvas[k];
					obj.attr('title',(item['title']?item.title:k));

					if(!options.overlay && options.group){
						if(options.group instanceof Array){
							if($.inArray(g.name,options.group)>=0){
								if(!obj.attr('href')){
									obj.removeAttr('href');
								}
							}else{
								if(g['url'] && g.url){
									obj.attr('href',g.url);
								}else{
									obj.removeAttr('href');
								}
							}
						}else{
							if(g['url'] && g.url){
								obj.attr('href',g.url);
							}else{
								obj.removeAttr('href');
							}
						}
					}
				}).end();
			},
			'fillShape':function(shape,color,opacity){
				var hex_to_decimal=function(hex){return Math.max(0, Math.min(parseInt(hex, 16), 255));};
				shape.fillStyle='rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
				shape.fill();
			},
			'highlight':function(canvas,area,options,areaOnly){
					if(areaOnly){
						$lib.addShape(canvas,area.getAttribute('shape').toLowerCase(),area.getAttribute('coords').split(','),options);
					}else{
						var data=area.data();
						var group=options.group && data['htmlmap.group'].name && (options.group instanceof Array?$.inArray(data['htmlmap.group'].name,options.group)<0:true);
						area.parent().find('area.'+(group?data['htmlmap.group'].name:data['htmlmap.key'])).each(function(k,c){
							$lib.addShape(canvas,c.getAttribute('shape').toLowerCase(),c.getAttribute('coords').split(','),options);
						});
						var $so=data['htmlmap.overlay'];
						if($so){
							if($.isArray($so)){
								$.each($so,function(i,v){
									$lib.addShape(canvas,(v.shape?v.shape:'poly'),v.coords,{
										'fill':{
											'color':v.color,
											'opacity':v.opacity
											}
									});
								});
							}else{
								$lib.addShape(canvas,($so.shape?$so.shape:'poly'),$so.coords,{
									'fill':{
										'color':$so.color,
										'opacity':$so.opacity
										}
								});
							}
						}
					}
			},
			'strokeShape':function(shape,color,opacity,width){
				var hex_to_decimal=function(hex){return Math.max(0, Math.min(parseInt(hex, 16), 255));};
				shape.strokeStyle='rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
				shape.lineWidth=width;
				shape.stroke();
			}
		},
		$o={
			'scheme':false,
			'group':false,
			'screen':false,
			'fill':false,
			'stroke':false,
			'fade':true,
			'base':{
				'width':1,
				'height':1
			}
		},
		$i=0
	;


	$.fn.htmlmap=function(o,m){
		var o=$.extend(true,{},$o,o);

		if(o['onBeforeLoad']){
			o.onBeforeLoad.call($cache[o.scheme],this);
		}

		if(o.overlay){
			var overlayid='site-overlay';
			$('<div class="overlay" id="'+overlayid+'"></div>').prependTo('body');
		}

		this.each(function(i){
			var obj=$(this);
			map=$lib.createMap(obj,(m?m:'map'+$i),o);
			var wrap=$('<div></div>').addClass('htmlmap-wrapper').css({
				display:'block',
				background:'url('+this.src+') no-repeat',
				position:'relative',
				padding:'0 0 10px',
				width:this.width,
				height:this.height
				});
			if(o.wrapClass) {
				wrap.addClass(o.wrapClass===true?obj.attr('class'):o.wrapClass);
			}
			obj.before(wrap).css('opacity', 0).css($config.canvasStyle).remove();
			if($config.hasVML){obj.css('filter','Alpha(opacity=0)');}
			wrap.append(obj,map).data('htmlmap.options',o);

			if(o.overlay){
				wrap.css({'cursor':'pointer'}).overlay({
					'target':'#'+overlayid,
					'expose':'#ffffff',
					'effect':'apple',
					'fixed':false,
					'top':'6px',
					'onBeforeLoad':function(e){
						var api=this;
						this.getOverlay().css({
							'width':o.base.width+'px',
							'height':o.base.height+'px'
						}).empty().append('<div class="close"></div><img class="'+o.scheme+'" alt="" src="/var/ezflow_site/storage/htmlmap/usamap/SARE-USA.png" width="627" height="5" />')
						.find('.close').click(function(){
							api.close();
						});
					},
					'onLoad':function(){
						o.overlay=false;
						this.getOverlay().css({'zIndex':100000}).find('.'+o.scheme).htmlmap(o,'map'+i+'_overlay');
					},
					'onClose':function(){
						this.getOverlay().empty();
					}
				});
			}

			var canvas=$lib.createCanvas(this.width,this.height);
			$(canvas).css($config.canvasStyle);

			if(o.screen){
				var screen=$lib.createCanvas(this.width,this.height);
				$(screen).css($config.canvasStyle);
			}
			obj.parent().find('area[coords]').each(function(){
				var area=$(this);
				if(o.screen && $.inArray(area.data('htmlmap.group').name,o.screen.group)>=0){
					$lib.highlight(screen,area.get(0),o.screen,true);
				}
				if(!o.overlay){
					area.mouseover(function(e){
						if(!$active){
							$lib.highlight(canvas,area,o);
						}
					}).mouseout(function(e){
						$active=!$lib.clearCanvas(canvas,e,o);
					});
				}
				
			});

			obj.before(canvas);
			if(o.screen){
				obj.before(screen);
			}

			var textCanvas=$lib.createCanvas(this.width,this.height);
			$(textCanvas).css($config.canvasStyle);

			var scale={'width':obj.innerWidth()/o.base.width,'height':obj.innerHeight()/o.base.height};
			scale.ratio=((scale.width+scale.height)/2);
			if ($config.hasCanvas){
				var textContext=textCanvas.getContext("2d");
				$.each($cache[o.scheme].groups,function(k,v){
					textContext.font='bold ' + v.font.size*scale.ratio + 'px sans-serif';
					textContext.textBaseline='top';
					textContext.shadowOffsetX=2*scale.ratio;
					textContext.shadowOffsetY=2*scale.ratio;
					textContext.shadowBlur=3*scale.ratio;
					textContext.shadowColor='rgba(0, 0, 0, .4)';
					textContext.lineWidth=4*scale.ratio;
					textContext.strokeStyle="rgba(255,255,255,0.7)";
					textContext.strokeText(v.title,v.coords.x*scale.width,v.coords.y*scale.height);
					textContext.lineWidth=2*scale.ratio;
					textContext.fillStyle='#000000';
					textContext.fillText(v.title,v.coords.x*scale.width,v.coords.y*scale.height);
				});
				obj.before(textCanvas);
			}else{
				var labels='';
				$.each($cache[o.scheme].groups,function(k,v){
					labels+='<span style="font-size:'+v.font.size*scale.ratio+'px;font-weight:bold;left:'+v.coords.x*scale.width+'px;position:absolute;top:'+v.coords.y*scale.height+'px;">'+v.title+'</span>';
				});
				obj.before(labels);
			}

			if($cache[o.scheme].exclude){
				var excluded=$lib.createCanvas(this.width,this.height);
				$(excluded).css($config.canvasStyle);
				$.each($cache[o.scheme].exclude,function(k,v){
					$.each(v.coords,function(i,c){
						$lib.addShape(excluded,'poly',c,(v.options?v.options:o));
					});
				});
				obj.before(excluded);
			}

		});

		if(o['onLoad']){
			o.onLoad.call($cache[o.scheme],this);
		}

		$i++;
		return this;
	};

	return {
		'config':$config,
		'changeScheme':function(item,scheme){
			var htmlmapWrapper=item.parents('.htmlmap-wrapper'),
				options=$.extend(true,{},htmlmapWrapper.data('htmlmap.options'),{
					'scheme':scheme,
					'onBeforeLoad':false,
					'onLoad':false
				}),
				mainParent=htmlmapWrapper.parent();
			htmlmapWrapper.remove();
			mainParent.prepend(item.removeAttr('style')).find('img').htmlmap(options);
		},
		'extend':function(scheme,definition,preload){
			$cache[scheme]={
				'canvas':{},
				'exclude':{},
				'definition':definition,
				'groups':{},
				'load':function(obj){
					obj.scheme=scheme;
					this.definition=this.definition.call(obj);
					this.loaded=true;
				},
				'loaded':false,
				'name':scheme
			}
			if(preload){
				$cache[scheme].load(this);
			}
		},
		'getCache':function(){
			return $.extend(true,{},$cache);
		},
		'initialize':function(options){
			if(!$config.initialized && $config.hasVML && $.browser.msie){
				document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
				var style=document.createStyleSheet();
				$.each(['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'], function() {
						style.addRule('v\\:' + this, "behavior: url(#default#VML); antialias:true");
					}
				);
				$config.initialized=true;
			}
			if(options && options.scheme){
				if(options.scheme.constructor==String){
					options.scheme=options.scheme.split(',');
				}
				for(var p in options.scheme){
					$cache[options.scheme[p]].load(this);
				}
			}
			if(options && options.load){options.load.call();}
		},
		'load':function(settings){
			var obj=this,
				scheme=this.scheme;
			$.ajax({
				'async':false,
				'url':settings['url'],
				'dataType':'json',
				'success':function(){
					settings['success'].call(obj,arguments[0],$cache[scheme]);
				}
			});
		},
		'register':function(selector,options){
				if(!$cache[options.scheme].loaded){
					$cache[options.scheme].load(this);
				}
				$(function(){
					$(selector).htmlmap(options);
				});
		},
		'registerArea':function(scheme,name,o){
			$cache[scheme].canvas[name]=o;
		},
		'registerGroup':function(scheme,name,o){
			$cache[scheme].groups[name]=o;
		},
		'set':function(o){
			$.extend($o,o);
		}
	};

})(jQuery);

