﻿/**
 *  hamutab.js with XPath
 *  var 1.3.1
 * 
 * Copyright (c) 2009 nagasakihamu.net
 * 
 * このソースは以下のライセンスにて配布します。
 * MIT License :
 * 米: http://www.opensource.org/licenses/mit-license.php
 * 日: http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license
 * 
 */
(function () {

//	スイッチタブには class 属性に "hamu-tab" を追加
//	表示させる領域には class 属性に "hamu-page" を追加
//	スイッチタブと表示領域はそれぞれの順番に対応して切り替わる。


//	XPathを利用したタブ切替js
//	Safari ３系,Firefox ２系, Opera ９系は DOM 3 XPath は実装されている。
//	Safari ２系 と IE6 , IE7 は DOM 3 XPath が実装されていないのでjavascript-XPath.jsを利用。

// hamutab
var hamutab = window.hamutab = {
    general: {
        tabClassName: "hamu-tab",
        pageClassName: "hamu-page",
        addClassPresent : true,
        addClassName: "present",
        speed : 50,
        initAlpha : 0
    },
    
    init: function(){
        // hamutab.setting が設定されていない場合は空のオブジェクトを代入
        if(!hamutab.setting){
            hamutab.setting = {};
        }
        // hamutab.setting の設定があればその値を、なければデフォルト値を代入
        hamutab.tabClassName = hamutab.setting.tabClassName || hamutab.general.tabClassName;
        hamutab.pageClassName = hamutab.setting.pageClassName || hamutab.general.pageClassName;
        hamutab.addClassPresent = (hamutab.setting.addClassPresent === false) ? false : hamutab.general.addClassPresent;
        hamutab.addClassName = hamutab.setting.addClassName || hamutab.general.addClassName;
        hamutab.speed = hamutab.setting.speed || hamutab.general.speed;
        hamutab.initAlpha = hamutab.setting.initAlpha || hamutab.general.initAlpha;
        // 変数設定
        // 要素を XPath で取得
        var tabs = hamu.AfroXPath('//*[contains(concat(" ",@class," "), " ' + hamutab.tabClassName + ' ")]', document.body);
        var pages = hamu.AfroXPath('//*[contains(concat(" ",@class," "), " ' + hamutab.pageClassName + ' ")]', document.body);
        // クラス設定用
        var tabClass;
        // 初期化開始
        for (var i=0; i<pages.length; i++) {
            // 初期設定：最初の要素以外を非表示にする
            if (i !== 0){
                pages[i].style.display = 'none';
            }
            // classPresent が true なら class属性に "present" を追加
            if (hamutab.addClassPresent){
                if (i == 0){
                    hamu.classChange.add(tabs[i], hamutab.addClassName);
                }
            }
            // IEだとリスナー設定で this の解釈が異なるため条件分けして設定
            if(hamu.checkBrowser.IE){
                tabs[i].onclick = function(event){
                    hamutab.showPage(this, tabs, pages);
                    hamu.event.stopDefaultEvent(event);
                };
            }else{
                hamu.event.addListener(tabs[i], 'click', function(event){
                    hamutab.showPage(this, tabs, pages);
                    hamu.event.stopDefaultEvent(event);
                });
            }
        }
    },
    
    showPage: function(obj, tabs, pages){
        // 変数設定
        var num;
        
        for(num=0; num<tabs.length; num++){
            if(tabs[num] === obj){
                break;
            }
        }
        
        for(var i=0; i<pages.length; i++){
            if(i == num){
                var pElm = pages[num];
                
                hamutab.ex.init(pElm, hamutab.speed, hamutab.initAlpha);
                
                // 表示させる領域のdisplayプロパティを "block" にして表示させる
                pages[num].style.display = 'block';
                
                // IEかどうかチェックしてIEならhaslayoutプロパティを有効にする
                if(hamu.checkBrowser.IE){
                    hamu.checkBrowser.setIEhaslayout(pElm);
                }
                
                if(hamutab.addClassPresent){
                    // class属性に hamutab.addClassName を追加
                    hamu.classChange.add(tabs[num], hamutab.addClassName);
                }
            }else{
                // それ以外を非表示にする
                pages[i].style.display = 'none';
                
                if (hamutab.addClassPresent) {
                    // クラス属性から hamutab.addClassName を削除
                    hamu.classChange.remove(tabs[i], hamutab.addClassName);
                }
            }
        }
    }
}

// フェードさせるエフェクト hamutab.ex 開始
hamutab.ex = {
    init: function(elm, speed, initAlpha){
        if(initAlpha < 0){
            initAlpha = 0;
        }else if(initAlpha > 10){
            initAlpha = 10;
        }
        if(speed < 10){
            speed = 10;
        }
        hamutab.ex.setEffect(elm, speed, initAlpha);
        return false;
    },
    
    setEffect: function repeatFadeIn(elm, speed, alpha){ // setTimeoutで段階的に透明度を変化
        if(alpha === 10){
            hamutab.ex.setOpacity(elm, alpha);
        }else if(alpha < 10){
            alpha += 1;
            hamutab.ex.setOpacity(elm, alpha);
            setTimeout(function(){repeatFadeIn(elm, speed, alpha)},speed);
        }
    },
    
    setOpacity: function(elm, alpha){ // 透明度をセット
        elm.style.opacity = alpha/10;
        elm.style.MozOpacity = alpha/10;
        elm.style.filter = 'alpha(opacity=' + alpha*10 + ')';
    }
} // フェードさせるエフェクト hamutab.ex 終了




// hamu の名前空間の定義
// タブ機能に直接関係しないモノを hamu に定義する
var hamu = {};

// class属性の追加・削除
hamu.classChange = {
    add : function(elm, classNameString){
        // class属性に classNameString がなければ追加
        if(!hamu.classChange.has(elm, classNameString)){
            elm.className += (elm.className ? " " : "") + classNameString;
        }
    },
    remove : function(elm, classNameString){
        var attrs;
        var myArray;
        // クラス属性から classNameString を削除
        attrs = elm.className; // 変数 attrs にclass属性を代入
        attrs = attrs.replace(classNameString, ""); // classNameString を削除
        myArray = attrs.split(/\s+/); // 半角スペースで区切られた文字列を配列で変数 myArray に代入
        attrs = myArray.join(" "); // 配列を半角スペースで結合
        elm.className = attrs; // 文字列をclass属性に代入
    },
    has : function(elm, classNameString){
        // elm の class属性に classNameString があるかどうか調べる
        if(elm){    // 念のため elm が存在しているかどうか
            var attrs = elm.className.toString().split(/\s+/);  // elm の class の属性値を文字列に変換して、空白の区切りで分割して配列にする。
            for(var i=0; i<attrs.length; i++){
                if(attrs[i] == classNameString){    // もし classNameString があったら true を返す。
                    return true;
                }
            }
        }
        return false;   // それ以外は false を返す。
    }
}
// ブラウザチェックとIE用cssセット
hamu.checkBrowser = {
    IE : !!(window.attachEvent && navigator.userAgent.indexOf("Opera") === -1),
    setIEhaslayout : function(elm){ // IEのhaslayoutプロパティを有効にするため zoom:1 を適用
        elm.style.zoom = 1;
    }
}

// イベント周りを定義
hamu.event = {
    addListener : function(elm, type, handler){
        if(elm.addEventListener){
            elm.addEventListener(type, handler, false);
        }else if(elm.attachEvent){
            elm.attachEvent("on" + type, handler);
        }
    },
    stopDefaultEvent : function(event){
        event = event || window.event;
        
        // イベントによる default 動作（ページ遷移）を無効化
        if(event.preventDefault){
            event.preventDefault();
        }else{
            event.returnValue = false;
        }
        
        // 必要であれば、イベント浮上も止める
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
}

// to Array from XPath "AfroXPath" を定義
hamu.AfroXPath = function(expression, parentElement){
    var toArray = [];
    var fromXPath = document.evaluate(expression, parentElement || document , null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE ,null);
    for (var i=0; i < fromXPath.snapshotLength; i++) {
        toArray.push(fromXPath.snapshotItem(i));
    }
    return toArray;
}

hamu.event.addListener(window, 'load', hamutab.init);

})();       // 匿名関数の定義が終了したので、すぐに呼び出す。

