//if(typeof(console)!='undefined'){window.alert=console.log;}
var $htmlimap=(function($){
	if(!$){return;}
	if(!$XMAP){throw "Unable to find the XMAP engine.";}

	var $C=$.extend({
			'datakey':'htmlimap',
			'defaultSelector':'.htmlimap-defaultimage',
			'initialized':false,
			'selector':'.htmlimap',
			'wrapperClass':'htmlmap-wrapper'
		},$XMAP.config)
	;

	$XMAP.setDataKey($C.datakey);
	var $S={
			'canvasStyle':{
				'position':'absolute',
				'left':0,
				'top':0,
				'padding':0,
				'border':0
			},
			'htmlmapWrapper':{
				'display':'block',
				'margin':'0 0 10px',
				'position':'relative'
			}
		}
	;

	var $lib={
			'ajax':function(options,context){
				if(context){
					$.extend(true,options,{'context':context});
				}
				$.ajax($.extend(true,{
					'async':false,
					'dataType':'json'
				},options));
			}
		}
	;

	var $schemeQueue={},
		$registeredItems={},
		$i=0,

		$active=false,
		$o={
			'scheme':false,
			'group':false,
			'screen':false,
			'highlight':{
				'fill':false,
				'stroke':false,
			},
			'fade':true,
			'base':{
				'width':1,
				'height':1
			}
		}
	;

	var _scheme={
			'addArea':function(name,o){
				if(!this.canvas){this.canvas={};}
				this.canvas[name]=o;
			},
			'addGroup':function(name,o){
				if(!this.groups){this.groups={};}
				this.groups[name]=o;
			},
			'ajax':$lib.ajax,
			'canvas':false,
			'defer':false,
			'definition':false,
			'exclude':false,
			'groups':false,
			'id':false,
			'image':{
				'alt':false,
				'src':false,
				'width':0,
				'height':0
			},
			'init':function(d,id,def){
				if($.isFunction(d)){
					this.definition=d;
				}else{
					this.url=d;
					this.definition=function(){
						this.ajax({'url':d,'success':$.proxy(function(data){
							if(data){
								$.extend(true,this,data);
							}
						},this)});
					}
				}
				if(id){this.id=id;}
				if(def){this.defer=def;}
			},
			'load':function(o){
				this.ajax({'url':o.url,'success':$.proxy(o.success,this)});
			},
			'loaded':false,
			'name':false,
			'url':false
		},
		_function={
			'apply':function(as,arg){
				this.func.apply(as?as:this.as,arg?arg:this.arguments);
			},
			'arguments':false,
			'as':false,
			'func':false,
			'init':function(f,as,args){
				this.func=f;
				this.as=as;
				this.arguments=args;
			}
		},
		_event={
			'name':false,
			'queue':[],
			'add':function(f){
				this.queue[this.queue.length]=f;
			},
			'run':function(as,arg){
				$.each(this.queue,function(q,f){
					f.apply(as,arg);
				});
			}
		}
	;



	$.fn.htmlimap=function(o){
//console.time('htmlimap');
		var options=$.extend(true,{},$o,o),
			data=this.data($C.datakey),
			image=data.image?data.image:this.find($C.selector),
			parent=image.parent(),
			last=parent.find(':last-child'),
			callbackArguments=[data,(options.scheme?$schemeQueue[options.scheme]:null)]
		;

		if(options['onBeforeLoad']){
			options.onBeforeLoad.apply(this,callbackArguments);
		}

		if(!data.image){
			this.data($C.datakey,$.extend(true,data,{'image':image}));
		}

		image.each(function(i){
			var imageAttributes={
					'src':this.src,
					'width':this.width,
					'height':this.height
				},
				clone=image.eq(i).clone(true,true)
			;
//$framework.log(options,$schemeQueue);
			if(options.scheme){
				var $scheme=$schemeQueue[options.scheme],
					wrapper=$('<div class="'+$C.wrapperClass+'"></div>')
				;

				if($scheme.image && $scheme.image.src){
					clone.attr($scheme.image);
					imageAttributes=$scheme.image;
				}

				map=$XMAP.createMap(clone,$scheme,options,imageAttributes,i);
				wrapper.css($S.htmlmapWrapper);

				if(o.highlight){
					wrapper.css({
						'background':'url('+imageAttributes.src+') no-repeat',
						'width':imageAttributes.width,
						'height':imageAttributes.height
					});
					clone.css($.extend(true,{},$S.canvasStyle,{'opacity':0}));
					if($C.hasVML){clone.css('filter','Alpha(opacity=0)');}

					var canvas=$XMAP.createCanvas(imageAttributes.width,imageAttributes.height);
					$(canvas).css($S.canvasStyle);

					map.find('area[coords]').each(function(){
						var area=$(this);
						area.mouseover(function(e){
							if(!$active){
								$XMAP.highlight(canvas,area,options);
							}
						}).mouseout(function(e){
							$active=!$XMAP.clearCanvas(canvas,e,options);
						});
					});

					wrapper.append(canvas);
				}
				image.eq(i).replaceWith(wrapper.append(clone,map))
			}
		});


		if(options['onLoad']){
			options.onLoad.apply(this,callbackArguments);
		}
//console.timeEnd('htmlimap');
		return this;
	}

	var $onschemeload=$utils.init(_event);
	$(function(){
//console.time('htmlimap_domready');
		if(!$C.initialized){
			throw "HTML Map has NOT been initialized.";
		}
		if(!$.isEmptyObject($schemeQueue)){
			$.each($schemeQueue,function(k,v){
				if(!v.defer){
					v.definition.call(v);
					if(!v.loaded){
						throw 'Unable to load scheme: '+(v.id?v.id:v.url);
					}
					return true;
				}
			});
		}
		if(!$.isEmptyObject($registeredItems)){
			$.each($registeredItems,function(k,v){
				$k=$(k);
				$k.data($C.datakey,v).htmlimap(v.options);
				if(v.options.onSchemeLoad){
					var callback=$utils.init(_function,[v.options.onSchemeLoad,$k,[v]]);
					$onschemeload.add(callback);
				}
			});
		}
//console.timeEnd('htmlimap_domready');
	});

	$(window).load(function(){
//console.time('htmlimap_windowload');
		if(!$.isEmptyObject($schemeQueue)){
			$.each($schemeQueue,function(k,v){
				if(!v.loaded){
					v.definition.call(v);
					if(!v.loaded){
						throw 'Unable to load scheme: '+(v.id?v.id:v.url);
					}
				}
			});
			$onschemeload.run();
		}
//$framework.log('$schemeQueue',$schemeQueue);
//console.timeEnd('htmlimap_windowload');
	});


	return{
		'config':$C,
		'addScheme':function(definition,sid,defer){
			if($utils.is(definition,'String')){
				if(!$schemeQueue[definition]){
					$schemeQueue[definition]=$utils.init(_scheme,[definition,sid,defer]);
					return true;
				}
				return false;
			}
			$schemeQueue[sid]=$utils.init(_scheme,[definition,sid]);
			return true;
		},
		'changeScheme':function(map,scheme){
			var data=map.data($C.datakey),
				options=$.extend(true,data.options,{'scheme':scheme}),
				existing=map.find('.'+$C.wrapperClass)
			;
			if(existing.length){
				existing.each(function(k,v){
					if(data.image){
						existing.eq(k).replaceWith(data.image.eq(k));
						return true;
					}
					existing.eq(k).remove();
				});
			}
			map.htmlimap(options);
		},
		'extend':function(sid,definition){
			if(!$C.initialized){
				this.addScheme(definition,sid);
			}
		},
		'getSchemeByURL':function(url){
			var scheme;
			$.each($schemeQueue,function(k,v){
				if(v.url==url){
					scheme=v;
					return false;
				}
			});
			return scheme;
		},
		'initialize':function(options){
			if(!$C.initialized){
				if($C.hasVML && $.browser.msie){
					document.namespaces.add('v','urn:schemas-microsoft-com:vml');
					var style=document.createStyleSheet();
					$.each($C.vmlElements,function(){
						style.addRule('v\\:'+this,'behavior: url(#default#VML); antialias:true');
					});
				}
				$C.initialized=true;
				return true;
			}
			return false;
		},
		'register':function(selector,scheme,options){
			var $this=this;
			if(scheme && $utils.is(scheme,['String','Array'])){
				if($utils.is(scheme,'String')){
					scheme=scheme.split(',');
				}
				$.each(scheme,function(k,v){
					$this.addScheme(v,null,v!==options.scheme);
				});
			}
			$registeredItems[selector]={
				'scheme':scheme,
				'options':options
			};
		}
	};

})(typeof(jQuery)!=='undefined'?jQuery:null);

