
Script.include("/js/animation.js");
Script.include("/js/css/selectors.js");

Script.namespace("com.civicscience.login");

new Script.Action(function() {
     
    // imports
    var $ = com.civicscience.css.selectors.$;
    var $$ = com.civicscience.css.selectors.$$;
    var Animation = com.civicscience.animation.Animation;
    var ElementHeightTransformer = com.civicscience.animation.ElementHeightTransformer;
    var ElementOpacityTransformer = com.civicscience.animation.ElementOpacityTransformer;
    var LinearPath = com.civicscience.animation.LinearPath;
    var OffsetPath = com.civicscience.animation.OffsetPath;
    var Sequencer = com.civicscience.animation.Sequencer;
    var Vector = com.civicscience.animation.Vector;

    (function() {
        
        var HTML = com.civicscience.geom.HTML;
        
        var bar = $(".nav_shell");
        if (bar != null) {
            
            var optionsBox = $(".login_options", bar);
            optionsBox.style.opacity = 0;
            optionsBox.style.filter = "Alpha(opacity=0)";
            
            var getOpacity = function(elt) {
                var opacity = elt.style.opacity;
                if (opacity == null) {
                    if (elt.style.visibility == "visible") {
                        opacity = 1;
                    } else {
                        opacity = 0;
                    }
                }
                return opacity;
            };
            
            var minH = HTML.getElementBounds(bar).height;
            var maxH = (function() {
                bar.style.height = "auto";
                var h = HTML.getElementBounds(bar).height;
                bar.style.height = "";
                return h;
            })();
            
            var sequencer = null;
            var expand = function() {
                if (sequencer != null) {
                    sequencer.stop();
                }
                // expand the login bar
                var dh = maxH - HTML.getElementBounds(bar).height;
                var path = new LinearPath(new Vector(1, [dh]));
                var xfrm = new ElementHeightTransformer(bar);
                var anim = new Animation(path, xfrm);
                sequencer = new Sequencer();
                sequencer.addAnimation(anim);
                sequencer.setDuration(250 * Math.round(dh / (maxH - minH)));
                sequencer.addCompletedListener(function() {
                    // fade-in the additional options
                    var opacity = optionsBox.style.opacity;
                    optionsBox.style.visibility = "visible";
                    var path = new LinearPath(new Vector(1, [1 - opacity]));
                    path = new OffsetPath(path, new Vector(1, [opacity]));
                    var xfrm = new ElementOpacityTransformer(optionsBox);
                    var anim = new Animation(path, xfrm);
                    sequencer = new Sequencer();
                    sequencer.addAnimation(anim);
                    sequencer.setDuration(100 * (1 - opacity));
                    sequencer.play();
                });
                sequencer.play();
            };
            var collapse = function() {
                if (sequencer != null) {
                    sequencer.stop();
                }
                // fade-out the additional options
                var opacity = optionsBox.style.opacity;
                var path = new LinearPath(new Vector(1, [-opacity]));
                path = new OffsetPath(path, new Vector(1, [opacity]));
                var xfrm = new ElementOpacityTransformer(optionsBox);
                var anim = new Animation(path, xfrm);
                sequencer = new Sequencer();
                sequencer.addAnimation(anim);
                sequencer.setDuration(100 * opacity);
                sequencer.addCompletedListener(function() {
                    // collapse login bar
                    optionsBox.style.visibility = "hidden";
                    var dh = minH - HTML.getElementBounds(bar).height;
                    var path = new LinearPath(new Vector(1, [dh]));
                    var xfrm = new ElementHeightTransformer(bar);
                    var anim = new Animation(path, xfrm);
                    sequencer = new Sequencer();
                    sequencer.addAnimation(anim);
                    sequencer.setDuration(250 * Math.round(dh / (minH - maxH)));
                    sequencer.play();
                });
                sequencer.play();
            };
            
            // increment/decrement focus count
            var count = 0;
            var incr = function() {
                if (count++ == 0) {
                    expand();
                }
            };
            var decr = function() {
                if (--count == 0) {
                    collapse();
                }
            };
            
            
            // event listeners to trigger expand/collapse
            var onmouseover = function(event) {
            	try {
	                var fromElt = event.relatedTarget || event.fromElement;
	                while (fromElt != null && fromElt.nodeType == 1 && fromElt != bar) {
	                    fromElt = fromElt.parentNode;
	                };
	                if (fromElt != bar) {
	                    var toElt = event.target || event.toElement;
	                    while (toElt != null && toElt.nodeType == 1 && toElt != bar) {
	                        toElt = toElt.parentNode;
	                    };
	                    if (toElt == bar) {
	                        incr();
	                    }
	                }
            	} catch (e) {
            		//firebox bug[208427]
            	}
            };
            var onmouseout = function(event) {
            	try {
	                var fromElt = event.target || event.fromElement;
	                while (fromElt != null && fromElt.nodeType == 1 && fromElt != bar) {
	                    fromElt = fromElt.parentNode;
	                };
	                if (fromElt == bar) {
	                    var toElt = event.relatedTarget || event.toElement;
	                    while (toElt != null && toElt.nodeType == 1 && toElt != bar) {
	                        toElt = toElt.parentNode;
	                    };
	                    if (toElt != bar) {
	                        decr();
	                    }
	                }
            	} catch(e) {
            		//firebox bug[208427]
            	}
            };
            var onblur = function(event) {
                if (event) {
                    // requeue in case there's an focus event pending
                    setTimeout(onblur, 0);
                } else {
                    decr();
                }
            };

            Events.addListener(bar, "mouseover", onmouseover);
            Events.addListener(bar, "mouseout", onmouseout);
            var form = $("form", bar);
            var controls = $$("a", form);
            var i;
            for (i = 0; i < form.elements.length; i++) {
                controls.push(form.elements[i]);
            }
            for (i = 0; i < controls.length; i++) {
                var ctl = controls[i];
                Events.addListener(ctl, "focus", incr);
                Events.addListener(ctl, "blur", onblur);
            }
            
            // clear watermark-style labels in user/pass text boxes
            Events.addListener($("#uname_input"), "focus", function() {
                if (this.value == "Username or E-mail") {
                    this.value = "";
                    Events.removeListener(this, "focus", arguments.callee);
                }
            });
            Events.addListener($("#passwd_input"), "focus", function() {
                if (this.value == "Password") {
                    this.value = "";
                    Events.removeListener(this, "focus", arguments.callee);
                }
            });
        }
                
    })();
    
    
 }).requires(
         "Events",
         "com.civicscience.animation.Animation",
         "com.civicscience.animation.ElementHeightTransformer",
         "com.civicscience.animation.LinearPath",
         "com.civicscience.animation.Sequencer",
         "com.civicscience.animation.Vector",
         "com.civicscience.css.selectors.$",
         "com.civicscience.css.selectors.$$",
         "com.civicscience.geom.HTML"
     ).run();
