// UTF-8

/**

 * scrollsmoothly.js

 * Copyright (c) 2008 KAZUMiX

 * http://d.hatena.ne.jp/KAZUMiX/

 * Licensed under the MIT License:

 * http://www.opensource.org/licenses/mit-license.php

 */



(function(){

    var easing = 0.25;

    var interval = 20;

    var d = document;

    var targetX = 0;

    var targetY = 0;

    var targetHash = '';

    var scrolling = false;

    var splitHref = location.href.split('#');

    var currentHref_WOHash = splitHref[0];

    var incomingHash = splitHref[1];

    var prevX = null;

    var prevY = null;



    // ドキュメント読み込み完了時にinit()を実行する

    addEvent(window, 'load', init);



    // ドキュメント読み込み完了時の処理

    function init(){

        // ページ内リンクにイベントを設定する

        setOnClickHandler();

        // 外部からページ内リンク付きで呼び出された場合

        if(incomingHash){

            if(window.attachEvent && !window.opera){

                // IEの場合はちょっと待ってからスクロール

                setTimeout(function(){scrollTo(0,0);setScroll('#'+incomingHash);},50);

            }else{

                // IE以外はそのままGO

                scrollTo(0, 0);

                setScroll('#'+incomingHash);

            }

        }

    }



    // イベントを追加する関数

    function addEvent(eventTarget, eventName, func){

        if(eventTarget.addEventListener){

            // モダンブラウザ

            eventTarget.addEventListener(eventName, func, false);

        }else if(window.attachEvent){

            // IE

            eventTarget.attachEvent('on'+eventName, function(){func.apply(eventTarget);});

        }

    }

    

    function setOnClickHandler(){

        var links = d.links;

        for(var i=0; i<links.length; i++){

            // ページ内リンクならスクロールさせる

            var link = links[i];

            var splitLinkHref = link.href.split('#');

            if(currentHref_WOHash == splitLinkHref[0] && d.getElementById(splitLinkHref[1])){

                addEvent(link, 'click', startScroll);

            }

        }

    }



    function startScroll(event){

        // リンクのデフォルト動作を殺す

        if(event){ // モダンブラウザ

            event.preventDefault();

            //alert('modern');

        }else if(window.event){ // IE

            window.event.returnValue = false;

            //alert('ie');

        }

        // thisは呼び出し元になってる

        setScroll(this.hash);

    }



    function setScroll(hash){

        // ハッシュからターゲット要素の座標をゲットする

        var targetEle = d.getElementById(hash.substr(1));

        if(!targetEle)return;

        // スクロール先座標をセットする

        var ele = targetEle

        var x = 0;

        var y = 0;

        while(ele){

            x += ele.offsetLeft;

            y += ele.offsetTop;

            ele = ele.offsetParent;

        }

        targetX = x;

        targetY = y;

        targetHash = hash;

        // スクロール停止中ならスクロール開始

        if(!scrolling){

            scrolling = true;

            scroll();

        }

    }



    function scroll(){

        var currentX = d.documentElement.scrollLeft||d.body.scrollLeft;

        var currentY = d.documentElement.scrollTop||d.body.scrollTop;

        var vx = (targetX - currentX) * easing;

        var vy = (targetY - currentY) * easing;

        var nextX = currentX + vx;

        var nextY = currentY + vy;

        if((Math.abs(vx) < 1 && Math.abs(vy) < 1)

           || (prevX === currentX && prevY === currentY)){

            // 目標座標付近に到達していたら終了

            scrollTo(targetX, targetY);

            scrolling = false;

            location.hash = targetHash;

            prevX = prevY = null;

            return;

        }else{

            // 繰り返し

            scrollTo(parseInt(nextX), parseInt(nextY));

            prevX = currentX;

            prevY = currentY;

            var scope = this;

            setTimeout(function(){scroll.apply(scope)},interval);

        }

    }



}());



