/* labely */
var Labels = {
    //pouzito jako macro v HelpdeskMacros
    //Form
    formBusy: 'Odesílám...',
    formError: 'Formulář obsahuje chyby, opravte prosím červeně vyznačená pole',

    // MultipleAttachments
    addFile: 'Přidat přílohu',

    //CoSubmitters
    addCoSubmitter : 'Přidat spoluzadavatele',

    // ProgressIndicator
    loading: 'Načítá se',
    abort: 'Zrušit akci',

    // Calendars
    calMonthLong: ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"],
    calDayShort: ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"],
    calNowButtonLabel: 'Nyní',
    calClearButtonLabel: 'Vymazat',
    multiselectbox: {checkAllText: 'Označit vše', uncheckAllText: 'Odznačit vše', noneSelectedText: 'Vyberte možnosti', selectedText: '# vybráno'}
}

/* pomocne funkce */

/* jQuery extensions */
$.fn.extend({
    nextTextNodeValue: function() {
        var n = this.get(0);
        n = n.nextSibling;
        while(n && n.nodeType != 3) {
            n = n.nextSibling;
        }
        return (n) ? n.nodeValue : '';
    }
});

/* HelpDesk framework */
var HD = {
    /* registruje event listener - deprecated */
    on: function (field_name, event, action, conditional_function) {
        HD.log('Registering on'+event+' event on ' + field_name);
        var field = YAHOO.util.Dom.getElementsBy(
          function (el) { return (el.getAttribute('name') == field_name); },
          null,
          document.body
        );
        if (field.length < 1) return;
        field = field[0];
        YAHOO.util.Event.on(field, event, function() {
            if (typeof conditional_function == 'function') {
                if (!conditional_function(field)) return;
            }
            action(field);
        });
    },
    getURLVar: function(varName) {
        var results = new RegExp('[\\?&]' + varName + '=([^&#]*)').exec(window.location.href);
        return results ? results[1] : false;
    },
    setURLVar: function (url, varName, varValue) {
        if (typeof url == 'object')
            url = url.toString();
        HD.log('Setting var ' + varName + ' to URL ' + url);
        var halves = url.split('?');
        if (halves[1]) {
            var parts = halves[1].split('&');
            var vars = [];
            for (var i = 0; i < parts.length; i++) {
                if (parts[i].substring(0, varName.length) != varName)
                    vars.push(parts[i]);
            }
            vars.push(varName + "=" + varValue);
            return halves[0] + "?" + vars.join('&');
        } else {
            return halves[0] + "?" + varName + "=" + varValue;
        }
    },
    redirect: function(href) {
        window.location.replace(href);
    },
    /* Log function, writes into browser console (IE8 or Firefox/Firebug) */
    log: function (message) {
	     if (typeof console === "object") console.info(message);
    },
    switchLanguage: function(lang){
        HD.redirect(HD.setURLVar(window.location, 'lang',lang));
        return false;
    },
    keepLoginOnline: function(){
        $.get('../servlet/HelpdeskKeepLogin', null, function(xml){
            if($(xml).find('Logged').text() == 'true'){
                setTimeout(HD.keepLoginOnline, 10*60*1000);
            }
        }, 'xml');
    }
};

/* Cookies */
var Cookie = {
    set: function(name, value, seconds) {
        var expires;
	    if (seconds) {
	    	var date = new Date();
	    	date.setTime(date.getTime() + (seconds * 1000));
	    	expires = "; expires=" + date.toGMTString();
	    }
	    else expires = "";
	    document.cookie = name + "=" + value + expires + "; path=/";
    },
    get: function(name) {
	    var nameEQ = name + "=";
	    var ca = document.cookie.split(';');
	    for(var i = 0; i < ca.length; i++) {
	    	var c = ca[i];
	       	while (c.charAt(0)==' ') c = c.substring(1, c.length);
	    	if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
	    }
	    return null;
    },
    unset: function(name) {
        if (Cookie.get(name))
            document.cookie = name + "=;expires=Thu, 01-Jan-1970 00:00:01 GMT";
    },
    toJSON: function (obj) {
        switch (typeof obj) {
            case 'object':
                if (obj) {
                    var list = [];
                    if (obj instanceof Array) {
                        for (var i=0;i < obj.length;i++) {
                            list.push(Cookie.toJSON(obj[i]));
                        }
                        return '[' + list.join(',') + ']';
                    } else {
                        for (var prop in obj) {
                            list.push('"' + prop + '":' + Cookie.toJSON(obj[prop]));
                        }
                        return '{' + list.join(',') + '}';
                    }
                } else {
                    return 'null';
                }
            case 'string':
                return '"' + obj.replace(/(["'])/g, '\\$1') + '"';
            case 'number':
            case 'boolean':
                return new String(obj);
        }
    },
    parseJSON: function(JSONString) {
        HD.log(JSONString);
        var out;
        eval('out = ' + JSONString);
        return out;
    }
}

/* HelpDesk progress indikátor (loading bar) */
var ProgressIndicator = {
    autoPreload: true,
    abortTimeout: null,
    preload: function() {
        HD.log('Preloading progress indicator');
        $(document.body).prepend('<div id="progress_indicator"><div id="progress_container">'
                + '<img src="../_images/loader.gif" width="32" height="32" /><p>'
                + Labels.loading + '</p></div></div>');
    },
    check: function() {
        if (!$('#progress_indicator')) ProgressIndicator.preload();
    },
    get: function() {
        HD.log('Attempting to get progress indicator');
        ProgressIndicator.check();
        return $('#progress_indicator');
    },
    show: function() {
        HD.log('Showing progress indicator');
        ProgressIndicator.check();
        $('#progress_indicator').css('display', 'block');
        ProgressIndicator.abortTimeout = setTimeout(ProgressIndicator.showAbortButton, 5000);
    },
    hide: function() {
        HD.log('Hiding progress indicator');
        ProgressIndicator.check();
        $('#progress_indicator').css('display', 'none');
    },
    showAbortButton: function() {
        ProgressIndicator.get().find('#progress_container')
            .append('<p><input type="button" name="abort" value="' + Labels.abort + '"/></p>');
        ProgressIndicator.get().find('input[name=abort]').click(function () {
            Form.backup();
            ProgressIndicator.abort();
            ProgressIndicator.hide();
        });
    },
    abort: function() {
        try {
            if ($.browser.msie) {
                document.execCommand("Stop");
            } else {
                window.stop();
            }
        }
        catch (error) {
            window.location.reload();
        }
    }
}

var Form = {
    autoConfig: true,
    registry: new Array(),
    originalValues: {},
    isValid: true,
    dynamicFieldDefinitions: null,
    /* zaregistruje hlavni handler pro odesilani formulare */
    bindSubmitEvent: function(){
        HD.log('Registering form onSubmit event handler');
        $('#hd_form').submit(function(event) {
            if (!Form.process()) event.preventDefault(); // zrusi submit event, pokud formular obsahuje chyby
        });
    },
    escape: function(field_name) { // escapovani kvuli jQuery selectorum - nova verze JQuery nepodporuje, nutne selector obalit uvozovkami
        return '"'+field_name+'"';
    },
    /* vrati DOM node specifickeho formularoveho prvku */
    getField: function(field_name, matchAll) {
        field_name = Form.escape(field_name);
        return $('#hd_form *' + (matchAll ? '' : ':first') + '[name=' + field_name + ']');
    },
    registerValidator: function(fieldName, validatorFunction) {
        HD.log('Registering validator for ' + fieldName);
        Form.registry.push(Array(fieldName, validatorFunction));
        var field = Form.getField(fieldName);
        if (field.length)
            Form.originalValues[fieldName] = field.val();    
    },
    registerDynamicFieldsValidator: function(fieldName) {
        HD.log('Registering dynamic fields validator for ' + fieldName);
        Form.registry.push(Array(fieldName, Form.dynamicFieldValidator));
    },
    assignDefaultValidators: function() {
        HD.log('Initializing auto-validation');
        $('span[class=field_required]').each(
            function (){
                var span = $(this);
                var fieldName = span.attr('rel');
            var field = Form.getField(fieldName);
                if(!field.length) return;
                if(fieldName.substr(0,14) == 'dynamicFields.')
                    Form.registerDynamicFieldsValidator(fieldName);
                else
                switch (fieldName) {
                    case 'hd_priority':
                        Form.registerValidator(fieldName, Form.hasChanged);
                        break;
                    case 'hd_e_mail':
                        Form.registerValidator(fieldName, Form.isEmail);
                        break;
                    case 'hd_phone':
                            Form.registerValidator(fieldName, Form.isPhone);
                        break;
                    default:
                        Form.registerValidator(fieldName, Form.isNotEmpty);
                }
                var label = $('label[for="' + fieldName + '"]');
                if (label.length) {
                    label.text(label.text() + '*');
                    span.css('display', 'none');
                }
            }
        );
        HD.log('Auto-validation initialized');
    },

    /* zvaliduje cely formular */
    process: function() {
        HD.log('Validating HD form');
        var sbm = Form.getField('hd_submit').get(0);
        var oldSubmitValue = sbm.value;
        sbm.value = Labels.formBusy;
        Form.isValid = true;
        for (var i = 0; i < Form.registry.length; i++) {
            var field = Form.getField(Form.registry[i][0]);
            if (!field.length) continue;
            HD.log('Validating ' + field);
            var valFunction = Form.registry[i][1];
            if (!valFunction(field.get(0))) {
                field.addClass('notValid');
                HD.log('Validation of ' + field.name + ' unsuccessful');
                Form.isValid = false;
            } else{
                field.removeClass('notValid');
                HD.log('Validation of ' + field.name + ' successful');
            }
        }
        if (!Form.isValid) {
            alert(Labels.formError);
            //sbm.disabled = false;
            sbm.value = oldSubmitValue;
        }
        return Form.isValid;
    },
    /* validacni funkce */
    isNotEmpty: function(field) {
      return field.value != "";
    },
    isPhone: function(field){
	    var numericExpression = /^\+?[0-9]+$/;
	    return field.value.match(numericExpression);
    },
    isNumeric: function(field){
	    var numericExpression = /^[0-9](\.[0-9]+)?$/;
	    return field.value.match(numericExpression);
    },
    isAlphabet: function (field) {
	    var alphaExp = /^[a-zA-Z]+$/;
	    return field.value.match(alphaExp);
    },
    isAlphanumeric: function (field) {
	    var alphaExp = /^[0-9a-zA-Z]+$/;
	    return field.value.match(alphaExp);
	},
    isEmail: function (field) {
	    var emailExp = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/;
	    return field.value.match(emailExp);
	},
    isDate: function (field) {
	    var dateExp = /^(([0-2]?[0-9])|30|31)\.([1-9]|10|11|12)\.[1-2][0-9]{3}$/;
	    return field.value.match(dateExp);
	},
    isDateTime: function (field) {
	    var dateTimeExp = /^(([0-2]?[0-9])|30|31)\.([1-9]|10|11|12)\.[1-2][0-9]{3}\ (([0-1]?[0-9])|20|21|22|23)\:[0-5][0-9]$/;
	    return field.value.match(dateTimeExp);
	},
    isTime: function (field) {
	    var timeExp = /^(([0-1]?[0-9])|20|21|22|23)\:[0-5][0-9]$/;
	    return field.value.match(timeExp);
	},
    hasChanged: function (field) {
        return $(field).val() != Form.originalValues[field.getAttribute('name')];
    },
    dynamicFieldValidator: function(field){
        var isValid = false;
        if(Form.dynamicFieldDefinitions == null){
            $.ajax({url:'ajaxFunctionServlet', data: {
                functionName: 'cz.bellman.jobpool.functions.DynamicFieldRequiredValueValidator',
                id: document.getElementsByName('id').length > 0 ? document.getElementsByName('id')[0].value : '',
                pool: document.getElementsByName('pool').length > 0 ? document.getElementsByName('pool')[0].value : '',
                fieldName: field.getAttribute('name').substr(14),
                fieldValue: $(field).val()
            }, success: function(data) {
                isValid = $(data).find('Validate').attr('isValid') == 'true';
            },async: false});
        }
        return isValid;
        /*var jqField = $(field);
        var defaultValue = Form.dynamicFieldDefinitions[field.getAttribute('name')].defaultValue;
        switch(Form.dynamicFieldDefinitions[jqField.getAttribute('name')].type){
            case 9: //Date
                return Form.isNotEmpty(field) && Form.isDate(field);
            case 11://DateTime
                return Form.isNotEmpty(field) && Form.isDateTime(field);
            case 13://Time
                return Form.isNotEmpty(field) && Form.isTime(field);
            case 10://Counter
                return Form.isNotEmpty(field) && Form.isNumeric(field) && $(field).val() != '0';
            case 12://Number
                if($(field).val() != defaultValue)
                    return !(defaultValue!='' && !Form.isNotEmpty(field));
        return false;
            case 3: //Checkbox
                return (defaultValue == "off" && ($(field).val() == "on" || $(field).val() == "true"))
                        || (defaultValue == "on" && ($(field).val() == "off" || $(field).val() == "false"));
            default:
                return $(field).val() != defaultValue;
        }*/
    },
    /* form backup and restore */
    getFields: function() {
        HD.log('Getting HD form fields');
        return $('#hd_form :input');
    },
    getFieldValues: function () {
        var fields = Form.getFields(); // fields je jQuery object
        var out = {};
        for (var i = 0; i < fields.length; i++) {
            var  field = fields.get(i);
            if (field.nodeName == 'SELECT' || field.nodeName == 'TEXTAREA' || field.type == 'text') {
                out[field.getAttribute('name')] = field.value;
                continue;
            }
            if (field.type == 'radio' || field.type == 'checkbox') {
                out[field.getAttribute('name')] = field.checked;
                continue;
            }
        }
        return out;
    },
    backup: function() {
        var fields = Form.getFieldValues();
        HD.log(fields);
        Cookie.set('hd_form_data', Cookie.toJSON(fields), 20);
        HD.log('HD form data was saved into cache');
        return true;
    },
    restore : function () {
        if (!Cookie.get('hd_form_data')) return;
        var fieldValues = Cookie.parseJSON(Cookie.get('hd_form_data'));
        var fields = Form.getFields(); // fields je jQuery object
        for (var i = 0; i < fields.length; i++) {
            var  field = fields.get(i);
            if (field.nodeName == 'SELECT' || field.nodeName == 'TEXTAREA' || field.type == 'text') {
                field.value = fieldValues[field.name];
                continue;
            }
            if (field.type == 'radio' || field.type == 'checkbox') {
                field.checked = fieldValues[field.name];
                continue;
            }
        }
        Cookie.unset('hd_form_data');
        HD.log('HD form data was restored');
    },
    makeFieldEditable: function(name, settings){
        var fieldHidden = Form.getField(name);
        if(fieldHidden.get(0).type == 'hidden'){
            var fieldInput = $('<input type="text" name="'+name+'" value="'+fieldHidden.get(0).value+'"/>');
            if(settings != null)
                for(var key in settings)
                    fieldInput.attr(key, settings[key]);
            fieldHidden.parent().replaceWith(fieldInput);
        }
    }
};

/* vicenasobne prilohy */
var MultipleAttachments = {
    autoConfig: true,
    /*
     * Tato funkce premeni pole input_name na "multiple" pole s moznosti pridavani
     * a ubirani jednotlivych poli. Kolem inputu se vytvori kontejner a v registru
     * se ulozi kopie puvodniho pole obalena dalsim kontejnerem a s tlacitkem pro
     * vymazani, ktera se pak vklada do hlavniho kontejneru pri pridavani prilohy
     * Pozn: input_name je treba zadavat bez koncovych "[]"
     */
    register: function(input_name, addFileLabel) {
        HD.log('Registering multiple attachments for ' + input_name);

        if (input_name.substring(input_name.length - 2, input_name.length) == "[]")
            input_name = input_name.substring(0, input_name.length - 2);

        var input = $('#hd_form :file[name=' + Form.escape(input_name+'[]') + ']').eq(0);
        if (!input.length) { HD.log(input.length);
          HD.log('File input ' + input_name + ' not found'); return;
        }

        var container = $('<div class="multiple_attachments_container"></div>');

        var closingInput = $('<p class="file_container"><a href="javascript:void(0);">'
                + '<img src="../_images/helpdesk/cross.png" alt="X" width="16" height="16" /></a></p>')
                .prepend(input.clone());

        var addContainer = $('<p class="multiple_attachments_add"><span>'
                + '<img src="../_images/helpdesk/attachment_blue.png" alt="+" width="12" height="12" />'
                + ' <a href="javascript:void(0);">'
                + (addFileLabel ? addFileLabel : Labels.addFile) +'</a></span></p>');

        input.replaceWith(container.append(addContainer));

        container.data('file_input', closingInput.clone());

        addContainer.find('span').click(function() {
                    var newClosingInput = $(this).closest('div').data('file_input').clone()
                    $(this).closest('p').before(newClosingInput);
                    newClosingInput.find('a').click(function() {
                        $(this).closest('p').remove();
                    });
                });
        addContainer.find('span').hover(
            function () {
                $(this).css('cursor', 'pointer');
            },
            function() { }
        );
        addContainer.find('span').trigger('click'); // vlozi prvni file input
        HD.log('Multiple attachments registered');
    }
};

/* AutoComplete */
var AutoComplete = {
    registry: [],
    registryWaiting: [],
    autoPreload: true,
    settings: {
        parse: function(xml) {
            var results = [];
            var attributes = this.responseSchema.fields;
            $(xml).find(this.responseSchema.resultNode).each(function() {
                var row = {};
                for(var keyIndex in attributes){
                    var key = attributes[keyIndex];
                    row[key] = jQuery(this).attr(key);
                }
                results[results.length] = {data: row, value: row[attributes[1]], result: row[attributes[0]]};
            });
            return results;
        },
        formatItem: function(data) {
            return data[this.responseSchema.fields[0]];
        },
        formatResult: function(data) {
            return data[this.responseSchema.fields[1]];
        },
        onSelect: function (event, data, formatted) {},
        mustMatch: false,
        minChars: 0,     //bylo minQueryLength: 0,
        responseSchema: {
            resultNode: 'user',
	        fields: ["username", "userid", "company", "email", "phone", "note"]
	    },
        max: 100,
        extraParams: {}, //bylo requestParams: {},
        onComplete: function(data) {
            HD.log('AutoComplete completely loaded');
        }
    },
    scriptsLoaded: false,
    loadScripts: function() {
        HD.log('Loading AutoComplete scripts');
        //$.ajaxSetup({cache: true});
        $("head").append("<link>");
        var cssEl = $("head").children(":last");
        cssEl.attr({
          rel:  "stylesheet",
          type: "text/css",
          href: "../_css/jquery/jquery.autocomplete.css"
        });
        $.getScript('../_js/jquery/jquery.bgiframe.min.js', function() { $.getScript('../_js/jquery/jquery.autocomplete.pack.js', function() {
            AutoComplete.scriptsLoaded = true;
            HD.log('AutoComplete scripts loaded');
            for(var waitingIndex in AutoComplete.registryWaiting){
                var regAcSetting = AutoComplete.registryWaiting[waitingIndex];
                AutoComplete.register(regAcSetting.fieldName, regAcSetting.requestURL, regAcSetting.options);
            }
        } ); });
        HD.log('End of AutoComplete loading procedure');
    },
    register: function(fieldName, requestURL, options) {

        if (!AutoComplete.scriptsLoaded) {
            AutoComplete.registryWaiting[AutoComplete.registryWaiting.length] = {fieldName: fieldName, requestURL: requestURL, options: options};
            HD.log('AutoComplete on ' + fieldName + ' add to register queue');
            return;
        }
        HD.log('Registering AutoComplete on ' + fieldName);

        var field = Form.getField(fieldName);
        if (!field.length) {
            HD.log('Error: field ' + fieldName + ' not found');
            return;
        }
        var acSettings = new Array();
        $.extend(acSettings, AutoComplete.settings, options);

        HD.log(acSettings.responseSchema);

        field.autocomplete(requestURL, acSettings);
        field.result(acSettings.onSelect);

	    var data = { acSettings: acSettings };

        AutoComplete.registry[fieldName] = data;

        AutoComplete.updateExtraParams(fieldName, acSettings.extraParams);

        if (acSettings.onComplete && $.isFunction(acSettings.onComplete)) {
            acSettings.onComplete(data);
        }
        return data;
    },
    updateExtraParams: function(fieldName, extraParams){
        $.extend(AutoComplete.registry[fieldName].acSettings.extraParams, AutoComplete.registry[fieldName].acSettings.extraParams, extraParams);
    }
};

/* Sortable tables */
var SortableTable = {
    sortingParsers: {
        'string': function(node) {
            return node.text();
        },
        'number': function(node) {
            return node.text();
        },
        'date': function(node) {
            var text = node.text();
            var dateRegexp = new RegExp("^([0-9]{1,2})(\.|\/)([0-9]{1,2})(\.|\/)([0-9]{4})$");
            var dateParts = dateRegexp.exec(text);
            if(dateParts == null)
                return "9999-99-99";
            return "" + dateParts[5]
                        + (dateParts[3].length < 2 ? '0' + dateParts[3] : dateParts[3])
                        + (dateParts[1].length < 2 ? '0' + dateParts[1] : dateParts[1]);
        },
        'datetime': function(node) {
            var text = node.text();
            var dateRegexp = new RegExp("^([0-9]{1,2})(\.|\/)([0-9]{1,2})(\.|\/)([0-9]{4})( )([0-9]{1,2})(\:)([0-9]{1,2})$");
            var dateParts = dateRegexp.exec(text);
            if(dateParts == null)
                return "9999-99-99 99:99";
            return "" + dateParts[5]
                        + (dateParts[3].length < 2 ? '0' + dateParts[3] : dateParts[3])
                        + (dateParts[1].length < 2 ? '0' + dateParts[1] : dateParts[1])
                        + (dateParts[7].length < 2 ? '0' + dateParts[7] : dateParts[7])
                        + (dateParts[9].length < 2 ? '0' + dateParts[9] : dateParts[9]);
        }
    },
    getTableObject: function(table){
        if (typeof table != "object") {
            return $('#' + table);
        } else {
            return $(table);
        }
    },
    getThIndex: function(th){
        if (typeof th != "object") {
            return th;
        } else {
            return $(th).prevAll().length;
        }
    },
    registry: [],
    register: function(table) { /* table element or ID */
        HD.log('Registering sorting table');
        table = SortableTable.getTableObject(table);
        var keys = new Array();
        table.find('thead th').each(function() {
            keys.push($(this).attr('rel'));
            if (!$(this).attr('rel')) return;
            $(this).wrapInner('<a href="javascript:void(0);"></a>').append('<span></span>');
            $(this).find('a').click(function() {
                SortableTable.sortBy(this.parentNode, table);
            }).focus(function() {
                $(this).blur();
            });
        });
        HD.log(keys);
        var cache = new Array();
        table.find('tbody tr').each(function() {
            var tds = $(this).find('td');
            var td, i, key;
            for (i = 0; i < tds.length; i++) {
                td = $(tds[i]);
                key = keys[i];
                if (td.attr('rel') || !key) continue;
                if (key && $.isFunction(SortableTable.sortingParsers[key])) {
                    td.attr('rel', SortableTable.sortingParsers[key](td));
                } else {
                    HD.log('Unable to apply sorting key ' + key);
                }
            }
            cache.push(this);
        });
        table.data('cache', cache);
        table.data('current_key', -1);
        table.data('current_sort_order', 0);
        if (table.attr('id')) SortableTable.registry[table.attr('id')] = table;
        SortableTable.sortByCookie(table);
        return table;
    },
    // current_key : index sloupce
    // current_sort_order: 0:vzestupne, 1:sestupne
    sortBy: function(thIndex, table) {
        table = SortableTable.getTableObject(table);
        var key = SortableTable.getThIndex(thIndex);
        HD.log("Table header index "+key);
        var currentKey = table.data('current_key');
        if (key != currentKey) {
            table.data('current_key', key);
            SortableTable.sortCache(table);
        }else if (table.data('not_revert_sort_order') == null) {
            SortableTable.revertCache(table);
        }
        table.data('not_revert_sort_order', null);
        var cache = SortableTable.initCache(table);
        var tBody = $('<tbody></tbody>');
        for (var i = 0; i < cache.length; i++) {
            tBody.append(cache[i]);
        }
        table.find('tbody').replaceWith(tBody);
        table.data('cache', cache);
        SortableTable.saveSortIntoCookie(table);
        table.find('thead th span').empty();
        table.find('thead th').eq(key).find('span').empty().html(table.data('current_sort_order') ? '&darr;' : '&uarr;');
    },
    sortByCookie: function(table){
        var str = Cookie.get('HD_table_sort');
        if(str != null){
            var key = str.substr(0, str.indexOf(" "));
            var sortOrder = str.substr(str.indexOf(" ")+1);
            table.data('current_key', key);
            SortableTable.sortCache(table);
            table.data('not_revert_sort_order', table.data('current_sort_order') == (sortOrder == "0" ? 0 : 1) ? 1 : null);
            SortableTable.sortBy(key, table);
        }
    },
    saveSortIntoCookie: function(table){
        var key = table.data('current_key');
        if(key != null && key >= 0){
            var str = table.data('current_key') + " " + table.data('current_sort_order');
            Cookie.set('HD_table_sort', str, 600);
        }
    },
    initCache: function(table){
        var cache = table.data('cache');
        if (!$.isArray(cache)) {
            cache = new Array();
            table.find('tbody tr').each(function () {
                cache.push(this);
            });
        }
        return cache;
    },
    sortCache: function(table){
        HD.log('Sorting table');
        var key = table.data('current_key');
        var cache = SortableTable.initCache(table);
        cache.sort(function(n1, n2) {
            n1 = $(n1).find('td')[key].getAttribute('rel');
            n2 = $(n2).find('td')[key].getAttribute('rel');
            if(n1 == undefined || n2 == undefined){
                if(n1 != undefined) return 1;
                if(n2 != undefined) return -1;
                return 0;
            }
            var f1 = parseFloat(n1);
            var f2 = parseFloat(n2);
            if (!isNaN(f1) && !isNaN(f2)) {
                if (f1 < f2)return -1;
                if (f1 > f2)return 1;
                return 0;
            }
            n1 = n1.toLowerCase();
            n2 = n2.toLowerCase();
            if (n1 < n2)return -1;
            if (n2 < n1)return 1;
            return 0;
        });
        table.data('current_sort_order', 0);
    },
    revertCache: function(table){
        HD.log('Reversing table');
        var cache = SortableTable.initCache(table);
        cache.reverse();
        table.data('current_sort_order', (table.data('current_sort_order') + 1) % 2);
    }
};

/*Objekt pro Javascriptove zmeny SLA
*   vyzaduje definovani polozky schemasMap - objekt sla definicí*/
var Sla = {
    autoConfig: true,
    initialized: false,
    schemaField: null,
    priorityField: null,
    schemasMap: null,
    init: function(){
        HD.log('Initializing Sla');
        if(!Sla.isSlaPresent()){
            HD.log('Sla components not found');
            return;
        }
        // nastavi aktualni schema
        Sla.schemaField.val(Sla.schemasMap.currentSchema);
        // nacte priority k danemu sla schematu
        Sla.updateSlaPriorities();
        // nastavi aktualni prioritu v ramci schematu
        Sla.priorityField.val(Sla.schemasMap.currentPriority);
        // po zmene schematu nacte nove priority
        Sla.schemaField.change(Sla.updateSlaPriorities);
        HD.log('Initialized Sla');
    },
    updateSlaPriorities: function() {
        HD.log('Updating Sla priorities');
        if(!Sla.isSlaPresent()){
            HD.log('Sla components not found');
            return;
        }
        var schemaBox = Sla.schemaField.get(0);
        var priorityBox = Sla.priorityField.get(0);
        for(var x = priorityBox.options.length-1; x >= 0; x--) // vymaze select box
            priorityBox.remove(x);
        if(typeof(Sla.schemasMap.schemas[schemaBox.value]) == "undefined")
            return;
        var schema = Sla.schemasMap.schemas[schemaBox.value];
        var newPriorityMap = schema.priorities;
        for (var priorityId in newPriorityMap)
            priorityBox.options[priorityBox.options.length] = new Option(newPriorityMap[priorityId], priorityId);
        priorityBox.value = schema.defaultPriority;
        HD.log('Updated Sla priorities');
        HD.log('Update Sla priorities - evaluating afterUpdateSla function');
        Sla.afterUpdateSla();
        HD.log('Update Sla priorities - evaluated afterUpdateSla function');
    },
    isSlaPresent: function(){
        if(Sla.schemaField == null)
            Sla.schemaField = Form.getField('hd_sla_schema');
        if(Sla.priorityField == null)
            Sla.priorityField = Form.getField('hd_sla_priority');
        return Sla.schemasMap != null && Sla.schemaField.length > 0 && Sla.priorityField.length > 0;
    },
    afterUpdateSla: function(){

    }
};

/* spoluzadavatele */
var CoSubmitters = {
    autoConfig: true,
    index: 0,
    nextIndex: function(){
        return CoSubmitters.index++;
    },
    /*
     * Tato funkce premeni pole input_name na "multiple" pole s moznosti pridavani
     * a ubirani jednotlivych poli. Kolem inputu se vytvori kontejner a v registru
     * se ulozi kopie puvodniho pole obalena dalsim kontejnerem a s tlacitkem pro
     * vymazani, ktera se pak vklada do hlavniho kontejneru pri pridavani spoluzadavatele
     */
    register: function() {
        HD.log('Registering co-submitters');
        var input_name = "hd_coSubmitters";

        var coSubmittersSpan = $('#hd_form span[name=' + Form.escape(input_name+"_span") + ']');
        if (!coSubmittersSpan.length) {
            HD.log('Co-submitters span not found');
            return;
        }

        var container = $('<div class="multiple_coSubmitter_container"></div>');

        var closingInput = $('<p class="coSubmitter_container"><input name="hd_coSubmitters[]" type=\"hidden\"/><input name="hd_coSubmitters[]_typeBox"/>' +
                             '<a href="javascript:void(0);"><img src="../_images/helpdesk/cross.png" alt="X" width="16" height="16" /></a></p>');

        var addContainer = $('<p class="multiple_coSubmitter_add"><input name="hd_coSubmitters_submitted" type=\"hidden\" value="true"/><span>'
                + '<img src="../_images/helpdesk/attachment_blue.png" alt="+" width="12" height="12" />'
                + '<a href="javascript:void(0);">' + Labels.addCoSubmitter + '</a></span></p>');

        container.data('coSubmitter_templateItem', closingInput.clone());

        $('#hd_form span[rel][name=' + Form.escape(input_name+'[]') + ']')
            .each(function(){
                var item = closingInput.clone();
                container.append(item);
                item.find('a').click(function() {
                    $(this).closest('p').remove();
                });
                item.find('input').get(0).value = $(this).attr('rel');
                item.find('input').get(1).value = $(this).text();
                var nameTypeBox = 'hd_coSubmitters'+CoSubmitters.nextIndex()+'_typeBox';
                item.find('input[name="hd_coSubmitters[]_typeBox"]').attr('name',nameTypeBox);
                eval("AutoComplete.register('"+nameTypeBox+"', '../loadHelpdeskAuthenticationSubusers', { onSelect : function (event, data, formatted) {"+
                                     "$(this).closest('p').find('input').get(0).value = data['userid'];" +
                                 "}, onComplete: function(data) { $(this).after($(this).closest('p').find('a')) } }, 0);");
            });

        coSubmittersSpan.replaceWith(container.append(addContainer));

        addContainer.find('span').click(function() {
            var newClosingInput = $(this).closest('div').data('coSubmitter_templateItem').clone();
            $(this).closest('p').before(newClosingInput);
            newClosingInput.find('a').click(function() {
                $(this).closest('p').remove();
            });
            var nameTypeBox = 'hd_coSubmitters'+CoSubmitters.nextIndex()+'_typeBox';
            newClosingInput.find('input[name="hd_coSubmitters[]_typeBox"]').attr('name',nameTypeBox);
            eval("AutoComplete.register('"+nameTypeBox+"', '../loadHelpdeskAuthenticationSubusers', { onSelect : function (event, data, formatted) {"+
                                 "$(this).closest('p').find('input').get(0).value = data['userid'];" +
                             "}, onComplete: function(data) { $(this).after($(this).closest('p').find('a')) } }, 0);");
        });
        addContainer.find('span').hover(
            function () {
                $(this).css('cursor', 'pointer');
            },
            function() { }
        );
        //addContainer.find('span').trigger('click'); // vlozi prvni file input

        HD.log('Multiple co-submitters registered');
    }
};

var Calendars = {
    autoConfig: true,
    scriptsLoaded: false,
    repeatedRequest: 0,
    globalShowNowButton: true,
    globalShowClearButton: true,
    addZero: function(number) {
        number = ''+number;
        return (number.length < 2) ? "0"+number : number;
    },
    removeZero: function(number) {
        var firstChar = number.substring(0,1);
        return (firstChar == "0") ? number.substring(1) : number;
    },
    loadScripts: function() {
        HD.log('Loading Calendar scripts');
        $("head").append("<link>");
        var css = $("head").children(":last");
        css.attr({
            rel:  "stylesheet",
            type: "text/css",
            href: "../_js/yui27/calendar/assets/calendar.css"
        });
        $.getScript('../_js/yui27/yahoo/yahoo-min.js', function() {
            $.getScript('../_js/yui27/event/event-min.js', function() {
                $.getScript('../_js/yui27/dom/dom-min.js', function() {
                    $.getScript('../_js/yui27/calendar/calendar-min.js', function() {
                        Calendars.scriptsLoaded = true;
                        HD.log('Calendar scripts loaded');
                        Calendars.init();
                    });
                });
            });
        });
        HD.log('End of Calendar loading procedure');
    },
    init: function(){
        HD.log('Initializing Calendars');
        $('input[rel=date], input[rel=datetime]').each(function(){
            Calendars.initCalendar({inputEl:this,showNowButton:false, showClearButton:false});
        });
        HD.log('Initialized Calendars');
    },
    initCalendar: function(args) {
        var inputEl = $(args.inputEl);
        var ID = inputEl.attr('name')+"_calendar_container";
        var container = $("<span class='calendarButtonContainer' id='"+inputEl.attr('name')+"_calendar_container' rel='"+inputEl.attr('name')+" "+inputEl.attr('rel')+"'></span>");
        var button = $("<img id='"+ID +"_button' src='../_js/yui2/button/assets/calendar_icon.gif' alt='Calendar'/>");
        container.append(button);
        container.append($("<span class='calendarMasterContainer'><div class='calendarContainer' id='"+ID+"_calendar_container'></div></span>"));
        inputEl.after(container);

        var oCalendar = new YAHOO.widget.Calendar(ID + '_cal', ID + '_calendar_container');
        oCalendar.cfg.setProperty("start_weekday", 1);
        oCalendar.cfg.setProperty('close', true);
        oCalendar.cfg.setProperty('title', null);
        if (Labels.calMonthLong && Labels.calDayShort) {
            oCalendar.cfg.setProperty("MONTHS_LONG",Labels.calMonthLong);
            oCalendar.cfg.setProperty("WEEKDAYS_SHORT",Labels.calDayShort);
        }

        var selDateTime = inputEl.val();
        if (selDateTime) {
            var date = selDateTime.indexOf(" ") > 0 ? selDateTime.substring(0,selDateTime.indexOf(" ")) : selDateTime;
            var d = date.split(".");
            oCalendar.cfg.setProperty("selected", Calendars.removeZero(d[0])+"/"+Calendars.removeZero(d[1])+"/"+d[2], false);
        }
        oCalendar.selectEvent.subscribe(function (p_sType, p_aArgs) {
            var aDate;
            if (p_aArgs) {
                aDate = p_aArgs[0][0];
                //muze se online menit, je nutne nacist aktualni hodnotu
                var type = $(args.inputEl).attr('rel');
                var calVal = aDate[2]+"."+aDate[1]+"."+aDate[0];
                if (type == "date") {
                    inputEl.get(0).value = calVal;
                } else if (type == "datetime") {
                    if (inputEl.val() != "" && inputEl.val().indexOf(" ") > 0)
                        inputEl.get(0).value = calVal + inputEl.val().substring(inputEl.val().indexOf(" "));
                     else
                        inputEl.get(0).value = calVal + " 00:00";
                }
            }
            oCalendar.hide();
        });

        oCalendar.render();
        oCalendar.hide();
        button.click(function(){ oCalendar.show(); });

        if (Calendars.globalShowNowButton || args.showNowButton) {
            var nowSpan = $("<span class='nowButton'>&nbsp;<a href='javascript:void(0)'>"+Labels.calNowButtonLabel+"</a></span>");
            container.append(nowSpan);
            YAHOO.util.Event.on(nowSpan.find('a'), 'click', function() {
                var date = new Date();
                var type = $(args.inputEl).attr('rel');
                var val = date.getDate() + '.' + (1 + date.getMonth()) + '.' + date.getFullYear();
                if (type == 'datetime') {
                    val += ' ' + date.getHours() + ':';
                    var min = date.getMinutes();
                    if(min < 10) val += '0';
                    val += date.getMinutes();
                }
                inputEl.get(0).value = val;
            });
        }
        if(Calendars.globalShowClearButton || args.showClearButton){
            var cleanSpan = $("<span class='nowButton'>&nbsp;<a href='javascript:void(0)'>"+Labels.calClearButtonLabel+"</a></span>");
            container.append(cleanSpan);
            YAHOO.util.Event.on(cleanSpan.find('a'), 'click', function() {
                inputEl.get(0).value = '';
            });
        }
        return oCalendar;
    }
};

var Multiselects = {
    autoConfig: true,
    scriptsLoaded: false,
    multiselectNames: [],
    loadScripts: function() {
        HD.log('Loading Multiselect scripts');
        //$.ajaxSetup({cache: true});
        $("head").append("<link>");
        var cssEl = $("head").children(":last");
        cssEl.attr({
          rel:  "stylesheet",
          type: "text/css",
          href: "../_css/jquery/jquery-ui-1.8.7.custom.css"
        });
        $("head").append("<link>");
        cssEl = $("head").children(":last");
        cssEl.attr({
          rel:  "stylesheet",
          type: "text/css",
          href: "../_css/jquery/jquery.multiselect.css"
        });
        $.getScript('../_js/jquery/jquery-ui-1.8.7.custom.min.js', function() {
            $.getScript('../_js/jquery/jquery.multiselect.min.js', function() { setTimeout(function() {
                Multiselects.scriptsLoaded = true;
                HD.log('Multiselect scripts loaded');
                Multiselects.initWidget();
            }, 200); });
        });
        HD.log('End of Multiselect loading procedure');
    },
    initWidget: function() {
        for(var multiselectNameIndex in Multiselects.multiselectNames){
            $('select[name="'+Multiselects.multiselectNames[multiselectNameIndex]+'"]').multiselect(Labels.multiselectbox);
        }
    },
    init: function() {
        Multiselects.loadScripts();
    },
    add: function(multiselectName) {
        Multiselects.multiselectNames[Multiselects.multiselectNames.length] = multiselectName;
    }
};

/* Inicializace, spusti se on DOM ready */
$(function() {
    HD.log('Initializing HD');

    // Nastaveni ID pro hlavni HD formular, nutne pro spravnou funkci skriptu
    /*$('form:first').attr('id', 'hd_form');  // nepracuje moc dobře */
    var form = $('form:first').get(0);
    if (form) form.setAttribute('id', 'hd_form');

    // Inicializace formulare, nacteni implicitnich validacnich funkci
    if (Form.autoConfig) {
        Form.bindSubmitEvent(); // inicializuje validaci po odeslani formulare, pri zruseni nutno volat explicitne
        Form.assignDefaultValidators();
    }

    // Inicializace vicenasobnych priloh
    if (MultipleAttachments.autoConfig) {
        $(':file').each(function() {
            MultipleAttachments.register(this.name);
        });
    }

    // Inicializace spoluzadavatelu
    if (CoSubmitters.autoConfig) {
        CoSubmitters.register();
    }

    // Preload progress indicatoru, zacleneni do stranky
    if (ProgressIndicator.autoPreload)
        ProgressIndicator.preload();

    // Nacteni skriptu nutne pro funkci AutoComplete
    if (AutoComplete.autoPreload)
        AutoComplete.loadScripts();

    if(Sla.autoConfig)
        Sla.init();

    if(Calendars.autoConfig){
        Calendars.loadScripts();
    }

    if(Multiselects.autoConfig){
        Multiselects.init();
    }
});
