/**
 * scroll.js 1.1 - http://dis.ne.jp
 *
 * (c) 2009 DOORS CORPORATION. and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

var SmoothMove = function(){
	/* ------------------------- [設定用の値] ------------------------- */
	//無視するID
	var ignoreIds = ['',''];
	//速度設定
	var speedMagnification = 0.92;
	//インターバル
	var baseInterval = 16;
	//ウィンドウの上端から停止位置までのオフセット
	var stopPositionOffset = 10;
	/* ---------------------------------------------------------------- */
	var distance = 0;		//残りの実行時間
	var startDistance = 0;	//全体の実行時間(計算しやすいように全体距離と同一とする)
	var nowPos = 0;			//進んだ距離
	var startY = 0;
	var sign = 1;
	
	//コンストラクタ
	var _constructor = function(){
		addEventListener(window, "load", fnOnload);
	};
	
	var fnOnload = function(){
		atags = document.getElementsByTagName('A');
		var pageUrl = location.href.replace(/#.*?$/, '');
		for(var i = 0,len = atags.length; i < len; i++){
			var a = atags[i];
			var href = a.getAttribute('href');
			if (href && new RegExp("^(?:"+escapeRegex(pageUrl)+")?#(.*?)$").test(href)){
				var label = RegExp.$1;
				var isIgnore = false;
				
				for (var j = 0, len2 = ignoreIds.length; j < len2; j++){
					if (ignoreIds[j] == label){
						isIgnore = true;
						break;
					}
				}
				if (isIgnore == false){
					var func = null;
					eval("func = function(){SmoothMove.moveTo('" + label + "')};");
					addEventListener(a, "click", func);
					a.removeAttribute('href');
				}
			}
		}
	};
	
	var escapeRegex = function(str){
		return str.replace(/([\\$^*+?(){}\[\].|])/g,"\\$1");
	};
	
	/**
	 * イベントを追加する関数
	 * @param	target	string		イベントを追加する対象
	 * @param	type	string		追加するイベント名
	 * @param	func	function	追加する関数
	 */
	var addEventListener = function(target, type, func){
		if( target.attachEvent ){
			target.attachEvent("on" + type, func);
		}else if( target.addEventListener ){
			target.addEventListener(type, func, true);
		}else{
			target["on" + type] = func;
		}
	};
	
	var intervalFunction = function(){
		distance = distance * speedMagnification;
		nowPos = startDistance - distance;
		window.scrollTo(0,startY + nowPos * sign);
		
		if (distance > 1){
			setTimeout(intervalFunction, baseInterval);
		}
	};
	
	var windowUtils = {};
	
	/**
	 *	Windowのスクリーン上の位置(Ｙ座標)
	 *	@return	Windowのスクリーン上のＹ座標
	 */
	windowUtils.getTop = function(){
		/* Mozilla */
		if( window.scrollY ){
			return window.scrollY;
		}
		/* Opera, NN4 */
		if( window.pageYOffset ){
			return window.pageYOffset;
		}
		/* 以下 IE */
		if( document.documentElement && document.documentElement.scrollTop ){
			return document.documentElement.scrollTop;
		}
		if( document.body && document.body.scrollTop ){
			return document.body.scrollTop;
		}
		return 0;
	};

	/**
	 * エレメント操作
	 */
	var eleUtils = {};

	/**
	 * 絶対座標を取得する。
	 * @param element 絶対座標を取得するオブジェクト
	 * @return 絶対座標
	 */
	eleUtils.getAbsOffset = getAbsOffset = function (element){
		var left = 0;
		var top = 0;
		while( element ){
			left += element.offsetLeft;
			top  += element.offsetTop;
			element = element.offsetParent;
		}
		return { "left": left, "top": top };
	};

	var pub = {};	
	/**
	 * 対象の要素に移動する
	 * @param string 移動先の要素のIdもしくはname
	 */
	pub.moveTo = function(eleId){
		var ele = document.getElementById(eleId);
		if (ele == null || ele.length == 0){
			var eleList = document.getElementsByName(eleId);
			if (eleList && eleList.length > 0){
				ele = eleList[0];
			}
		}
		if (ele == null || ele.length == 0){
			return false;
		}
		
		var offsetArray = eleUtils.getAbsOffset(ele);
		var targetY = offsetArray.top;
		startY = windowUtils.getTop();

		if ( startY > targetY){
			startDistance = (startY - targetY + stopPositionOffset);
			sign = -1;
		}else if(startY < targetY){
			startDistance = (targetY - startY - stopPositionOffset);
			sign = +1;
		}else{
			return true;
		}
		distance = startDistance;
		nowPos = 0;
		intervalFunction();
		return true;
	};
	_constructor();
	return pub;
}();
