var qs = {
    scriptBaseUrl: null,

    create: function() {
        return function() {
          this.initialize.apply(this, arguments);
        }
    },

    getScriptBaseUrl: function ()
    {
        if (null === qs.scriptBaseUrl) {
            qs.scriptBaseUrl = BASE_URL + '/js' + SITE_REVISION_SUFFIX;
        }
        return qs.scriptBaseUrl;
    },

    includeBodyScript: function(src)
    {
        $.ajaxSetup({async: false});
        $.getScript(qs.getScriptBaseUrl() + '/' + src);
        $.ajaxSetup({async: true});
    },

    getParentTag: function (obj, tag)
    {
        var tmp = obj;
        while (tmp = tmp.parentNode) {
            if (tmp.nodeName == tag) {
                return tmp;
            }
        }
        return null;
    },

    getPreviousTag: function(obj, tag)
    {
        var tmp = obj;
        while (tmp = tmp.previousSibling) {
            if (tmp.nodeName == tag) {
                return tmp;
            }
        }
        return null;
    },

    getNextTag: function(obj, tag)
    {
        var tmp = obj;
        while (tmp = tmp.nextSibling) {
            if (tmp.nodeName == tag) {
                return tmp;
            }
        }
        return null;
    },

    openPopupByLocation: function(location, target, width, height)
    {
        if (typeof width != 'number') {
            if (width == 'MAX') {
                width = screen.width;
            } else {
                width = screen.width/2;
            }
        }
        if (typeof height != 'number') {
            if (height == 'MAX') {
                height = screen.height;
            } else {
                height = screen.height - screen.height/3;
            }
        }
        var top = screen.height/2-height/2;
        var left = screen.width/2-width/2;
        var params = 'toolbar=0,location=0,menubar=0,resizable=1,status=0,scrollbars=yes,screenX='
                   + left + ',screenY=' + top + ',top=' + top + ',left=' + left
                   + ',width=' + width + ',height=' + height;
        var wnd = window.open(location, target, params);
            wnd.opener = self;
            wnd.focus();
    },

    openPopup: function (a, width, height)
    {
        qs.openPopupByLocation(a.href, a.getAttribute('target'), width, height);
        return false;
    },

    // getElementPos
    getPosition: function (obj)
    {
        var l = 0;
        var t = 0;
        var w = obj.offsetWidth;
        var h = obj.offsetHeight;
        while (obj) {
            l += obj.offsetLeft;
            t += obj.offsetTop;
            if ((obj.tagName != "TABLE") && (obj.tagName != "BODY")) {
                l += (obj.clientLeft)?obj.clientLeft:0;
                t += (obj.clientTop)?obj.clientTop:0;
            }
            obj = obj.offsetParent;
        }
        var res = new Object();
        res.x = l;
        res.y = t;
        res.left = l;
        res.top = t;
        res.w = w;
        res.h = h;
        res.width = w;
        res.height = h;
        return res;
    },

    popupImage: function (url)
    {
        var startW = 150;
        var startH = 100;
        var top = screen.height/2-startH;
        var left = screen.width/2-startW/2;
        var params = 'Toolbar=0,location=0,Menubar=0,resizable=0,Scrollbars=no';//,screenX='+left+',screenY='+top+',top='+top+',left='+left;
        var wnd = window.open('', 'ppimg', params);
        wnd.resizeTo(300, 450);
        wnd.document.writeln('<html>');
        wnd.document.writeln('<head>');
        wnd.document.writeln('<style>');
        wnd.document.writeln('html, body {margin:0px; padding:0px;}');
        wnd.document.writeln('</style>');
        wnd.document.writeln('<script type="text/javascript">');
        wnd.document.writeln('function myResize(w,h){');
        wnd.document.writeln('window.resizeTo(w,h);');
        wnd.document.writeln('}');
        wnd.document.writeln('var img = new Image(); ');
        wnd.document.writeln('window.onload = function(){');
        wnd.document.writeln('img.onload=function(){');
        wnd.document.writeln('document.getElementById(\'id_image\').src=this.src; ');
        wnd.document.writeln('window.resizeBy(this.width-document.body.clientWidth, this.height-document.body.clientHeight);');
        wnd.document.writeln('var top = screen.height/2-this.height/2; ');
        wnd.document.writeln('var left = screen.width/2-this.width/2; ');
        wnd.document.writeln('window.moveTo(left, top)');
        wnd.document.writeln('}');
        wnd.document.writeln('img.src=\''+url+'\'; ');
        wnd.document.writeln('}');
        wnd.document.writeln('</script>');
        wnd.document.writeln('</head>');
        wnd.document.writeln('<body>');
        wnd.document.writeln('<img id="id_image" src="images/loading-arrow-16x16.gif" onclick = "window.close();" alt="Click to close window.">');
        wnd.document.writeln('</body>');
        wnd.document.writeln('</html>');
        wnd.document.close();
        return false;
    },

    getPageSize: function ()
    {
        var xScroll, yScroll;

        if (window.innerHeight && window.scrollMaxY) {
            xScroll = window.innerWidth + window.scrollMaxX;
            yScroll = window.innerHeight + window.scrollMaxY;
        } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
            xScroll = document.body.scrollWidth;
            yScroll = document.body.scrollHeight;
        } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
            xScroll = document.body.offsetWidth;
            yScroll = document.body.offsetHeight;
        }

        var windowWidth, windowHeight;

    //  console.log(self.innerWidth);
    //  console.log(document.documentElement.clientWidth);

        if (self.innerHeight) { // all except Explorer
            if(document.documentElement.clientWidth){
                windowWidth = document.documentElement.clientWidth;
            } else {
                windowWidth = self.innerWidth;
            }
            windowHeight = self.innerHeight;
        } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
            windowWidth = document.documentElement.clientWidth;
            windowHeight = document.documentElement.clientHeight;
        } else if (document.body) { // other Explorers
            windowWidth = document.body.clientWidth;
            windowHeight = document.body.clientHeight;
        }

        // for small pages with total height less then height of the viewport
        if(yScroll < windowHeight){
            pageHeight = windowHeight;
        } else {
            pageHeight = yScroll;
        }

    //  console.log("xScroll " + xScroll)
    //  console.log("windowWidth " + windowWidth)

        // for small pages with total width less then width of the viewport
        if(xScroll < windowWidth){
            pageWidth = xScroll;
        } else {
            pageWidth = windowWidth;
        }
    //  console.log("pageWidth " + pageWidth)

        arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
        return arrayPageSize;
    },

    backgroundImage: function (inputId, image)
    {
        var input = document.getElementById(inputId);
        if (!input) {
            return false;
        }
        input.style.backgroundRepeat = 'no-repeat';
        $(input).focus(function() {
            this.style.backgroundImage = '';
        }).blur(function() {
            if (this.value == '') {
                this.style.backgroundImage = "url('" + image +"')";
            } else {
                this.style.backgroundImage = '';
            }
        }).blur();
    },

    imageFs: function (image, width, height, method)
    {
        var result = '';
        var pos = image.lastIndexOf('.');
        var name = '';
        var extension = '';
        if (pos == -1) {
            name = image;
        } else {
            name = image.substr(0, pos);
            extension = image.substr(pos + 1);
        }
        width = intval(width);
        height = intval(height);
        if (width || height) {
            result = name + '_' + width + 'x' + height;
            if (method == 'outer') {
                result += 'o';
            }
        } else {
            result = name
        }
        if (extension.length) {
            result += '.' + extension;
        }
        result = result.replace(/\/userfiles\/files\//, '/userfiles/images/');
        return result;
    },

    getPlural: function (word, count)
    {
        var count = Math.abs(count);
        if (is_array(word)) {
            if (count > 1 || count == 0) {
                if (typeof word[1] != 'undefined') {
                    return word[1];
                }
                return null;
            }
            return word[0];
        } else if (is_string(word)) {
            if (count > 1 || count == 0) {
                return word + 's';
            }
            return word;
        }
        return null;
    }
}

var Qs_Message = qs.create();

Qs_Message.prototype = {

    initialize: function (messages)
    {
        this.messages = messages;
    },

    get: function (name, language)
    {
        if (typeof language == 'undefined') {
            language = CURRENT_LANGUAGE;
        }
        if (typeof this.messages[language] == 'undefined') {
            return '';
        }
        if (typeof this.messages[language][name] == 'string') {
            return this.messages[language][name];
        }
        if (typeof this.messages[DEFAULT_LANGUAGE][name] == 'string') {
            return this.messages[DEFAULT_LANGUAGE][name];
        }
        return '';
    }
}

var Qs_Array = {
    get: function (data, field, defaultValue)
    {
        if (typeof field != 'undefined') {
            field = field.replace(/\]/g, '');
            var parts = field.split(/\[/);
            while ((name = array_shift(parts))) {
                if (!array_key_exists(name, data)) {
                    return (typeof defaultValue != 'undefined') ? defaultValue : null;
                }
                data = data[name];
            }
        }
        return data;
    },

    set: function (data, field, value)
    {
        if (typeof field == 'undefined') {
            return false;
        }
        field = field.replace(/\]/g, '');
        var parts = field.split(/\[/);
        var _data = data;
        while ((name = array_shift(parts))) {
            if (parts.length == 0) {
                _data[name] = value;
                break;
            }
            if (!array_key_exists(name, _data)) {
                _data[name] = {};
            }
            _data = _data[name];
        }
        return true;
    },

    isAssoc: function (array)
    {
        if (is_array(array)) {
            return false;
        }
        var i = 0;
        for (var j in array) {
            if (parseInt(j, 10) != i++) {
                return true;
            }
        }
        return false;
    },

    collapse: function(array, belongsTo)
    {
        if (typeof belongsTo == 'undefined') {
            belongsTo = '';
        }
        result = {};
        for (var key in array) {
            var value = array[key];
            var itemBelongsTo = belongsTo + (empty(belongsTo) ? key : '[' + key + ']');
            if (is_array(value)) {
                result = array_merge(result, Qs_Array.collapse(value, itemBelongsTo));
            } else {
                result[itemBelongsTo] = value;
            }
        }
        return result;
    }
}

var Qs_ViewHelper = {

    escape: function (value)
    {
        return value;
    },

    _initId: function (attribs)
    {
        if (typeof attribs.id != 'undefined') {
            return false;
        }
        var id = attribs.name;
        if (id.substr(-2) == '[]') {
            id = id.substr(0, id.length - 2);
        }
        if (-1 != id.indexOf(']')) {
            id = trim(id, ']');
            id = id.replace(/\]\[/, '-');
            id = id.replace(/\[/, '-');
        }
        attribs.id = id;
    },

    _initClass: function (attribs)
    {
        if (typeof attribs['class'] == 'undefined') {
            attribs['class'] = attribs.type;
        }
    },

    renderAttribs: function (attribs)
    {
        var content = '';
        for (var name in attribs) {
            content += name + '="' + Qs_ViewHelper.escape(attribs[name]) + '" ';
        }
        return content;
    },

    formHidden: function (name, value, attribs)
    {
        if (typeof attribs == 'undefined') {
            attribs = {};
        }
        if (typeof value == 'undefined') {
            value = '';
        }
        attribs.type = 'hidden';
        attribs.name = name;
        attribs.value = value;
        Qs_ViewHelper._initId(attribs);
        Qs_ViewHelper._initClass(attribs);
        return '<input ' + Qs_ViewHelper.renderAttribs(attribs) + ' />';
    },

    formText: function (name, value, attribs)
    {
        if (typeof attribs == 'undefined') {
            attribs = {};
        }
        if (typeof value == 'undefined') {
            value = '';
        }
        attribs.type = 'text';
        attribs.name = name;
        attribs.value = value;
        Qs_ViewHelper._initId(attribs);
        Qs_ViewHelper._initClass(attribs);
        return '<input ' + Qs_ViewHelper.renderAttribs(attribs) + ' />';
    },

    formCheckbox: function (name, value, attribs, checkedOptions)
    {
        if (typeof attribs == 'undefined') {
            attribs = {};
        }
        if (typeof value == 'undefined') {
            value = '';
        }
        if (typeof checkedOptions == 'undefined') {
            checkedOptions = {checkedValue: 1, uncheckedValue: 0};
        }
        hiddenAttribs = {name: name, type: 'hidden', value: checkedOptions.uncheckedValue};
        attribs.type = 'checkbox';
        attribs.name = name;
        attribs.value = checkedOptions.checkedValue;
        if (value == attribs.value) {
            attribs.checked = true;
        }
        Qs_ViewHelper._initId(attribs);
        Qs_ViewHelper._initClass(attribs);
        Qs_ViewHelper._initClass(hiddenAttribs);
        if (typeof attribs.checked != 'undefined') {
            if (attribs.checked) {
                attribs.checked = 'checked';
            }
        }
        return '<input ' + Qs_ViewHelper.renderAttribs(hiddenAttribs) + ' />'
             + '<input ' + Qs_ViewHelper.renderAttribs(attribs) + ' />';
    },

    formLabel: function (name, value, attribs)
    {
        if (typeof attribs == 'undefined') {
            attribs = {};
        }
        if (typeof value == 'undefined') {
            value = '';
        }
        attribs.name = name;
        Qs_ViewHelper._initId(attribs);
        attribs['for'] = attribs.id;
        delete attribs.name;
        delete attribs.id;
        if (typeof attribs.disableFor != 'undefined' && attribs.disableFor) {
            delete attribs['for'];
        }
        return '<label ' + Qs_ViewHelper.renderAttribs(attribs) + '>' + Qs_ViewHelper.escape(value) + '</label>';
    }
}

var Qs_Form_Element_Select = {
    /**
     *
     * @param HTMLSelectElement element
     * @param options Object
     * @param mixed emptyTitle string|bool|undefined
     */
    setOptions: function (element, options, emptyTitle)
    {
        var i;
        var emptyOption = false;
        if (typeof emptyTitle == 'string') {
            emptyOption = document.createElement('OPTION');
            emptyOption.text = emptyTitle;
            emptyOption.value = '';
        } else if (true === emptyTitle) {
            var firstOption = element.options.item(0);
            if (firstOption) {
                emptyOption = document.createElement('OPTION');
                emptyOption.text = firstOption.text;
                emptyOption.value = firstOption.value;
            }
        }
        for(i = element.options.length - 1; i >= 0; i--) {
            element.remove(i);
        }
        if (false !== emptyOption) {
            element.options.add(emptyOption);
        }
        var isAssoc = Qs_Array.isAssoc(options);
        for (i in options) {
            var option = document.createElement('OPTION');
            option.value = isAssoc ? i : options[i].value;
            option.text = isAssoc ? options[i] : options[i].text;
            element.options.add(option);
        }
    },
    getValue: function (element)
    {
        if (element.multiple) {
            var value = [];
            for (var j in element.options) {
                if (
                    element.options[j] != null
                    && typeof element.options[j].tagName == 'string'
                    && element.options[j].tagName == 'OPTION'
                    && element.options[j].selected
                ) {
                    value.push(element.options[j].value);
                }
            }
            return value;
        } else {
            return element.value;
        }
    },

    setValue: function(element, value)
    {
        if (element.multiple) {
            if (!is_array(value)) {
                value = [value];
            }
            for (var j in element.options) {
                if (
                    element.options[j] != null
                    && typeof element.options[j].tagName == 'string'
                    && element.options[j].tagName == 'OPTION'
                ) {
                   element.options[j].selected = in_array(element.options[j].value, value);
                }
            }
        } else {
            element.value = value;
        }
    }
};
