(function(window, undefined) {
    var doc = window.document,
		body,
		slice = Array.prototype.slice,
		_domready = false;


    var sau = {

        bound: {},

        init: function() {

            var self = this;
            body = $findTag("body")[0];

            this.bound.hide = $bind(this.hide, this);
            this.bound.show = $bind(this.show, this);
            this.bound.resize = $bind(this.resize, this);

            this.element = $find("saumbrella");
            this.toggles = $findAll("sau-top-level", this.element);
            this.toganchors = $findAll("sau-top-level-anchor", this.element);

            this.enforceMinWidth();
            this.animate($supportsAnimation() ? "CSS" : "JS");


            this.subs = {};
            $each(this.toggles, function(tog, index) {
                var sub = $findAll("sau-subnav", tog),
					hasSub = !!sub.length && sub[0];

                this.subs[index] = hasSub;

                $addEvent(tog, "mouseover", function(e) {
                    self.bound.show(index);
                });

                $addEvent(tog, "mouseout", function(e) {
                    var check = $mouseCheck(e, tog);
                    if (check === true) return self.bound.hide(index);
                });

                if (hasSub) $addEvent(this.toganchors[index], "click", function(e) {
                    $stopEvent(e);
                });

            }, this);

            this.Notify.init();

            return this;
        },

        show: function(index) {
            var sub = this.subs[index];

            if (sub) {
                $addClass(this.toggles[index], "sau-top-level-active");
                $addClass(sub, "sau-subnav-enabled");
            }

            return this;
        },

        hide: function(index) {
            var sub = this.subs[index];
            if (sub) {
                $removeClass(this.toggles[index], "sau-top-level-active")
                $removeClass(sub, "sau-subnav-enabled")
            }

            return this;
        },

        animate: function(how) {
            var hasCookie = $cookie.getCookie("saumbrellaanimate") !== null;

            if (!hasCookie) {
                $cookie.setCookie("saumbrellaanimate", "hasseenanimate", 1);

                var delay = 250,
					toggles = this.toggles,
					isIE = $browser.name == "ie";

                var propFunc = function(element, val) {
                    element.style.opacity = val;
                };

                if (isIE) propFunc = function(element, val) {
                    element.style.filter = (val >= 1) ? "" : "alpha(opacity=" + Math.round(val * 100) + ")";
                }

                switch (how) {
                    case "CSS":
                        $each(this.toganchors, function(tog, index) {
                            if (!$hasClass(toggles[index], "sau-top-level-current")) {
                                $addClass(tog, "sau-supports-transition");
                                setTimeout(function() {
                                    $addClass(tog, "sau-animate");
                                }, delay * index);
                            }
                        }, this);
                        break;

                    case "JS":
                        $each(this.toganchors, function(tog, index) {
                            var toggle = toggles[index];
                            if (!$hasClass(toggle, "sau-top-level-current")) {
                                var animator = new $Animator(toggle, propFunc, 0.7, 1, 30, 500, function() { });
                                animator.set(0.7);

                                setTimeout(function() {
                                    animator.start();
                                }, delay * index);
                            }
                        }, this);

                        break;
                }

            }

        },

        resize: function() {
            this.element.style.width = ((doc.documentElement.clientWidth || body.clientWidth) < 1000) ? "1000px" : "";
        },

        enforceMinWidth: function() {
            $addEvent(window, "resize", this.bound.resize);
            this.bound.resize();
        },

        checkNotification: function() {
        var notification = $find("sau-notification"),
				close = $find("sau-notification-close"),
				element = this.element;

            if (notification && close) {
                $addEvent(close, "click", function(e) {
                    try {
                        element.removeChild(notification);
                    } catch (e) { }
                });
            }
        }

    };


    sau.Notify = {
        enterDelay: 5000,
        exitDelay: 8000,
        timer: null,
        duration: 500,
        bound: {},
        animating: false,
        direction: "out",
        firstTime: true,

        init: function() {

        this.element = $find("sau-notification");
            this.toggleBtn = $find("sau-notify-toggle");
            this.notification = $find("sau-notification-content");




            var hasCookieForSite = $cookie.getCookie("samesite");

            if (hasCookieForSite == null) {
                $cookie.setCookie("samesite", "hasseennotify", 1);
            }



            var hasCookie = $cookie.getCookie("saumbrellanotify") !== null,
				hasQs = window.location.href.indexOf("sau=true") !== -1;

            if (hasQs) $cookie.setCookie("saumbrellanotify", "hasseennotify", 1);

            if (this.element && this.toggleBtn && this.notification) {
                this.height = this.notification.offsetHeight;
                this.bound.out = $bind(this.animateOut, this);
                this.bound.hide = $bind(this.hide, this);
                this.bound.toggle = $bind(this.toggle, this);
                $addEvent(this.toggleBtn, "click", this.bound.toggle);
                
                
                if (!hasCookie && !hasQs && !hasCookieForSite) {
                    this.timer = setTimeout($bind(this.animateIn, this), this.enterDelay);
                }
//                if (window.location.host == 'apidra.intouch-dev.com' || window.location.host == 'vendordev.apidra.com' || window.location.host == 'development.apidra.com' || window.location.host == 'staging.apidra.com' || window.location.host == 'www.apidra.com' || window.location.host == 'localhost:55215') {
//                    this.timer = setTimeout($bind(this.animateIn, this), 1000);
//                }

            }

            return this;
        },

        toggle: function(ignore) {
            if (this.animating) return;
            clearTimeout(this.timer);
            this.firstTime = false;

            var visible = this.direction === "in";

            this[visible ? "animateOut" : "animateIn"]();

        },

        hide: function() {
            clearTimeout(this.timer);
            this.animateOut();
        },

        animateIn: function() {
            if (this.animating) return;

            var duration = this.duration;
            this.animating = true;
            this.direction = "in";

            $addClass(this.toggleBtn, "sau-notify-active");

            var elementFx = new $Animator(
					this.element,
					function(element, val) {
					    element.style.height = val + "px";
					},
					0,
					this.height,
					30,
					duration,
					function() { }
				),

				notifyFx = new $Animator(
					this.notification,
					function(element, val) {
					    element.style.top = val + "px";
					},
					-this.height,
					0,
					30,
					duration,
					$bind(function() {
					    $cookie.setCookie();
					    this.animating = false;

					    if (this.firstTime) {
					        //if (window.location.host != 'apidra.intouch-dev.com' && window.location.host != 'vendordev.apidra.com' && window.location.host != 'development.apidra.com' && window.location.host != 'staging.apidra.com' && window.location.host != 'www.apidra.com' && window.location.host != 'localhost:55215') {
					            this.firstTime = false;
					            this.timer = setInterval(this.bound.toggle, this.exitDelay);
					        //}
					    }
					    
					    
					}, this)
				);

            elementFx.set(0);
            notifyFx.set(-this.height);

            notifyFx.start();
            elementFx.start();


            return this;
        },

        animateOut: function() {
            var duration = this.duration;

            this.animating = true;
            this.direction = "out";

            $removeClass(this.toggleBtn, "sau-notify-active");

            var elementFx = new $Animator(
					this.element,
					function(element, val) {
					    element.style.height = val + "px";
					},
					this.height,
					0,
					30,
					duration,
					function() { }
				),

				notifyFx = new $Animator(
					this.notification,
					function(element, val) {
					    element.style.top = val + "px";
					},
					0,
					-this.height,
					30,
					duration,
					$bind(function() {
					    this.animating = false;
					}, this)
				);

            elementFx.set(this.height);
            notifyFx.set(0);

            notifyFx.start();
            elementFx.start();

            return this;
        }
    };

    // Quirksmode cookie functions
    var $cookie = {

        getCookie: function(cookieName) {
            var nameEQ = cookieName + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        },

        setCookie: function(cookieName, cookieValue, duration) {
            var name = cookieName,
				value = cookieValue,
				days = duration;

            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                var expires = "; expires=" + date.toGMTString();
            }
            else var expires = "";
            document.cookie = name + "=" + value + expires + "; path=/";
        }
    };


    var $browser = (function() {
        // user agent tests inspired by mootools and yui implementations
        var parseVersion = function(s) {
            var c = 0;
            return parseFloat(s.replace(/\./g, function() {
                return (c++ == 1) ? '' : '.';
            }));
        },

				ua = navigator.userAgent.toLowerCase(),
				loc = window.location && window.location.href,
				browser = {
				    ie: 0,
				    firefox: 0,
				    chrome: 0,
				    safari: 0,
				    opera: 0,

				    name: null,
				    webkit: false,
				    mobile: null
				},

				match;

        browser.secure = loc && loc.toLowerCase().indexOf("https") === 0;

        // check IE
        match = ua.match(/msie\s([\w\d\.]+)/);
        if (match && match[1]) {
            browser.name = "ie";
            browser.ie = parseVersion(match[1]);
        }
        else {
            // check firefox
            match = ua.match(/firefox[\s\/:]([\w\d\.]+)/); // /rv:([\w\d\.]+).*?gecko/
            if (match && match[1]) {
                browser.name = "firefox";
                browser.firefox = parseVersion(match[1])
            }
            // check chrome
            else {
                match = ua.match(/chrome[\s\/:]([\w\d\.]+)/);
                if (match && match[1]) {
                    browser.name = "chrome";
                    browser.webkit = true;
                    browser.chrome = parseVersion(match[1]);
                }
                // check safari
                else {
                    match = ua.match(/version[\s\/:]([\w\d\.]+).*?safari[\s\/:][\w\d\.]+/);
                    if (match && match[1]) {
                        browser.name = "safari";
                        browser.webkit = true;
                        browser.safari = parseVersion(match[1]);
                    }
                    // check opera
                    else {
                        match = ua.match(/^opera.*?version\/([\w\d\.]+)$|opera\s([\w\d\.]+)$/);
                        if (match) {
                            browser.name = "opera";
                            browser.opera = parseVersion(match[1] || match[2]);
                        }
                    }
                }

            }

        }

        return browser;
    })();

    /* 	
    UTILITY
    =======
    */
    var $each = function(arr, callback, context) {
        var len = arr.length;

        if (len > 0) {
            for (var i = 0; i < len; i++) {
                callback.call(context, arr[i], i, arr);
            }
        }

        return this;
    };

    var $bind = function(func, context) {
        var args = (arguments.length > 2) ? slice.call(arguments, 2) : [],
			bound = function() {
			    if (!args) return func.call(context);
			    return func.apply(context, args.concat(slice.call(arguments)));
			};


        return bound;
    };


    var $mouseCheck = function(e, element) {
        var type = e.type,
			related = e.relatedTarget || e[(type == "mouseover" ? "from" : "to") + "Element"];

        if (related == null) return true;
        if (!related) return false;
        return (related != element && !$contains(element, related));
    };

    // loosely based off of work by modernizr
    var $supportsAnimation = function() {
        var testElement = doc.createElement("div"),
			style = testElement.style,
			prefixes = "animationName webkitAnimationName mozAnimationName oAnimationName msAnimationName khtmlAnimationName".split(" "),
			support = false;

        for (var i = 0, l = prefixes.length; i < l; i++) {
            if (prefixes[i] in style) {
                support = true;
                break;
            }
        }


        return support;
    }


    /* 	
    DOM TRAVERSING
    ==============
    */

    var $contains = function(element, child) {
        while (child != element && child != doc)
            child = child.parentNode

        if (child == element) return true;
        else return false;
    };


    // alias for getElementById
    var $find = function(id) {
        return doc.getElementById(id);
    };

    // alias for getElementsByTagName
    var $findTag = function(tag, context) {
        return (context || doc).getElementsByTagName(tag);
    };

    // get elements by class name
    var $findAll = function(cName, context) {

        //check for native support
        if (doc.getElementsByClassName) {
            return (context || doc).getElementsByClassName(cName);
        }

        // check for xpath support
        else if (!!(doc.evaluate)) {
            var q = ".//*[contains(concat(' ', @class, ' '), ' " + cName + " ')]";
            return doc._getElementsByXPath(q, context || doc);
        }

        // do it the dustin diaz way
        var context = context || doc,
			results = [],
			pattern = new RegExp("(?:^|\\s+)" + cName + "(?:\\s+|$)"),
			elements = (context || doc).getElementsByTagName("*"),
			len = elements.length;

        for (var i = 0; i < len; i++) {
            if (elements[i].className.match(pattern)) {
                results.push(elements[i]);
            }
        }

        return results;

    };

    var $addClass = function(element, cls) {
        if (!$hasClass(element, cls)) element.className = element.className + " " + cls;
        return element;
    };

    var $removeClass = function(element, cls) {
        element.className = element.className.replace(new RegExp('(^|\\s)' + cls + '(?:\\s|$)'), '$1');
        return element;
    };

    var $hasClass = function(element, cls) {
        return element.className.indexOf(cls) > -1;
    };

    /* 	
    EVENTS
    ======
    */
    var $stopEvent = function(e) {
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false;

        if (e.stopPropagation) e.stopPropagation();
        else e.cancelBubble = true;
    };

    var $addEvent = function(element, type, callback) {
        if (element.addEventListener) element.addEventListener(type, callback, false);
        else element.attachEvent('on' + type, callback);
    };

    var $removeEvent = function(element, type, callback) {
        if (element.removeEventListener) element.removeEventListener(type, callback, false);
        else element.detachEvent('on' + type, element);
    };


    /* 	
    ANIMATION
    =========
    mootools' Fx class (paired down)
    */
    var $Animator = function() { this.init.apply(this, arguments) };
    $Animator.prototype = {
        timer: null,

        init: function(element, property, from, to, fps, duration, callback) {
            this.element = element;
            this.property = property;
            this.from = from;
            this.to = to;
            this.callback = callback;


            this.fps = fps || 30;
            this.duration = duration || 500;

            return this;
        },

        set: function(val) {
            this.property(this.element, val);
            //this.element.style[this.property] = val + this.suffix;
            return this;
        },

        step: function() {
            var time = (Date.now) ? Date.now() : +(new Date);
            if (time < this.time + this.duration) {
                var delta = this.transition((time - this.time) / this.duration);
                this.set(this.compute(this.from, this.to, delta));
            }
            else {
                this.set(this.compute(this.from, this.to, 1));
                this.stop();
            }

            return this;
        },

        start: function() {
            this.time = (Date.now) ? Date.now() : +(new Date);
            var self = this;

            this.timer = setInterval(function() {
                self.step();
            }, Math.round(1000 / this.fps));

            return this;
        },

        stop: function() {
            clearInterval(this.timer);
            this.callback();
            return this;
        },

        compute: function(from, to, delta) {
            return (to - from) * delta + from;
        },

        transition: function(x) {
            return -(Math.cos(Math.PI * x) - 1) / 2;
        }
    };

    // start init on domready
    // doScroll technique by Diego Perini
    (function(callback) {

        if (_domready) return callback();

        var done = false,
				timer;

        var domready = function() {
            if (!done) {
                clearTimeout(timer);
                done = _domready = true;

                $removeEvent(doc, "DOMContentLoaded", domready);
                $removeEvent(doc, "readystatechange", iedomcheck);

                callback();
            }
        };

        var iedomcheck = function() {
            if (doc.readyState == "complete") {
                domready();
            }
        }

        $addEvent(doc, "DOMContentLoaded", domready);

        // ie
        if ('onreadystatechange' in doc) {

            (function check() {
                try {
                    doc.documentElement.doScroll("left");
                } catch (e) {
                    timer = setTimeout(check, 50);
                    return;
                }
                domready();
            })();

            $addEvent(doc, "readystatechange", iedomcheck);

        }

    })($bind(function() {
        this.init();
    }, sau));

})(window);
