aagForms = {
    
    // CSS tridy pro schovavani a odkryvani objektu
    classShow : 'show',
    classHide : 'hide',
  
    // CSS trida, ktera je dynamicky pridana a obaluje objekty, na ktere je nastaven
    // JS scroll
    classScroll : 'jScrollPaneContainer',
  
    // CSS tridy pro selectBox
    classSelectBox : 'ui-selectbox',
    classBoxOptions : 'ui-options',        
    classSelectOption : 'selected',
    classActiveOption : 'active',
  
    activeSelect : false,
  
    /**
     * Fce vytvari formular selectBoxaaa
     */
    createSelectBox : function () {

        var thisObject = this;
        
        // Vybira selecBoxy
        var elSelectBox = jQ('div.' + this.classSelectBox + '.unbound');

        // Nastavi tridu, ktera oznaci, ze udalost byla nastavena
        jQ(elSelectBox).removeClass('unbound').addClass('bound');
        
        // EVENT: Zavira vsechny boxy
        jQ('body').unbind('click.closeSelect').unbind('click.closeSelect').bind('click.closeSelect', function() {
            thisObject.closeAllSelectBox();
        });

        // EVENT: Osetruje, pokud se zmeni hodnota realneho selectBoxu
        jQ(elSelectBox).find('select').unbind('change.select').bind('change.select', function() {
            var selIndex = 0;
            var selTitle = '';
            jQ(this).children('option').each(function(index) {
                if (this.selected == true) {
                    selIndex = index;
                    selTitle = this.text;                    
                    return false; // Nahrazuje break
                }
            });
            var elFakeOption = jQ(this).parent().find('ul li:eq(' + selIndex + ')');              
            thisObject.setSelectedOption(elFakeOption);
            
            var elBox = jQ(this).parent().parent();
            thisObject.setTitle(elBox, selTitle);
       	});
        
        // Nastavuje hodnotu formulare dle realne polozky
        jQ(elSelectBox).each(function() {
            var valOption = jQ('option:selected', this).text();
            thisObject.setTitle(this, valOption);
        });
        
        // EVENT:
        // Na body na nastavena udalost pro zavreni vsech boxu
        // Zastavuje dalsi probublavani udalosti
        jQ(elSelectBox).unbind('click').bind('click', function(event) {
            event.stopPropagation();
        });
        
        // EVENT: Pri najeti na comboBox se jiz nacitaci polozky, aby se zrychlilo zobrazeni po kliknutu
        jQ(elSelectBox).find("div.select_cover, span").unbind('mouseover').bind('mouseover', function() {

            // Vytvori imaginarni seznam
            var elParent = jQ(this).parent();
            var elFakeSelectBox = jQ(elParent).find('ul');
            var elSelect = jQ(elParent).children('select');
            var elOptions = jQ(elSelect).children('option');
            var elFakeOptions = jQ(elFakeSelectBox).children('li');

            // Pokud se zmenil pocet optionu, vygeneruje se novy seznam
            if ( (elOptions.length != elFakeOptions.length) || (jQ(elFakeSelectBox).hasClass('refresh') == true) ) {

                jQ(elFakeSelectBox).removeClass('refresh');
                
                thisObject.setOptions(elSelect, elFakeSelectBox, elOptions);
                
                elFakeOptions = jQ(elFakeSelectBox).children('li');
                
                // Zvyrazneni optionu pri otevreni comba, pokud bylo jiz vybrane
                jQ(elFakeOptions).hover(
                    function() { jQ(this).addClass(thisObject.classActiveOption); },
                    function() { jQ(this).removeClass(thisObject.classActiveOption); }
                );
                
                // Vybrani hodnoty z polozky seznamu
                jQ(elFakeOptions).click(function() {

                    // TODO (pokud vite jak jinak??) li->ul->div->div.scrollPaneContainer->div.selectbox-body
                    elBox = jQ(this).parent().parent().parent().parent();    
                   
                    // Nastavi vyber pro realny select
                    var selectIndex = jQ(elFakeOptions).index(this);
                    var testOption = jQ(elSelect).find('option:eq(' + selectIndex + ')').attr('selected', 'selected');

                    // Vyvola udalosti selectu pro onchange
                    jQ(elSelect).change();

                    // Nahrazeni viditelne vybrane hodnoty falesneho
                    thisObject.setTitle(elBox, jQ(this).text());
                    
                    // Nastavi zvolenou li polozku
                    thisObject.setSelectedOption(this); 
                    
                    // Zavira panel nabidky
                    thisObject.visibilityOptionList(elBox); 
                });
           	}
        });
        
        // EVENT: Otvirani / zavirani seznamu polozek
        jQ(elSelectBox).find("div.select_cover, span").unbind('click').bind('click', function() {
            var elBox = jQ(this).parent().parent();
            thisObject.visibilityOptionList(elBox);
            thisObject.setKeyEvent(elBox); 
        });
    },
    
    /**
     * 
     */
    setKeyEvent : function(elBox) {

        var thisObject = this;
                
        var elListSelect = jQ(elBox).find('div select');
        var countItems = jQ(elBox).find('div select option').length;        
        var elListFake = jQ(elBox).find('div div div ul li');

        jQ(document).unbind('keydown');
        jQ(document).bind('keydown', function(e) {
        
            if (thisObject.activeSelect != true) {
                return true;
            }
            
            e.stopPropagation();

            selectIndex = 0;
            jQ(elListFake).each(function(index) {
                if (jQ(this).hasClass('active')) {
                    selectIndex = index;
                    return false;
                } else if (jQ(this).hasClass('selected')) {
                    selectIndex = index;
                }
            });
            
            var code = (e.keyCode ? e.keyCode : e.which);

            // Ovladani sipkami
            if (code == 38 || code == 40)  {
                
                if (code == 38) {
                    selectIndex--;
                } else if (code == 40) {
                    selectIndex++;
                }

                if (0 <= selectIndex && selectIndex < countItems) {
                    jQ(elListFake).trigger('mouseleave');
                    jQ(elListFake).eq(selectIndex).triggerHandler('mouseenter');
                    thisObject.setPositionScroll(elBox, selectIndex);
                }
            } else if (48 <= code && code <= 90) {
                findIndex = null;
                jQ(elListFake).eq(selectIndex).nextAll().each(function(index) {
                    var textVal = jQ(this).text();
                    if (textVal.charCodeAt(0) == code) {
                        findIndex = selectIndex + index + 1;
                        return false;
                    }
                });
                if (findIndex == null) {
                    jQ(elListFake).each(function(index) {
                        var textVal = jQ(this).text();
                        if (index >= selectIndex) {
                            return false;
                        } else if (textVal.charCodeAt(0) == code) {
                            findIndex = index;
                            return false;
                        }
                    });
                }

                if (findIndex != null) {
                    jQ(elListFake).trigger('mouseleave');
                    jQ(elListFake).eq(findIndex).triggerHandler('mouseenter');
                    thisObject.setPositionScroll(elBox, scrollIndex);
                }
            } else if (code == 13) {
                jQ(elListFake).eq(selectIndex).triggerHandler('click');
            }
            return false;
        });
    },
   
    /**
     * Posouva kurzor na pozadovonou polozku
     *
     * @param elBox DOMobject
     * @param index integer
     */
    setPositionScroll : function(elBox, index) {
        var scrollIndex = index * 16 - (5 * 16);
        if (scrollIndex < 0) scrollIndex = 0;
        jQ(elBox).find('.' + this.classBoxOptions)[0].scrollTo(scrollIndex);
    },

    /**
     * Pridava option do realneho selectu
     *
     * @param string idSelect ID selectu
     * @param string value Hodnota polozky
     * @param string title Popis polozky
     */
    appendOption : function (idSelect, value, title) {
        jQ(idSelect).append('<option value="' + value + '">'+ title +'</option>');
    },
    
    /**
     * Nastavuje vybranou hodnotu do falesneho formulare
     *
     * @param DOMobject elBox
     * @param string strTitle
     */
    setTitle : function (elBox, strTitle) {
       jQ('div.select_cover', elBox).text(strTitle);
    },
    
    /**
     * Znovu vytvori select 
     *
     * @param DOMobject elSelect Objecty select
     */
    refreshSelect : function (elSelect) {
        var elSelectAll = jQ(elSelect).parent().parent();
        jQ(elSelectAll).addClass('unbound').removeClass('bound');  
        jQ(elSelect).find('option:first').attr('selected', 'selected');
        jQ(elSelectAll).find('ul').addClass('refresh');
        this.createSelectBox();
    },
  
  	/**
  	 * Generuje fake seznam na zaklade realneho
  	 *
  	 * @param DOMobject elSelect Realny selectBox
  	 * @param DOMobject elFakeSelectBox Fake selectBox  	 
  	 * @param DOMobject elOptions Realne option
  	 */
  	setOptions : function(elSelect, elFakeSelectBox, elOptions) {              ;
        var selectVal = '';        
        var optionHtml = '';
        jQ(elOptions).each(function() {
            if (this.selected == true) {
                selectVal = this.text;
                optionHtml += ('<li class="selected">' + this.text  + '</li>');                                        
            } else {
                optionHtml += ('<li>' + this.text  + '</li>');
            }
        });

        jQ(elFakeSelectBox).html(optionHtml);
        jQ(elSelect).parent().find('div.select_cover').html(selectVal);
  	},
  
    /**
     * Zvyraznuje vybrany option
     *
     * @param DOMobject elOption Vybrana polozka li
     */
    setSelectedOption : function(elOption) {
        jQ(elOption).parent().find('li').removeClass(this.classSelectOption);
        jQ(elOption).addClass(this.classSelectOption);
    },
    
    /**
     * Otvira/zavira seznam polozek selectBoxu
     * 
     * @param elSelectBox
     */
    visibilityOptionList : function(elSelectBox) {
        var elScroll =  jQ(elSelectBox).find('div.' + this.classScroll);
        var setActive = false;
        
        // Zavira veskere selectBoxy
        if (jQ(elScroll).hasClass(this.classHide)) {
            this.closeAllSelectBox();
        } else {
            this.closeAllSelectBox();
            jQ(elScroll).removeClass(this.classHide);
        }

                
        // Nastavuje prvni inicializaci comba
        if (elScroll.length == 0)  {
            var elOptionBox = jQ(elSelectBox).find('div.' + this.classBoxOptions);
            jQ(elOptionBox).removeClass(this.classHide).addClass(this.classShow);
            this.setScroll(elOptionBox);
            setActive = true;
        }
        var selIndex = jQ(elSelectBox).find('select')[0].selectedIndex;
        this.setPositionScroll(elSelectBox, selIndex);
        
        // Pridava tridu pro zvirazneni ikony pro rozbaleni comboBoxu
        if (jQ(elScroll).hasClass(this.classHide) || setActive) {
            jQ(elScroll).removeClass(this.classHide);
            jQ(elSelectBox).find('span').addClass('active');
            this.activeSelect = true;
        } else {
            jQ(elScroll).addClass(this.classHide);
            jQ(elSelectBox).find('span').removeClass('active');          
            this.activeSelect = false;
        }
    },
    
    /**
     * Pridava scroll
     *
     * @param DOMobject DOM objekt, na ktery bude scroll aplikovan
     */
    setScroll : function(elObject) {
        jQ(elObject).jScrollPane({
            showArrows: true,
            dragMinHeight: 10,
            scrollbarWidth: 17,
            enableKeyboardNavigation: false,
            scrollbarMargin: 0,
            maintainPosition: true
        });
    },
    
    /**
     * Zavira ceskere komboBoxy
     */
    closeAllSelectBox : function() {
        this.activeSelect = false;
        var elSelectBox = jQ('div.' + this.classSelectBox + '.bound');
        var elScroll =  jQ(elSelectBox).find('div.' + this.classScroll);
        jQ(elScroll).addClass(this.classHide);
        jQ(elSelectBox).find('span').removeClass('active');
    }

}

/**
 * Komponenta inputu type radio
 * Pro funkcnost staci zavolat metodu create
 */
inputRadio = {

    /**
     * @var DOMobject elRadio Object s komponentami
     */
    elRadio : null,

    /**
     * Zakladni fce, jez se volan na onLoad
     * Nastavuje udalosti pro funkcnost komponenty
     */
    create : function() {
        
        var thisObject = this;    

        // Nastavi tridu, ktera oznaci, ze udalost byla nastavena
        this.elRadio = jQ('span.ui-radio.unbound');
   
        jQ(this.elRadio).removeClass('unbound').addClass('bound');
   
        // Neexistuji-li zadne formulare ukoncuje nastavovani
        if (this.elRadio.length == 0) {
            return false;
        }
    
        // Nastavuje a definuje fce na realne formulare
        jQ(this.elRadio).parent().click(function() {
            jQ(this).find('span span').click();    
        });
    
        // Nastavuje a definuje fce na realne formulare
        jQ('input', this.elRadio).change(function() {
            thisObject.setChoose(this);        
        });
    
        // Nastavuje a fce na fake formular
        jQ('span', this.elRadio).click(function() {
            var elInput = jQ(this).parent().find('input');
            thisObject.setChoose(elInput);
        });
        
    },
    
    /**
     * Nastavuje hodnotu inputu a ovlivnuje vsechny spriznene
     *
     * @param DOMobject elInput Vybrany input
     */
    setChoose : function(elInput) {
    
        var inputName = jQ(elInput).attr('name');
        var elAllInput = jQ(this.elRadio).find('input:radio[@name=' + inputName + ']');
    
        // Nastavi unchecked pro skupinu inputu
        jQ(elAllInput).removeAttr('checked');
        jQ(elAllInput).parent().find('span').removeClass('checked').addClass('unchecked');
    
        // Nastavi checked pro aktivni input
        jQ(elInput).attr('checked', 'checked');
        jQ(elInput).parent().find('span').removeClass('unchecked').addClass('checked');
    }
}

/**

 * Komponenta inputu type checkbox

 * Pro funkcnost staci zavolat metodu create

 */

inputCheckbox = {

    /**
     * @var DOMobject elCheckbox Object s komponentami
     */
    elCheckbox : null,

    /**
     * Zakladni fce, jez se volan na onLoad
     * Nastavuje udalosti pro funkcnost komponenty
     */
    create : function() {

        var thisObject = this;    

        this.elCheckbox = jQ('span.ui-checkbox.unbound');

        jQ(this.elCheckbox).removeClass('unbound').addClass('bound');        

        // Neexistuji-li zadne formulare ukoncuje nastavovani
        if (this.elCheckbox.length == 0) {
            return false;
        }

        // Nastavuje a definuje fce na realne formulare
        jQ('input', this.elCheckbox).bind('change', function() { 

            var elInputFake = jQ(this).prev();

            if (this.checked == true) {
                jQ(elInputFake).addClass('checked');
            } else {
                jQ(elInputFake).removeClass('checked');
            }
        });
        
        // Nastavuje a definuje fce na realne formulare
        jQ('.ui-checkbox span').bind('click', function(event) {

            var elInput = jQ(this).next();
            
            // Pokud je formular obalen do labelu, vyvola se pouze change realneho
            if (jQ(this).parent().parent('label').length == 0) {   
                if (jQ(elInput).is(':checked') == true) {
                    jQ(elInput).attr('checked', false);
                    jQ(this).removeClass('checked');
                } else {
                    jQ(elInput).attr('checked', true);
                    jQ(this).addClass('checked');
                }
            } else {
                jQ(elInput).change();
            }
        });
        
    }
}
