(function(window){

function FlickPaper(){
	this.initialize.apply(this,arguments);
}
var p = FlickPaper.prototype;
	p.papers = null;
	p.initialize = function(){
		this.papers = [];
	}
	p.add = function(element,point1,point2){
		var that = this;
		var callback = {
			start:function(e){that.onStart.call(that,e);},
			move:function(e){that.onMove.call(that,e);},
			end:function(e){that.onEnd.call(that,e);}
		};
		this.papers.push(new Paper(element,this.papers.length,point1,point2,callback));
	}
	p.onStart = function(e){
		var i,l;
		if(e.current == 0){
			for(i=e.id,l=this.papers.length; i< l;i++){
				if(this.papers[i].current == e.current)	this.papers[i].start(e.x,e.y);
			}
		}
		else if(e.current == 1){
			for(i=e.id; i >= 0;i--){
				if(this.papers[i].current == e.current) this.papers[i].start(e.x,e.y);
			}
		}
	}
	p.onMove = function(e){
		var i,l;
		if(e.current == 0){
			for(i=e.id,l=this.papers.length; i< l;i++){
				if(this.papers[i].current == e.current)	this.papers[i].move(e.x,e.y);
			}
		}
		else if(e.current == 1){
			for(i=e.id; i >= 0;i--){
				if(this.papers[i].current == e.current) this.papers[i].move(e.x,e.y);
			}
		}
	}
	p.onEnd= function(e){
		var i,l;
		if(e.current == 0){
			for(i=e.id,l=this.papers.length; i< l;i++){
				if(this.papers[i].current == e.current)	this.papers[i].end(e.x,e.y);
			}
		}
		else if(e.current == 1){
			for(i=e.id; i >= 0;i--){
				if(this.papers[i].current == e.current) this.papers[i].end(e.x,e.y);
			}
		}
	}

function Paper(){
	this.initialize.apply(this,arguments);
}
var p = Paper.prototype;
	p.element = null;
	p.prop = null;
	p.startElementPosition = null;
	p.startMousePosition = null;
	p.moveMousePosition = null;
	p.point1 = null;
	p.point2 = null;
	p.intervalId = null;
	p.tween = null;
	p.callBack = null;
	p.current = 0;
	p.id = 0;
	p.eventStack = null;
	p.accell = null;
	p.isMove = false;

	p.initialize = function(element,id,point1,point2,callback){
		this.element = element;
		this.id = id;
		this.point1 = point1;
		this.point2 = point2;
		this.callback = callback;
		this.prop = {top:0,left:0};
		this.left(point1.x);
		this.top(point1.y);
		this.tween = {from:{left:0,top:0},to:{left:0,top:0},startTime:0,time:0};
		this.eventStack = {};
		addListener(this.element,"mousedown",this.onTouchStart,this,null,true,true);
		addListener(this.element,"touchstart",this.onTouchStart,this,null,true,true);
	}
	p.onTouchStart = function(e){
		this.isDragging = true;
		this.callback.start({id:this.id,current:this.current,x:getPointer(e).x,y:getPointer(e).y});
		this.eventStack.mousemove = addListener(document,"mousemove",this.onTouchMove,this,null,true,true);
		this.eventStack.touchmove = addListener(this.element,"touchmove",this.onTouchMove,this,null,true,true);
		this.eventStack.mouseup = addListener(document,"mouseup",this.onTouchEnd,this,null,true,true);
		this.eventStack.touchend = addListener(this.element,"touchend",this.onTouchEnd,this,null,true,true);
	}
	p.onTouchMove = function(e){
		if(!this.isDragging) return;
		this.callback.move({id:this.id,current:this.current,x:getPointer(e).x,y:getPointer(e).y});
	}
	p.onTouchEnd = function(e,arg){
		removeListener(this.eventStack.mousemove);
		removeListener(this.eventStack.touchmove);
		removeListener(this.eventStack.mouseup);
		removeListener(this.eventStack.touchend);
		this.isDragging = false;
		this.callback.end({id:this.id,current:this.current,x:getPointer(e).x,y:getPointer(e).y});
	}
	p.start = function(x,y){
		this.startMousePosition = {x:x,y:y};
		this.moveMousePosition = {x:x,y:y};
		this.startElementPosition = {left:this.left(),top:this.top()};
		this.accell = {x:0,y:0};
		this.isMove = false;
		this.stop();
	}
	p.move = function(x,y){
		this.accell = {x:x - this.moveMousePosition.x,y:y - this.moveMousePosition.y};
		if(Math.abs(x - this.startMousePosition.x) > 3) this.isMove = true;
		this.left(x - this.startMousePosition.x + this.startElementPosition.left);
		this.top(y - this.startMousePosition.y + this.startElementPosition.top);
		this.moveMousePosition = {x:x,y:y};
	}
	p.end = function(x,y){
		if(!this.isMove){
			if(this.current == 1) this.moveTo(0);
			else if(this.current == 0) this.moveTo(1);
		}
		else if(this.accell.x > 3 && this.current == 0) this.moveTo(1);
		else if(this.accell.x < -3 && this.current == 1) this.moveTo(0);
		else{
			var dist1 = Math.pow(this.left() - this.point1.x,2) + Math.pow(this.top() - this.point1.y,2);
			var dist2 = Math.pow(this.left() - this.point2.x,2) + Math.pow(this.top() - this.point2.y,2);
			if(dist1 < dist2) this.moveTo(0);
			else this.moveTo(1);
		}
	}
	p.stop = function(){
		clearInterval(this.intervalId);
	}
	p.moveTo = function(id){
		this.current = id;
		if(id == 0) this.tween = {from:{left:this.left(),top:this.top()},to:{left:this.point1.x,top:this.point1.y},startTime:new Date().getTime(),time:500};
		else if(id == 1) this.tween = {from:{left:this.left(),top:this.top()},to:{left:this.point2.x,top:this.point2.y},startTime:new Date().getTime(),time:500};
		this.stop();
		this.update();
	}
	p.update = function(){
		var currentTime =new Date().getTime() - this.tween.startTime;
		this.left(this.easing(currentTime,this.tween.from.left,this.tween.to.left - this.tween.from.left,this.tween.time));
		this.top(this.easing(currentTime,this.tween.from.top,this.tween.to.top - this.tween.from.top,this.tween.time));
		var that = this;

		if(currentTime <  this.tween.time) this.intervalId = setTimeout(function(){that.update.call(that)},20);
		else {
			this.top(this.tween.to.top);
			this.left(this.tween.to.left);
		}
	}
	p.easing = function(t, b, c, d) { return c * ((t = t / d - 1) * t * t * t * t + 1) + b;  }
	p.top = function(value){
		if(typeof value !== 'undefined')
		{
			this.prop.top = value;
			this.element.style.top = value + "px";
		}
		else return this.prop.top;
	}
	p.left = function(value){
		if(typeof value !== 'undefined')
		{
			this.prop.left = value;
			this.element.style.left = value + "px";
		}
		else return this.prop.left;
	}



function getPointer(e){
		var pointer = {x:0,y:0};
		if(e && e.touches && e.touches[0]){
			pointer.x = e.touches[0].pageX;
			pointer.y = e.touches[0].pageY;
		}
		else if(e && e.pageX ){
			pointer.x = e.pageX;
			pointer.y = e.pageY;
		}
		else if(typeof event != 'undefined' && event.clientX){
			pointer.x = event.clientX;
			pointer.y = event.clientY;
		}
		return pointer;
	}


function addListener(target,eventName,func,scope,arg,preventDefault,stopPropagation){
	var preventDefault = (preventDefault) ? true : false;
	var stopPropagation = (stopPropagation) ? true : false;
	var scope = (scope) ? scope : window;
	var arg = (arg) ? arg : {};
	var f = function(e){
		if(preventDefault){
			if(e.preventDefault) e.preventDefault();
			else if(window.event) window.event.returnValue = false;
		}
		if(stopPropagation){
			if(e.stopPropagation) e.stopPropagation();
			else if(window.event) window.event.cancelBubble = true;
		}
		func.call(scope,e,arg);
	};
	if(target.addEventListener){
		target.addEventListener(eventName,f,false);
		if(eventName == "mousewheel") window.addEventListener('DOMMouseScroll', f, false);// Firefox
	}
	else if(target.attachEvent){
		target.attachEvent("on" + eventName,f);
	}
	return {target:target,eventName:eventName,func:f};
}
function removeListener(obj){
	if(document.addEventListener) {
		obj.target.removeEventListener(obj.eventName,obj.func,false);
		if(obj.eventName == "mousewheel") obj.target.removeEventListener('DOMMouseScroll',obj.func,false);
	}
	else if(document.detachEvent) obj.target.detachEvent("on" + obj.eventName,obj.func);
}

/*
function addListener(target,eventName,func,scope,arg,preventDefault,stopPropagation){
	var preventDefault = (preventDefault) ? true : false;
	var stopPropagation = (stopPropagation) ? true : false;
	var scope = (scope) ? scope : window;
	var arg = (arg) ? arg : {};
	var f = function(e){
		if(preventDefault){
			if(e.preventDefault) e.preventDefault();
			else if(window.event) window.event.returnValue = false;
		}
		if(stopPropagation){
			if(e.stopPropagation) e.stopPropagation();
			else if(window.event) window.event.cancelBubble = true;
		}
		func.call(scope,e,arguments,arg);
	};
	if(target.addEventListener) target.addEventListener(eventName,f,false);
	else target.attachEvent("on" + eventName,f);
}
function removeListener(target,eventName,func){
	if(document.addEventListener) target.removeEventListener(eventName,func,false);
	else target.detachEvent("on" + eventName,func);
}

*/









window.FlickPaper = FlickPaper;

}(window))
