if (!Array.prototype.contains) {
    Array.prototype.contains = function(obj) {
        var i = this.length;
        while (i--) {
            if (this[i] === obj) {
                return true;
            }
        }
        return false;
    };

    Array.prototype.findById = function(id) {
        var i = this.length;
        while (i--) {
            if (this[i]['id'] === id) {
                return this[i];
            }
        }
        return null;
    };
}

if (!String.prototype.urlEncode) {
    String.prototype.urlEncode = function() {
        return escape(this).replace(new RegExp('\\+', 'g'), '%2b') + '&';
    };    
}


var Atms = {};
Atms.Dom = {
    addClass: function(el, c) {
        el = this.getById(el);
        if (el) {
            el.className += ' ' + c;
        }
    },

    addOptions: function(list, endIndex, creator) {
        list = this.getById(list);
        if (list && list.options) {
            creator = creator || function(i) {
                return Atms.Dom.createOption(i.toString());
            };
            for (var i = list.options.length; i < endIndex; ++i) {
                list.options.add(creator(i), i);
            }
        }
    },

    createOption: function(v, t, selected) {
        var o = document.createElement('OPTION');
        o.value = v;
        o.text = (t || o.value);
        o.selected = selected;
        return o;
    },

    disable: function(el) {
        var el = this.getById(el);
        if (el) el.disabled = true;
    },

    enable: function(el) {
        var el = this.getById(el);
        if (el) el.disabled = false;
    },

    getById: function(el) {
        return typeof el == 'string' ? document.getElementById(el) : el;
    },
    
    hasClass: function(el, c){
        el = this.getById(el);
        return el && el.className == c;
    },
    
    focus: function(el) {
        el = Atms.Dom.getById(el);
        if (el && el.focus) el.focus();
    },
    
    removeClass :function(el, c){
        el = Atms.Dom.getById(el);
        if(el) el.className = '';
    },

    removeOptions: function(list, startIndex) {
        list = this.getById(list);
        if (list && list.options) {
            for (var i = startIndex; i < list.options.length; ) {
                list.remove(i);
            }
        }
    }
};

Atms.Event = {
    attachEvent: function(el, evType, fn, useCapture) {
        el = Atms.Dom.getById(el);

        if (el) {
            if (el.addEventListener) {
                el.addEventListener(evType, fn, useCapture);
                return true;
            } else if (el.attachEvent) {
                return el.attachEvent('on' + evType, fn);
            } else {
                el['on' + evType] = fn;
            }
        }
    },

    attachLoad: function(fn) {
        this.attachEvent(window, 'load', fn);
    },

    getTarget: function(evt) {
        evt = (evt) ? evt : ((window.event) ? window.event : '');
        return evt ? evt.target || evt.srcElement : null;
    },

    detachEvent: function(el, evType, fn, useCapture) {
        el = Atms.Dom.getById(el);

        if (el.removeEventListener) {
            el.removeEventListener(evType, fn, useCapture);
            return true;
        } else if (el.detachEvent) {
            return el.detachEvent('on' + evType, fn);
        } else {
            el['on' + evType] = null;
        }
    },

    stop: function(evt) {
        if (evt) {
            evt.cancelBubble = true;
            if (evt.stopPropagation) evt.stopPropagation();
            if (evt.preventDefault) evt.preventDefault();
        }
        else if (window.event) {
            window.event.cancelBubble = true;
        }
    }
};


Atms.Ajax = {

    _registeredAjaxControlIds: [],

    _create: function() {
        try {
            return window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Msxml2.XMLHTTP.3.0");
        } catch (err) {
            return null;
        }
    },

    _on: function(f, req) {
        if (f && typeof f == 'function')
            f(req);
    },

    load: function(url, element, onSuccess, onFailure) {
        this.get(url, function(req) {

            try {
                Atms.Dom.getById(element).innerHTML = req.responseText;
            } catch (err) { /* For Internet Explorer */
                var span = document.createElement('span');
                span.innerHTML = req.responseText;
                Atms.Dom.getById(element).appendChild(span);
            }

            Atms.Ajax._on(onSuccess, req);

        }, onFailure);
    },

    get: function(url, onSuccess, onFailure) {
        var req = this._create();

        if (!req) {
            this._on(onFailure, req);
            return;
        }
        req.onreadystatechange = function() {
            if (req.readyState == 4)
                Atms.Ajax._on(req.status == 200 ? onSuccess : onFailure, req);
        }
        try {
            req.open("GET", url, true);
            req.send(null);
        } catch (err) {
            this._on(onFailure, req);
        }
    },

    post: function(url, params, onSuccess, onFailure) {
        var req = this._create();
        if (!req) {
            this._on(onFailure, req);
            return;
        }
        req.onreadystatechange = function() {
            if (req.readyState == 4)
                Atms.Ajax._on(req.status == 200 ? onSuccess : onFailure, req);
        }
        try {
            req.open("POST", url, true);
            req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
            req.send(params);
        } catch (Error) {
            this._on(onFailure, req);
        }
    },

    isSupported: function() {
        return this._create();
    },

    registerControlForCustomPostBack: function(id, container, url, callback) {
        this._registeredAjaxControlIds.push({ 'id': id, 'container': container, 'callback': callback || function() { return true; }, 'url': url });

        if (!this._defaultPostBack) {
            this._defaultPostBack = window.__doPostBack;
            var c = this;
            window.__doPostBack = function() { c._customPostBack.apply(c, arguments); };
        }
    },

    _customPostBack: function(t, a) {
        var control = this._registeredAjaxControlIds.findById(t);
        var postBackError = this._defaultPostBack;

        if (control && (!control.callback || control.callback(a))) {
            var params = "__EVENTTARGET=" + t +
                        "&__EVENTARGUMENT=" + a +
                        "&__VIEWSTATE=" + Atms.Dom.getById('__VIEWSTATE').value.urlEncode();
            this.post(control.url || window.location.href.replace(/\#.*/g, ""), params,
                function(req) {
                    if (!control['container'])
                        return;
                    try {
                        Atms.Dom.getById(control['container']).innerHTML = req.responseText;
                    } catch (err) { /* For Internet Explorer */
                        var span = document.createElement('span');
                        span.innerHTML = req.responseText;
                        Atms.Dom.getById(control['container']).appendChild(span);
                    }
                },
                function() {
                    postBackError(t, a);
                }
            );
        }
        else {
            this._defaultPostBack(t, a);
        }
    }
};


Atms.Utils = {
    defaultButton: function(el, btn) {
        Atms.Event.attachEvent(el, 'keydown', function(evt) {
            try {
                if (evt.keyCode == 13 || evt.which == 13) {
                    Atms.Event.stop(evt);
                    var el = Atms.Dom.getById(btn);
                    if (el && typeof (el.click) != "undefined") el.click();
                    return false;
                }
            } catch (Error) { alert(Error); }
        });
    },

    getUrlParam: function(n, href) {
        n = n.replace(/[\[]/, '\\\["').replace(/[\]]/, '\\\]');
        var r = new RegExp('[\\?&]' + n + '=([^&#]*)').exec(href || window.location.href);
        return r ? r[1] : '';
    }
};

Atms.DateSelector = function(d, m, y) {
    d = Atms.Dom.getById(d);
    m = Atms.Dom.getById(m);
    y = Atms.Dom.getById(y);

    if (d && m && y) {
        var update = function() {
            var days = Atms.DateSelector.daysInMonth(parseInt(m.value) - 1, parseInt(y.value));
            var opts = d.options;
            if (opts.length < days) {
                for (var i = opts.length + 1; i <= days; ++i)
                    opts.add(Atms.Dom.createOption(i));
            } else {
                d.selectedIndex = parseInt(d.value) > days ? days - 1 : d.selectedIndex;
                opts.length = days;
            }
        };
        update();
        Atms.Event.attachEvent(m, 'change', update);
        Atms.Event.attachEvent(y, 'change', update);
    }
};

Atms.DateSelector.daysInMonth = function(m, y) {
    return 32 - new Date(y, m, 32).getDate();
};

Atms.HoverMenu = function(entries, activeIndex) {
    this._entries = new Array();

    var hm = this;

    for (var i = 0; i < entries.length; ++i)
        this._entries.push(new Atms.HoverMenuEntry(entries[i], i == activeIndex, function(entry){
            hm._onEntryShowCallback(entry);
        }));
};

Atms.HoverMenu.prototype._onEntryShowCallback = function(entry) {
    for (var i = 0; i < this._entries.length; ++i) {
        if (this._entries[i] != entry) this._entries[i].hide();
    }
};

Atms.HoverMenuEntry = function(el, active, onShowCallback) {
    this._el = el;
    this._active = active;
    this._onShowCallback = onShowCallback || function() { };
    this._href = Atms.HoverMenuEntry._findHref(Atms.Dom.getById(el));
    this._contentDiv = Atms.HoverMenuEntry._contentDiv(Atms.Dom.getById(el));

    var me = this;

    Atms.Event.attachEvent(this._href, 'mouseover', function(event) {
        me.show();
        Atms.Event.stop(event);
    });
};

Atms.HoverMenuEntry.prototype.hide = function() {
    if (this._active) {
        
        this._active = false;

        if (this._contentDiv)
            this._contentDiv.style.display = 'none';

        Atms.Dom.removeClass(this._href, 'selected');
    }
};

Atms.HoverMenuEntry.prototype.show = function() {
    if (this._active) return;

    this._active = true;

    this._onShowCallback(this);

    if (this._contentDiv)
        this._contentDiv.style.display = 'block';

    Atms.Dom.addClass(this._href, 'selected');
};

Atms.HoverMenuEntry._contentDiv = function(el) {
    if (el == null || Atms.Dom.hasClass(el, 'Dropdown'))
        return el;
    else if (!el.childNodes)
        return null;

    for (var i = 0; i < el.childNodes.length; ++i) {
        var d = Atms.HoverMenuEntry._contentDiv(el.childNodes[i]);
        if (d) return d;
    }
};

Atms.HoverMenuEntry._findHref = function(el){
    if (el == null || el.tagName == 'A')
        return el;
    else if (!el.childNodes)
        return null;
    
    for(var i = 0; i < el.childNodes.length; ++i){
        var a = Atms.HoverMenuEntry._findHref(el.childNodes[i]);
        if(a) return a;
    }  
};

Atms.PriceSelector = function(itemMax, pMax, seMax, ffMax, ffSeMax) {
    this.itemMax = itemMax || 10;
    this.pMax = pMax || this.itemMax;
    this.seMax = seMax || this.itemMax;
    this.ffMax = ffMax || this.itemMax;
    this.ffSeMax = ffSeMax || this.itemMax;
    this.prices = new Array();
};

Atms.PriceSelector.prototype.adjustSelects = function() {
    var items = this.getNumberOfItems();
    var pItems = this.getNumberOfItems(function(p) { return p.isP; });
    var seItems = this.getNumberOfItems(function(p) { return p.isSE && !p.isFF; });
    var ffItems = this.getNumberOfItems(function(p) { return !p.isSE && p.isFF; });
    var ffSeItems = this.getNumberOfItems(function(p) { return p.isSE && p.isFF; });

    for (i = 0; i < this.prices.length; ++i) {
        var p = this.prices[i];

        var el = Atms.Dom.getById(p.el);
        var val = parseInt(el.value) * p.qtyToReceive;

        // calculate the newQty
        var qty = this.itemMax - items + 1 + val;

        if (p.qtyToReceive && p.qtyToReceive > 1)
            qty = Math.min(qty > p.qtyToReceive ? Math.floor(qty / p.qtyToReceive) + 1 : 1, qty);

        // adjust for passes
        qty = p.isP ? Math.min(this.pMax - pItems + 1 + val, qty) : qty;

        // adjust if non-family and friend special event
        qty = p.isSE && !p.isFF ? Math.min(this.seMax - seItems + 1 + val, qty) : qty;

        // adjust if family-friend price
        qty = !p.isSE && p.isFF ? Math.min(this.ffMax - ffItems + 1 + val, qty) : qty;

        // adjust if family-friend special event price
        qty = p.isSE && p.isFF ? Math.min(this.ffSeMax - ffSeItems + 1 + val, qty) : qty;

        // ensure we don't go over the max for the price
        qty = p.maxQty ? Math.min(p.maxQty + 1, qty) : qty;

        Atms.Dom.addOptions(el, qty);
        Atms.Dom.removeOptions(el, qty);
    }
};

Atms.PriceSelector.prototype.getNumberOfItems = function(compare) {
    var count = 0;

    for (var i = 0; i < this.prices.length; ++i) {
        if (!compare || compare(this.prices[i])) {
            count += this.prices[i].qtyToReceive * parseInt(Atms.Dom.getById(this.prices[i].el).value || '0');
        }
    }

    return count;
};

Atms.PriceSelector.prototype.register = function(elId, isGroup, isP, isSE, isFF, maxQty, qtyToReceive) {
    var element = Atms.Dom.getById(elId);
    if (element) {
        this.prices.push({ el: elId, isGroup: isGroup, isP: isP, isSE: isSE, isFF: isFF, maxQty: maxQty, qtyToReceive: qtyToReceive || 1 });
        Atms.Event.attachEvent(element, 'change', Atms.PriceSelector.onQtyChange);
        element.priceSelector = this;

        this.adjustSelects();
    }
};

Atms.PriceSelector.onQtyChange = function(event) {

    var el = Atms.Event.getTarget(event);

    if (el && el.priceSelector)
        el.priceSelector.adjustSelects();
};

// Obsolete
//Atms.Tooltip = {
//    hide: function() {
//        if (this.div) {
//            this.div.style.visibility = "hidden";
//        }
//    },

//    show: function(msg, evt) {
//        if (!this.div) {
//            var d = document.createElement('DIV');
//            d.className = 'toolTip';
//            this.div = document.body.appendChild(d);
//        }

//        evt = evt || window.event;

//        var u = document.all ? evt.clientY + document.documentElement.scrollTop : evt.pageY;
//        var l = document.all ? evt.clientX + document.documentElement.scrollLeft : evt.pageX;

//        this.div.innerHTML = "<p>" + msg + "</p>";
//        this.div.style.top = parseInt(u) + 2 + "px";
//        this.div.style.left = parseInt(l) + 10 + "px";
//        this.div.style.visibility = "visible";
//    }
//};

Atms.Controls = {
    formattedButton: function(id, imgUrl) {
        var el = Atms.Dom.getById(id);
        if (!el)
            return;

        var a = document.createElement('a');
        var p = el.parentNode;
        Atms.Dom.addClass(a, el.getAttribute('class'));

        if (imgUrl) {
            a.innerHTML = '<img src="' + imgUrl + '" alt="' + el.getAttribute('value') + '"  />';
        } else {
            a.innerHTML = el.getAttribute('value');
        }

        
        a.setAttribute('id', id);
        a.setAttribute('name', el.getAttribute('name'));
        a.setAttribute('href', "javascript:__doPostBack('" + el.getAttribute('name') + "','')");
        p.removeChild(el);
        p.appendChild(a);
    }
};

function AddToCalendar(calendar, sch) {
    var url = 'calendar.aspx?sch=' + sch + '&calendar=' + calendar;
    
    if (calendar == 'outlook' || calendar == 'ical')
        document.location.href = url; 
    else
        window.open(url, 'calendar', 'toolbar=yes, menubar=yes, location=yes, status=yes, scrollbars=yes,resizable=yes, width=800, height=600, left=0, top=0');
}
