
/*
 * flickScroll.js
 * 
 * @author		GLIDE ARTS STUDIO.
 * @version		0.4
 * @2011-06-24
 * @2012-02-04
 * Copyright (C) 2011 GLIDE ARTS STUDIO.
 * 
 */

var minWidth    = 960;
var minHeight   = 700;
var duration    = 500;
var os          = UA.os;
var browser     = UA.browser;
var version     = UA.version;
var device      = UA.device;

function setTutorial() {
	var figure = document.createElement("figure");
	var img = document.createElement("img");
	var image = new Image();
	image.src = "http://www.glide.co.jp/images/tutorial1.gif";
	image.onload = function () {
		figure.setAttribute("id", "tutorial");
		figure.appendChild(img);
		img.setAttribute("src", image.src);
		document.getElementsByTagName("body")[0].appendChild(figure);
		
		setTimeout(function () {
			figure.setAttribute("class", "fadeIn");
		}, 500);
		
		setTimeout(function () {
			figure.setAttribute("class", "fadeOut");
		}, 5000);
		
		setTimeout(function () {
			document.getElementsByTagName("body")[0].removeChild(figure);
		}, 6000);
	}
}

var FlickScroll = function (targetContainer, targetArea, targetItems, tweenObject){
	
	this.name        = typeof targetContainer == "string" ? targetContainer : targetContainer.getAttribute("id");
	this.tween       = tweenObject;
	this.tweenStatus = "stop"; // "ready", "play", "pause", "stop"
	this.container   = typeof targetContainer == "string" ? document.getElementById(targetContainer) : targetContainer;
	this.target      = getChildNodes(this.container); // ie
	this.items       = this.container.getElementsByTagName(targetItems);
	
	this.isMouseDown = false;
	this.isDragging  = false;
	this.isVDragging = false;
	this.len         = this.items.length;
	this.itemsCSS    = this.items[0].currentStyle || document.defaultView.getComputedStyle(this.items[0], ''); // cssの値を取得
	
	this.contentsChildMR = parseInt(this.itemsCSS.marginRight);
	this.contentsChildML = parseInt(this.itemsCSS.marginLeft);
	this.contentsChildPR = parseInt(this.itemsCSS.paddingRight);
	this.contentsChildPL = parseInt(this.itemsCSS.paddingLeft);
	this.limitLeft       = 0;
	this.limitRight      = 0;
	this.contentsWidth   = 0;
	this.loadedCount     = 0;
	this.eventType       = "click";
	
	this.curX   = 0;
	this.diffX  = 0;
	this.diffY  = 0;
	this.newX   = 0;
	this.oldX   = 0;
	this.newY   = 0;
	this.oldY   = 0;
	this.xp     = 0;
	this.burden = 2;
	
	this.checkOverflowId;
	this.overflowId;
	
	var IE_clientX    = 0;
	var IE_scrollLeft = 0;
	
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		this.eventType = "touchend";
		this.container.setAttribute("class", "flickableArea multitouchDevice");
	}
}

var isVerticalScrolling = false;
var isCheckAspect = true;

FlickScroll.prototype.init = function () {
	
	var thisTarget = this.target;
	var t = this;
	
	this.resetContainerSize();
	this.container.style.visibility = "visible";
	this.target.style.width = this.contentsWidth;
	this.target.style.left = "0";
	this.target.setAttribute("class", "handCursor");
	this.id = 0;
	this.defTimeoutId = 0;
	
	// ---------------------------------------------------------------------------------------------
	// Pointing Device
	// ---------------------------------------------------------------------------------------------
	
	var onMouse = function (event) {
		
		var eventType = event.type;
		var relatedTarget = event.relatedTarget;
		var doc = document;
		var windowWidth = window.innerWidth || doc.documentElement.clientWidth || doc.body.clientWidth;
		var css = t.target.currentStyle || document.defaultView.getComputedStyle(t.target, "");
		var browser = UA.browser;
		
		if (browser !== "msie") event.preventDefault();
		
		if ((eventType === "mousemove" || eventType === "mousedown" || eventType === "onmousemove" || eventType === "onmousedown") && t.isMouseDown === true) {
			
			if (!t.isDragging) t.levitate();
			t.isDragging = true
			t.isMouseDown = true;
			clearTimeout(t.defTimeoutId);
			clearTimeout(t.id);
			t.defTimeoutId = setTimeout(function () {
				
				t.diffX = 0.01;
				t.curX = parseInt(css.left);
			},50);
			
			// Outside the Window
			if (event.pageX < 0 || event.pageX > windowWidth) {
				t.dragEnd();
				t.endLevitate();
				
			// Dragging
			} else {
				t.move(event);
				t.tweenStatus = "play";
			}
			
		} else if (eventType === "mousedown" || eventType === "onmousedown") {
			
			checkStatus(t);
			clearTimeout(t.id);
			
			thisTarget.style.width = t.contentsWidth;
			thisTarget.setAttribute("class", "handHoldCursor");
			t.tween.removeTweens();
			t.resetContainerSize();
			t.oldX = getPageX(event);
			t.diffX = 0;
			t.isMouseDown = true;
			t.id = setTimeout(function () {
				var css = t.target.currentStyle || document.defaultView.getComputedStyle(t.target, "");
				t.diffX = 0.01;
				t.curX = parseInt(css.left);
				t.levitate();
				if (browser !== "msie") event.preventDefault();
			}, 300);
			
			clearInterval(t.checkOverflowId);
			clearTimeout(t.overflowId);
			
		} else if (eventType === "mouseup" || eventType === "onmouseup") {
			
			clearTimeout(t.id);
			t.endLevitate();
			
			// Throw or Stop
			if ((t.isMouseDown || t.isDragging) && t.diffX !== 0) {
				t.dragEnd();
				return false;
			// Click
			} else if (t.tweenStatus === "ready") {
				t.resetTargetArea("stop");
			// Stopped and moving.
			} else if (t.tweenStatus === "pause") {
				t.resetTargetArea("stop");
			}
		}
		
		return false;
	}
	
	
	
	// ---------------------------------------------------------------------------------------------
	// Multi-Touch Device
	// ---------------------------------------------------------------------------------------------
	
	var touchRadius = 10;
	
	var onTouch = function (event) {
		
		var eventType = event.type;
		var touch = event.touches[0];
		var windowWidth = window.innerWidth;
		var angle = 0;
		
		if (eventType === "touchmove" && t.isMouseDown === true) {
			
			clearTimeout(t.id);
			t.isDragging = true
			t.isMouseDown = true;
			
			// 方向が決まっていなくて一定範囲内なら 方向を決める
			if (!isCheckAspect) {
				if ((t.oldX - touch.pageX >= 15 || t.oldX - touch.pageX <= -15)) {
					isVerticalScrolling = false; // 横
				} else {
					isVerticalScrolling = true; // 縦
				}
				isCheckAspect = true;
			}
			
			// 横移動の場合
			if (isVerticalScrolling === false) {
				
				setTimeout(moveTimeout, 300);
				
				// Outside the Window
				if (touch.pageX < 0 || touch.pageX > windowWidth) {
					t.dragEnd();
					//t.endLevitate();
					
				// Dragging
				} else {
					t.move(touch);
					t.tweenStatus = "play";
				}
				
				event.preventDefault();
			}
			
		} else if (eventType === "touchstart") {
			
			checkStatus(t)
			
			isCheckAspect = false;
			thisTarget.style.width = t.contentsWidth;
			t.stop(touch);
			//t.resetContainerSize();
			t.oldX = touch.pageX;
			t.oldY = touch.pageY;
			t.diffX = 0;
			t.isMouseDown = true;
			t.id = setTimeout(function(){
				event.preventDefault();
				//t.levitate();
			}, 120);
			
		} else if (eventType === "touchend") {
			
			clearTimeout(t.id);
			//t.endLevitate();
			
			if (isVerticalScrolling) {
				t.resetTargetArea("stop");
				
			// Throw
			} else if (t.isDragging || t.diffX !== 0) {
				t.dragEnd();
				return false;
				
			// Click / Stopped and moving.
			} else if (t.tweenStatus === "ready" || t.tweenStatus === "pause") {
				t.resetTargetArea("stop");
				
			}
			
			isCheckAspect = false;
			isVerticalScrolling = false;
		}
	}
	
	function checkStatus(t) {
		// Pause
		if (t.tweenStatus === "play") {
			t.resetTargetArea("pause");
			
		// New
		} else if (t.tweenStatus === "stop") {
			t.tweenStatus = "ready";
			t.diffX = 0;
		}
	}
	
	function moveTimeout() {
		t.diffX = 0.01;
	}
	
	var len = t.len;
	for (var i = 0; i < len; i++) {
		action(t.items[i].getElementsByTagName("span")[0], t);
	}
	
	function action(tar, t) {
		
		if (device === "iphone" || device === "ipod" || device === "ipad") {
			tar.addEventListener("touchend", function(event){onImageClickHandler(event, t, tar)}, false);
			
		} else if (document.attachEvent) {
			tar.attachEvent("onclick",  function(event){onImageClickHandler(event, t, tar);});
			tar.attachEvent("onclick",  function(){return false;});
			
		} else {
			tar.addEventListener("mouseover", function(event){event.preventDefault();}, false);
			tar.addEventListener("click", function(event){onImageClickHandler(event, t, tar)}, false);
		}
	}
	
	function func() {
		onImageClickHandler(event, t, tar);
	}
	
	function onImageClickHandler(event, th, anchor) {
		
		if (isVerticalScrolling) return false;
		if (browser !== "msie") event.preventDefault();
		if (th.diffX === 0) {
			var t = anchor.getAttribute("title") || null;
			var a = anchor.getAttribute("data-href") || "";
			var g = anchor.getAttribute("rel") || false;
			var i = anchor.getAttribute("data-id") || false;
			G_ModalWindowOpen(t, a, g, i);
			th.diffX = 0.01;
			th.dragEnd();
		}
		return false;
	}
	
	// Device's aspect change.
	function onOrientationChange(event) {
		t.resetContainerSize();
	}
	
	// Add Events
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		
		window.addEventListener("orientationchange", onOrientationChange, false);
		this.container.addEventListener("touchstart", onTouch, false);
		this.container.addEventListener("touchmove", onTouch, false);
		this.container.addEventListener("touchend", onTouch, false);
		
	} else if (browser === "msie") {
		
		document.attachEvent("onmousemove", onMouse);
		document.attachEvent("onmouseup", onMouse);
		document.attachEvent("onmouseout", onMouse);
		this.container.attachEvent("onmousedown", onMouse);
		this.container.attachEvent("onmouseout", onMouse);
		
	} else {
		
		document.addEventListener("mousemove", onMouse, true);
		document.addEventListener("mouseup", onMouse, true);
		this.container.addEventListener("mousedown", onMouse, true);
		this.container.addEventListener("mouseout", onMouse, true);
		
	}
}





FlickScroll.prototype.resetTargetArea = function (status) {
	
	var css = this.target.currentStyle || document.defaultView.getComputedStyle(this.target, "");
	
	this.tweenStatus = status;
	this.diffX = 0;
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		this.oldX = this.getWebKitCSSMatrix().e;
		
	} else {
		this.oldX = parseInt(css.left);
	}
	
	this.xp = this.oldX;
	this.isMouseDown = false;
	this.isDragging = false;
	this.target.style.width = this.contentsWidth;
	this.target.setAttribute("class", "handCursor");
}

FlickScroll.prototype.move = function (touch) {
	
	if (this.isMouseDown === true) {
		
		this.newX = getPageX(touch);
		this.newY = getPageY(touch);
		this.diffX = this.newX - this.oldX;
		this.diffY = this.newY - this.oldY;
		this.isDragging = true;
		this.curX > this.limitLeft || this.curX < this.limitRight ? this.xp += this.diffX / this.burden : this.xp += this.diffX;
		this.curX = this.xp;
		this.oldX = this.newX;
		
		if (device === "iphone" || device === "ipod" || device === "ipad") {
			this.target.style.webkitTransitionTimingFunction = "linear";
			this.target.style.webkitTransitionDuration = "100ms";
			this.target.style.webkitTransform = "translate3d(" + this.xp + "px, 0px, 0px)";
			this.target.style.webkitTransitionDuration = "0s";
		} else {
			this.tween.play(this.target, {left:this.xp + "px"}, 0.0, easeOutExpo);
		}
	}
}

FlickScroll.prototype.stop = function (touch) {
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		this.target.style.webkitTransitionDuration = "0s";
		this.target.style.webkitTransform = "translate3d(" + this.getWebKitCSSMatrix().e + "px, 0px, 0px)";
		clearInterval(this.checkOverflowId);
		clearTimeout(this.overflowId);
	}
}

FlickScroll.prototype.dragEnd = function () {
	this.target.style.width = this.contentsWidth;
	this.target.setAttribute("class", "handCursor");
	this.touchEnd(this.diffX);
}

FlickScroll.prototype.touchEnd = function (difference) {
	
	var t = this;
	var lastX = t.curX + (difference * 15);
	var confX = 0;
	var maxOverrun = 600;
	var maxOverrunReturnPoint = maxOverrun / 2;
	
	t.isMouseDown = false;
	t.isDragging = false;
	
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		t.target.style.webkitTransform = "translate3d(" + difference + "px, 0px, 0px)";
	}
	
	// 大きくオーバーする場合は補正
	if (lastX > t.limitLeft + maxOverrun) {
		lastX = t.limitLeft + maxOverrun;
	} else if (lastX < t.limitRight - maxOverrun) {
		lastX = t.limitRight - maxOverrun;
	}
	
	if (t.curX > t.limitLeft ) {
		confX = t.xp = t.curX = t.limitLeft;
		
	} else if (t.curX < t.limitRight) {
		confX = t.xp = t.limitRight;
		
	} else {
		confX = lastX;
		t.xp = lastX;
		t.curX = lastX;
	}
	
	if (t.contentsWidth < minWidth) {
		confX = t.xp = t.curX = t.limitLeft;
	}
	
	if (device === "iphone" || device === "ipod" || device === "ipad") {
		
		t.target.style.webkitTransitionTimingFunction = "cubic-bezier(0, 0.8, 0.2, 1)";
		t.target.style.webkitTransitionDuration = "1000ms";
		t.target.style.webkitTransform = "translate3d(" + confX + "px, 0px, 0px)";
		t.tweenStatus = "stop";
		t.diffX = 0;
		t.diffY = 0;
		
	} else {
		t.tween.play(t.target, {left:confX + "px"}, 0.5, easeOutExpo, finish);
	}
	
	clearTimeout(t.overflowId);
	clearInterval(t.checkOverflowId);
	
	t.checkOverflowId = setInterval(function(){checkOverflow(t)}, 10);
	
	var removeId;
	var style = t.target.currentStyle || document.defaultView.getComputedStyle(t.target, '');
	
	// 現在の位置をチェック
	function checkOverflow(t) {
		var x;
		
		if (device === "iphone" || device === "ipod" || device === "ipad") {
			x = t.getWebKitCSSMatrix().e;
		} else {
			x = parseInt(style.left);
		}
		
		if (x > t.limitLeft) {
			t.overflowId = setTimeout(function(){overflow(t, t.limitLeft)}, 30);
			clearInterval(t.checkOverflowId);
		} else if (x < t.limitRight) {
			t.overflowId = setTimeout(function(){overflow(t, t.limitRight)}, 30);
			clearInterval(t.checkOverflowId);
		}
	}
	
	// 大きくはずれていた場合
	function overflow(t, limit) {
		clearTimeout(t.overflowId);
		confX = limit;
		t.xp = limit;
		
		if (device === "iphone" || device === "ipod" || device === "ipad") {
			t.target.style.webkitTransitionTimingFunction = "cubic-bezier(0.2, 0.5, 0.3, 1)";
			t.target.style.webkitTransitionDuration = "500ms";
			t.target.style.webkitTransform = "translate3d(" + limit + "px, 0px, 0px)";
		} else {
			t.tween.removeTweens();
			t.tween.play(t.target, {left:limit + "px"}, 0.8, easeOutExpo, finish);
		}
	}
	
	function finish() {
		var css = t.target.currentStyle || document.defaultView.getComputedStyle(t.target, "");
		clearInterval(t.checkOverflowId);
		t.tweenStatus = "stop";
		t.tween.removeTweens();
		t.diffX = 0;
		t.diffY = 0;
		t.curX = parseInt(css.left);
	}
}

FlickScroll.prototype.getWebKitCSSMatrix = function () {
	var t = this;
	var matrix = new WebKitCSSMatrix(window.getComputedStyle(t.target).webkitTransform);
	return matrix;
}

FlickScroll.prototype.resetContainerSize = function () {
	
	var len          = this.len;
	var marginTotal  = 0;
	var paddingTotal = 0;
	
	this.contentsWidth = 0;
	
	for (var i = 0; i < len; i++) {
		this.contentsWidth += parseInt(this.itemsCSS.width);
	}
	
	marginTotal = (this.contentsChildMR * len) + (this.contentsChildML * len);
	paddingTotal = (this.contentsChildPR * len) + (this.contentsChildPL * len);
	
	this.contentsWidth += marginTotal + paddingTotal;
	this.limitRight = parseInt(this.container.offsetWidth) - this.contentsWidth;
	this.target.style.width = this.contentsWidth + "px";
	
}





FlickScroll.prototype.levitate = function () {
	var len = this.len;
	for(var i = 0; i < len; i++){
		this.items[i].setAttribute("class", "levitate");
	}
}

FlickScroll.prototype.endLevitate = function () {
	var len = this.len;
	for(var i = 0; i < len; i++){
		this.items[i].setAttribute("class", "");
	}
}



function imagesOnResize(event) {
	
	var photolog = document.getElementById("photolog");
	var photologLineTotal = photolog.getElementsByTagName("ul").length;
	var items = 0;
	var ul;
	var containerWidth;
	var containerHeight;
	
	for (var i = 0; i < photologLineTotal; i++) {
		
		ul = photolog.getElementsByTagName("ul")[i];
		items = ul.getElementsByTagName("img").length;
		
		if (ul.getElementsByTagName("li")[0] != undefined) {
			containerWidth = ul.getElementsByTagName("li")[0].offsetWidth;
			containerHeight = ul.getElementsByTagName("li")[0].offsetHeight;
			
			for (var j = 0; j < items; j++) {
				var img = ul.getElementsByTagName("img")[j];
				img.style.left = (containerWidth / 2 - img.width / 2) + "px";
				img.style.top = (containerHeight / 2 - img.height / 2) + "px";
			}
			
			if (flickScrollArray[i]) flickScrollArray[i].resetContainerSize();
		}
	}
}

if (document.attachEvent) {
	window.attachEvent("resize", imagesOnResize);
} else {
	window.addEventListener("resize", imagesOnResize, false);
}



/* ---------------------------------------------------------------------------------------------- */



function getChildNodes(element) {
	var childNodes;
	for (var i = 0; i < 5; i++) {
		if (element.childNodes[i].tagName != undefined) {
			childNodes = element.childNodes[i];
			break;
		}
	}
	return childNodes;
}

function getPageX(event) {
	
	var pageX = 0;
	var doc = document;
	
	if (browser === "msie") {
		pageX = doc.body.scrollLeft + window.event.clientX;
		
	} else {
		pageX = event.pageX;
	}
	
	return pageX;
}

function getPageY(event) {
	
	var pageY = 0;
	var doc = document;
	
	if (browser === "msie") {
		pageY = doc.body.scrollTop + window.event.clientY;
		
	} else {
		pageY = event.pageY;
	}
	
	return pageY;
}

