/**
    * Klasa do nawigacji 'zakladkowej' -  nawigacja opiera sie na hash'ach w linkach, ktore musza byc rowne ID elemenu na ktory wskazuja.
    * Last edited: 14:03 2008-11-03 by pio
    * @parm oConfig - obiekt
*/
var TabNavigation2 = new Class({
    initialize: function(oConfig) {
        this.sNavId = oConfig.sNavId;
        this.sActiveClassName = oConfig.sActiveClassName || '';
        this.sDisplayNoneClassName = oConfig.sDisplayNoneClassName;
        this.bAddClassToParentElement = oConfig.bAddClassToParentElement || 0; // ustaw na true, jezeli klasa 'sActiveClassName' ma byc nadawana rodzicowi linka (np. elementowi li)    	
        this.aCustomElements = oConfig.aCustomElements;    
        this.prefix = oConfig.prefix || '';
            
        this.aItems = [];
        this.oActive;
    },
    
    init: function() {
        this.getItemsFromAnchors();
    	this.getItemsFromCustomElements();
        if (this.aItems.length == 0) return;
        
        this.addEvent();
        this.getActive();
        this.run();
    },
    
    run: function() {
        this.aItems.each(function(item, i) {
        	if (item == this.oActive) {
                this._show(item.target);
                if (this.sActiveClassName != '')
                    item.elWithClass.addClass(this.sActiveClassName);
                if (this.prefix != '')
                    location.hash = '#' + item.prefix + item.target.id;
            } else {
            	this._hide(item.target);
                if (this.sActiveClassName != '')
                	item.elWithClass.removeClass(this.sActiveClassName);
            }
        }, this);
    },
    
    addEvent: function() {
    	var This = this;
        this.aItems.each(function(el, i) {
        	el.el.addEvent('click', function(e) {
        		This.handleEvent(e, el);
        	});
        });
    },
    
    handleEvent: function(e, oItem) {
        e.stop();
        this.oActive = oItem;
        this.run();
    },
   
    getItemsFromAnchors: function() {
        $(this.sNavId).getElements('a').each(function(el, i) {
            var id = el.hash.substring(1);
            var targetEl = $(id);
            
            if (targetEl) {
                this.aItems.push({
                    el: el,
                    target: targetEl,
                    prefix: this.prefix,
                    elWithClass: ((this.bAddClassToParentElement) ? el.getParent() : el)
                });
            }           
        }, this);    
    },
    
    getItemsFromCustomElements: function() {
    	if (!this.aCustomElements || this.aCustomElements.length == 0) return;
        this.aCustomElements.each(function(el, i) {
            this.aItems.push({
                el: $(el.el),
                target: $(el.target),
                prefix: (el.prefix) ? el.prefix : '',
                elWithClass: ((el.elWidthClass) ? el.elWidthClass : $(el.el))
            });
        }, this);
    },
    
    getActive: function() {
        var hash = window.location.hash.substring(1);
        if (hash != '') {
        	for (var i=0; i<this.aItems.length; i++) {
                if (this.aItems[i].prefix + this.aItems[i].target.id == hash) {
                    this.oActive = this.aItems[i];
                    return;
                }
    		}
        }
        
        if (this.sActiveClassName != '') {
    		for (var i=0; i<this.aItems.length; i++) {
                if (isClassName(this.aItems[i].elWithClass, this.sActiveClassName)) {
                    this.oActive = this.aItems[i];
                    break;
                }
    		}
    	} else {
    		this.oActive = this.aItems[0];
    	}
    },
       
    _show: function(el) {
        if (!this.sDisplayNoneClassName)
            el.style.display = "block";
        else
    	    el.removeClass(this.sDisplayNoneClassName);
    },
    
    _hide: function(el) {
        if (!this.sDisplayNoneClassName)
            el.style.display = "none";
        else
    	    el.addClass(this.sDisplayNoneClassName);
    }
});

/**
 * 18:43 2008-11-11 /pio
 */
var CountTrips = new Class({
    Implements: Options,
    options: {
        iGlobalTimeOut: 10,
        loader: ''
    },
    
	initialize: function(req, options) {
		this.oForm = req.oForm;
        this.aFields = req.aFields;
        this.oContainer = req.oContainer;
        this.setOptions(options);

        this.aItems = [];
        this.oDataToSend = {};
        this.timeout;
	},
    
    init: function() {
    	this.getItems();
        this.addEvents();
        this.prepareDataAndSend();
    },
    
    addEvents: function() {
    	var This = this;
        this.aItems.each(function(item, i) {
        	if (item.conf.event == 'change') {
                item.obj.addEvent('change', function() {
                    This.handleEvent(item);
                });
        	} else if (item.conf.event == 'keypress') {
        		// Dopisac
        	}
            if (item.conf.specialEvent) {
            	item.obj.addEvent(this.aItems[i].conf.specialEvent, function() {
                    This.handleEvent(item);
            	});
            }
        }, this);
    },
    
    handleEvent: function(oItem) {
        clearTimeout(this.timeout);
        oItem.value = this.getValue(oItem.obj);
        this.prepareDataAndSend(oItem);
    },
    
    prepareDataAndSend: function(oItem) {
        var This = this, time;
        this.oContainer.set('html', this.options.loader);
        this.oDataToSend = {};
        this.oDataToSend['state'] = 'countTrips';
        for (var i=0; i<this.aItems.length; i++) {
    		this.oDataToSend[this.aItems[i].name] = this.aItems[i].value;
    	}
        
        if (oItem)
            time = (oItem.conf.time) ? oItem.conf.time : this.options.iGlobalTimeOut;
        else 
        	time = this.options.iGlobalTimeOut;
        
        this.timeout = setTimeout(function() {This.send();}, time);
    },
    
    send: function() {
        var This = this, o = {This: this};
        Ajax.addToQueue('turystyka_wycieczki', 1, this.oDataToSend, o, This.getResponse, 1);
    },
    
    getResponse: function(o, oRes, sRes) {
        try {
        	o.This.oContainer.set('html', oRes.count);
        } catch (e) {console.error('CountTrips.getResponse wyrzuca wyjatek: %o', e);}
    },
    
    getValue: function(o) {
    	var form = new Form(this.oForm);
        return form.getValue(o);
    },
    
    getItems: function() {
        var val;
        this.aFields.each(function(item, i) {
        	val = this.getValue(this.oForm[this.aFields[i].name]);
            this.aItems.push({
                obj: $(this.oForm[this.aFields[i].name]),
                name: this.aFields[i].name,
                value: val,
                conf: this.aFields[i].conf
            });
        }, this);
    }
});


/**
 * last edited: 18:43 2008-11-11 by pio
 */
var ModalWindow = new Class({
    initialize: function(o) {
        this.oContent = o.oContent;
        this.sContent = o.sContent;
        this.oWindowCss = o.oWindowCss;
    	this.sWindowClassName = o.sWindowClassName || 'modal-window';
        this.sHiddenClassNameForSelects = o.sHiddenClassNameForSelects || 'hidden';
        this.bBackground = o.bBackground || 0;
        this.iOpacity = o.iOpacity || 60;
        this.bgColor = o.bgColor || '#000';
        this.position = o.position;
        
        this.window = {};
        this.bg = null;
        this.width = 0;
        this.height = 0;
    },
    
    init: function() {
        this.createWindow();
        this.appendWindow();
        this.getPosition();
        this.setPosition();
        if (_Browser.ie6) {this.selects = $$('select'); this._handleSelects();}
        
        if (this.bg) {
            var This = this;
            
            this.scrollEvent = window.addEvent('scroll', function() {
                This.setPosition();
                This.setBackgroundPosition();
            });
            this.scrollEvent = window.addEvent('resize', function() {
                This.setPosition();
                This.setBackgroundPosition();
            });
        }
    },
    
    /**
        * Metoda do zamykania okna
    */
    close: function() {
    	if (this.bg)
    		this.bg.parentNode.removeChild(this.bg);

        this.window.parentNode.removeChild(this.window);
        window.removeEvent('scroll', this.scrollEvent);
        window.removeEvent('resize', this.resizeEvent);
        
        if (_Browser.ie6) this._showSelects();
    },
    
    flash: function(i) {
        this.init();
        var This = this;
    	setTimeout(function() {This.close();}, i);
    },
    
    /**
        * Jak widac, wstawia html'a do okna
    */
    insertContent: function(content) {
    	this.window.innerHTML = content;
    },
    
    insertObject: function(o) {
    	this.window.innerHTML = '';
        this.window.appendChild(o);
    },
      
    getPosition: function() {
        this.width = this.window.getStyle('width').toInt();
    	this.height = this.window.getStyle('height').toInt();
        
        if (isNaN(this.width) || isNaN(this.hieght)) {
        	var size = this.window.getSize();
            this.width = size.x;
            this.height = size.y;
        }
    },
    
    setPosition: function() {
        if (!this.position) {
            this.placeCenter();
            return;
        }       
            
        if (this.position.absolute) this.placeAbsolute(this.position.absolute);
        if (this.position.center) this.placeRelativeCenter(this.position.center);
    },
    
    placeAbsolute: function(o) {
    	this.window.style.top = o.y + 'px';
        this.window.style.left = o.x + 'px';
    },
    
    placeRelativeCenter: function(o) {
    	this.window.style.top = o.y - (this.height / 2) + 'px';
        this.window.style.left = o.x - (this.width / 2) + 'px';
    },
    
    placeCenter: function() {
    	var obszar = window.getSize();
        var scroll = window.getScroll();
        
        var l = Math.ceil(obszar.x / 2 - (this.width/2));
        var t = Math.ceil(obszar.y / 2 - (this.height/2));
             
        this.window.style.top = t + scroll.y + 'px';
        this.window.style.left = l + scroll.x + 'px';
    },
    
    createWindow: function() {
    	this.window = new Element('div', {'class': this.sWindowClassName});
        if (this.oContent) this.window.appendChild(this.oContent);
        else if (this.sContent) this.insertContent(this.sContent);
        else this.insertContent(' ');
        
        if (this.oWindowCss) {
            for (var key in this.oWindowCss) {
                this.window.style[key] = this.oWindowCss[key];
            }
        }
    },
    
    appendWindow: function() {
    	var place = document.body;
        if (this.bBackground) this.createBackground();
        place.insertBefore(this.window, place.firstChild);
    },
    
    createBackground: function() {
    	this.bg = new Element('div', {
            'styles': {
                'position' : 'absolute',
                'background-color' : this.bgColor,
                'z-Index' : '9998',
                'overflow' : 'hidden'
            }
        });
        
        this.setBackgroundPosition();
        
        if (_Browser.ie6)
        	this.bg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+this.iOpacity+')';
        else
            this.bg.style.opacity = this.iOpacity / 100;
        
        this.bg.inject(document.body, 'top');
    },
    
    setBackgroundPosition: function() {
        var zxc = window.getScrollSize();
        this.bg.setStyles({
            'top': 0,
            'left': 0,
            'width': zxc.x + 'px',
            'height': zxc.y + 'px'
        });
    },
   
    _handleSelects: function() {
        if (this.bBackground) {
            this._hideSelects();
            return;
        }
        var c = this.window.getCoordinates(), sc, s;
        var w = {x1: c.left,x2: c.left+c.width,y1: c.top,y2: c.top+c.height};
        this.selects.each(function(select, i) {
            sc = select.getCoordinates();
            s = {x1: sc.left,x2: sc.left+sc.width,y1: sc.top,y2: sc.top+sc.height};
            if ((s.x1 > w.x2) || (s.x2 < w.x1) || (s.y1 > w.y2) || (s.y2 < w.y1)) {
            	select.removeClass(this.sHiddenClassNameForSelects);
            } else {
                select.addClass(this.sHiddenClassNameForSelects);
            }
        }, this);
        
    },
   
    _hideSelects: function() {
        this.selects.each(function(select, i) {
        	select.addClass(this.sHiddenClassNameForSelects);
        }, this);
    },
    
    _showSelects: function() {
        this.selects.each(function(select, i) {
        	select.removeClass(this.sHiddenClassNameForSelects);
        }, this);
    }
});


var SearchEngineCore = new Class({
    initialize: function(oForm, oConfig) {
    	this.oForm = oForm;
        this.oConfig = oConfig || null;
        this.vars = getUrlVars();
    },
    
    /**
    * pobiera wartosc pola formularza. nie interesuje nas jakiego rodzaju jest to pole.
    * @parm o - DOM FORM ELEMENT
    * @return - wartosc pola
    */
    getFieldValue: function(o) {
        var formObject = new Form(this.oForm);
        return formObject.getValue(o);
    },    
    
    /**
    * Tworzy nowe options dla selectow i uruchamia metode do ustawiania
    * @parm oSelect - obiekt selecta zdefiniowany w 'konstruktorze'
    * @parm aNewSelectValues - tablica obiektow postaci: {key: costam, name: costam}
    * @parm oCustom - obiekt wartosci domyslnych dla selecta np. {blank: {name: 'domyslny', value: 0}}
    */
    update: function(oSelect, aNewSelectValues, oCustom) {
        var opt = {}; oSelect.length = 0;
        
        if (oCustom.blank) {
            opt = document.createElement('option');
            opt.value = oCustom.blank.value;
            opt.text = oCustom.blank.name;
            oSelect.options.add(opt);
        }
        
        for (var i=0; i<aNewSelectValues.length; i++) {
            opt = document.createElement('option');
            opt.value = aNewSelectValues[i].key;
            opt.text = aNewSelectValues[i].name;
            oSelect.options.add(opt);
    	}    
        
        if (oCustom.noSet) return;
        this.set(oSelect, oCustom);
    },
    
    /**
     * Ustawia danego selecta, biorac pod uwage parametry w urlu i obiekt konfiguracyjny
     * @parm oSelect - obiekt selecta zdefiniowany w 'konstruktorze'
     * @parm oCustom - niewymagany (nietestowany) - obiekt wartosci domyslnych dla selecta np. {customValue: 0}
     */
    set: function(oField, oCustom) {
        var valueFromUrl = decodeURIComponent(this.vars[oField.name]);
        var valueToSet = (valueFromUrl != 'undefined') ? valueFromUrl : 
            ((oCustom.customValue) ? oCustom.customValue : oCustom.blank.value);
        
        if (!valueToSet) return;
        var f = new Form(this.oForm);
        f.setValue(oField, valueToSet);
    }
});


/**
    * Klasa do ustawiania pol wyszukiwarki, zastepuje funkcje prepareCountrylist itp.
    * W zaleznosci od portalu, niektore metody trzeba przerobic
    * 18:44 2008-11-11 by pio
    * @parm oForm - obiekt formularza
    * @parm oConfig - obiekt konfiguracyjny
*/
var SearchEngine = new Class({
    Extends: SearchEngineCore,
    initialize: function(oForm, oConfig) {
    	this.oForm = oForm;
        this.oConfig = oConfig || null;
        this.vars = getUrlVars();
        
        this.oTransport = this.oForm['tripTransport2'];
        this.oKategoria = this.oForm['tripTransport'];
        this.oKraj = this.oForm['tripCountryName'];
        this.oWyjazd = this.oForm['tripFrom'];
        
        this.aKraje = arrCountries;
        this.aWyjazdy = arrWyjazdy;
        this.aTransporty = arrTransport;
    },
    
    init: function() {
        if (!this.oConfig) {throw new Error('SEARCH ENGINE - uzupelnij config'); return;}

        this.updateOnLoad();
        this._setFromUrl();
       
        this.addEventToKraj();
        this.addEventToTransport();
        this.addEventToKategoria();
    },


    /**
        * tu wazne sa kolejnosci wykonywania funkcji. 
        * np. zeby poprawnie ustawic wyjazd potrzebujemy ustawionych pol, ktore na niego wplywaja
    */
    updateOnLoad: function() {
        this.updateKategoria();
        this.updateTransport();
        this.updateKraj();
        this.updateWyjazd();
    },
    
    /**
        * wszystkie megody addEventTo... odpowiedzialne sa za zaleznosci.
        * np. transport ma uaktualniac pola kraj i wyjazd
        * wybieramy tez rodzaj zdazenia: 'click' lub 'change'.
    */
    addEventToTransport: function() {
        var This = this;
        // w tym przypadku transport jest polem typu radio, dlatego nadajemy eventy do wszystkich inputow
        for (var i=0; i<this.oTransport.length; i++) {
             pioEvent.addEvent(this.oTransport[i], 'click', function() {
                This.updateKraj(); // zmiana transportu ma wplyawac na zmiane kraju
                This.updateWyjazd(); // zmiana transportu ma wplywac na zmiane wyjazdu
            });       	
        }
    },
    

    addEventToKategoria: function() {
        var This = this;
        pioEvent.addEvent(this.oKategoria, 'change', function() {
            This.updateKraj(); // zmiana kategori ma wplywac na zmiane kraju
        });
    },
    
    addEventToKraj: function() { /*nie ma eventu w tym przypadku*/},
    
    
    /**
        * metody update... odpowiedzialne sa za samo zmienianie wartosci pol i ich ustawianie
        * po przeprowadzeniu operacji na tablicach (kiedy to jest wymagane) uruchamiamy jedna z dwoch metod (update lub set):
        * update - zmienia 'opcje selectow' i ustawia tego selecta (wybiera aktualna wartosc)
        * set - tylko ustawia selecta (wybiera aktualna wartosc)
        * UWAGA - wszystkie 4 pola (transport, kategoria, kraj, wyjazdy) musza wywolywac przynajmniej set
    */
    updateTransport: function() {
        this.set(this.oTransport, this.oConfig.transport);
    },

    updateKategoria: function() {
        this.set(this.oKategoria, this.oConfig.kategoria);
    },

    updateKraj: function() {
        var aNewKraje = [];
        var tV = this.getFieldValue(this.oTransport);
        var kV = this.getFieldValue(this.oKategoria);
        
        if (kV != 0) {
            for (var i=0; i<this.aKraje.length; i++) {
            	if (this.aKraje[i].transport[tV] == 1 && this.aKraje[i].categories[kV] == 1) {
            		aNewKraje.push({
                        key: this.aKraje[i].key,
                        name: this.aKraje[i].name
                    });
            	}
            }
        } else {
        	for (var i=0; i<this.aKraje.length; i++) {
            	if (this.aKraje[i].transport[tV] == 1) {
            		aNewKraje.push({
                        key: this.aKraje[i].key,
                        name: this.aKraje[i].name
                    });
            	}
            }
        }
        this.update(this.oKraj, aNewKraje, this.oConfig.kraj);
    },
    
    updateWyjazd: function() {
        var aNewWyjazdy = [];
        var tV = this.getFieldValue(this.oTransport);
        
        for (var i=0; i<this.aWyjazdy.length; i++) {
        	if (this.aWyjazdy[i].transport[tV] == 1) {
        		aNewWyjazdy.push({
                    key: this.aWyjazdy[i].key,
                    name: this.aWyjazdy[i].name
                });
        	}
        }
        this.update(this.oWyjazd, aNewWyjazdy, this.oConfig.wyjazd);
    },
        
    _setFromUrl: function() {
        if (this.vars.length == 0) return;
        var arr = [];
        for (var x in this.vars) {
        	var o = {name: x, value: decodeURIComponent(this.vars[x])};
            // te wartosci sa ustawiane wczesniej, wiec je pomijamy
            if (o.name != this.oTransport.name && o.name != this.oKraj.name &&
                o.name != this.oWyjazd.name && o.name != this.oKategoria.name && o.name != 'pid' && o.name != 'step') {
                
                if (this.oConfig.formElements.step1) {
                	var a = this.oConfig.formElements.step1;
                    for (var i=0; i<a.length; i++) {
                    	if (o.name == a[i]) {
                    		arr.push(o);
                    	}
                    }
                } else {
                	arr.push(o);
                }
            }
        }
        var step1 = new Form(this.oForm);
        step1.setValues(arr);
        
        var advId = (this.oConfig.advSearchFormId) ? this.oConfig.advSearchFormId : 'step1a';
        var adv;
        if (adv = document.getElementById(advId)) {
            var arr = [];
            for (var x in this.vars) {
            	var o = {name: x, value: decodeURIComponent(this.vars[x])};
                
                if (this.oConfig.formElements.step1a) {
                	var a = this.oConfig.formElements.step1a;
                    for (var i=0; i<a.length; i++) {
                    	if (o.name == a[i]) {
                    		arr.push(o);
                    	}
                    }
                } else {
                	arr.push(o);
                }
            }
            var step1a = new Form(adv);
            step1a.setValues(arr);
        }
    }
});



/**
    * Klasa do validacji formularza rezerwacyjnego
    * a: pio le: 18:46 2008-11-11 by pio
    * @parm oConfig - obiekt
*/
var ReservValidation = new Class({
    initialize: function(oConfig) {
    	this.oConfig = oConfig;
    	this.oForm = this.oConfig.form;
        this.aStale = this.oConfig.stale;
        this.oZmienne = this.oConfig.zmienne;
        this.errorClassName = this.oConfig.klasaBlednegoElementu || 'reservation-error';
        this.errorDivId = this.oConfig.branchErrorDivId || 'reservation-branch-error';
        this.sSubmitInputName = this.oConfig.sSubmitInputName || 'booking';
        
        this.aItems = []; // tablica przechowuje obiekty pol formularzy z rugulami
        this.aRooms = []; // index to index pokoju, wartosc to liczba osob dla danego pokoju
        this.aErrors = []; // przechowuje obiekty Items ktore byly blednie wypelnione
        this.branchContainer = {};
    },
    
    init: function() {
        this._getRooms();
    	this._getItems();
        this._addEvents();
        this.createBranchContainer();
    },
    
    _addEvents: function() {
        var This = this, oRadio;
    	for (var i=0; i<this.aItems.length; i++) {
            // sprawdza czy jest polem typu radio
            if (this.aItems[i].obj.type == undefined) {
            	oRadio = this.aItems[i].obj;
                for (var j=0; j<oRadio.length; j++) {
                	pioEvent.addEvent(oRadio[j], 'blur', function() {
                        This.checkItem(This._getItem(this.name), 1);
                    });
                }
                continue;
            }
            pioEvent.addEvent(this.aItems[i].obj, 'blur', function() {
                This.checkItem(This._getItem(this.name), 1);
    		});         
    	}
        
        var submit = this.oForm[this.sSubmitInputName];
        if(!submit) {throw new Error('ReservValidation._addEvents: zle zdefiniowane pole wysylajace formularz'); return;}
        pioEvent.addEvent(submit, 'click', function(e) {
            This.checkAll(e);
        });
    },
    
    checkAll: function(e) {
        this.aErrors = [];
    	for (var i=0; i<this.aItems.length; i++) {
    		this.checkItem(this.aItems[i], 0);
    	}
        
        if (this.aErrors.length != 0) {
            var e = pioEvent.getEvent();
            e.preventDefault();
        	this.showBranchOfErrorMsgs();
            return;
        }
        this.clearBranchContainer();
    },
    
    checkItem: function(oItem, b) {
        this.clearItemErrorMsg(oItem);
        
        if (oItem.rules.notNull) this.notNull(oItem);
        if (oItem.rules.post_code) this.post_code(oItem);
        if (oItem.rules.number) this.number(oItem);
        if (oItem.rules.onlyLetters) this.onlyLetters(oItem);
        if (oItem.rules.email) this.email(oItem);
        if (oItem.rules.chosen) this.chosen(oItem);
        if (oItem.rules.checked) this.checked(oItem);
        if (oItem.rules.selected) this.selected(oItem);
        if (oItem.rules.minSize) this.minSize(oItem, oItem.rules.minSize);
        if (oItem.rules.maxSize) this.maxSize(oItem, oItem.rules.maxSize);
        if (oItem.rules.size) this.size(oItem, oItem.rules.size);
        if (oItem.rules.dateFormat) this.dateFormat(oItem, oItem.rules.dateFormat);        
        if (oItem.rules.doubleEmail) this.doubleEmail(oItem);
        if (oItem.rules.custom) this.custom(oItem);
        
        this.handleError(oItem, b);
    },
    
    notNull: function(oItem) {
        if (oItem.obj.value == '') 
            this.setError(oItem, 'Pole '+oItem.clientName+' nie może być puste.');
    },
    
    post_code: function(oItem) {
    	var res = oItem.obj.value.match(/^[\d]{2}-[\d]{3}$/gi);
        if (!res && oItem.obj.value != '' || oItem.obj.value == '00-000') 
            this.setError(oItem, oItem.clientName+' jest błędnie wpisany.');
    },
    
    number: function(oItem) {
    	var res = oItem.obj.value.match(/^[\d]+$/gi);
        if (!res && oItem.obj.value != '')  
            this.setError(oItem, 'W polu '+oItem.clientName+' mogą występować tylko liczby.');
    },
    
    onlyLetters: function(oItem) {
    	var res = oItem.obj.value.match(/^[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+$/);
        if (!res && oItem.obj.value != '')
            this.setError(oItem, 'W polu '+oItem.clientName+' mogą występować tylko litery.');
    },

    minSize: function(oItem, num) {
        if (oItem.obj.value.length < num)
            this.setError(oItem, oItem.clientName+' musi mieć minium '+num+' znaków.');
    },

    email: function(oItem) {
    	var res = oItem.obj.value.match(/^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/);
        if (!res)
            this.setError(oItem, oItem.clientName+' ma nieprawidłową formę.');
    },
    
    maxSize: function(oItem, num) { 
        if (oItem.obj.value.length > num && oItem.obj.value != '')
            this.setError(oItem, oItem.clientName+' moze mieć maksimum '+num+' znaków.');
    },
    
    size: function(oItem, num) {
        if (oItem.obj.value.length != num && oItem.obj.value != '')
            this.setError(oItem, oItem.clientName+' musi mieć '+num+' znaków.');
    },

    dateFormat: function(oItem, separator) {
        if (separator == ".") {
            var reg_date = /[0-3][0-9].(0|1)[0-9].(19|20)[0-9]{2}/;
        }
        else if (separator == "-") {
            var reg_date = /[0-3][0-9]-(0|1)[0-9]-(19|20)[0-9]{2}/;
        }
        if(oItem.obj.value.match(reg_date) && oItem.obj.value != '') {
            var date_array = oItem.obj.value.split(separator);
            var day = date_array[0];
            // miesiÄ?ce w js sÄ? w numerowane 0 - 11
            var month = date_array[1] - 1; 
            var year = date_array[2];
            
            source_date = new Date(year,month,day);

            if(year != source_date.getFullYear())
                this.setError(oItem, oItem.clientName+' ma niepoprawny rok (prawidłowy format daty: d'+ separator +'m'+ separator +'Y).');        

            if(month != source_date.getMonth())
                this.setError(oItem, oItem.clientName+' ma niepoprawny miesiÄ?c (prawidłowy format daty: d'+ separator +'m'+ separator +'Y).');        

            if(day != source_date.getDate())
                this.setError(oItem, oItem.clientName+' ma niepoprawny dzieĹ? (prawidłowy format daty: d'+ separator +'m'+ separator +'Y).');        
        }
        else {
            this.setError(oItem, oItem.clientName+' ma niepoprawny format (prawidłowy format daty: d'+ separator +'m'+ separator +'Y).');
        }
    },
    
    //for radio
    chosen: function(oItem) {
        var b = 0;
    	for (var i=0; i<oItem.obj.length; i++) {
    		if (oItem.obj[i].checked == true) b = 1;
    	}
        if (b == 0) this.setError(oItem, 'Pole '+oItem.clientName+' musi być zaznaczone.');
    },
    
    //for checkbox
    checked: function(oItem) {
        if (oItem.obj.checked == false)
            this.setError(oItem, 'Pole '+oItem.clientName+' musi być zaznaczone.');
    },
    
    selected: function(oItem) {
        if (oItem.obj.value == '0')
            this.setError(oItem, 'W polu '+oItem.clientName+' musi być wybrana opjca.');
    },
    
    doubleEmail: function(oItem) {
    	if (oItem.obj.value != this.oForm['client[email]'].value) 
            this.setError(oItem, 'Pola email mają różne wartości.');
    },
    
    custom: function(oItem) {
        var res = oItem.obj.value.match(oItem.rules.custom.re);
         if (!res)
            this.setError(oItem, oItem.rules.custom.msg);
    },
    
    setError: function(oItem, s) {
        // ustawienie wiadomosci o bledzie
        if (!oItem.errorMsg)
        	oItem.errorMsg = s;
        else
            oItem.errorMsg += ' ' + s;
        
        // dodanie do tablicy bledow blednego elementu
        if (this.aErrors.length == 0) {
            this.aErrors.push(oItem);
            return;
        }
        // jezeli element jest juz w tablicy bledow to go pomijamy
        for (var i=0; i<this.aErrors.length; i++) {
        	if (this.aErrors[i] == oItem) {
        		return;
        	}
        }
        this.aErrors.push(oItem);
    },
    
    clearItemErrorMsg: function(oItem) {    
    	if (oItem.errorMsg) oItem.errorMsg = null;
    },
    
    handleError: function(oItem, b) {
    	if (oItem.errorMsg) {
    		this.setErrorCN(oItem);
            if (b == 1) this.showErrorMsg(oItem);
    	} else {
    		this.removeErrorCN(oItem);
            if (b == 1) this.removeErrorMsg(oItem);
    	}
    },
    
    setErrorCN: function(oItem) {
        var obj = this._getObj(oItem);
        if (!obj || (obj instanceof Array)) return;
                   
        // nadanie klasy bledu
        try {
            if (isClassName(obj, this.errorClassName) == false)
            	addClassName(obj, this.errorClassName);
        } catch(e) {}
    },
    
    removeErrorCN: function(oItem) {
        var obj = this._getObj(oItem);
        if (!obj || (obj instanceof Array)) return;
        
        // usuwanie klasy bledu
        try {
            if (isClassName(obj, this.errorClassName) == true && !oItem.errorMsg)
            	removeClassName(obj, this.errorClassName);
        } catch(e) {}
    },
    
    _getObj: function(oItem) {
    	var obj = oItem.obj;
        
        if (obj.type == undefined) {
        	var l = this.oForm.getElementsByTagName('label');
            for (var i=0; i<l.length; i++) {
            	if (l[i].getAttribute('for') == obj[0].name) 
                return l[i];
            }
        }
        
        // w przypadku checkboxow klase nadajemy elementom label
        if (obj.type == 'checkbox') {
        	var l = this.oForm.getElementsByTagName('label');
            for (var i=0; i<l.length; i++) {
            	if (l[i].getAttribute('for') == obj.id) 
                return l[i];
            }
        }
        return obj;
    },
    
    showErrorMsg: function(oItem) {
    	var s;
        if (s = document.getElementById('error_' + oItem.obj.name))  { // wiadomosc juz istnieje
            s.innerHTML = oItem.errorMsg;
            return;
        }
        
        s = document.createElement('span');
        s.id = 'error_' + oItem.name;
        s.innerHTML = oItem.errorMsg;
        this.branchContainer.appendChild(s);
    },
    
    removeErrorMsg: function(oItem) {
    	var s;
        if (s = document.getElementById('error_' + oItem.name))
            this.branchContainer.removeChild(s);
    },
    
    showBranchOfErrorMsgs: function() {
        this.clearBranchContainer();
        var f = document.createDocumentFragment();
        for (var i=0; i<this.aErrors.length; i++) {
        	var s = document.createElement('span');
            s.id = 'error_' + this.aErrors[i].name;
            s.innerHTML = this.aErrors[i].errorMsg;
            f.appendChild(s);
        }
        this.branchContainer.appendChild(f);
    },
    
    createBranchContainer: function() {
    	var el = this.oForm[this.sSubmitInputName];
        var fieldset = el.parentNode;
        this.branchContainer = document.createElement('div');
        this.branchContainer.id = this.errorDivId;
        fieldset.insertBefore(this.branchContainer, fieldset.firstChild);
    },
    
    clearBranchContainer: function() {
    	this.branchContainer.innerHTML = '';
    },
    
    _getItem: function(name) {
        for (var i=0; i<this.aItems.length; i++) {
        	// pole radio
            if (this.aItems[i].obj.type == undefined) {
                if (this.aItems[i].obj[0].name == name) {
            		return this.aItems[i];
            	}        		
        	}
            
            if (this.aItems[i].obj.name == name) {
        		return this.aItems[i];
        	}
        }
    },
    
    _getItems: function() {
        //stale
        var o, name;
        for (var i=0; i<this.aStale.length; i++) {
        	o = this.oForm[this.aStale[i].name];
            name = (o.name) ? o.name : o[0].name;
            if(!name) throw new Error('ReservValidation._getItems: pole nie ma ustawionego atrybutu NAME.');
            this.aItems.push({
                obj: o,
                name: name,
                rules: this.aStale[i].rules,
                clientName: this.aStale[i].clientName
            });
        }        
        
        //osoby (zmienne) - tylko dla nowej rezerwacji
        if (!this.oZmienne) return;
        var p = this.oZmienne.persons;
        for (var i=0; i<this.aRooms.length; i++) {
        	for (var j=0; j<this.aRooms[i]; j++) {
                for (var k=0; k<p.length; k++) {
                    o = this.oForm['room['+i+'][person]['+j+']['+p[k].name+']'];
                    name = (o.name) ? o.name : o[0].name;
                    this.aItems.push({
                        obj: o,
                        name: name,
                        rules: p[k].rules,
                        clientName: p[k].clientName
                    });    		
                }
        	}
        }
    },

    _getRooms: function() {
        var i = 0;
        while (this.oForm['room['+i+'][id]'] != null) {
            this.aRooms[i] = this._countPersons(i);
            i++;
        }
    },
    
    _countPersons: function(iRoomIndex) {
    	var i = 0;
        while (this.oForm['room['+ iRoomIndex +'][person]['+ i +'][type]'] != null) {
            i++;
        }
        return i;
    }
});


/**
	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 = new Class({
    initialize: 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++) {
        	pioEvent.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
 * le: 11:08 2008-11-13 by pio    
 */
var Basket = new Class({
    Implements: Options,
    
    options: {
        sCheckboxId: 'basket_',
        sCheckboxClassName: 'addToBasket',
        sRemoveLinkClassName: 'removeFromBasket',
        msg: {
            time: 1000,
            css: {border: '1px solid #ccc', background: '#fff', padding: '1em', position: 'absolute', zIndex: 9999},
            text: {add: 'dodano do schowka', remove: 'usunieto ze schowka'},
            iPlusPositionX: 25,
            iPlusPositionY: -12
        }
    },
    
    initialize: function(options) {
        this.setOptions(options);
        this.aChecks = [];
        this.aReoveLinks = [];
    },

    init: function() {
        var This = this, code;
        var check = $$('input.'+this.options.sCheckboxClassName);
        check.each(function(check, i) {
    		if (this._getOfferCodeFromId(check.id) != false) {
                check.disabled = false;
                check.addEvent('click', function(e) {
                    This._handleEvent(e, this, This._getOfferCodeFromId(check.id), 0);
                });
    		}
    	}, this);
      
        var link = $$('a.'+this.options.sRemoveLinkClassName);
        link.each(function(link, i) {
            if (this._getOfferCodeFromHref(link.href) != false) {
                link.addEvent('click', function(e) {
                    This._handleEvent(e, this, This._getOfferCodeFromHref(link.href), 1);
                });
    		}
    	}, this);
    },
    
    _handleEvent: function(e, el, val, isLink) {
        var sOperation, o = {This: this, isLink: isLink, el: el};
        if (!isLink) {
        	if (el.checked) {
        		sOperation = 'add';
                o.sText = this.options.msg.text.add;
        	} else {
        		sOperation = 'delete';
                o.sText = this.options.msg.text.remove;
            }
    	} else {
            e.stop();
            sOperation = 'delete';
    	}
        Ajax.addToQueue('turystyka_koszyk', 1, {offer: val, oper: sOperation}, o, o.This._getResponse);
    },
    
    _getResponse: function(o, oRes, sRes) {
        if (oRes['state'] != 0) {
            if (o.isLink != 1) { // checkbox
                o.This.showStatus(o.el, o.sText);
            } else { // link
            	if (oRes['state'] == 'del') o.This._removeRow(o.el);
            }
    	}
    },
 
    showStatus: function(el, sText) {
    	var p = el.getPosition();
        var s = el.getSize();
        var m = new ModalWindow({
            sContent: sText,
            oWindowCss: this.options.msg.css,
            sWindowClassName: 'basket-modal-window',
            position: {absolute: {x: p.x+this.options.msg.iPlusPositionX, y: p.y+this.options.msg.iPlusPositionY}}
        }); m.flash(this.options.msg.time);
    },
 
    _removeRow: function(o) {
        o = o.getParent('tr');
        if (o.getParent().getChildren('tr').length > 1) {
            (new Fx.Tween(o)).start('opacity', 0).chain(function() {o.dispose();});
        } else {
            o = o.getParent('table');
            var h = new Element('h2', {
                'class': 'error',
                'text': 'Showek jest pusty'
            });
            
            (new Fx.Tween(o)).start('opacity', 0).chain(function() {
                h.inject(o, 'before');
                o.dispose();
            });
        }
    },
    
    _getOfferCodeFromId: function(s) {
        var res = s.match(new RegExp("" + this.options.sCheckboxId + "(.+)", "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];    	
    }
});

/**
    * 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 = new Class({
    initialize: 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._append();
        this.TimeoutID = setTimeout(function () {This.hide();}, time);
    },    
    
    _append: function() {
    	if (this.oItem.firstPlace)
            this.oItem.parent.insertBefore(this.el, this.oItem.parent.firstChild);
        else 
            this.oItem.parent.appendChild(this.el);
    },
    
    hide: function() {
    	this.oItem.parent.removeChild(this.el);
    }
});

/**
    * Klasa do newslettera
    * przerobil: pio
    * le: 10:42 2008-08-29 by pio
    * @parm sNewsletterPriceSpliter - string - niewymagany - standardowo 'spacja'
    * dziala przy dominatorze 2.3*
*/
var Newsletter = new Class({
    initialize: 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 || window.opener.addRSSOffer))  {                
            for (var i=0; i<this.aLinks.length; i++) {
            	this.aLinks[i].style.display = 'inline';
                if (window.opener.addRSSOffer) {
                    this.aLinks[i].textContent = "Dodaj do RSS";
                }
                pioEvent.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 = pioEvent.getEvent();
        
        if (window.opener && window.opener.addRSSOffer) {            
            bReturn = window.opener.addRSSOffer( sValue );
            if( bReturn == 1){
                alert( 'Oferta została dodana do wiadomości RSS.' );
                return false;        
            } else {
                alert( 'Wystąpił błąd podczas dodawania oferty.' );
                return true;
            }
        } else {
            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 szczegolow terminu na step4 / zastepuje funkcje activateDetailView
    * Trzeba pozmieniac troche tpl'ke. dodac id'ki dla linku i ukrytej tr'ki - ze wspolna liczba na koncu.
    * a: pio
    * le: 16:25 2008-09-15 by pio
    * @parm ob - obiekt 
        {obszarRoboczy: DOM Element, // np tabblock, page0 - zeby nie iterowac wszystkich linkow na stronie
        linkClassName: string, 
        trId: string, // np. 'detail_nr_' - w szablonie na koncu jest liczba
        trHideClassName: string} // klasa do ukrywania tr'ki
*/
var DetailView = new Class({
    initialize: function(ob) {
    	this.sLinkClassName = ob.linkClassName || 'detail';
        this.or = ob.obszarRoboczy;
        this.sTrId = ob.trId || 'detail_';
        this.sTrHideClassName = ob.trHideClassName || 'hide';
        this.aLinks = [];
    },
    
    init: function() {
        if (!this.or) {echo('DETAIL VIEW: uzupelnij konfig o obszarRoboczy'); return;}
    	this._getLinks();
        if (this.aLinks.length == 0) return;
        this._addEvents();
    },
    
    _addEvents: function() {
    	var This = this;
        for (var i=0; i<this.aLinks.length; i++) {
        	pioEvent.addEvent(this.aLinks[i], 'click', function(e) {
        		This._handleEvent(e, this);
        	});
        }
    },
    
    _handleEvent: function(e, o) {
    	var e = pioEvent.getEvent();
        e.preventDefault();
        
        var tr = document.getElementById(this.sTrId + this._re(o.id));
        if (isClassName(tr, this.sTrHideClassName)) {
        	removeClassName(tr, this.sTrHideClassName);
        } else {
        	addClassName(tr, this.sTrHideClassName);
        }
    },
    
    _re: function(s) {
    	var res = s.match(/(\d+)$/gi);
        return parseInt(res);
    },
    
    _getLinks: function() {
    	var links = this.or.getElementsByTagName('a');
        for (var i=0; i<links.length; i++) {
        	if (isClassName(links[i], this.sLinkClassName)) {
        		this.aLinks.push(links[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 = new Class({
    initialize: 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;
                
        var url = (SiteConfig.urlSite) ? SiteConfig.urlSite : "http://" + window.location.hostname + "/";
        for (var i=0; i<this.aForms.length; i++) {                
            pioEvent.addEvent(this.aForms[i], "submit", function(e) {
                This._createSearchUrl(e, url, 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 = pioEvent.getEvent();
        e.preventDefault();
        
        var form = new Form(oForm);
        form.getAllElements();
        
        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: 10:32 2008-09-15 by pio
    * @parm oForm - obiekt formularza
*/
var Form = new Class({
    initialize: function(oForm) {
        this.oForm = oForm;
        this.aElements = []; 
    },
    
    /**
        * @parm o - DOM Element
        * @return - string
    */    
    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;
        }    	
    },
    
    /**
        * @parm o -DOM Element
        * @parm val - mixed - wartosc pola
    */
    setValue: function(o, val) {
        switch (o.type) {
            case 'checkbox':
                if (val != 0) {
                    o.checked = true;
                } else {
                	o.checked = false;
                }
                break;
            case undefined: // radio
                for (var j=0; j<o.length; j++) {
                    if (o[j].value == val) {
                        o[j].checked = true;
                    }
                }    
                break;
            default: 
                return o.value = val;
        }        	
    },

    /**
        * przepisuje wartosci pol formularza do tablicy aElements;
    */
    getAllElements: function() {
        var aNames = [];
        var aEl = this.oForm.elements;
        
        add: for (var i=0; i<aEl.length; i++) {
            if (aEl[i].name) {
            	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++) {
            if (this.oForm[aNames[i]]) {
                var o = {};
                o.obj = this.oForm[aNames[i]];
                o.name = aNames[i];
                o.value = this.getValue(o.obj);
                this.aElements[i] = o;
            }
        }
    },  
    
    /**
        * nadaje wartosci hurtem dla wszystkich pol.
        * @parm a - array - tablica obiektow {name: 'FildName', value: 'FildValue'}
        * @return - void
    */    
    setValues: function(a) {
    	if (!a) return;
        this.getAllElements();
        
                
        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();
    },    
    
    _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].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;
                    
    		}
    	}
    }  
    
});