﻿if (typeof (Control) == 'undefined') Control = {};
var $value = function(value) { return typeof (value) == 'function' ? value() : value; };
/************************* OBJECT.EVENT **********************/
Object.Event = {
    extend: function(object) {
        object._objectEventSetup = function(event_name) { this._observers = this._observers || {}; this._observers[event_name] = this._observers[event_name] || []; };
        object.observe = function(event_name, observer) {
            if (typeof (event_name) == 'string' && typeof (observer) != 'undefined') { this._objectEventSetup(event_name); if (!this._observers[event_name].include(observer)) this._observers[event_name].push(observer); } else
                for (var e in event_name) this.observe(e, event_name[e]);
        };
        object.stopObserving = function(event_name, observer) {
            this._objectEventSetup(event_name);
            if (event_name && observer)
                this._observers[event_name] = this._observers[event_name].without(observer);
            else if (event_name)
                this._observers[event_name] = [];
            else
                this._observers = {};
        };

        object.observeOnce = function(event_name, outer_observer) {
            var inner_observer = function() {
                outer_observer.apply(this, arguments);
                this.stopObserving(event_name, inner_observer);
            } .bind(this);
            this._objectEventSetup(event_name);
            this._observers[event_name].push(inner_observer);
        };
        object.notify = function(event_name) {
            this._objectEventSetup(event_name);
            var collected_return_values = [];
            var args = $A(arguments).slice(1);
            try {
                for (var i = 0; i < this._observers[event_name].length; ++i)
                    collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i], args) || null);
            } catch (e) {
                if (e == $break)
                    return false;
                else
                    throw e;
            }
            return collected_return_values;
        };
        if (object.prototype) {
            object.prototype._objectEventSetup = object._objectEventSetup;
            object.prototype.observe = object.observe;
            object.prototype.stopObserving = object.stopObserving;
            object.prototype.observeOnce = object.observeOnce;
            object.prototype.afterRemoveObervers = object.prototype.destroy;
            object.prototype.destroy = function() {
                if (typeof (this.afterRemoveObervers) != "undefined") this.afterRemoveObervers();
                delete this._observers;
            };
            object.prototype.notify = function(event_name) {
                if (object.notify) {
                    var args = $A(arguments).slice(1);
                    args.unshift(this);
                    args.unshift(event_name);
                    object.notify.apply(object, args);
                }
                this._objectEventSetup(event_name);
                var args = $A(arguments).slice(1);
                var collected_return_values = [];
                try {
                    if (this.options && this.options[event_name] && typeof (this.options[event_name]) == 'function')
                        collected_return_values.push(this.options[event_name].apply(this, args) || null);
                    for (var i = 0; i < this._observers[event_name].length; ++i) {
                        collected_return_values.push(this._observers[event_name][i].apply(this._observers[event_name][i], args) || null);
                        if (typeof (this._observers) == "undefined" || this._observers == null) break;
                    }

                } catch (e) { if (e == $break) return false; else throw e; } return collected_return_values;
            };
        }
    }
};

/********************** CHECKBOX *******************/
/* CONSTRUCTOR
new Control.Checkbox($("myBox"));   
where myBox is defined as :
<div id="myBox" class="checkbox"></div>
EVENTS
1. Event "changed" fired when the value of the checkbox changes
Arguments: isChecked
*/

Control.Checkbox = Class.create({
    initialize: function(element) {
        this.element = $(element);
        this.element.observe("click", this.clicked.bindAsEventListener(this));
        this.disabled = false;
    },
    element: null,
    isChecked: false,
    getValue: function() { return this.isChecked; },
    setValue: function(isChecked) {
        if (this.disabled) return;
        if (this.isChecked != isChecked) {
            this.isChecked = isChecked;
            this.notify("change", { isChecked: isChecked });
            if (isChecked) this.notify("check"); else this.notify("uncheck");
            if (this.isChecked)
                this.element.addClassName("on");
            else
                this.element.removeClassName("on");
        }
    },
    clicked: function(e) {
        this.setValue(!this.getValue());
    }
});
Object.Event.extend(Control.Checkbox);


/****************** TABS ****************/
Control.Tabs = Class.create({
    initialize: function(tabDoms, bodyDoms) {
        this.tabDoms = tabDoms;
        this.bodyDoms = bodyDoms;
        this.currentTab = 0;
        for (var tI = 0; tI < tabDoms.length; tI++) {
            tabDoms[tI].observe("click", this.tabClicked.bind(this, tI));
        }
    },
    tabDoms: null, bodyDoms: null,
    currentTab: 0,
    tabClicked: function(tIndex) {
        if (tIndex === this.currentTab) return;
        this.currentTab = tIndex;
        for (var tI = 0; tI < this.bodyDoms.length; tI++) {
            if (tI !== tIndex) this.bodyDoms[tI].style.display = "none";
            this.tabDoms[tI].className = tI == tIndex ? "highlighted" : "";
        }
        var tab = this.bodyDoms[tIndex];
        tab.style.display = "block";
        tab.style.visibility = "visible";
        var tabC = this.tabDoms[0].parentNode;
        while (tabC.tagName.toUpperCase() !== "DIV") tabC = tabC.parentNode;
        tIndex++;
        tabC.className = "qbTabs state" + tIndex;
    }
});


Object.Event.extend(Control.Tabs);

/****************** WATERMARKED TEXTBOX ********************/
WatermarkTextbox = function(element, watermarkText, _options) {
    this.watermarkText = watermarkText;
    this.element = $(element);
    this.config = _options || {};
    this.element.observe("blur", this.onblur.bind(this, this.alterElement));
    if (Prototype.Browser.IE && this.config.password === true) {
        this.alterElement = $(document.createElement("input"));
        for (var sI in this.element.style) {
            try { if (sI.indexOf("border") < 0) this.alterElement.style[sI] = this.element.style[sI]; } catch (ex) { }
        }
        this.alterElement.className = this.element.className;
        Element.addClassName(this.alterElement, "watermark");
        this.alterElement.value = watermarkText;
        this.alterElement.style.display = "none";
        this.element.parentNode.insertBefore(this.alterElement, this.element);

        this.alterElement.observe("focus", this.onfocus.bind(this));
        this.alterElement.observe("keydown", this.onkeydown.bind(this));
    } else {
        this.alterElement = null;
        this.element.observe("focus", this.onfocus.bind(this));
        this.element.observe("blur", this.onblur.bind(this, this.element));
    }
    this.element.observe("keydown", this.onkeydown.bind(this));
    this.element.observe("keypress", this.onkeydown.bind(this));
    this.setWatermark(true);
};
WatermarkTextbox.prototype = {
    watermarkText: "", element: null, config: null, alterElement: null,
    onfocus: function() {
        if (typeof this._preventOnFocusHandler != "undefined" && this._preventOnFocusHandler >= new Date().getTime()) {
            return;
        }
        this._preventOnFocusHandler = new Date().getTime() + 100;
        this.setWatermark(false);
    },
    select: function(_selectAll) {
        var _empty = this.getValue().length == 0;
        var _el;
        this._preventOnFocusHandler = new Date().getTime() + 100;
        if (_empty) {
            this.setWatermark(true);
            if (this.alterElement === null) _el = this.element;
            else { _el = this.alterElement; }
            try { _el.focus(); } catch (ex) { }
        } else {
            _el = this.element;
            _el.focus();
            if (!Object.isUndefined(_selectAll) && _selectAll === true) {
                if (_el.setSelectionRange) {
                    _el.setSelectionRange(0, _el.value.length);
                } else {
                    if (_el.createTextRange) {
                        var range = _el.createTextRange();
                        range.moveStart("character", 0);
                        range.moveEnd("character", _el.value.length);
                        range.select();
                    }
                }
            }
        }
    },
    focus: function() {
        this._preventOnFocusHandler = new Date().getTime() + 100;
        var _el;
        if (this.alterElement === null) _el = this.element;
        else { _el = this.alterElement; }
        _el.focus();
        if (_el.setSelectionRange) {
            _el.setSelectionRange(0, 0);
        } else {
            if (_el.createTextRange) {
                var range = _el.createTextRange();
                range.moveStart("character", 2);
                range.moveEnd("character", -_el.getValue().length);
                range.select();
            }
        }
    },
    onblur: function(el) {
        if (typeof this._preventOnFocusHandler != "undefined" && this._preventOnFocusHandler >= new Date().getTime()) {
            return;
        }
        this._preventOnFocusHandler = new Date().getTime() + 100;
        this.setWatermark(true);
    },
    onkeydown: function() {
        if (this.alterElement === null && this.element.value === this.watermarkText) {
            this.element.value = "";
            this.setWatermark(false);
        } else
            Element.removeClassName(this.element, "watermark");
    },

    setWatermark: function(_blurred) {
        var empty = this.element.value.length === 0 || this.element.value === this.watermarkText;
        if (_blurred) {
            if (empty) {
                if (this.alterElement === null && this.config.password == true) this.element.type = "text";
                this.element.value = this.watermarkText;
                Element.addClassName(this.element, "watermark");
                if (this.alterElement != null) {
                    this.element.style.display = "none";
                    this.alterElement.style.display = "";
                }
            } else {
                if (this.alterElement != null) {
                    this.alterElement.style.display = "none";
                    this.element.style.display = "";
                } else {
                    Element.removeClassName(this.element, "watermark");
                }
                if (this.alterElement === null && this.config.password == true) this.element.type = "password";
            }
        } else {
            if (empty) {
                if (this.alterElement === null) {
                    if (this.element.value === this.watermarkText) { this.element.value = ""; Element.removeClassName(this.element, "watermark"); }
                    if (this.config.password == true) this.element.type = "password";
                } else {
                    if (this.alterElement.style.display !== "none") {
                        this.alterElement.style.display = "none";
                        this.element.value = "";
                        this.element.style.display = "";
                        this.element.focus();
                    }
                }
            } else {
                if (this.alterElement === null && this.config.password == true) this.element.type = "password";
            }
        }
        return;
        if (this.element.value.length === 0 && setText || this.element.value === this.watermarkText) {

            if (this.alterElement !== null) {
                this.element.style.display = "none";
                if (setText)
                    this.alterElement.value = this.watermarkText;
                this.alterElement.style.display = "";
                this.element.value = "";
            } else {
                this.element.type = "text";
                Element.addClassName(this.element, "watermark");
                if (setText)
                    this.element.value = this.watermarkText;
            }
        } else {
            if (this.alterElement === null && this.config.password == true) { if (this.element.value == this.watermarkText) this.element.value = ""; this.element.type = "password"; }
            if (this.alterElement !== null && this.alterElement.style.display !== "none") { this.alterElement.style.display = "none"; this.element.style.display = ""; this.element.focus(); }
            else this.element.style.display = "";
            if (this.alterElement === null) Element.removeClassName(this.element, "watermark");
        }
    },
    getValue: function() {
        if (this.element.value === this.watermarkText) return "";
        return this.element.value;
    }
};


/***************** SLIDESHOW **********************/
Control.Slideshow = {};
Control.Slideshow._imageLoaded = function(_img, _mainImage, _imageContainer) {
    var _currentHeight = _imageContainer.scrollHeight, _currentWidth = _imageContainer.scrollWidth;
    _imageContainer.className = "container";
    if (_img.width > 0) {
        _mainImage.style.width = _img.width;
        _mainImage.style.height = _img.height;
    } else { _mainImage.style.width = ""; _mainImage.style.height = ""; }
    _mainImage.src = _img.src;
    _mainImage.style.display = "block";
    if (_currentHeight != _img.height)
        new Effect.Tween(null, _currentHeight, _img.height, function(p) { _imageContainer.style.height = p + "px"; });
    if (_currentWidth != _img.width)
        new Effect.Tween(null, _currentWidth, _img.width, function(p) { _imageContainer.style.width = p + "px"; });
}
Control.Slideshow.setImage = function(_mainImage, _index, _photos, _imageContainer) {
    _mainImage.style.display = "none";
    _imageContainer.className = "spinning container";
    var _img = new Image();
    _img.onload = Control.Slideshow._imageLoaded.curry(_img, _mainImage, _imageContainer);
    if (_index === "+") _index = (_imageContainer._index + 1) % _photos.length;
    else { if (_index === "-") _index = (_imageContainer._index + _photos.length - 1) % _photos.length; }
    _imageContainer._index = _index;
    _img.src = _photos[_index];
}
Control.Slideshow.show = function(_parent, _photos, _thumbnails, _options) {
    if (!Object.isArray(_photos) || _photos.length === 0) return;
    _options = _options || {};

    var _body = document.createElement("div");
    var _modalOptions = { fade: true,
        bodyContent: _body
    };
    var _modal = new Control.Modal(null, _modalOptions);

    var largeScreen = document.viewport.getHeight() > 750;
    if (_parent != null && typeof (_parent) != "undefined") {
        _parent = $(_parent);
        _modalOptions.position = 'relative';
        _modalOptions.relativeTo = _parent;
        var _parentDimensions = Element.getDimensions(_parent);
        _modalOptions.width = _parentDimensions.width + 44;
        _modalOptions.offsetLeft = -22;
        if (_modalOptions.width != 694) {
            _modalOptions.offsetLeft += Math.floor((_modalOptions.width - 694) / 2);
            _modalOptions.width = 694;
        }
        Effect.ScrollTo(_parent, { offset: largeScreen ? -50 : 0 });
    }

    var table, row, cell;
    if (Object.isString(_options.title)) {
        table = document.createElement("table"); table.style.width = "100%"; table.className = "windowTitle";
        _body.appendChild(table);
        row = table.insertRow(-1); cell = Object.extend(row.insertCell(-1), { innerHTML: "<h3>" + _options.title + "</h3>" });
        var _closeIcon = Object.extend(new Element("div"), { className: "closeIcon" });
        cell = row.insertCell(-1); cell.style.textAlign = "right"; cell.style.width = "37px";
        cell.appendChild(_closeIcon);
        _closeIcon.observe('click', _modal.close.bind(_modal));
    }


    var _div = document.createElement("div"); _div.style.textAlign = "center";
    var _thumbsContainer, _leftDiv, _rightDiv;

    var _arrowsTable;
    if (_photos.length > 1) {
        _arrowsTable = document.createElement("table");
        _body.appendChild(_arrowsTable);
        row = _arrowsTable.insertRow(-1);
        cell = row.insertCell(-1); cell.className = "leftArrow";
        _leftDiv = document.createElement("div");
        cell.appendChild(_leftDiv);

        cell = row.insertCell(-1);
        cell.appendChild(_div);
        cell = row.insertCell(-1); cell.className = "rightArrow";
        _rightDiv = document.createElement("div");
        cell.appendChild(_rightDiv);
        row = _arrowsTable.insertRow(-1);
        row.insertCell(-1);
        _thumbsContainer = row.insertCell(-1);

    } else {
        _arrowsTable = _leftDiv = _rightDiv = null;
        _thumbsContainer = _div;
        _body.appendChild(_div);
    }

    var _imageContainer = new Element("div");
    _div.appendChild(_imageContainer);

    var _mainImage = document.createElement("img"); _mainImage.className = "mainImage"; _mainImage.style.display = "none";
    _imageContainer.style.height = "270px"; _imageContainer.style.width = "600px"; _imageContainer.className = "spinning container";
    _imageContainer.appendChild(_mainImage);
    var thumbs = document.createElement("div");
    _thumbsContainer.appendChild(thumbs);
    var thumb;
    table = document.createElement("table"); table.className = "thumbs";
    thumbs.appendChild(table);
    if (typeof (_thumbnails) == "undefined" || _thumbnails == null) {
        _thumbnails = [];
        for (var ii = 0; ii < _photos.length; ii++) {
            _thumbnails.push(_photos[ii].replace(".jpg", ".90x40.jpg"));
        }
    }
    if (_thumbnails.length > 1) {
        for (var ii = 0; ii < _thumbnails.length; ii++) {
            thumb = document.createElement("img");
            thumb.className = "thumb";
            thumb.height = "40"; thumb.width = "90";
            thumb.src = _thumbnails[ii];
            if (ii % 6 == 0) row = table.insertRow(-1);
            cell = row.insertCell(-1);
            if (ii % 6 > 0) cell.style.paddingLeft = "6px";
            if (ii % 6 < 5 && (ii < _photos.length - 1 || _thumbnails.length > 6)) cell.style.paddingRight = "6px";
            Event.observe(thumb, "click", Control.Slideshow.setImage.curry(_mainImage, ii, _photos, _imageContainer));
            cell.appendChild(thumb);
        }
        Event.observe(_rightDiv, "click", Control.Slideshow.setImage.curry(_mainImage, "+", _photos, _imageContainer));
        Event.observe(_leftDiv, "click", Control.Slideshow.setImage.curry(_mainImage, "-", _photos, _imageContainer));
    }
    _body.className = "modalWindow slideshow";
    _modal.open();
    Control.Slideshow.setImage(_mainImage, 0, _photos, _imageContainer);
    return _modal;
};
/******************* COMBOBOX **********************/
/*  CONSTRUCTOR
new Control.Combobox($("myCombo"),config);
where myBox is defined as :
<div id="myCombo" class="combobox"></div>
Config object can contain the following properties:
1.  "options" must contains the options set in the dropdown list, if any, in a array.
Eg: {options:[[1,'Texte 1'],[2,'Texte 2']]}
2.  "watermark" can contain the prompt text displayed when no option is seleted
3.  "defaultIndex" contains the index of the selection.
4.  "dropHeight" can be set tot he drop list height
5.  "dropWidth" can be set tot he drop list width. May be set to "auto".
6.  "defaultValue" contains the value of the default item
METHODS
1.  setSelectedIndex(index)
Set the currently selected index to the specified integer, if valid.
If not valid, the currently seleted item is cleared.
EVENTS
1.  Event "changed" fired when the value of the checkbox changes
Arguments: isChecked
*/
Control.Combobox = Class.create({
    initialize: function(element, config) {
        this.element = $(element);
        this.config = config || {};
        if (typeof (this.config.input) == "undefined") {
            if (typeof (element.firstChild) != "undefined" && element.firstChild !== null && element.firstChild.tagName === "INPUT")
                this.config.input = element.firstChild;
            else
                this.config.input = false;
        }
        if (this.config.input) {
            this.config.input = $(this.config.input);
            this.config.input.setAttribute("autocomplete", "off");
            Event.observe(this.config.input, "keyup", this._editAutocomplete.bindAsEventListener(this));
            Event.observe(this.config.input, "blur", this._editNormalize.bindAsEventListener(this, true));
        }
        if (typeof (this.config.links) == "undefined") this.config.links = false;
        this._options = [];
        this.watermarkText = config.watermarkText;
        if (Object.isArray(this.config.options))
            this.addOptions(this.config.options);
        else if (typeof (this.config.options) != "undefined" && this.config.options != null) {
            this.listElement = $(this.config.options);
            this.listElement.style.position = "absolute";
            this.listElement.style.visibility = "hidden";
            this.listElement.style.display = "block";
            if (!this.config.links) Event.observe(this.listElement, "click", Event.stop.bindAsEventListener(this));
            Event.observe(document.body, "click", this._autoCollapse.bind(this));
            this._options.push(false);
        }
        this.selectedIndex = -1;
        this.element.observe("click", this._onclick.bind(this));
        if (this.config.links === false) {
            this.setSelectedIndex(config.defaultIndex);
            if (typeof (config.defaultValue) != "undefined") this.setSelectedValue(config.defaultValue);
        }
    },
    destroy: function() {
        delete this.config;
        delete this._options;
        delete this.listElement;
    },
    element: null, listElement: null, selectedIndex: -1, watermarkText: null,
    _options: [], config: null,
    clearOptions: function() {
        this._options = [];
        if (this.listElement !== null) { this.collapse(); this._populateList(); }
    },
    isCollapsed: function() {
        if (Element.hasClassName(this.element, "comboboxExpanded")) return false;
        if (this.listElement === null) return true;
        if (this.listElement.style.display === "none") return true;
        return false;
    },
    collapse: function() {
        Element.removeClassName(this.element, "comboboxExpanded");
        if (this.listElement === null) return;
        if (this.listElement.style.display === "none") return;
        if (typeof Effect != "undefined") {
            Effect.BlindUp(this.listElement, { duration: 0.3 });
        } else {
            this.listElement.style.visibility = "hidden";
            this.listElement.style.display = "none";
        }
    },
    addOptions: function(options) {
        if (options === null || typeof options == "undefined") return;
        for (var oI = 0; oI < options.length; oI++)
            this._options.push(options[oI]);
        if (this.listElement !== null) this._populateList();
    },
    getSelectedIndex: function() { return this.selectedIndex; },
    getValue: function() { var sI = this.selectedIndex; if (sI < 0 || sI > this._options.length) return null; return this._options[sI][0]; },
    setSelectedValue: function(_value) {
        if (Object.isUndefined(_value) || _value === null) {
            this.setSelectedIndex(-1);
            return false;
        }
        var _uValue = _value;
        if (Object.isString(_value)) _uValue = _value.toUpperCase();
        var _option, _optionText;
        for (var oI = 0; oI < this._options.length; oI++) {
            _option = this._options[oI];
            _optionText = this.getDisplayedText(_option);
            if (_option[0] == _value || _optionText == _value || _optionText.toUpperCase() == _uValue) {
                this.setSelectedIndex(oI);
                return true;
            }
        }
        return false;
    },
    setSelectedIndex: function(_index) {
        var _previousIndex = this.selectedIndex;
        if (Object.isNumber(_index) && _index < this._options.length && _index >= 0) {
            var _option = this._options[_index];
            this.setText(this.getDisplayedText(_option), _option);
            this.selectedIndex = _index;
        }
        else {
            this.setText(null, null);
            this.selectedIndex = -1;
        }
        if (_previousIndex !== this.selectedIndex)
            this.notify('changed', this.selectedIndex);
    },
    refresh: function() {
        this.setSelectedIndex(this.selectedIndex);
    },
    _lastClick: null,
    _clickPrevented: function() {
        return this._lastClick !== null && this._lastClick > new Date().getTime();
    },
    expand: function() {
        if (this._options.length === 0) return;
        this._initList();
        var isHidden = this.listElement.style.display === "none" || this.listElement.style.visibility !== "visible";
        if (!isHidden) return;
        this.listElement.style.visibility = "hidden";
        this.listElement.style.display = "block";
        if (typeof (this.config.dropWidth) != "undefined") {
            if (navigator.userAgent.indexOf("MSIE 6") < 0) {
                //IE6 does not support minWidth style
                this.listElement.style.minWidth = this.element.clientWidth.toString() + "px";
            }

            this.listElement.style.width = "";
            if (this.config.dropWidth === "auto") {
                if (this.listElement.clientWidth < this.element.clientWidth)
                    this.listElement.style.width = this.element.clientWidth.toString() + "px";
            }
            else this.listElement.style.width = this.config.dropWidth + "px";

        } else { this.listElement.style.width = (this.element.clientWidth) + "px"; }

        var _finalHeight, _overflowY;
        if (typeof (this.config.dropHeight) != "undefined") {
            _finalHeight = this.config.dropHeight + "px";
            _overflowY = "auto";
        } else { _finalHeight = ""; _overflowY = ""; }
        var finalFn = (function(h, oy) {
            this.style.height = h;
            this.style.overflowY = oy;
        }).bind(this.listElement, _finalHeight, _overflowY);

        if (typeof Effect != "undefined") {
            this.listElement.style.display = "none";
            this.listElement.style.visibility = "visible";
            Effect.BlindDown(this.listElement, { duration: 0.5, afterFinish: finalFn });
        } else
            this.listElement.style.visibility = "visible";
        Element.addClassName(this.element, "comboboxExpanded");
        this.notify('expand');
    },
    _onclick: function(e) {
        if (this._clickPrevented()) return;
        this._lastClick = new Date().getTime() + 300;
        if (this._options.length === 0) return;
        this._initList();
        var wasHidden = this.listElement.style.display === "none" || this.listElement.style.visibility !== "visible";
        if (wasHidden) {
            this.expand();

        } else {
            Element.removeClassName(this.element, "comboboxExpanded");
            if (typeof Effect != "undefined")
                Effect.BlindUp(this.listElement, { duration: 0.3 });
        }
    },
    _editAutocomplete: function(e) {
        if (e.keyCode == 46 || e.keyCode == 8 || e.keyCode == 27)//delete or backspace or escape
            return;
        if (e.keyCode == 13) { this._editNormalize(e, false); this.collapse(); return; }

        this.expand();
        var txt = this.config.input;
        var o, otxt, v = txt.value.toUpperCase(), _foundIndex = -1;
        var vl = v.length;
        if (vl > 0) {
            for (var oI = 0; oI < this._options.length; oI++) {
                o = this._options[oI];
                otxt = this.getDisplayedText(o);
                if (otxt === null || otxt.length == 0) continue;
                if (otxt.toUpperCase().startsWith(v)) {
                    _foundIndex = oI;
                    if (otxt.toUpperCase() === v) break;
                    if (txt.setSelectionRange) {
                        this.setText(txt.value + otxt.substring(vl), o);
                        txt.setSelectionRange(vl, otxt.length);
                    } else {
                        if (this.element.createTextRange) {
                            this.setText(txt.value + otxt.substring(vl), o);
                            var range = this.element.createTextRange();
                            range.moveStart("character", vl);
                            range.moveEnd("character", otxt.length);
                            range.select();
                        }
                    }

                    break;
                }
            }
        }
        var _highlight = false;
        if (e.keyCode == 38 && _foundIndex >= 0) {//Up
            this.setSelectedIndex(_foundIndex - 1);
            _foundIndex = this.getSelectedIndex();
            _highlight = true;
        } else if (e.keyCode == 40) {//Down
            this.setSelectedIndex(_foundIndex + 1);
            _highlight = true;
            _foundIndex = this.getSelectedIndex();
        }
        _highlight = true;
        if (typeof (this.config.dropHeight) != "undefined") _highlight = true;
        if (_highlight) {
            var fn, el;
            for (var oI = 0; oI < this._options.length; oI++) {
                fn = oI === _foundIndex ? Element.addClassName : Element.removeClassName;
                el = this.listElement.childNodes[oI];
                fn(el, "hover");
                if (oI === _foundIndex && typeof (this.config.dropHeight) != "undefined") {
                    if (el.offsetTop < this.listElement.scrollTop) {
                        this.listElement.scrollTop = el.offsetTop;
                    } else if (el.offsetTop + el.clientHeight >= this.listElement.scrollTop + this.listElement.clientHeight) {
                        this.listElement.scrollTop = el.offsetTop - this.listElement.clientHeight + el.clientHeight;
                    }
                }
            }
        }
        Event.stop(e);
        return false;
    },
    _editNormalize: function(e, collapse) {
        if (collapse) {
            this.collapse();
        }
        Event.stop(e);
        var txt = this.config.input;
        var o, otxt, v = txt.value.toUpperCase();
        var vl = v.length;
        if (vl > 0) {
            for (var oI = 0; oI < this._options.length; oI++) {
                o = this._options[oI];
                otxt = this.getDisplayedText(o);
                if (otxt === null || otxt.length == 0) continue;
                if (otxt.toUpperCase().startsWith(v)) {
                    this.setSelectedIndex(oI);
                    return;
                }
            }
        }
        this.setSelectedIndex(-1);
    },
    setText: function(text) {
        if (typeof text == "undefined" || text === null || text.length == 0) {
            this.element.addClassName("watermark");
            text = this.watermarkText || "";
        } else {
            this.element.removeClassName("watermark");
        }
        if (this.config.input) {
            this.config.input.value = text;
        } else {
            this.element.innerHTML = '<div style="padding-top:1px">' + text + '</div>';
        }
    },
    _onoptionclick: function(e, index, option) {
        try { Event.stop(e); } catch (ex) { }
        this.setText(this.getDisplayedText(option), option);
        if (this.selectedIndex !== index) {
            this.selectedIndex = index;
            this.notify('changed', this.selectedIndex);
        }
        this.collapse();
    },
    getDisplayedText: function(record) {
        return record[1];
    },
    getDisplayedTextInList: function(record) {
        return this.getDisplayedText(record);
    },
    _populateList: function() {
        this._initList();
        Element.empty(this.listElement);
        var o, _div;
        for (var oI = 0; oI < this._options.length; oI++) {
            o = this._options[oI];
            _div = new Element("div");
            _div.innerHTML = this.getDisplayedTextInList(o);
            _div.observe("click", this._onoptionclick.bindAsEventListener(this, oI, o));
            _div.observe("mouseover", Element.addClassName.bind(this, _div, "hover"));
            _div.observe("mouseout", Element.removeClassName.bind(this, _div, "hover"));
            this.listElement.appendChild(_div);
        }

        if (!Object.isUndefined(this.config.hint) && this.config.hint !== null) {
            _div = new Element("div");
            if (Object.isString(this.config.hint)) {
                _div.innerHTML = this.config.hint;
                _div.className = "comboHint";
            }
            else
                _div.appendChild(this.config.hint);
            this.listElement.appendChild(_div);
        }

    },
    _autoCollapse: function() {
        if (!this._clickPrevented()) this.collapse();
    },
    _initList: function(existingList) {
        if (this.listElement === null) {
            this.listElement = document.createElement("div");
            this.listElement.className = "comboboxDropdown";
            this.listElement.style.position = "absolute";
            this.listElement.style.visibility = "hidden";
            if (this.element.nextSibling !== null && typeof this.element.nextSibling != "undefined")
                this.element.parentNode.insertBefore(this.listElement, this.element.nextSibling);
            else
                this.element.parentNode.appendChild(this.listElement);
            if (typeof (this.config.dropHeight) != "undefined") {
                this.listElement.style.overflowX = "hidden";
                this.listElement.style.overflowY = "auto";
                this.listElement.style.height = this.config.dropHeight + "px";
                this.listElement.makeClipping = function() { return this; };
                this.listElement.undoClipping = function() { return this; };
            }
            this._populateList();
            Event.observe(document.body, "click", this._autoCollapse.bind(this));
        }
    }
});
Object.Event.extend(Control.Combobox);

/************** RequiredField ****************/
var RequiredField = function(element, config) {
    this.dom = this.element = $(element);
    this.config = config || {};
    if (typeof (this.config.enabled) != "undefined")
        this.enabled = this.config.enabled;
    else
        this.enabled = true;

    if (typeof (this.element.element) != "undefined") this.dom = this.element.element;
    if (typeof (this.config.container) != "undefined") {
        if (this.config.container == "parent")
            this.container = this.dom.parentNode;
        else
            this.container = this.config.container;
    }
    else
        this.container = this.dom;
    var input = this.dom;
    if (typeof (this.element.config) != "undefined" && Object.isElement(this.element.config.input)) input = this.element.config.input;
    Event.observe(input, "keyup", this.unmark.bind(this));
    Event.observe(input, "keypress", this.unmark.bind(this));
    Event.observe(input, "blur", this._isValidDelayed.bind(this, true));

    if (Object.isFunction(this.element.observe)) { this.element.observe("changed", this.isValid.bind(this, true)); }
    this.customValidation = this.config.customValidation;
    this.label = this.config.label;
};

RequiredField.prototype = {
    element: null, dom: null, config: null, container: null,
    _baseClass: function() {
        if (Element.hasClassName(this.container, "textbox")) return "textbox";
        if (Element.hasClassName(this.container, "comboboxExpanded")) return "comboboxExpanded";
        if (Element.hasClassName(this.container, "comboboxDropdown")) return "comboboxDropdown";
        if (Element.hasClassName(this.container, "editableCombobox")) return "editableCombobox";
        if (Element.hasClassName(this.container, "combobox")) return "combobox";
        return "";
    },
    mark: function() {
        Element.addClassName(this.container, this._baseClass() + "invalid");
        if (!Object.isUndefined(this.label)) Element.addClassName($(this.label), "invalidLabel");
    },
    unmark: function() {
        Element.removeClassName(this.container, this._baseClass() + "invalid");
        if (!Object.isUndefined(this.label)) Element.removeClassName($(this.label), "invalidLabel");
    },
    enabled: true, customValidation: null, label: null,
    getValue: function() {
        if (!this.enabled) return undefined;
        var _value;
        if (typeof (this.element.getValue) != "undefined")
            _value = this.element.getValue();
        else
            _value = this.dom.value;
        if (!(typeof (_value) == "undefined" || _value === null || _value.length == 0) && typeof (this.config.regex) != "undefined") {
            if (Object.isString(this.config.regex)) this.config.regex = new RegExp(this.config.regex);
            if (!Object.isString(_value) || !_value.match(this.config.regex))
                _value = undefined;
        }
        return _value;
    },
    _isValidDelayed: function(mark) {
        setTimeout(this.isValid.bind(this, mark), 60);
    },

    isValid: function(mark) {
        if (!this.enabled) {
            if (mark) this.unmark();
            return true;
        }
        var _value = this.getValue();
        if (typeof (_value) == "undefined" || _value === null || _value.length == 0) {
            {
                if (mark) this.mark();
                return false;
            }
        } else {
            if (Object.isFunction(this.customValidation)) {
                if (!this.customValidation(_value)) {
                    if (mark) this.mark();
                    return false;
                }
            }
            this.unmark();
            return true;
        }
    }
};

window.locale = window.locale || {};
window.locale.code = window.locale.code || 'fr-fr';
window.locale.isocode = window.locale.isocode || window.locale.code.substr(0, 2).toLowerCase();
window.locale.monthNames = window.locale.monthNames || ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
window.locale.shortMonthNames = window.locale.shortMonthNames || ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
window.locale.dayNames = window.locale.dayNames || ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
window.locale.shortDayNames = window.locale.shortDayNames || ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
window.locale.dateFormat = window.locale.dateFormat || 'dd/MM/yyyy';
window.locale.longDateFormat = window.locale.dateFormat || 'dddd MM yyyy';
if (typeof (window.locale.firstWeekDay) == "undefined") window.locale.firstWeekDay = 1;
window.cssLocation = window.cssLocation || '/css/';

DateFormat = Class.create();
Object.extend(DateFormat, {
    LZ: function(x) { return (x < 0 || x > 9 ? "" : "0") + x },
    compareDates: function(date1, dateformat1, date2, dateformat2) { var d1 = DateFormat.parseFormat(date1, dateformat1); var d2 = DateFormat.parseFormat(date2, dateformat2); if (d1 == 0 || d2 == 0) return -1; else if (d1 > d2) return 1; return 0; },
    format: function(date, format) {
        if (typeof format == "undefined") format = window.locale.dateFormat;
        format = format + ""; var result = ""; var i_format = 0; var c = ""; var token = ""; var y = date.getYear() + ""; var M = date.getMonth() + 1; var d = date.getDate(); var E = date.getDay(); var H = date.getHours(); var m = date.getMinutes(); var s = date.getSeconds(); var yyyy, yy, MMMM, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k;
        // Convert real date parts into formatted versions
        var _value = new Object(); if (y.length < 4) { y = "" + (y - 0 + 1900); }
        _value["y"] = "" + y; _value["yyyy"] = y; _value["yy"] = y.substring(2, 4); _value["M"] = M; _value["MM"] = DateFormat.LZ(M); _value["MMMM"] = window.locale.monthNames[M - 1]; _value["MMM"] = window.locale.shortMonthNames[M - 1]; _value["d"] = d; _value["dd"] = DateFormat.LZ(d); _value["ddd"] = window.locale.shortDayNames[E]; _value["dddd"] = window.locale.dayNames[E]; _value["H"] = H; _value["HH"] = DateFormat.LZ(H); if (H == 0) { _value["h"] = 12; } else if (H > 12) { _value["h"] = H - 12; } else { _value["h"] = H; } _value["hh"] = DateFormat.LZ(_value["h"]); if (H > 11) { _value["K"] = H - 12; } else { _value["K"] = H; } _value["k"] = H + 1; _value["KK"] = DateFormat.LZ(_value["K"]); _value["kk"] = DateFormat.LZ(_value["k"]); if (H > 11) { _value["a"] = "PM"; } else { _value["a"] = "AM"; } _value["m"] = m; _value["mm"] = DateFormat.LZ(m); _value["s"] = s; _value["ss"] = DateFormat.LZ(s);
        while (i_format < format.length) { c = format.charAt(i_format); token = ""; while ((format.charAt(i_format) == c) && (i_format < format.length)) token += format.charAt(i_format++); if (_value[token] != null) result += _value[token]; else result += token; }
        return result;
    },
    _isInteger: function(val) { var digits = "1234567890"; for (var i = 0; i < val.length; i++) if (digits.indexOf(val.charAt(i)) == -1) return false; return true; },
    _getInt: function(str, i, minlength, maxlength) { for (var x = maxlength; x >= minlength; x--) { var token = str.substring(i, i + x); if (token.length < minlength) return null; if (DateFormat._isInteger(token)) return token; } return null; },
    parseFormat: function(val, format) {
        if (typeof format == "undefined") format = window.locale.dateFormat;
        val = val + ""; format = format + ""; var i_val = 0; var i_format = 0; var c = ""; var token = ""; var x, y; var now = new Date(); var year = now.getYear(); var month = now.getMonth() + 1; var date = 1; var hh = now.getHours(); var mm = now.getMinutes(); var ss = now.getSeconds(); var ampm = "";
        while (i_format < format.length) {
            // Get next token from format string
            c = format.charAt(i_format);
            token = "";
            while ((format.charAt(i_format) == c) && (i_format < format.length))
                token += format.charAt(i_format++);
            // Extract contents of value based on format token
            if (token === "yyyy" || token === "yy" || token === "y") { if (token === "yyyy") x = 4; y = 4; if (token === "yy") x = 2; y = 2; if (token === "y") x = 2; y = 4; year = DateFormat._getInt(val, i_val, x, y); if (year == null) return 0; i_val += year.length; if (year.length == 2) { if (year > 70) year = 1900 + (year - 0); else year = 2000 + (year - 0); } }
            else if (token === "MMMM" || token === "MMM") { month = 0; for (var i = 0; i < window.locale.monthNames.length; i++) { var month_name = window.locale.monthNames[i]; if (val.substring(i_val, i_val + month_name.length).toLowerCase() === month_name.toLowerCase()) { if (token === "MMMM" || (token === "MMM" && i > 11)) { month = i + 1; if (month > 12) month -= 12; i_val += month_name.length; break; } } } if ((month < 1) || (month > 12)) return 0; }
            else if (token === "dddd" || token === "ddd") { for (var i = 0; i < window.locale.dayNames.length; i++) { var day_name = window.locale.dayNames[i]; if (val.substring(i_val, i_val + day_name.length).toLowerCase() === day_name.toLowerCase()) { i_val += day_name.length; break; } } }
            else if (token === "MM" || token === "M") { month = DateFormat._getInt(val, i_val, token.length, 2); if (month == null || (month < 1) || (month > 12)) return 0; i_val += month.length; }
            else if (token === "dd" || token === "d") { date = DateFormat._getInt(val, i_val, token.length, 2); if (date == null || (date < 1) || (date > 31)) return 0; i_val += date.length; }
            else if (token === "hh" || token === "h") { hh = DateFormat._getInt(val, i_val, token.length, 2); if (hh == null || (hh < 1) || (hh > 12)) return 0; i_val += hh.length; }
            else if (token === "HH" || token === "H") { hh = DateFormat._getInt(val, i_val, token.length, 2); if (hh == null || (hh < 0) || (hh > 23)) return 0; i_val += hh.length; }
            else if (token === "KK" || token === "K") { hh = DateFormat._getInt(val, i_val, token.length, 2); if (hh == null || (hh < 0) || (hh > 11)) return 0; i_val += hh.length; }
            else if (token === "kk" || token === "k") { hh = DateFormat._getInt(val, i_val, token.length, 2); if (hh == null || (hh < 1) || (hh > 24)) return 0; i_val += hh.length; hh--; }
            else if (token === "mm" || token === "m") { mm = DateFormat._getInt(val, i_val, token.length, 2); if (mm == null || (mm < 0) || (mm > 59)) return 0; i_val += mm.length; }
            else if (token === "ss" || token === "s") { ss = DateFormat._getInt(val, i_val, token.length, 2); if (ss == null || (ss < 0) || (ss > 59)) return 0; i_val += ss.length; }
            else if (token === "a") { if (val.substring(i_val, i_val + 2).toLowerCase() == "am") ampm = "AM"; else if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") ampm = "PM"; else return 0; i_val += 2; }
            else { if (val.substring(i_val, i_val + token.length) != token) return 0; else i_val += token.length; }
        }
        // If there are any trailing characters left in the value, it doesn't match
        if (i_val != val.length) return 0;
        // Is date valid for month?
        if (month == 2) {            // Check for leap year
            if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) { if (date > 29) return 0; } else if (date > 28) { return 0; }
        }
        if ((month === 4) || (month === 6) || (month === 9) || (month === 11)) if (date > 30) return 0;
        // Correct hours value
        if (hh < 12 && ampm === "PM") hh = hh - 0 + 12; else if (hh > 11 && ampm === "AM") hh -= 12;
        var _newdate = new Date(year, month - 1, date, hh, mm, ss);
        return _newdate;
    },
    parse: function(val, format) {
        if (format) { return DateFormat.parseFormat(_value, format); } else {
            var _preferEuro = (arguments.length == 2) ? arguments[1] : false;
            var _generalFormats = new Array('y-M-d', 'MMMM d, y', 'MMMM d,y', 'y-MMMM-d', 'd-MMMM-y', 'MMMM d');
            var _monthFirst = new Array('M/d/y', 'M-d-y', 'M.d.y', 'MMMM-d', 'M/d', 'M-d');
            var _dateFirst = new Array('d/M/y', 'd-M-y', 'd.M.y', 'd-MMMM', 'd/M', 'd-M');
            var _checkList = [_generalFormats, _preferEuro ? _dateFirst : _monthFirst, _preferEuro ? _monthFirst : _dateFirst];
            var d = null;
            var cJ, JL;
            for (var cI = 0; cI < _checkList.length; cI++) {
                JL = checkList[cI];
                for (cJ = 0; cJ < JL.length; cJ++) {
                    d = DateFormat.parseFormat(_value, JL[cJ]);
                    if (d != 0) return new Date(d);
                }
            }
            return null;
        }
    }
});
DateFormat.prototype = { initialize: function(format) { this.format = format; }, parse: function(_value) { return DateFormat.parseFormat(_value, this.format); }, format: function(_value) { return DateFormat.format(_value, this.format); } }
Date.prototype.format = function(format) { return DateFormat.format(this, format); }


/************* DATEPICKER ***************/
/*
CONSTRUCTOR
DatePicker(element, options)
element must be an input box dom node.
options can contain the following properties:
1. minDate : minimum allowed date
2. maxDate : maxnimum allowed date
EVENTS
"changed" when a new date is set
*/
Control.DatePicker = Class.create();
Control.DatePicker.activePicker = null;
Control.DatePicker.prototype = {
    initialize: function(element, options) {
        this.element = $(element);
        options = options || {};
        if (typeof (options.minDate) != "undefined") options.minDate.setHours(0, 0, 0, 0);
        if (typeof (options.maxDate) != "undefined") options.maxDate.setHours(0, 0, 0, 0);
        this.handlers = { onClick: options.onClick,
            onSelect: options.onSelect
        };

        this.options = Object.extend(options || {}, {
            onClick: this.pickerClicked.bind(this),
            onSelect: this.datePicked.bind(this)
        });

        this.setValue(this.options.date = DateFormat.parseFormat(this.element.value, window.locale.dateFormat));
        // Lazy load to avoid excessive CPU usage with lots of controls on one page
        this.datepicker = null;

        this.originalValue = null;
        this.hideTimeout = null;
        Event.observe(this.element, 'click', this.togglePicker.bindAsEventListener(this));
        Event.observe(this.element, 'blur', this.inputBlur.bind(this));
        this.hidePickerListener = this.delayedHide.bind(this);
        Event.observe(this.element, 'keydown', this.keyHandler.bindAsEventListener(this));
        Event.observe(document, 'keydown', this.docKeyHandler.bindAsEventListener(this));

        this.pickerActive = false;
    },
    currentDate: 0,
    inputBlur: function() {
        var d = DateFormat.parseFormat(this.element.value, window.locale.dateFormat);
        if (typeof (d) == "undefined" || d === 0 || d === null) {
            if (this.currentDate === 0 || this.currentDate === null) {
                this.element.value = "";
                return;
            }
        }
        this.setValue(d);

    },
    getValue: function() {
        if (this.currentDate === null || typeof (this.currentDate) == "undefined" || this.currentDate === 0)
            return null;
        else
            return new Date(this.currentDate.getTime());
    },
    setValue: function(newDate) {
        if (newDate !== 0 && typeof (this.options.minDate) != "undefined" && newDate.getTime() < this.options.minDate.getTime())
            newDate = this.options.minDate;
        if (newDate !== 0) newDate.setHours(0, 0, 0, 0);
        if ((newDate === 0 || this.currentDate === 0 || this.currentDate.getTime() != newDate.getTime()) && newDate !== this.currentDate) {
            this.currentDate = newDate;
            this.notify("changed");
        }
        if (this.currentDate !== 0)
            this.element.value = DateFormat.format(this.currentDate);
        else
            this.element.value = "";
    },
    tr: function(str) {
        return this.i18n.tr(str);
    },
    delayedHide: function() {
        var prevented = typeof this._clickPrevented != "undefined" && this._clickPrevented >= new Date().getTime();
        this._clickPrevented = new Date().getTime() + 110;
        if (prevented) return;
        this.hideTimeout = setTimeout(this.hide.bind(this), 100);
    },
    pickerClicked: function() {
        if (this.hideTimeout) { clearTimeout(this.hideTimeout); this.hideTimeout = null; }
        if (this.handlers.onClick) this.handlers.onClick();
    },
    datePicked: function(date) {
        this.setValue(date);
        this.element.focus();
        this.hide();
        if (this.handlers.onSelect)
            this.handlers.onSelect(date);
        if (this.element.onchange)
            this.element.onchange();
    },

    togglePicker: function(e) {
        var prevented = typeof this._clickPrevented != "undefined" && this._clickPrevented >= new Date().getTime();
        this._clickPrevented = new Date().getTime() + 110;
        if (prevented) return;
        if (this.pickerActive) {
            this.element.value = this.originalValue;
            this.hide();
        } else {
            this.show();
        }
        //Event.stop(e);
        //return false;
    },
    docKeyHandler: function(e) {
        if (e.keyCode == Event.KEY_ESC && this.pickerActive) {
            this.element.value = this.originalValue;
            this.hide();
        }
    },
    keyHandler: function(e) {
        switch (e.keyCode) {
            case Event.KEY_ESC:
                if (this.pickerActive)
                    this.element.value = this.originalValue;
            case Event.KEY_TAB:
                this.hide();
                return;
            case Event.KEY_DOWN:
                if (!this.pickerActive) {
                    this.show();
                    Event.stop(e);
                }
        }
        if (this.pickerActive)
            return false;
    },
    hide: function() {
        if (this.pickerActive && !this.element.disabled) {
            this.pickerActive = false;
            Control.DatePicker.activePicker = null;
            this.datepicker.releaseKeys();
            Event.stopObserving(document, 'click', this.hidePickerListener, true);
            Effect.BlindUp(this.datepicker.element, {
                duration: 0.3,
                afterFinish: (function() {
                    Element.remove(this.datepicker.element);
                }).bind(this)
            });
        }
    },
    scrollOffset: function(element) {
        var valueT = 0, valueL = 0;
        do {
            if (element.tagName == 'BODY') break;
            valueT += element.scrollTop || 0;
            valueL += element.scrollLeft || 0;
            element = element.parentNode;
        } while (element);
        return Element._returnOffset(valueL, valueT);
    },
    show: function() {
        if (!this.pickerActive) {
            if (Control.DatePicker.activePicker) Control.DatePicker.activePicker.hide();
            this.element.focus();
            if (!this.datepicker) this.datepicker = new Control.DatePickerPanel(this.options);
            this.originalValue = this.element.value;

            var pos = Position.positionedOffset(this.element);
            var dim = Element.getDimensions(this.element);
            var pickerTop = /MSIE/.test(navigator.userAgent) ? (pos[1] + dim.height - 12) + 'px' : (pos[1] + dim.height - 11) + 'px';
            this.datepicker.element.style.position = 'absolute';
            this.datepicker.element.style.top = pickerTop;
            this.datepicker.element.style.left = (pos[0] - 20) + 'px';
            this.datepicker.element.style.zIndex = '99';
            var d = DateFormat.parseFormat(this.element.value);
            if (d !== null && typeof (d) != "undefined") this.datepicker.selectDate(d);
            this.datepicker.captureKeys();

            this.datepicker.element.style.display = "none";

            this.element.parentNode.appendChild(this.datepicker.element);
            Effect.BlindDown(this.datepicker.element, { duration: 0.3, afterFinish: (function() { this.datepicker.element.style.height = ""; }).bind(this) });
            this._clickPrevented = new Date().getTime() + 110;
            Event.observe(document, 'click', this.hidePickerListener, true);
            this.pickerActive = true;
            Control.DatePicker.activePicker = this;
            this.pickerClicked();
        }
    }
};
Object.Event.extend(Control.DatePicker);

Control.DatePickerPanel = Class.create();
Object.extend(Control.DatePickerPanel.prototype, {
    initialize: function(options) {
        this.options = Object.extend({
            className: 'datepickerControl',
            closeOnToday: true,
            selectToday: true,
            showOnFocus: false
        }, options || {});
        // Make sure first weekday is in the correct range
        this.keysCaptured = false;
        this.currentDate = this.options.date ? this.options.date : new Date();
        this.dayOfWeek = 0;
        this.selectedDay = null;
        this.currentDays = [];
        this.element = this.createPicker();
        this.selectDate(this.currentDate);
    },
    createPicker: function() {
        var container = document.createElement("div");
        container.className = this.options.className;
        container.style.position = 'absolute';
        this.table = document.createElement("table");
        container.appendChild(this.table);
        var cell;
        var colGroup = document.createElement("colgroup");
        var col = document.createElement("col"); col.width = "22"; colGroup.appendChild(col);
        for (cI = 0; cI < 7; cI++) {
            col = document.createElement("col"); col.width = "27"; colGroup.appendChild(col);
        }
        col = document.createElement("col"); col.width = "22"; colGroup.appendChild(col);
        this.table.appendChild(colGroup);
        var row = this.table.insertRow(-1); row.insertCell(-1).className = "shtlGreen"; Object.extend(row.insertCell(-1), { className: "shtGreen", colSpan: 7 }); row.insertCell(-1).className = "shtrGreen";
        row = this.table.insertRow(-1); row.insertCell(-1).className = "shlGreen";
        cell = row.insertCell(-1); cell.className = "navigation"; Event.observe(cell, "click", this.movePreviousMonthListener()); cell.innerHTML = '<div class="arrowLeft"></div>';
        Object.extend(row.insertCell(-1), { colSpan: 5, className: "monthLabel" });
        cell = row.insertCell(-1); cell.className = "navigation"; Event.observe(cell, "click", this.moveNextMonthListener()); cell.innerHTML = '<div class="arrowRight"></div>';
        row.insertCell(-1).className = "shrGreen";

        var cI, dN;

        row = this.table.insertRow(-1); row.insertCell(-1).className = "shl";
        for (cI = 0; cI < 7; cI++) {
            cell = row.insertCell(-1);
            cell.className = 'dayLabel' + (cI === 0 ? ' first' : '');
            cell.style.width = '27px';
            dN = this.dayName((window.locale.firstWeekDay + cI) % 7)
            if (dN.length > 4) dN = dN.charAt(0);
            cell.innerHTML = dN;
        }
        row.insertCell(-1).className = "shr";

        for (var rI = 0; rI < 6; rI++) {
            row = this.table.insertRow(-1); row.insertCell(-1).className = "shl";
            for (cI = 0; cI < 7; cI++) {
                cell = row.insertCell(-1);
                Event.observe(cell, "mouseout", Element.removeClassName.bind(this, cell, "hover"));
                Event.observe(cell, "mouseover", this.cellHover.bind(this, cell));
                Event.observe(cell, "click", this.cellClicked.bindAsEventListener(this, cell));
            }
            row.insertCell(-1).className = "shr";
        }

        row = this.table.insertRow(-1); row.insertCell(-1).className = "shbl"; cell = row.insertCell(-1); cell.className = "shb"; cell.colSpan = 7; row.insertCell(-1).className = "shbr";

        this.drawCalendar(this.table, this.currentDate);

        Event.observe(this.table, 'click', this.clickHandler.bindAsEventListener(this));
        Event.observe(this.table, 'dblclick', this.dblClickHandler.bindAsEventListener(this));
        this.documentKeyListener = this.keyHandler.bindAsEventListener(this);
        if (this.options.captureKeys) this.captureKeys();
        return container;
    },
    tr: function(str) { return this.i18n.tr(str); },
    captureKeys: function() { Event.observe(document, 'keydown', this.documentKeyListener, true); this.keysCaptured = true; },
    releaseKeys: function() { Event.stopObserving(document, 'keydown', this.documentKeyListener, true); this.keysCaptured = false; },
    setDate: function(date) {
        if (date) {
            // Clear container
            this.drawCalendar(this.table, date);
        }
    },
    drawCalendar: function(table, date) {
        this.currentDate = date;
        this.currentDays = [];

        var today = new Date();
        var previousMonth = new Date(date.getFullYear(), date.getMonth() - 1, 1)
        var nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1)

        var cell;

        cell = table.rows[1].cells[1];
        cell.title = this.monthName(previousMonth.getMonth()) + ' ' + previousMonth.getFullYear();

        cell = table.rows[1].cells[2];
        cell.innerHTML = this.monthName(date.getMonth()) + ' ' + date.getFullYear();

        cell = table.rows[1].cells[3];
        cell.title = this.monthName(nextMonth.getMonth()) + ' ' + nextMonth.getFullYear();

        var row;
        var workDate = new Date(date.getFullYear(), date.getMonth(), 1);
        var day = workDate.getDay();
        var j = (day + 7 - window.locale.firstWeekDay) % 7;

        for (var cI = 1; cI <= day; cI++) {
            cell = table.rows[3].cells[cI];
            this.setCellClass(cell, null, cI === 1);
            cell.innerHTML = "";
        }
        var rI = Math.floor(3 + (j / 7)), cI = 1 + j % 7;
        while (workDate.getMonth() == date.getMonth()) {
            cell = table.rows[rI].cells[cI];
            this.setCellClass(cell, workDate, cI === 1);
            cell.innerHTML = workDate.getDate();
            this.currentDays[workDate.getDate()] = cell;

            workDate.setDate(workDate.getDate() + 1);
            cI++;
            if (cI === 8) { cI = 1; rI++; }
        }
        do {
            while (cI < 8) {
                cell = table.rows[rI].cells[cI];
                this.setCellClass(cell, null, cI === 1);
                cell.innerHTML = "&nbsp;";
                cI++;
            }
            rI++; cI = 1;
        } while (rI <= 8);
    },
    isSelectable: function(date) {
        return date !== null && (typeof (this.options.minDate) === "undefined" || date >= this.options.minDate) && (typeof (this.options.maxDate) === "undefined" || date <= this.options.maxDate);
    },
    setCellClass: function(cell, date, firstOfWeek) {
        cell.className = "day" + (firstOfWeek ? ' first' : '');
        var disabled = date !== null && !this.isSelectable(date);
        cell.style.cursor = date === null || disabled ? "default" : "pointer";
        if (disabled)
            Element.addClassName(cell, "disabled");
    },
    movePreviousMonthListener: function() {
        return function(e) {
            var prevMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, this.currentDate.getDate(), 0, 0);
            if (prevMonth.getMonth() != (this.currentDate.getMonth() + 11) % 12) prevMonth.setDate(0);
            if (typeof (this.options.minDate) != "undefined") {
                var firstOfMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 0, 0, 0);
                if (firstOfMonth < this.options.minDate) {
                    Event.stop(e);
                    return;
                }
            }
            this.selectDate(prevMonth);
            Event.stop(e);
        } .bindAsEventListener(this);
    },
    moveNextMonthListener: function() {
        return function(e) {
            var nextMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, this.currentDate.getDate(), 0, 0);
            if (nextMonth.getMonth() != (this.currentDate.getMonth() + 1) % 12) nextMonth.setDate(0);
            if (typeof (this.options.maxDate) != "undefined") {
                if (nextMonth > this.options.maxDate) {
                    Event.stop(e);
                    return;
                }
            }
            this.selectDate(nextMonth);
            Event.stop(e);
        } .bindAsEventListener(this);
    },
    monthName: function(month) { return window.locale.monthNames[month]; },
    dayName: function(day) { return window.locale.shortDayNames[day]; },
    dblClickHandler: function(e) { if (this.options.onSelect) this.options.onSelect(this.currentDate); Event.stop(e); },
    clickHandler: function(e) { if (this.options.onClick) this.options.onClick(); Event.stop(e); },
    keyHandler: function(e) {
        var days = 0;
        switch (e.keyCode) {
            case Event.KEY_RETURN: if (this.options.onSelect) this.options.onSelect(this.currentDate); break;
            case Event.KEY_LEFT: days = -1; break;
            case Event.KEY_UP: days = -7; break;
            case Event.KEY_RIGHT: days = 1; break;
            case Event.KEY_DOWN: days = 7; break;
            case 33: // PgUp
                var lastMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, this.currentDate.getDate()); days = -this.getDaysOfMonth(lastMonth); break;
            case 34: // PgDn
                days = this.getDaysOfMonth(this.currentDate); break;
            case 13: // enter-key (forms without submit buttons)
                this.dateClicked(this.currentDate); break;
            default: return;
        }
        if (days != 0) {
            var moveDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() + days);
            if (this.isSelectable(moveDate)) this.selectDate(moveDate);
        }
        Event.stop(e);
        return false;
    },
    getDaysOfMonth: function(date) { var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0); return lastDay.getDate(); },
    getNextMonth: function(month, year, increment) { if (p_Month == 11) return [0, year + 1]; else return [month + 1, year]; },
    getPrevMonth: function(month, year, increment) { if (p_Month == 0) return [11, year - 1]; else return [month - 1, year]; },
    dateClicked: function(date) { if (date && this.isSelectable(date)) { if (this.options.onSelect) this.options.onSelect(date); this.selectDate(date); } },
    cellClicked: function(e, cell) {
        for (var cI in this.currentDays) {
            if (this.currentDays[cI] === cell) {
                var date = new Date();
                date.setFullYear(this.currentDate.getFullYear(), this.currentDate.getMonth(), cI);
                this.dateClicked(date);
                break;
            }
        }
        Event.stop(e);
        return false;
    },
    cellHover: function(cell) {
        for (var cI in this.currentDays) {
            if (this.currentDays[cI] === cell) {
                var date = new Date();
                date.setFullYear(this.currentDate.getFullYear(), this.currentDate.getMonth(), cI);
                if (this.isSelectable(date))
                    Element.addClassName(cell, "hover");
                break;
            }
        }
    },
    selectDate: function(date) {
        if (date) {
            if (date.getMonth() != this.currentDate.getMonth() || date.getFullYear() != this.currentDate.getFullYear())
                this.setDate(date);
            else
                this.currentDate = date;

            if (date.getDate() < this.currentDays.length) {
                if (this.selectedDay)
                    Element.removeClassName(this.selectedDay, 'selected');
                this.selectedDay = this.currentDays[date.getDate()];
                Element.addClassName(this.selectedDay, 'selected');
            }
        }
    }
});


/*********************** Window ******************/
Control.Window = Class.create({
    initialize: function(container, options) {
        Control.Window.windows.push(this);

        //attribute initialization
        this.container = false;
        this.isOpen = false;
        this.sourceContainer = false; //this is optionally the container that will open the window
        this.ajaxRequest = false;
        this.remoteContentLoaded = false; //this is set when the code to load the remote content is run, onRemoteContentLoaded is fired when the connection is closed
        this.numberInSequence = Control.Window.windows.length + 1; //only useful for the effect scoping
        this.effects = {
            fade: false,
            appear: false
        };
        //options
        this.options = Object.extend({
            //lifecycle
            beforeOpen: Prototype.emptyFunction,
            afterOpen: Prototype.emptyFunction,
            beforeClose: Prototype.emptyFunction,
            afterClose: Prototype.emptyFunction,
            bodyContent: null,
            //dimensions and modes
            height: null,
            width: null,
            className: 'window',
            position: 'center', //'center', 'relative', [x,y], [function(){return x;},function(){return y;}]
            offsetLeft: 0, //available only for anchors opening the window, or windows set to position: hover
            offsetTop: 0, //""
            hover: false, //element object to hover over, or if "true" only available for windows with sourceContainer (an anchor or any element already on the page with an href attribute)
            closeOnClick: false, //does not work with hover,can be: true (click anywhere), 'container' (will refer to this.container), or element (a specific element)
            //effects
            fade: false,
            fadeDuration: 0.4,
            //draggable
            /*draggable: false,*/
            //resizable
            /*resizable: false,*/
            removeOnClose: true
        }, options || {});

        //container setup
        if (container) {
            this.container = $(container);
            //need to create the container now for tooltips (or hover: element with no container already on the page)
            //second call made below will not create the container since the check is done inside createDefaultContainer()
            this.createDefaultContainer(container);
            //if an element with an href was passed in we use it to activate the window
            if (this.options.hover && this.options.hover !== true) {
                this.sourceContainer = $(this.options.hover);
                //hover or click handling
                this.sourceContainerOpenHandler = function(event) {
                    this.open(event);
                    event.stop();
                    return false;
                } .bindAsEventListener(this);
                this.sourceContainerCloseHandler = function(event) {
                    this.close(event);
                } .bindAsEventListener(this);
                this.sourceContainerMouseMoveHandler = function(event) {
                    this.position(event);
                } .bindAsEventListener(this);
                if (this.options.hover) {
                    this.sourceContainer.observe('mouseenter', this.sourceContainerOpenHandler);
                    this.sourceContainer.observe('mouseleave', this.sourceContainerCloseHandler);
                    if (this.options.position == 'mouse')
                        this.sourceContainer.observe('mousemove', this.sourceContainerMouseMoveHandler);
                }
            }
        }
        if (typeof (options.relativeTo) != "undefined")
            this.sourceContainer = $(options.relativeTo);

        this.createDefaultContainer(container);
        var styles = {
            margin: 0,
            position: 'absolute',
            zIndex: Control.Window.initialZIndexForWindow()
        };
        if (this.options.width)
            styles.width = $value(this.options.width) + 'px';
        if (this.options.height)
            styles.height = $value(this.options.height) + 'px';
        this.container.setStyle(styles);
        if (this.options.className)
            this.container.addClassName(this.options.className);
        this.positionHandler = this.position.bindAsEventListener(this);
        this.outOfBoundsPositionHandler = this.ensureInBounds.bindAsEventListener(this);
        this.bringToFrontHandler = this.bringToFront.bindAsEventListener(this);
        this.container.observe('mousedown', this.bringToFrontHandler);
        this.container.hide();
        this.closeHandler = this.close.bindAsEventListener(this);

        //makes sure the window can't go out of bounds
        Event.observe(window, 'resize', this.outOfBoundsPositionHandler);

        this.notify('afterInitialize');
    },
    open: function(event) {
        if (this.isOpen) {
            this.bringToFront();
            return false;
        }
        if (this.notify('beforeOpen') === false)
            return false;
        //closeOnClick
        if (this.options.closeOnClick) {
            if (this.options.closeOnClick === true)
                this.closeOnClickContainer = $(document.body);
            else if (this.options.closeOnClick === 'container')
                this.closeOnClickContainer = this.container;
            else if (this.options.closeOnClick === 'overlay') {
                Control.Overlay.load();
                this.closeOnClickContainer = Control.Overlay.container;
            } else
                this.closeOnClickContainer = $(this.options.closeOnClick);
            this.closeOnClickContainer.observe('click', this.closeHandler);
        }
        this.finishOpen(event);
        return true
    },
    close: function(event) { //event may or may not be present
        if (!this.isOpen || this.notify('beforeClose', event) === false)
            return false;
        if (this.options.closeOnClick)
            this.closeOnClickContainer.stopObserving('click', this.closeHandler);
        if (this.options.fade && !Prototype.Browser.IE) {
            this.effects.fade = new Effect.Fade(this.container, {
                queue: {
                    position: 'front',
                    scope: 'Control.Window' + this.numberInSequence
                },
                from: 1,
                to: 0,
                duration: this.options.fadeDuration / 2,
                afterFinish: function() {
                    this.isOpen = false;
                    this.notify('afterClose');
                    if (this.options.removeOnClose) this.destroy();
                } .bind(this)
            });
        } else {
            this.isOpen = false;
            this.container.hide();
        }
        if (this.ajaxRequest)
            this.ajaxRequest.transport.abort();
        if (/*!(this.options.draggable || this.options.resizable) &&*/this.options.position == 'center')
            Event.stopObserving(window, 'resize', this.positionHandler);
        if (/*!this.options.draggable && */this.options.position == 'center')
            Event.stopObserving(window, 'scroll', this.positionHandler);
        if (!this.options.fade || Prototype.Browser.IE) {
            this.isOpen = false;
            this.notify('afterClose');
            if (this.options.removeOnClose) this.destroy();
        }
        return true;
    },
    position: function(event) {
        //this is up top for performance reasons
        if (this.options.position == 'mouse') {
            var xy = [Event.pointerX(event), Event.pointerY(event)];
            this.container.setStyle({
                top: xy[1] + $value(this.options.offsetTop) + 'px',
                left: xy[0] + $value(this.options.offsetLeft) + 'px'
            });
            return;
        }
        var container_dimensions = this.container.getDimensions();
        var viewport_dimensions = document.viewport.getDimensions();
        Position.prepare();
        var left, top;
        if (this.options.position == 'center') {
            left = (Position.deltaX + Math.floor((viewport_dimensions.width - container_dimensions.width) / 2));
            top = (Position.deltaY + ((viewport_dimensions.height > container_dimensions.height) ? Math.floor((viewport_dimensions.height - container_dimensions.height) / 2) : 0));
            this.container.setStyle({
                top: (container_dimensions.height <= viewport_dimensions.height) ? ((top != null && top > 0) ? top : 0) + 'px' : 0,
                left: (container_dimensions.width <= viewport_dimensions.width) ? ((left != null && left > 0) ? left : 0) + 'px' : 0
            });
        } else if (this.options.position == 'relative') {
            var xy = this.sourceContainer.cumulativeOffset();
            top = xy[1] + $value(this.options.offsetTop);
            left = xy[0] + $value(this.options.offsetLeft);
            this.container.setStyle({
                top: (container_dimensions.height <= viewport_dimensions.height) ? top + 'px' : top - Math.floor((container_dimensions.height / viewport_dimensions.height) / 2) + 'px',
                left: (container_dimensions.width <= viewport_dimensions.width) ? left + 'px' : left - Math.floor((container_dimensions.width / viewport_dimensions.width) / 2) + 'px'
            });
        } else if (this.options.position.length) {
            top = $value(this.options.position[1]) + $value(this.options.offsetTop);
            left = $value(this.options.position[0]) + $value(this.options.offsetLeft);
            this.container.setStyle({
                top: (container_dimensions.height <= viewport_dimensions.height) ? top + 'px' : 0,
                left: (container_dimensions.width <= viewport_dimensions.width) ? left + 'px' : 0
            });
        }
    },
    ensureInBounds: function() {
        if (!this.isOpen)
            return;
        if (this.options.position == 'relative') {
            this.position();
            return;
        }
        var viewport_dimensions = document.viewport.getDimensions();
        var container_offset = this.container.cumulativeOffset();
        var container_dimensions = this.container.getDimensions();
        if (container_offset.left + container_dimensions.width > viewport_dimensions.width) {
            this.container.setStyle({
                left: (Math.max(0, viewport_dimensions.width - container_dimensions.width)) + 'px'
            });
        }
        if (container_offset.top + container_dimensions.height > viewport_dimensions.height) {
            this.container.setStyle({
                top: (Math.max(0, viewport_dimensions.height - container_dimensions.height)) + 'px'
            });
        }
    },
    bringToFront: function() {
        Control.Window.bringToFront(this);
        this.notify('bringToFront');
    },
    destroy: function() {
        this.container.stopObserving('mousedown', this.bringToFrontHandler);
        if ((this.container && !this.sourceContainer || this.options.removeOnClose) && this.container.parentNode)
            this.container.parentNode.removeChild(this.container);
        if (this.sourceContainer) {
            if (this.options.hover) {
                this.sourceContainer.stopObserving('mouseenter', this.sourceContainerOpenHandler);
                this.sourceContainer.stopObserving('mouseleave', this.sourceContainerCloseHandler);
                if (this.options.position == 'mouse')
                    this.sourceContainer.stopObserving('mousemove', this.sourceContainerMouseMoveHandler);
            }
        }
        Event.stopObserving(window, 'resize', this.outOfBoundsPositionHandler);
        Control.Window.windows = Control.Window.windows.without(this);
    },
    body: null,
    createDefaultContainer: function(container) {
        if (!this.container) {
            //no container passed or found, create it
            this.container = new Element('table', {
                id: 'ctrlw_' + this.numberInSequence,
                className: 'window'
            });
            var row = this.container.insertRow(-1);
            row.insertCell(-1).className = "shtl";
            row.insertCell(-1).className = "sht";
            row.insertCell(-1).className = "shtr";
            row = this.container.insertRow(-1);
            row.insertCell(-1).className = "shl";
            this.body = $(row.insertCell(-1)); this.body.className = "body";
            if (this.options.bodyContent) this.body.insert(this.options.bodyContent);
            row.insertCell(-1).className = "shr";
            row = this.container.insertRow(-1);
            row.insertCell(-1).className = "shbl";
            row.insertCell(-1).className = "shb";
            row.insertCell(-1).className = "shbr";


            $(document.body).insert(this.container);
            if (typeof (container) == "string" && $(container) == null && !container.match(/^#(.+)$/) && !container.match(Control.Window.uriRegex))
                this.body.update(container);
        }
        else
            this.body = this.container;
    },
    finishOpen: function(event) {
        this.bringToFront();
        if (this.options.fade && !Prototype.Browser.IE) {
            if (typeof (Effect) == "undefined")
                throw "Control.Window requires effects.js to be loaded."
            if (this.effects.fade)
                this.effects.fade.cancel();
            this.effects.appear = new Effect.Appear(this.container, {
                queue: {
                    position: 'end',
                    scope: 'Control.Window.' + this.numberInSequence
                },
                from: 0,
                to: 1,
                duration: this.options.fadeDuration / 2,
                afterFinish: function() {
                    this.isOpen = true;
                    this.notify('afterOpen');
                } .bind(this)
            });
        } else {
            this.isOpen = true;
            this.container.show();
        }
        this.position(event);
        if (!(/*this.options.draggable || */this.options.resizable) && this.options.position == 'center')
            Event.observe(window, 'resize', this.positionHandler, false);
        if (/*!this.options.draggable && */this.options.position == 'center')
            Event.observe(window, 'scroll', this.positionHandler, false);
        if (!this.options.fade || Prototype.Browser.IE) {
            this.isOpen = true;
            this.notify('afterOpen');
        }
        return true;
    }
});
//class static methods
Object.extend(Control.Window, { windows: [],
    baseZIndex: 9999,
    uriRegex: /^(\/|\#|https?\:\/\/|[\w]+\/)/,
    bringToFront: function(w) {
        Control.Window.windows = Control.Window.windows.without(w);
        Control.Window.windows.push(w);
        Control.Window.windows.each(function(w, i) {
            var z_index = Control.Window.baseZIndex + i;
            w.container.setStyle({
                zIndex: z_index
            });
        });
    },
    //protected
    initialZIndexForWindow: function(w) {
        return Control.Window.baseZIndex + (Control.Window.windows.length - 1);
    }
});
Object.Event.extend(Control.Window);

//this is the observer for both Resizables and Draggables
Control.Window.LayoutUpdateObserver = Class.create({
    initialize: function(w, observer) {
        this.w = w;
        this.element = $(w.container);
        this.observer = observer;
    },
    onStart: Prototype.emptyFunction,
    onEnd: Prototype.emptyFunction
});

/********************* Overlay for Control.Modal ******************/
Control.Overlay = {
    id: 'control_overlay',
    loaded: false,
    container: false,
    lastOpacity: 0,
    styles: {
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        zIndex: 9998
    },
    ieStyles: {
        position: 'absolute',
        top: 0,
        left: 0,
        zIndex: 9998
    },
    effects: {
        fade: false,
        appear: false
    },
    load: function() {
        if (Control.Overlay.loaded)
            return false;
        Control.Overlay.loaded = true;
        Control.Overlay.container = new Element('div', {
            id: Control.Overlay.id
        });
        var _body = $(document.body);
        _body.insert(Control.Overlay.container);
        _body.addClassName("overlayPresent");

        if (Prototype.Browser.IE) {
            Control.Overlay.container.setStyle(Control.Overlay.ieStyles);
            Event.observe(window, 'scroll', Control.Overlay.positionOverlay);
            Event.observe(window, 'resize', Control.Overlay.positionOverlay);
            Control.Overlay.observe('beforeShow', Control.Overlay.positionOverlay);
        } else
            Control.Overlay.container.setStyle(Control.Overlay.styles);
        Control.Overlay.container.hide();
        return true;
    },
    unload: function() {
    if (!Control.Overlay.loaded)
            return false;
        Event.stopObserving(window, 'resize', Control.Overlay.positionOverlay);
        Control.Overlay.stopObserving('beforeShow', Control.Overlay.positionOverlay);
        Control.Overlay.container.remove();
        Control.Overlay.loaded = false;
        return true;
    },
    show: function(opacity, fade) {
        if (Control.Overlay.notify('beforeShow') === false)
            return false;
        $(document.body).addClassName("overlayPresent");
        Control.Overlay.lastOpacity = opacity;
        if (fade) {
            if (typeof (Effect) == "undefined") return;
            if (Control.Overlay.effects.fade)
                Control.Overlay.effects.fade.cancel();
            Control.Overlay.effects.appear = new Effect.Appear(Control.Overlay.container, {
                queue: {
                    position: 'end',
                    scope: 'Control.Overlay'
                },
                afterFinish: function() {
                    Control.Overlay.notify('afterShow');
                },
                from: 0,
                to: Control.Overlay.lastOpacity,
                duration: (fade === true ? 0.75 : fade) / 2
            });
        } else {
            Control.Overlay.container.setStyle({
                opacity: opacity || 1
            });
            Control.Overlay.container.show();
            Control.Overlay.notify('afterShow');
        }
        return true;
    },
    hide: function(fade) {
        if (Control.Overlay.notify('beforeHide') === false)
            return false;
        $(document.body).removeClassName("overlayPresent");
        if (Control.Overlay.effects.appear)
            Control.Overlay.effects.appear.cancel();
        if (fade) {
            Control.Overlay.effects.fade = new Effect.Fade(Control.Overlay.container, {
                queue: {
                    position: 'front',
                    scope: 'Control.Overlay'
                },
                afterFinish: function() {
                    Control.Overlay.notify('afterHide');
                },
                from: Control.Overlay.lastOpacity,
                to: 0,
                duration: (fade === true ? 0.75 : fade) / 2
            });
        } else {
            Control.Overlay.container.hide();
            Control.Overlay.notify('afterHide');
        }
        return true;
    },
    //IE only
    positionOverlay: function() {
        Control.Overlay.container.setStyle({
            width: document.body.clientWidth + 'px',
            height: document.body.clientHeight + 'px'
        });
    }
};
Object.Event.extend(Control.Overlay);

Control.ToolTip = Class.create(Control.Window, {
    initialize: function($super, container, tooltip, options) {
        $super(tooltip, Object.extend(Object.extend(Object.clone(Control.ToolTip.defaultOptions), options || {}), {
            position: 'mouse',
            hover: container
        }));
    }
});
Object.extend(Control.ToolTip, {
    defaultOptions: {
        offsetLeft: 10
    }
});

Control.Modal = Class.create(Control.Window, {
    initialize: function($super, container, options) {
        Control.Modal.InstanceMethods.beforeInitialize.bind(this)();
        $super(container, Object.extend(Object.clone(Control.Modal.defaultOptions), options || {}));
    }
});
Object.extend(Control.Modal, {
    defaultOptions: {
        overlayOpacity: 0.5,
        closeOnClick: 'overlay'
    },
    current: false,
    open: function(container, options) {
        var _modal = new Control.Modal(container, options);
        _modal.open();
        return _modal;
    },
    alert: function(_options) {
        _options = _options || {};
        var _body = document.createElement("div");
        var _closeIcon;
        if (Object.isString(_options.title)) {
            var table = document.createElement("table"); table.style.width = "100%"; table.className = "windowTitle";
            _body.appendChild(table);
            var row = table.insertRow(-1); var cell = Object.extend(row.insertCell(-1), { innerHTML: "<h3>" + _options.title + "</h3>" });
            _closeIcon = Object.extend(new Element("div"), { className: "closeIcon" });
            cell = row.insertCell(-1); cell.style.textAlign = "right"; cell.style.width = "37px";
            cell.appendChild(_closeIcon);
        } else
            _closeIcon = null;
        if (typeof (_options.text) != "undefined")
            _body.appendChild(Object.extend(document.createElement("div"), { innerHTML: _options.text }));
        if (typeof (_options.bodyNode) != "undefined")
            _body.appendChild(_options.bodyNode);
        _body.className = "modalWindow";
        var _okButton;
        if (Object.isString(_options.button)) {
            _okButton = new Element("button");
            _okButton.className = "defaultButton";
            _okButton.appendChild(Object.extend(document.createElement("div"), { className: "chevron", innerHTML: _options.button }));
            _body.appendChild(_okButton);
        } else
            _okButton = null;
        var _modal = Control.Modal.open(null, {fade: true,bodyContent: _body, width: _options.width});
        if (_closeIcon !== null) _closeIcon.observe('click', _modal.close.bind(_modal));
        if (_okButton !== null) _okButton.observe('click', _modal.close.bind(_modal));
        return _modal;
    },
    close: function() {
        if (Control.Modal.current)
            Control.Modal.current.close();
    },
    InstanceMethods: {
        beforeInitialize: function() {
            Control.Overlay.load();
            this.overlayFinishedOpening = false;
            this.observe('beforeOpen', Control.Modal.Observers.beforeOpen.bind(this));
            this.observe('afterOpen', Control.Modal.Observers.afterOpen.bind(this));
            this.observe('afterClose', Control.Modal.Observers.afterClose.bind(this));
            Event.observe(document, "keypress", Control.Modal.Observers.documentOnKeyDown.bind(this));
        }
    },
    Observers: {
        beforeOpen: function() {
            if (!this.overlayFinishedOpening) {
                Control.Overlay.observeOnce('afterShow', function() {
                    this.overlayFinishedOpening = true;
                    this.open();
                } .bind(this));
                Control.Overlay.show(this.options.overlayOpacity, this.options.fade ? this.options.fadeDuration : false);
                throw $break;
            } else
                Control.Window.windows.without(this).invoke('close');
        },
        afterOpen: function() {
            Control.Modal.current = this;
        },
        afterClose: function() {
            Control.Overlay.hide(this.options.fade ? this.options.fadeDuration : false);
            Control.Modal.current = false;
            this.overlayFinishedOpening = false;
        },
        documentOnKeyDown: function(e) {
            var key = e.which || e.keyCode;
            if (key === Event.KEY_ESC)
                this.close();
        }
    }
});


/************************ Quick booking ************************/
///Display a popup prompting the user to enter a card number
function qbCardShow(e, relativeTo, _options) {

    Event.stop(e);
    var _body = document.createElement("div"); _body.className = "modalWindow qbLoginWindow";
    var _holder = new WatermarkTextbox(document.createElement("input"), _options.holder);
    _holder.element.style.width = "150px";
    var _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(_holder.element);
    _body.appendChild(_div);

    var _card = new WatermarkTextbox(document.createElement("input"), _options.card);
    _card.element.style.width = "150px";
    _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(_card.element);
    _body.appendChild(_div);

    _div = document.createElement("div");
    _div.style.height = "10px";
    _body.appendChild(_div);

    var _errorDiv = document.createElement("div");
    _errorDiv.innerHTML = _options.invalidId;
    _errorDiv.className = "error";
    _errorDiv.style.display = "none";
    _body.appendChild(_errorDiv);

    var _validationButton = $(document.createElement("button"));
    _validationButton.className = "";
    _validationButton.innerHTML = '<div class="chevron">' + _options.validate + '</div>';
    _div = document.createElement("div");
    _div.appendChild(_validationButton);
    _body.appendChild(_div);

    var _errorHideFn = function() { if (this.style.height == "" && this.style.display !== "none") Effect.BlindUp(this); } .bind(_errorDiv);
    $(_holder.element).observe("keypress", _errorHideFn);
    $(_card.element).observe("keypress", _errorHideFn);

    var _modal = Control.Modal.alert({
        fade: true,
        bodyNode: _body,
        title: _options.title,
        position: 'relative',
        relativeTo: relativeTo,
        offsetTop: 10
    });
    _modal.observe('afterOpen', _holder.select.bind(_holder, true));
    var _validFn = function() {

        var params = { st: 'CA', s: 'CA', mh: _holder.getValue(), mc: _card.getValue() };
        if (typeof (scenarioId) != "undefined") params.t = scenarioId;
        var url = _options.wbe + "geo.authenticate.ashx";
        safeRequest(url, { method: 'GET', parameters: params, onSuccess: function(transport) {
            var res = transport.responseJSON;
            if (res.result !== "ok") {
                relativeTo.innerHTML = _options.choose;
                Effect.BlindDown(_errorDiv, { duration: 0.3, afterFinish: (function() { this.style.height = ""; }).bind(_errorDiv) });
                _holder.element.focus();
            } else {
                relativeTo.innerHTML = Object.isString(res.holder) ? "<div>" + res.holder + "</div>" : _options.choose;
                _modal.close();
            }
        }, onFailure: function(transport) {
            if (Object.isString(window.locale.networkFailure)) Control.Modal.alert({ title: window.locale.error, text: window.locale.networkFailure, button: window.locale.ok });
        }
        });
    };
    _validationButton.observe('click', _validFn);
    onEnter(_holder.element, _card.focus.bind(_card));
    onEnter(_card.element, _validFn);
}
var lastAjaxVariableId = 0;
function jsonWbeLoaded(result, context) {
    var _options = window.jsonOptions[context];
    _options.onSuccess({ responseJSON: result });
    window.jsonOptions[context] = null;
}
function safeRequest(url, _options) {
    if (typeof (window.locale) != "undefined" && typeof (window.locale.distanceFromCenter) != "undefined") {
        new Ajax.Request(url, _options);
    } else {
        var head = document.getElementsByTagName("head")[0];
        var newScript = document.createElement("script");
        if (typeof (window.jsonOptions) == "undefined") window.jsonOptions = [];
        window.jsonOptions[lastAjaxVariableId] = _options;
        newScript.type = 'text/javascript';
        //newScript.onload =
        newScript.src = url + "?" + Object.toQueryString(_options.parameters) + "&jsonCallback=" + lastAjaxVariableId + "&random=" + (new Date().getTime().toString());
        lastAjaxVariableId++;
        head.appendChild(newScript);
    }

}


///Display a popup prompting the user to enter an account login and password
function qbAccountLoginShow(e, _options) {
    Event.stop(e);
    var _body = document.createElement("div"); _body.className = "modalWindow qbLoginWindow";
    var _loginDom = document.createElement("input");
    var _div = document.createElement("div"); _div.className = "textbox";
    _body.appendChild(_div);
    var _login = new WatermarkTextbox(_loginDom, _options.login);
    _login.element.style.width = "150px";
    _div.appendChild(_loginDom);

    var passDom = document.createElement("input"); passDom.setAttribute('type', 'password');
    _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(passDom);
    var _password = new WatermarkTextbox(passDom, _options.password, { password: true });
    _password.element.style.width = "150px";
    _body.appendChild(_div);
    _div = document.createElement("div");
    _div.style.height = "10px";
    _body.appendChild(_div);

    onEnter(_loginDom, _password.focus.bind(_password));



    var _errorDiv = document.createElement("div");
    _errorDiv.innerHTML = _options.invalidId;
    _errorDiv.className = "error";
    _errorDiv.style.display = "none";
    _body.appendChild(_errorDiv);


    var _spinner = document.createElement("div");
    _spinner.style.cssFloat = _spinner.style.styleFloat = "right";
    _spinner.style.paddingTop = "10px";
    _spinner.style.display = "none";
    _spinner.innerHTML = '<img src="' + _options.wbe + '/ca/css/spinner.small.gif" width="16" height="16" alt="" />';
    _body.appendChild(_spinner);

    _div = document.createElement("div");
    var _validationButton = $(document.createElement("button"));
    _validationButton.className = "";
    _validationButton.innerHTML = '<div class="chevron">' + _options.validate + '</div>';
    _div.appendChild(_validationButton);
    _body.appendChild(_div);

    var _errorHideFn = (function() { if (this.style.height == "" && this.style.display !== "none") Effect.BlindUp(this, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) }); }).bind(_errorDiv);
    $(_login.element).observe("keypress", _errorHideFn);
    $(passDom).observe("keypress", _errorHideFn);

    var _modal = Control.Modal.alert({
        fade: true,
        bodyNode: _body,
        title: _options.title
    });
    _modal.observe('afterOpen', _login.select.bind(_login, true));
    var _validateFn = _qbAccountLoginTry.curry(_login, _password, _modal, _errorDiv, _spinner, _options.wbe, null);
    _validationButton.observe('click', _validateFn);
    onEnter(passDom, _validateFn);
}
function _qbAccountLoginTry(_login, _password, _modal, _errorDiv, _spinner, wbeBase, _callback) {
    var _shakeFn = function() {
        Effect.BlindDown(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
        _login.focus();
    };
    var effect = null;
    if (_errorDiv.style.height == "" && _errorDiv.style.display !== "none") effect = Effect.BlindUp(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
    var params = { st: window.brand || "CA", actl: _login.getValue(), actp: _password.getValue(), rand: new Date().getTime() };
    if (params.actl === null || params.actl.length == 0 || params.actp === null || params.actp.length == 0) {
        _shakeFn();
        return;
    }
    _spinner.style.display = "";
    safeRequest(wbeBase + "geo.authenticate.ashx", { method: 'GET', parameters: params,
        onSuccess: function(transport) {
            var res = transport.responseJSON;
            if (res.result === "ok") {
                window.location.href = wbeBase + "CA/account.aspx?from=site";
            } else {
                _spinner.style.display = "none";
                if (effect !== null) effect.cancel();
                _errorDiv.style.height = "";
                _shakeFn();
            }
        }
    });
}




///Display a popup prompting the user to enter a helho card
function qbheLHoShow(e, _options) {

    Event.stop(e);
    var _body = document.createElement("div"); _body.className = "modalWindow qbLoginWindow";
    var _cardDom = document.createElement("input");
    var _div = document.createElement("div"); _div.className = "textbox";
    _body.appendChild(_div);
    var _card = new WatermarkTextbox(_cardDom, _options.card);
    _card.element.style.width = "150px";
    _div.appendChild(_cardDom);

    var _lastDom = document.createElement("input");
    _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(_lastDom);
    var _last = new WatermarkTextbox(_lastDom, _options.holder);
    _last.element.style.width = "150px";
    _body.appendChild(_div);
    _div = document.createElement("div");
    _div.style.height = "10px";
    _body.appendChild(_div);

    onEnter(_cardDom, _last.focus.bind(_last));



    var _errorDiv = document.createElement("div");
    _errorDiv.innerHTML = _options.invalidId;
    _errorDiv.className = "error";
    _errorDiv.style.display = "none";
    _body.appendChild(_errorDiv);


    var _spinner = document.createElement("div");
    _spinner.style.cssFloat = _spinner.style.styleFloat = "right";
    _spinner.style.paddingTop = "10px";
    _spinner.style.display = "none";
    _spinner.innerHTML = '<img src="' + _options.wbe + '/ca/css/spinner.small.gif" width="16" height="16" alt="" />';
    _body.appendChild(_spinner);

    _div = document.createElement("div");
    var _validationButton = $(document.createElement("button"));
    _validationButton.className = "";
    _validationButton.innerHTML = '<div class="chevron">' + _options.validate + '</div>';
    _div.appendChild(_validationButton);
    _body.appendChild(_div);

    var _errorHideFn = (function() { if (this.style.height == "" && this.style.display !== "none") Effect.BlindUp(this, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) }); }).bind(_errorDiv);
    $(_lastDom).observe("keypress", _errorHideFn);
    $(_cardDom).observe("keypress", _errorHideFn);

    var _modal = Control.Modal.alert({
        fade: true,
        bodyNode: _body,
        title: _options.title
    });
    _modal.observe('afterOpen', _card.select.bind(_card, true));
    var _validateFn = _qbheLHoTry.curry(_card, _last, _modal, _errorDiv, _spinner, _options.wbe, null);
    _validationButton.observe('click', _validateFn);
    onEnter(_lastDom, _validateFn);
}
function _qbheLHoTry(_card, _last, _modal, _errorDiv, _spinner, wbeBase, _callback) {
    var _shakeFn = function() {
        Effect.BlindDown(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
        login.focus();
    };
    var effect = null;
    if (_errorDiv.style.height == "" && _errorDiv.style.display !== "none") effect = Effect.BlindUp(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
    var params = { "mc": _card.getValue(), "mh": _last.getValue(), rand: new Date().getTime() };
    if (params.mh === null || params.mh.length == 0 || params.mc === null || params.mc.length == 0) {
        _shakeFn();
        return;
    }
    _spinner.style.display = "";
    safeRequest(wbeBase + "geo.authenticate.ashx", { method: 'GET', parameters: params,
        onSuccess: function(transport) {
            var res = transport.responseJSON;
            if (res.result === "ok") {
                window.location.href = wbeBase + "CA/account.aspx?stays&from=site";
            } else {
                _spinner.style.display = "none";
                if (effect !== null) effect.cancel();
                _errorDiv.style.height = "";
                _shakeFn();
            }
        }
    });
}



///Display a popup prompting the user to enter a helho card
function qbConfShow(e, _options) {
    Event.stop(e);
    var _body = document.createElement("div"); _body.className = "modalWindow qbLoginWindow";
    var _confDom = document.createElement("input");
    var _div = document.createElement("div"); _div.className = "textbox";
    _body.appendChild(_div);
    var _conf = new WatermarkTextbox(_confDom, _options.confirmation);
    _conf.element.style.width = "150px";
    _div.appendChild(_confDom);

    var _lastDom = document.createElement("input");
    _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(_lastDom);
    var _last = new WatermarkTextbox(_lastDom, _options.last);
    _last.element.style.width = "150px";
    _body.appendChild(_div);
    onEnter(_confDom, _last.focus.bind(_last));

    var _ccDom = document.createElement("input");
    _div = document.createElement("div"); _div.className = "textbox";
    _div.appendChild(_ccDom);
    var _cc = new WatermarkTextbox(_ccDom, _options.cc);
    _ccDom.style.width = "150px";
    _body.appendChild(_div);
    _div = document.createElement("div");
    _div.style.height = "10px";
    _body.appendChild(_div);
    onEnter(_lastDom, _cc.focus.bind(_cc));



    var _errorDiv = document.createElement("div");
    _errorDiv.innerHTML = _options.invalidId;
    _errorDiv.className = "error";
    _errorDiv.style.display = "none";
    _body.appendChild(_errorDiv);


    var _spinner = document.createElement("div");
    _spinner.style.cssFloat = _spinner.style.styleFloat = "right";
    _spinner.style.paddingTop = "10px";
    _spinner.style.display = "none";
    _spinner.innerHTML = '<img src="' + _options.wbe + '/ca/css/spinner.small.gif" width="16" height="16" alt="" />';
    _body.appendChild(_spinner);

    _div = document.createElement("div");
    var _validationButton = $(document.createElement("button"));
    _validationButton.className = "";
    _validationButton.innerHTML = '<div class="chevron">' + _options.validate + '</div>';
    _div.appendChild(_validationButton);
    _body.appendChild(_div);

    var _errorHideFn = (function() { if (this.style.height == "" && this.style.display !== "none") Effect.BlindUp(this, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) }); }).bind(_errorDiv);
    $(_lastDom).observe("keypress", _errorHideFn);
    $(_confDom).observe("keypress", _errorHideFn);

    var _modal = Control.Modal.alert({
        fade: true,
        bodyNode: _body,
        title: _options.title
    });
    _modal.observe('afterOpen', _conf.select.bind(_conf, true));
    var _validateFn = _qbConfTry.curry(_conf, _last, _cc, _modal, _errorDiv, _spinner, _options.wbe, null);
    _validationButton.observe('click', _validateFn);
    onEnter(_lastDom, _validateFn);
}
function _qbConfTry(_conf, _last, _cc, _modal, _errorDiv, _spinner, wbeBase, _callback) {
    var _shakeFn = function() {
        Effect.BlindDown(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
        login.focus();
    };
    var effect = null;
    if (_errorDiv.style.height == "" && _errorDiv.style.display !== "none") effect = Effect.BlindUp(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
    var params = { "conf": _conf.getValue(), "last": _last.getValue(), "cc": _cc.getValue(), rand: new Date().getTime() };
    if (params.conf === null || params.conf.length == 0 || params.last === null || params.last.length == 0) {
        _shakeFn();
        return;
    }
    _spinner.style.display = "";
    safeRequest(wbeBase + "geo.authenticate.ashx", { method: 'GET', parameters: params,
        onSuccess: function(transport) {
            var res = transport.responseJSON;
            if (res.result === "ok") {
                window.location.href = wbeBase + "CA/account.aspx?stays&from=site";
            } else {
                _spinner.style.display = "none";
                if (effect !== null) effect.cancel();
                _errorDiv.style.height = "";
                _shakeFn();
            }
        }
    });
}

function setAutoHeight() {
    this.style.height = "auto";
}

Ajax.Request.prototype.abort = function() {
    // prevent and state change callbacks from being issued
    this.transport.onreadystatechange = Prototype.emptyFunction;
    // abort the XHR
    this.transport.abort();
    // update the request counter
    Ajax.activeRequestCount--;
};

function allowXScroll(v) {
    var html = document.body.parentNode;
    if (typeof (html) != "undefined") html.style.overflowX = v ? "scroll" : "hidden";
}
function moveDivsInScreen() {
    var vw = document.viewport.getWidth();
    var offset = vw - 1026, delta;
    var l1 = $("layout1") || $("layout"), l2 = $("layout2"), bs = $("bandSplit"), bsi = $("bandSplitImage");
    if (offset < 0) {
        if (offset < -30) offset = -30;
        delta = offset / 2;
        offset = delta.toString() + "px";
        if (l1) l1.style.marginLeft = offset;
        if (l2) l2.style.marginLeft = offset;
        if (bs) { bs.style.width = "1026px"; if (!Prototype.Browser.IE) bs.style.marginLeft = offset; }
        if (bsi && navigator.userAgent.indexOf("MSIE 6") >= 0) {
            bsi.style.marginLeft = (-delta).toString() + "px";
        }
        if (bsi && !Prototype.Browser.IE) {
            bsi.style.marginLeft = offset;
        }
        allowXScroll(vw < 998);
    }
    else {
        delta = 0;
        if (l1) l1.style.marginLeft = "";
        if (l2) l2.style.marginLeft = "";
        if (bs) { bs.style.width = ""; bs.style.marginLeft = ""; }
        if (bsi) bsi.style.marginLeft = "";
        allowXScroll(false);
    }
    var homeNews = $("homeNews");
    if (homeNews) { homeNews.style.position = "relative"; homeNews.style.position = ""; }

}

document.observe("dom:loaded", function() {
    Event.observe(window, 'resize', moveDivsInScreen);
    moveDivsInScreen();
});
function wbeIForgot(e, _options) {
    var _body = document.createElement("div"); _body.className = "modalWindow qbLoginWindow";
    var _loginDom = document.createElement("input");
    var _div = document.createElement("div");
    _div.innerHTML = _options.prompt;
    _body.appendChild(_div);

    _div = document.createElement("div"); _div.className = "textbox";
    _body.appendChild(_div);
    var _defaultLogin = _options.login.getValue();
    if (_defaultLogin !== null && _defaultLogin.length > 0)
        _loginDom.value = _defaultLogin;

    var _login = new WatermarkTextbox(_loginDom, _options.login.watermarkText);
    _loginDom.style.width = "170px";
    _div.appendChild(_loginDom);

    _div = document.createElement("div");
    _div.style.height = "10px";
    _body.appendChild(_div);




    var _errorDiv = document.createElement("div");
    _errorDiv.innerHTML = _options.invalidId;
    _errorDiv.className = "error";
    _errorDiv.style.display = "none";
    _body.appendChild(_errorDiv);


    var _spinner = document.createElement("div");
    _spinner.style.cssFloat = _spinner.style.styleFloat = "right";
    _spinner.style.paddingTop = "10px";
    _spinner.style.display = "none";
    _spinner.innerHTML = '<img src="' + _options.wbe + '/ca/css/spinner.small.gif" width="16" height="16" alt="" />';
    _body.appendChild(_spinner);

    _div = document.createElement("div");
    var _validationButton = $(document.createElement("button"));
    _validationButton.className = "";
    _validationButton.innerHTML = '<div class="chevron">' + _options.validate + '</div>';
    _div.appendChild(_validationButton);
    _body.appendChild(_div);

    var _errorHideFn = (function() { if (this.style.height == "" && this.style.display !== "none") Effect.BlindUp(this, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) }); }).bind(_errorDiv);
    $(_loginDom).observe("keypress", _errorHideFn);

    var _modal = Control.Modal.alert({
        fade: true,
        bodyNode: _body,
        title: _options.title
    });
    _modal.observe('afterOpen', _login.select.bind(_login, true));
    var _validateFn = _qbForgotTry.curry(_login, _modal, _errorDiv, _spinner, _options.wbe, _options.title, _options.ok, _options.locale);
    _validationButton.observe('click', _validateFn);
    onEnter(_loginDom, _validateFn);
}
function _qbForgotTry(_login, _modal, _errorDiv, _spinner, _wbeBase, _modalTitle, _ok, _locale) {
    var _shakeFn = function() {
        Effect.BlindDown(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
        _login.focus();
    };
    var effect = null;
    if (_errorDiv.style.height == "" && _errorDiv.style.display !== "none") effect = Effect.BlindUp(_errorDiv, { duration: 0.3, afterFinish: setAutoHeight.bind(_errorDiv) });
    var params = { st: window.brand || "CA", actl: _login.getValue(), rand: new Date().getTime(), l: _locale };
    if (params.actl === null || params.actl.length == 0) {
        _shakeFn();
        return;
    }
    _spinner.style.display = "";
    safeRequest(_wbeBase + "forgot.ashx", { method: 'GET', parameters: params,
        onSuccess: function(transport) {
            var res = transport.responseJSON;
            if (res.status === "ok") {
                if (!Object.isUndefined(res.message)) {
                    _modal.options.fade = false;
                    _modal.close();
                    Control.Modal.alert({
                        fade: true,
                        button: _ok,
                        text: res.message,
                        title: _modalTitle
                    });
                } else
                    _modal.close();

            } else {
                _spinner.style.display = "none";
                if (effect !== null) effect.cancel();
                _errorDiv.style.height = "";
                _shakeFn();
            }
        }, onFailure: function() {
            _spinner.style.display = "none";
            if (effect !== null) effect.cancel();
            _errorDiv.style.height = "";
            _shakeFn();
        }
    });
}
function wbeLogout(wbe) {
    document.location = wbe + "?" + encodeURIComponent(document.location);
}

function wbeConnect(e, _options) {

    try { e = e || window.event; if (!Object.isUndefined(e)) Event.stop(e || window.event); } catch (ex) { }

    _options.drop.style.top = ""; _options.drop.style.left = "";
    _options.drop.style.position = "";
    Position.absolutize(_options.drop);

    var login = _options.login.getValue();
    var password = _options.password.getValue();
    if (login === null || password === null || login.length == 0 || password.length == 0) return;

    var url = _options.wbe + "geo.authenticate.ashx";
    var wbeOk = $("wbeOk");
    new Effect.Opacity(wbeOk, { to: 0.5 });
    safeRequest(url, { method: 'GET', parameters: { actl: login, actp: password }, onSuccess: function(transport) {
        var res = transport.responseJSON;
        if (res.result === "ok") {
            window.location.href = _options.wbe + "CA/account.aspx?stays";
        } else {
            wbeOk.setOpacity(1.0);
            if (_options.invalid.style.display == "none")
                Effect.BlindDown(_options.invalid, { duration: 0.3, afterFinish: function() { _options.invalid.style.height = ""; } });
            _options.password.element.focus();
        }
    }, onFailure: function(transport) {
        new Effect.Opacity(wbeOk, { to: 1.0 });
        if (_options.invalid.style.display == "none")
            Effect.BlindDown(_options.invalid, { duration: 0.3, afterFinish: function() { _options.invalid.style.height = ""; } });
    }
    });


}
function wbeHideInvalid(invalid) {
    if (invalid.style.display != "none") Effect.BlindUp(invalid);
}
function onKeyPressedEnter(e, element, target) {
    try {
        if (e && e.keyCode === 13) {
            target();
            Event.stop(e);
            return false;
        }
    } catch (ex) { }
}
function onEnter(element, target) { if (element === null || Object.isUndefined(element)) return; Event.observe(element, "keydown", onKeyPressedEnter.bindAsEventListener(this, element, target)); }

function trackExternalLink(link) {
    _gaq.push(['_trackPageview', link.href]);
    if (typeof (link.target) == "undefined" || link.target == null || link.target == "") {
        window.setTimeout(function() { document.location.href = link.href; }, 100);
        return false;
    } else {
        return true; //There is a target
    }
}
