(function(window){

function AccessMap(){
	this.initialize.apply(this,arguments);
}
var p = AccessMap.prototype;
	p.element = null;
	p.context  = null;
	p.canvasWidth = 0;
	p.canvasHeight = 0;
	p.map = null;
	p.maskAry = null;
	p.lineAry = null;
	p.initialize = function(element,address,replaceImageSrc){
		if(!element.getContext) {
			this.createMask = function(){return {	tween:function(){}}};
			var replaceImage = document.createElement('img');
			replaceImage.setAttribute('src',replaceImageSrc);
			replaceImage.style.width='525px';
			replaceImage.style.height='525px';
			element.parentNode.replaceChild(replaceImage,element);
			return;
		}
		this.element = element;
		this.context = element.getContext('2d');
		this.canvasWidth = this.element.width;
		this.canvasHeight = this.element.height;
		this.maskAry = [];
		this.lineAry = [];
		var img = document.createElement('img');
		img.src=address;
		var that = this;
		img.onload = function(){ that.map = this; }
		this.update();
	}
	p.createMask = function(){
		var mask = new CircleMask();
		this.maskAry.push(mask);
		return mask;
	}
	p.createLine = function(element){
		return new LineCanvas(element);
	}
	p.update = function(){
		var i,l;
		this.context.save();
		this.context.clearRect(0,0,this.canvasWidth,this.canvasHeight);

		this.context.beginPath();
		for(i = 0,l =this.maskAry.length; i < l ; i++){
			var mask = this.maskAry[i];
			mask.update();
			this.context.arc(mask.x,mask.y,mask.r,0,Math.PI*2,true);
			this.context.closePath();
		}
		this.context.clip();
		if(this.map != null) this.context.drawImage(this.map,0,0);

		this.context.restore();
		var that = this;
		var arg = arguments;
		setTimeout(function(){that.update.apply(that,arg);},20);
	}

function CircleMask(){
	this.initialize.apply(this,arguments);
}
var p = CircleMask.prototype;
	p.x = 0;
	p.y = 0;
	p.r = 0;
	p.to = {};
	p.from = {};
	p.initialize = function(){
		this.to = {x:0,y:0,r:0}
		this.from = {x:0,y:0,r:0}
	}
	p.update = function(){
		var currentTime = (new Date().getTime() - this.from.time)/1000;
		var time = this.to.time - this.from.time;
		if(time > currentTime){
			this.x = this.easing(currentTime,this.from.x,this.to.x-this.from.x,time);
			this.y = this.easing(currentTime,this.from.y,this.to.y-this.from.y,time);
			this.r = this.easing(currentTime,this.from.r,this.to.r-this.from.r,time);
		}
		else{
			this.x = this.to.x;
			this.y = this.to.y;
			this.r = this.to.r;
		}
		if(this.r < 0) this.r = 0;
	}
	p.tween = function(x,y,r,time){
		this.to.x = (x == null) ? this.x : x ;
		this.to.y = (y == null) ? this.y : y ;
		this.to.r = (r == null) ? this.r : r ;
		this.to.time = new Date().getTime() + time;
		this.from.x = this.x;
		this.from.y = this.y;
		this.from.r = this.r;
		this.from.time = new Date().getTime();
		if(time == 0) this.update();
	}
	p.easing = function(t, b, c, d ) {
		var s = 1.70158;
		if ((t /= d / 2) < 1) {
			return c / 2 * (t * t * (((s * 1.525) + 1) * t - s * 1.525)) + b;
		}
		return c / 2 * ((t -= 2) * t * (((s * 1.525) + 1) * t + s * 1.525) + 2) + b;
	}

function LineCanvas(){
	this.initialize.apply(this,arguments);
}
var p = LineCanvas.prototype;
	p.pathAry = null;
	p.time = 0;
	p.element = null;
	p.context = null;
	p.initialize = function(element){
		this.pathAry = [];
		this.element = element;
		this.context = this.element.getContext('2d');
		this.context.strokeStyle = "rgb(0,155,228)";
	}
	p.update = function(startTime){
		var progress = (new Date().getTime() - startTime)/1000/this.time;
		var order = Math.floor(progress/(1/this.pathAry.length));
		var pos = (progress%(1/this.pathAry.length)) / (1/this.pathAry.length);
		if(order < this.pathAry.length-1 ){
			var x = (this.pathAry[order][0]*(1-pos) + this.pathAry[order+1][0]*pos)/2;
			var y = (this.pathAry[order][1]*(1-pos) + this.pathAry[order+1][1]*pos)/2;
			this.context.lineTo(x,y);
			this.context.stroke();
			var that = this;
			setTimeout(function(){that.update.call(that,startTime);},50);
		}
	}
	p.draw = function(pathAry,time)
	{
		this.pathAry = pathAry;
		this.time = time;
		this.context.beginPath();
		this.update(new Date().getTime());
	}

window.AccessMap = AccessMap;
}(window))
