/**
    Obiekt do tworzenia, usuwania, przechwytywania Eventow. 
    Ujednolica nazewnictwo wiekszosci wlasciwosci Eventu (jezeli chodzi o Mozille i IE)
    przypisz do zmiennej 'e' metode 'getEvent' w funkcji/metodzie obslugujacej event aby uzyskac ten efekt.
    autor: pio
    le: 10:04 2008-08-11 by pio
*/

var Event = {  
    addEvent: function (obj, type, fn) {
    	if (obj.addEventListener)
    		obj.addEventListener(type, fn, false);
    	else if (obj.attachEvent) {
    		obj["e"+type+fn] = fn;
    		obj[type+fn] = function() { obj["e"+type+fn](window.event); }
    		obj.attachEvent("on"+type, obj[type+fn]);
    	}
        return fn; // zwraca funkcje, zeby mozna bylo usunac event w przypadku funkcji anonimowej
    },

    removeEvent: function (obj, type, fn) {
    	if (obj.removeEventListener)
    		obj.removeEventListener(type, fn, false);
    	else if (obj.detachEvent) {
    		obj.detachEvent("on"+type, obj[type+fn]);
    		obj[type+fn] = null;
    		obj["e"+type+fn] = null;
    	}
    },
    
    getEvent: function () {
    	if (window.event) {
    		return this._formatEvent(window.event);
    	} else {
    		return Event.getEvent.caller.arguments[0];
    	}
    },
    
    _ie: function() {
    	return (document.all && !window.opera);
    },
    
    _formatEvent: function(e) {
        if (this._ie() == true) {
        	e.charCode = (e.type == "keypress") ? e.keyCode : 0;
            e.eventPhase = 2;
            e.isChar = (e.charCode > 0);
            e.pageX = e.clientX + document.body.scrollLeft;
            e.pageY = e.clientY + document.body.scrollTop;
            e.target = e.srcElement;
            e.preventDefault = function () { this.returnValue = false; };
            e.stopPropagation = function () { this.cancelBubble = true; };
            e.timeStamp = (new Date).getTime();
            if (e.type == "mouseout") {
            	e.relatedTarget = e.toElement;
            } else if (e.type == "mouseover") {
                e.relatedTarget = e.fromElement;
            }
        }
        return e;
    }    
};



/** 
    pio: opis na stronie http://dean.edwards.name/weblog/2006/03/base/
    Generalnie klasa dzieki ktorej mozemy pobawic sie OOP w JS'sie, czyli przyjemne tworzenie klas, obsluga dziedziczenia itd.
*/
/*
	Base.js, version 1.1
	Copyright 2006-2007, Dean Edwards
	License: http://www.opensource.org/licenses/mit-license.php
*/
var Base=function(){};Base.extend=function(_instance,_static){var extend=Base.prototype.extend;Base._prototyping=true;var proto=new this;extend.call(proto,_instance);delete Base._prototyping;var constructor=proto.constructor;var klass=proto.constructor=function(){if(!Base._prototyping){if(this._constructing||this.constructor==klass){this._constructing=true;constructor.apply(this,arguments);delete this._constructing;}else if(arguments[0]!=null){return(arguments[0].extend||extend).call(arguments[0],proto);}}};klass.ancestor=this;klass.extend=this.extend;klass.forEach=this.forEach;klass.implement=this.implement;klass.prototype=proto;klass.toString=this.toString;klass.valueOf=function(type){return(type=="object")?klass:constructor.valueOf();};extend.call(klass,_static);if(typeof klass.init=="function")klass.init();return klass;};Base.prototype={extend:function(source,value){if(arguments.length>1){var ancestor=this[source];if(ancestor&&(typeof value=="function")&&(!ancestor.valueOf||ancestor.valueOf()!=value.valueOf())&&/\bbase\b/.test(value)){var method=value.valueOf();value=function(){var previous=this.base||Base.prototype.base;this.base=ancestor;var returnValue=method.apply(this,arguments);this.base=previous;return returnValue;};value.valueOf=function(type){return(type=="object")?value:method;};value.toString=Base.toString;}
this[source]=value;}else if(source){var extend=Base.prototype.extend;if(!Base._prototyping&&typeof this!="function"){extend=this.extend||extend;}
var proto={toSource:null};var hidden=["constructor","toString","valueOf"];var i=Base._prototyping?0:1;while(key=hidden[i++]){if(source[key]!=proto[key]){extend.call(this,key,source[key]);}}
for(var key in source){if(!proto[key])extend.call(this,key,source[key]);}}
return this;},base:function(){}};Base=Base.extend({constructor:function(){this.extend(arguments[0]);}},{ancestor:Object,version:"1.1",forEach:function(object,block,context){for(var key in object){if(this.prototype[key]===undefined){block.call(context,object[key],key,object);}}},implement:function(){for(var i=0;i<arguments.length;i++){if(typeof arguments[i]=="function"){arguments[i](this.prototype);}else{this.prototype.extend(arguments[i]);}}
return this;},toString:function(){return String(this.valueOf());}});


/**
    * author: pio
    * Klasa do nawigacji 'zakladkowej' -  nawigacja opiera sie na hash'ach w linkach, ktore musza byc rowne ID elemenu na ktory wskazuja.
    * Last edited: 2008.07.16 12:00 by pio
    * @parm sNavId - string (wymagany) - ID elementu ul lub wyzszego, zawierajacego linki (a)
    * @parm sActiveClassName - string (niewymagany) - nazwa klasy linku aktywnego
    * @parm sDisplayNoneClassName - string (niewymagany) - nazwa klasy dla ukrywania elementow (np. .hide), bez niej ukrywanie bedzie sie opierac na display:none
    * @parm bAllowAdressNav - true/false (niewymagany, domyslnie false) - jezeli true to dodaje do adresu hashe, jak rowniez znienia elementy docelowe w zaleznosci od hasha w adresie
    * @parm aTargets - (niewymagany) tablica id'kow jezeli ma byc mniej niz wszystkie
*/
function TabNavigation(sNavId, sActiveClassName, sDisplayNoneClassName, bAllowAdressNav, aTargets) {
    this.sNavId = sNavId;
    this.sActiveClassName = sActiveClassName;
    this.sDisplayNoneClassName = sDisplayNoneClassName;
    this.bAllowAdressNav = bAllowAdressNav || false;
    this.aTargets = aTargets || new Array();
    this.sDefaultTarget = new String;
    this.useParentElement = new Boolean; // ustaw na true, jezeli klasa 'sActiveClassName' ma byc nadawana rodzicowi linka (np. elementowi li)
}

TabNavigation.prototype.init = function () {
    var nav = document.getElementById(this.sNavId); if (!nav) return;
    var aAnchors = nav.getElementsByTagName("a");
    var obj = this;
    var tmp = this.aTargets.length;
    var aAnchorsTmp = new Array();

    for (var i = 0; i < aAnchors.length; i++) {
        if (aAnchors[i].hash && aAnchors[i].hash != '#') {
            // ustawia sDefaultTarget, gdy jakis link ma nadana klase sActiveClassName
            if (this.sActiveClassName && this._isClass(this._elementWidthClass(aAnchors[i]), this.sActiveClassName) == true)
                this.sDefaultTarget = aAnchors[i].hash.substring(1);
            
            // tworzona jest tablica sTargetow na podstawie hasha w linkach, jezeli nie zrobiono tego recznie
            if (tmp == 0)
                this.aTargets.push(aAnchors[i].hash.substring(1));
            
            // tworzony jest sTarget, gdy jest hash w url'u
            if (window.location.hash && window.location.hash == aAnchors[i].hash) 
                var sTarget = window.location.hash.substring(1);
            
            aAnchors[i].onclick = function(e) {
                obj._run(this.hash.substring(1), aAnchors, true, e);
            }
            aAnchorsTmp.push(aAnchors[i].hash.substring(1)); 
        }
    }
    
    if (this.sDefaultTarget == '') 
        this.sDefaultTarget = aAnchorsTmp[0];

    //jezeli sTarget dostajemy z url'a
    if (sTarget && this.bAllowAdressNav == true)
        this._run(sTarget);
    // jezeli sTarget dostajemy na podstawie domyslnego linka
    else if (this.sDefaultTarget != '')
        this._run(this.sDefaultTarget, aAnchors);
};


TabNavigation.prototype._run = function (sTarget, aAnchors, click, e) {
    // return false dla klikniecia
    if (click) {
        if (!e) e = window.event;
        if (e.preventDefault) 
            e.preventDefault(); 
        else 
            e.returnValue = false;         
    }
    
    // nadawanie linkom klas
    for (var i = 0; i < aAnchors.length; i++) {
        if (aAnchors[i].hash == "#" + sTarget) {
            this._addClass(this._elementWidthClass(aAnchors[i]), this.sActiveClassName);
        } else {
            this._removeClass(this._elementWidthClass(aAnchors[i]), this.sActiveClassName);
        }
    }
    
    // pokazywanie i ukrywanie tresci
    for (var i=0; i<this.aTargets.length; i++) {
        // jezeli hash klikniety lub podany w url'u jest rowny jednemu z id'kow
        if (sTarget == this.aTargets[i]) {
            // jezeli istniej docelowy element - to go pokazuje
            if (document.getElementById(this.aTargets[i]))
                this._show(document.getElementById(this.aTargets[i]), this.sDisplayNoneClassName);
            // jezeli nie ma docelowego elementu - pokazuje domyslny
            else if (this.sDefaultTarget)
                this._show(document.getElementById(this.sDefaultTarget), this.sDisplayNoneClassName);
        }
        // ukrywa wszystkie pozostale
        else {
            if (document.getElementById(this.aTargets[i])) 
                this._hide(document.getElementById(this.aTargets[i]), this.sDisplayNoneClassName);
        }
    }
    
    // zmienianie adresu
    if (this.bAllowAdressNav == true)
        window.location.replace("#" + sTarget);
};

TabNavigation.prototype._elementWidthClass = function (el) {
    if (this.useParentElement == true)
        return el.parentNode;
    else
        return el;
};

TabNavigation.prototype._show = function (el, cl) {
    if (!cl) {
        el.style.display = "block";
    } else {
	    this._removeClass(el, cl);
    }       
};

TabNavigation.prototype._hide = function (el, cl) {
    if (!cl) {
        el.style.display = "none";
    } else {
	    this._addClass(el, cl);
    }       
};

TabNavigation.prototype._addClass = function (el, cl) {
    if (!el.className.match(new RegExp("" + cl + "", "i")))
        el.className += (el.className ? " " : "") + cl;
};

TabNavigation.prototype._isClass = function (el, cl) {
    if (el.className.match(new RegExp("" + cl + "", "i")))
        return true;
    else
        return false;
};

TabNavigation.prototype._removeClass = function (el, cl) {
    el.className = el.className.replace(new RegExp(" \\b" + cl + "\\b|\\b" + cl + "\\b ?", "gi"), "");
};


