/**
    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;
    }    
};

var Cookie = {  
    /**
    *   @parm name - string - required
    *   @parm val - string - required (do utworzenie) - kiedy null - ciacho usuwane
    *   @parm sec - integral - czas w sekundach kiedy ciacho wygasa (kiedy null - ciacho istnieje tylko w sesji)
    */
    set: function(name, val, sec) {
        if (val) {
            document.cookie = name + "=" + escape (val) +
                ((sec) ? "; expires=" + this._time(sec): "");
        } else if (this.get(name)) {
            document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
        }
    },
    
    get: function(name) {
        var arg = name + "=";
        var aLen = arg.length;
        var cLen = document.cookie.length;
        var i = 0;
        while (i < cLen) {
            var j = i + aLen;
            if (document.cookie.substring(i, j) == arg) {
                return this._getValue(j);
            }
            i = document.cookie.indexOf(" ", i) + 1;
            if (i == 0) break; 
        }
        return null;   	
    },
    
    _time: function(i) {
        if(!i) var i = 0;
        else i = i*1000;
    	var expDate = (new Date).getTime();
        expDate = expDate + i;
        var newDate = new Date(expDate);
        return newDate.toGMTString();
    },
    
    _getValue: function(offset) {
        var end = document.cookie.indexOf (";", offset);
        if (end == -1) {
            end = document.cookie.length;
        }
        return unescape(document.cookie.substring(offset, end));
    }    
};

/** 
    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 aTargets - (niewymagany) tablica id'kow jezeli ma byc mniej niz wszystkie
*/
var TabNavigation = Base.extend({
    constructor: function(sNavId, sActiveClassName, sDisplayNoneClassName, aTargets) {
        this.sNavId = sNavId;
        this.sActiveClassName = sActiveClassName || '';
        this.sDisplayNoneClassName = sDisplayNoneClassName;
        this.aTargets = aTargets || [];
        this.sDefaultTarget = '';
        this.useParentElement = false; // ustaw na true, jezeli klasa 'sActiveClassName' ma byc nadawana rodzicowi linka (np. elementowi li)    	
    },
    
    init: function() {
        var nav = document.getElementById(this.sNavId); if (!nav) return;
        var aAnchors = nav.getElementsByTagName("a");
        if (aAnchors.length == 0) return;
        
        var This = 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 && isClassName(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));

                aAnchors[i].onclick = function(e) {
                    This._run(this.hash.substring(1), aAnchors, true, e);
                }
            }
        }
        
        if (this.sDefaultTarget == '') 
            this.sDefaultTarget = aAnchors[0].hash.substring(1);

        if (this.sDefaultTarget != '')
            this._run(this.sDefaultTarget, aAnchors);    	
    },
    
    _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
        if (this.sActiveClassName != '') {
            for (var i = 0; i < aAnchors.length; i++) {
                if (aAnchors[i].hash == "#" + sTarget) {
                    addClassName(this._elementWidthClass(aAnchors[i]), this.sActiveClassName);
                } else {
                    removeClassName(this._elementWidthClass(aAnchors[i]), this.sActiveClassName);
                }
            }
        }
        
        // pokazywanie i ukrywanie tresci
        for (var i=0; i<this.aTargets.length; i++) {
            // jezeli hash klikniety jest rowny jednemu z id'kow
            if (sTarget == this.aTargets[i]) {
                if (document.getElementById(this.aTargets[i]))
                    this._show(document.getElementById(this.aTargets[i]), this.sDisplayNoneClassName);
                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);
            }
        }
    },
    
    _elementWidthClass: function(el) {
        if (this.useParentElement == true)
            return el.parentNode;
        else
            return el;    	
    },
    
    _show: function(el, cl) {
        if (!cl) {
            el.style.display = "block";
        } else {
    	    removeClassName(el, cl);
        }          	
    },
    
    _hide: function(el, cl) {
        if (!cl) {
            el.style.display = "none";
        } else {
    	    addClassName(el, cl);
        }          	
    }
});


/**
	klasa dodajaca 'onchange' do selectow na nowej rezerwacji, ktore przeladowuja formularz
    a: pio
    le: 16:49 2008-08-14 by pio
    * @parm oTriggers - patrz plik init.js na sunfunie
*/
var ReservActualisation = Base.extend({
    constructor: function(oForm, oTriggers) {
    	this.oForm = oForm;
    	this.oTriggers = oTriggers;
        this.aFields = [];
    },

    init: function() {
        var This = this;
        this._getFields();

        for (var i=0; i<this.aFields.length; i++) {
        	Event.addEvent(this.aFields[i], 'change', function(e) {
        		This._handleChange(e);
        	});
        }
    },
    
    _getFields: function() {
        var iNumRooms = 1;
        
        //zmienne
        if (this.oTriggers.zmienne.room)
            iNumRooms = this._getNumRooms(this.oTriggers.zmienne.room[0]);
        
        for (var key in this.oTriggers.zmienne) {
            for (var i=0; i<this.oTriggers.zmienne[key].length; i++) {
                for (var j=0; j<iNumRooms; j++) {
                    if (this.oForm[key+'['+j+']['+this.oTriggers.zmienne[key][i]+']'] != null)
                        this.aFields.push(this.oForm[key+'['+j+']['+this.oTriggers.zmienne[key][i]+']']);
                }
            }
        }
        
        //stale
        for (var i=0; i<this.oTriggers.stale.length; i++) {
        	this.aFields.push(this.oForm[this.oTriggers.stale[i]]);
        }
    },

    _getNumRooms: function(s) {
        var i = 0;
        while (this.oForm['room['+i+']['+s+']'] != null) {
            i++;
        }
        return i;
    },
    
    _handleChange: function() {
        var input = document.createElement('input');
        input.type = 'hidden';
        input.name = 'update';
        input.value = '1';
        this.oForm.appendChild(input);   
        
        this.oForm.submit();
    }
});

/**
    * Klasa do koszyka / schowka  - wykorzystujaca ajaxa
    * a: pio
    * le: 16:35 2008-08-26 by pio    
    * @parm sCheckboxCN - string - className checkbox'a ktory ma dodawac lub usuwac z koszyka oferty
    * @parm sRemoveLinkCN - string - klasa elementu (odnosnika) ktory w widoku schowka ma usuwac z niego elementy - UWAGA - musi miec poprawny atrybut HREF
    * @parm przedrostek - string - przedrostek atrybutu ID checkboxa - po nim ma byc  kod do usuniecia (np. basket_123123;12312;11 - przedrostek: basket_)
    * @parm oMsgConfig - obiekt - konfiguracja pojawiajacego sie komunikatu np.:
        {item: 'div', 
        css: {border: '1px solid #ccc', background: '#fff', padding: '1em', position: 'absolute'}, 
        time: 1000}  // milisekundy po ktorych wiadomosc jest usuwana     
    * @parm oTxt - obiekt - tresc pojawiajacego sie komunikatu, np: 
        {add: 'dodano do schowka',
        remove: 'usunieto ze schowka'}
*/
var Basket = Base.extend({
    constructor: function(sCheckboxCN , sRemoveLinkCN, przedrostek, oMsgConfig, oTxt) {
    	this.sCheckboxCN = sCheckboxCN;
        this.sRemoveLinkCN = sRemoveLinkCN;
        this.przedrostek = przedrostek;
        this.oMsgConfig = oMsgConfig;
        this.oTxt = oTxt;
        this.aChecks = [];
        this.aReoveLinks = [];
    },

    init: function() {
    	this._getChecks();
        this._getRemoveLinks();
        if (this.aChecks.length > 0) {
            this._addEventToChecks();
        }
        if (this.aReoveLinks.length > 0) {
        	this._addEventToRemoveLinks();
        }
    },
    
    _addEventToChecks: function() {
    	var This = this;
        for (var i=0; i<this.aChecks.length; i++) {
            Event.addEvent(this.aChecks[i], 'click', function(e) {
            	This._handleEvent(e, This._getOfferCodeFromId(this.id));
            });
        }
    },

    _addEventToRemoveLinks: function() {
    	var This = this;
        for (var i=0; i<this.aReoveLinks.length; i++) {
            Event.addEvent(this.aReoveLinks[i], 'click', function(e) {
            	This._handleRLEvent(e, This._getOfferCodeFromHref(this.href));
            });
        }    	
    },   
    
    _handleEvent: function(e, offerCode) {
        var This = this;
        var e = Event.getEvent();
        var sOperation;
        var oSendData = {};
        oSendData.node = e.target;
        oSendData.This = this;
        oSendData.text = this.oTxt;

    	if (e.target.checked) {
    		sOperation = 'add';
    	} else {
    		sOperation = 'delete';
    	}
              
                
        Ajax.addToQueue('turystyka_koszyk', 1, {offer: offerCode, oper: sOperation}, oSendData, This._sendRequestHandle);
    },
    
    _sendRequestHandle: function(oSendData, aResponse, sResponse) {
    	if (aResponse['state'] != 0) {
            var oItem = {};
            oItem.parent = oSendData.node.parentNode;
            
            if (aResponse['state'] == 'add') {
                oItem.content = document.createTextNode(oSendData.text.add);
            } else {
                oItem.content = document.createTextNode(oSendData.text.remove);
            }
    		
            var msg = new Komunikat(oItem, oSendData.This.oMsgConfig);
            msg.flash(oSendData.This.oMsgConfig.time);
    	}
    },

    _handleRLEvent: function(e, offerCode) {
        var This = this;
        var e = Event.getEvent();
        e.preventDefault();
        var sOperation = 'delete';
        var oSendData = {};
        oSendData.node = e.target;
        oSendData.This = this;
        
        Ajax.addToQueue('turystyka_koszyk', 1, {offer: offerCode, oper: sOperation}, oSendData, This._sendDeleteRequestHandle);
    },
    
    _sendDeleteRequestHandle: function(oSendData, aResponse, sResponse) {
    	if (aResponse['state'] == 'del') {
            oSendData.This._removeRow(oSendData.node);
        }
    },
    
    _removeRow: function(o) {
    	while(o.tagName.toLowerCase() != 'tr') {
    		o = o.parentNode;
    	}
        
        if (o.parentNode.getElementsByTagName('tr').length > 1)
            o.parentNode.removeChild(o);
        else {
        	while(o.tagName.toLowerCase() != 'table') {
        		o = o.parentNode;
        	}
            
            o.parentNode.removeChild(o);
        }
    },
    
    _getOfferCodeFromId: function(s) {
        var res = s.match(new RegExp("" + this.przedrostek + "(.+)", "i"));
        if (!res) return false;
        return res[1];
    },
    
    _getOfferCodeFromHref: function(s) {
        var res = s.match(new RegExp("del=(.+)", "i"));
        if (!res) return false;
        return res[1];    	
    },
    
    _getChecks: function() {
    	var aTmp = document.getElementsByTagName('input');
        for (var i=0; i<aTmp.length; i++) {
        	if (isClassName(aTmp[i], this.sCheckboxCN) && this._getOfferCodeFromId(aTmp[i].id) != false) {
        		aTmp[i].disabled = false;
                this.aChecks.push(aTmp[i]);
        	}
        }
    },
    
    _getRemoveLinks: function() {
    	var aTmp = document.getElementsByTagName('a');
        for (var i=0; i<aTmp.length; i++) {
        	if (isClassName(aTmp[i], this.sRemoveLinkCN) && this._getOfferCodeFromHref(aTmp[i].href) != false) {
                this.aReoveLinks.push(aTmp[i]);
        	}
        }
    }
});

/**
    * to miala byc generalnie klasa pomocnicza do klasy Basket, ale mozna ja jeszcze rozbudowac i wykorzystac gdzie indziej
    * @parm oItem - obiekt : 
        {parent: el, // document obiekt - wiadomosc bedzie wstawiona jako dziecko tego elementu
        content: el} // document obiekt - tresc wiadomosci (np. textNode)
    * @parm oConfig - obiekt: 
        {css: ob, // obiekt css np {padding: '0px'}
        attributes: ob} // obiekt atrybutow np {id: 'dupa', className: 'dupablada'}
*/
var Komunikat = Base.extend({
    constructor: function(oItem, oConfig) {
    	this.oConfig = oConfig;
        this.oItem = oItem
        this.el = {};
        this._create();
    },
    
    _create: function() {
        if (!this.oItem.content || !this.oItem.parent) return;
        var sTmp = (this.oItem.item) ? this.oItem.item : 'div'; 
        this.el = document.createElement(sTmp);
    
        if (this.oConfig.css) {
            for (var key in this.oConfig.css) {
                this.el.style[key] = this.oConfig.css[key];
            }
        }
        
        if (this.oConfig.attributes) {
            for (var key in this.oConfig.attributes) {
                this.el[key] = this.oConfig.attributes[key];
            }
        }

        this.el.appendChild(this.oItem.content);
    },
    
    flash: function(time) {
        if (!time) time = 1000;
        var This = this;
        this.oItem.parent.appendChild(this.el);
        this.TimeoutID = setTimeout(function () {This.hide();}, time);
    },    
    
    hide: function() {
    	this.oItem.parent.removeChild(this.el);
    }
});

/**
    * Klasa do newslettera
    * a: pio
    * le: 10:42 2008-08-29 by pio
    * @parm sNewsletterPriceSpliter - string - niewymagany - standardowo 'spacja'
    * dziala przy dominatorze 2.3*
*/
var Newsletter = Base.extend({
    constructor: function(sNewsletterPriceSpliter) {
    	this.sNewsletterPriceSpliter = sNewsletterPriceSpliter || ' ';
        this.aLinks = [];
    },
    
    init: function() {
    	this._getLinks();
        if (this.aLinks.length == 0) return;
        var This = this;
        
        if (window.opener && window.opener.addNewsletterOffer)  {
            for (var i=0; i<this.aLinks.length; i++) {
            	this.aLinks[i].style.display = 'inline';
                Event.addEvent(this.aLinks[i], 'click', function(e) {
                	This._sendToNewsletter(e, this.getAttribute('newsletter'));
                });
            }
        } else {
            for (var i=0; i<this.aLinks.length; i++) {
            	this.aLinks[i].style.display = 'none';
            }
        }
    },
    
    _sendToNewsletter: function(e, sValue) {
    	var e = Event.getEvent();
        e.stopPropagation();
        
        var aPricePosition = [5,13];
        for (var i=0; i<aPricePosition.length ; i++) {
            var iPrice = sValue.split('||_')[aPricePosition[i]].toString();
            if (iPrice.match(/^\s*[0-9]+\s*$/)) {
                var sNewPrice = '';
                for (var j=1; j<=iPrice.length; j++) {
                    sNewPrice = iPrice.charAt(iPrice.length-j) + sNewPrice;
                    if (j % 3 == 0 && j < iPrice.length)
                        sNewPrice = this.sNewsletterPriceSpliter + sNewPrice;
                }
                sValue = sValue.replace(iPrice, sNewPrice);
            }
        }

        var bReturn = window.opener.addNewsletterOffer(sValue);
        if ( bReturn == -1) {
            if (confirm('Podobna oferta już została dodana, mimo to kontynuować ?')) {
                bReturn = window.opener.addNewsletterOffer(sValue, true);
            } else {
                return false;
            }
        } else if (bReturn == 1) {
            alert('Oferta została dodana do biuletynu.');
            return false;        
        } else {
            alert('Wystąpił błąd podczas dodawania oferty.');
            return true;
        }        
    },
    
    _getLinks: function() {
    	var aTmp = document.getElementsByTagName('a');
        for (var i=0; i<aTmp.length; i++) {
        	if (aTmp[i].getAttribute('newsletter')) {
        		this.aLinks.push(aTmp[i]);
        	}
        }
    }
});


/**
    * Klasa do tworzenia ladnego urla dla wyszukiwarki; metoda wywolujaca 'initSearch';
    * po kliknieciu szukaj zamienia wartosci pol formularzy na poprawny string url'a
    * a: pio
    * le: 10:44 2008-08-29 by pio
*/
var FriendlyURL = Base.extend({
    constructor: function() {
    	this.aForms = []; // tablica obiektow formularzy
    },
    
    /**
        * @parm aFormsIds - tablica id'kow formularzy np. ['step1', 'step1a']
    */
    initSearch: function(aFormsIds) {
        var This = this;        
        
        this._getForms(aFormsIds);
        if (this.aForms.length == 0) return;
                
        for (var i=0; i<this.aForms.length; i++) {                
            Event.addEvent(this.aForms[i], "submit", function(e) {
                This._createSearchUrl(e, "http://" + window.location.hostname + "/", this);                    
            });
        }    	
    },
    
    _getForms: function(aFormsIds) {
    	for (var i=0; i<aFormsIds.length; i++) {
            if (document.getElementById(aFormsIds[i])) {
                this.aForms.push(document.getElementById(aFormsIds[i]));
            }
    	}
    },
    
    _createSearchUrl: function(e, urlSite, oForm) {
    	var e = Event.getEvent();
        e.preventDefault();
        
        var form = new Form(oForm);
        
        var sVars = '', sBegin, bTmp;
        for (var i=0; i<form.aElements.length; i++) {
        	if (form.aElements[i].name == 'pidName') {
                sBegin = form.aElements[i].value + '.html';
            } else {
            	sVars += ((!bTmp) ? '?' : '&') + form.aElements[i].name + '=' + form.aElements[i].value;
                bTmp = 1;
            }        	
        }
        document.location.href = urlSite + sBegin + sVars;
    }
});


/**
    * Klasa ulatwiajaca pobieranie i ustawianie wartosci pol formularzy
    * autor: pio
    * le: 16:45 2008-08-31 by pio
    * @parm oForm - obiekt formularza
*/
var Form = Base.extend({
    constructor: function(oForm) {
        this.oForm = oForm;
        this.aElements = []; // utowrzony obiekt zwraca ta tablice (obiektow formularza)
        this.getElements();
    },
    
    /**
        * @return - array - tablica obiektow {obj: DOMElement, name: 'FildName', value: 'FildValue'}
    */
    getValues: function(aNames) {
    	return this.aElements;
    },
    
    /**
        * @parm sName - nazwa pola
        * @return - object - {obj: DOMElement, name: 'FildName', value: 'FildValue'}
    */    
    getValue: function(sName) {
        for (var i=0; i<this.aElements.length; i++) {
    		if (this.aElements[i].name == sName) 
                return this.aElements[i];
    	}
        return false;
    },
    
    /**
        * @parm a - array - tablica obiektow {name: 'FildName', value: 'FildValue'}
        * @return - void
    */    
    setValues: function(a) {
    	if (!a) return;
        for (var i=0; i<a.length; i++) {
        	for (var j=0; j<this.aElements.length; j++) {
                if (a[i].name == this.aElements[j].name) {
            		this.aElements[j].value = a[i].value;
            	}
            }
        }
        this._setValues();
    },
    
    /**
        * przepisuje wartosci pol formularza do tablicy aElements;
        * mozna traktowac ta funkcje jako 'odswiezacz'
    */
    getElements: function() {
        var aNames = [];
        var aEl = this.oForm.elements;
        
        add: for (var i=0; i<aEl.length; i++) {
            for (var j=0; j<aNames.length; j++) {
                if (aEl[i].name == aNames[j]) {
                   continue add;
                }
            }
            aNames.push(aEl[i].name);
        }
        
        for (var i=0; i<aNames.length; i++) {
            var o = {};
            o.obj = this.oForm[aNames[i]];
            o.name = aNames[i];
            o.value = this._getValue(o.obj);
            this.aElements[i] = o;
        }
    },      
    
    _setValues: function() {
    	for (var i=0; i<this.aElements.length; i++) {
    		switch (this.aElements[i].obj.type) {
                case 'checkbox':
                    if (this.aElements[i].value == 0 || this.aElements[i].value == '') {
                        this.aElements[i].obj.checked = false;
                    } else {
                        this.aElements[i].obj.checked = true;
                    }
                    break;
                case undefined: // radio
                    for (var j=0; j<this.aElements[i].obj.length; j++) {
                    	if (this.aElements[i].obj[j].value == this.aElements[i].value) {
                            this.aElements[i].obj[j].checked = true;
                    	}
                    }
                    break;
                default: 
                    this.aElements[i].obj.value = this.aElements[i].value;
    		}
    	}
    },  
    
    _getValue: function(o) {
        switch (o.type) {
            case 'checkbox':
                if (o.checked == true) {
                    return o.value;
                } else {
                	return 0;
                }
                break;
            case undefined: // radio
                for (var j=0; j<o.length; j++) {
                    if (o[j].checked == true) {
                        return o[j].value;
                    }
                }    
                break;
            default: 
                return o.value;
        }    	
    }
});