(function($) {
     $.effects.nmSlide = function(o) {
         return this.queue(function() {
                               var el = $(this);

                               var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode

                               // Animate
                               el.animate({ width: mode === 'show' ? '258px' : '0' },
                                          { queue: false,
                                            duration: o.duration,
                                            easing: o.options.easing,
                                            complete: function() {
                                                if(o.callback) o.callback.apply(this, arguments); // Callback
                                                el.dequeue();
                                            }});
                           });
     };
 })(jQuery);

/*
 * Takes a jQuery wrapped dom element which contains the label text
 */

function LinkLabel(el) {
    el.css({display:'none'});
    
    var fadingIn = false;
    var fadeInTimer;

    var resetFadingState = function() {
	fadingIn = false;
    };

    var fadeInAction = function() {
        el.fadeIn("fast", resetFadingState);
	fadingIn = true;
    };

    /*
     * Sets the fade in timer for the link, which should happen towards the end of the animation
     */

    this.activate = function() {
	fadeInTimer = setTimeout(fadeInAction, 250);
    };

    /*
     * Deactivates a link by clearing any timer set, stoping any begun animation, and hiding the link
     */
    this.deactivate = function() {
	clearTimeout(fadeInTimer);
	if (fadingIn === true) {
	    el.stop(true, true);
	    fadingIn = false;
	}
	el.fadeOut("fast");
    };
};

/*
 * Needs jQuery wrapped <li> element for initialization
 * Parent is an ExpandableNavigation object
 */

function NavElement(root, parent) {
    if (root.hasClass('current')) {
        return;
    }

    var link = root.children(); // link wrapping elements -- should be set of 1
    var bar	= $('.bar', link).css({ width:'0' }); // expandable bar containing label
    var lw	= bar.children(); // find text descendant, div.lw -- should be set of 1
    var label	= new LinkLabel(lw);

    /*
     * Callback setup
     */

    var li = this;
    var slideInTimer;

    var expand = function() {
	// if we're already out, let the hover function above take care of the slideInTimer
	if (parent.isCurrent(li)) {
            return;
	}

	// perform expanding animation
	bar.show("nmSlide");
	label.activate();
	parent.setExpanding(li);
    };

    var slideIn = function() {
        label.deactivate(); // stop fade in animation and hide label text
        bar.hide("nmSlide"); // slide back in
	parent.clearExpanding(li); // clear expanding var on parent
    };

    var clearSlideIn = function() {
        clearTimeout(slideInTimer);
    };

    var setSlideIn = function() {
        slideInTimer = setTimeout(slideIn, 650);
    };

    var keepOpen = function() {
        clearSlideIn();
        return true;
    };

    /*
     * Resets action
     */

    this.reset = function() {
        clearTimeout(slideInTimer); // clear slide in timer if set
	bar.stop(true, true); // stop slide out animation if in process
        label.deactivate(); // stop fade in animation and hide label text
        bar.hide("nmSlide"); // slide back in
    };

    link.bind("mouseenter", expand);
    link.hover(clearSlideIn, setSlideIn);
    link.click(keepOpen);
}

/*
 * Constructor for navigation element, ie the <ul> in the DOM
 * It creates an object for each <li> element
 */

function ExpandableNavigation(id_selector) {
    var ul = $(id_selector);

    if(!ul) {
        alert('failed to find navigation element in DOM with id of "' + id_selector + '"');
        return;
    }

    var expanding = null;
    var subnav = $('#pNav'); // current project subnav
	var audioPlayerOffset = null;
    var fadeInTimer;
    var fadingIn = false;

    var resetFadingState = function() {
	fadingIn = false;
    };

    var subnavFadeIn = function() {
	subnav.fadeIn("fast", resetFadingState);
	$("#audioPlayer").css({ position: "absolute", left: audioPlayerOffset.left + "px", top: audioPlayerOffset.top + "px" });
	fadingIn = true;
    };

   /*
    * Set currently expanding element and reverse/disable any actions/settings on previous element
    */

    this.setExpanding = function(el) {
	var cur = expanding;

	clearTimeout(fadeInTimer);

	// if nothing is currently out, fade out the menu
	if(!cur) {
	    if(fadingIn === true) {
		subnav.stop(true,true);
	    }
		subnav.fadeOut("fast");
	
		if (!audioPlayerOffset) {
			audioPlayerOffset = $("#audioPlayer").offset();
		}
		$("#audioPlayer").css({ position: "absolute", left: "-20px", top: "-20px" });
		
	    fadingIn = false;
	}

	/*
	 * slide in previously expanding li
	 */
	if (cur && cur != el) {
	    cur.reset();
	}

	expanding = el;
    };

    this.clearExpanding = function(el) {
	if(expanding === el) {
	    expanding = null;

	    // set timer to fade in subnav
	    fadeInTimer = setTimeout(subnavFadeIn, 200);
	}
    };

    this.isCurrent = function(el) {
	return expanding === el;
    };

    var children = ul.children();

    for(var i=0; i < children.length; ++i) {
        new NavElement($(children[i]), this); // wrap child element
    }
}

var MailingList = {
	subscribe: function(form) {
		$.ajax({
			async: true,
			success: MailingList.success,
			data: $.param($(form).serializeArray()),
			dataType: 'json',
			url: form.action,
			type: form.method
		});
		
		$('#emailSubmit').attr('disabled', true).attr('value', 'Loading');
	},
	
	success: function(result) {
		if (result.success) {
			alert('Thank you for joining our mailing list.');
			
			var container = $("#mailingForm");
			var form = $("form", container);
			
			container.animate({ height: "0px" });
			form.animate({ opacity: 0 }, function() {
				container.animate({ width: "0px" }, function() {
					container.hide();
				});
			});			
		} else {
			alert('Unable to add you to the mailing list: ' + result.errors.join(', '))
		}
		
		$('#emailSubmit').attr('value', 'Submit').removeAttr('disabled');
		$('#emailInput').select();
	}
};

$(document).ready(function() {
	$("#mailingLink a").click(function(event) {
		event.preventDefault();
		
		var container = $("#mailingForm");
		var form = $("form", container);

		if (container.width() < 100) {
			form.css({ opacity: 0 });
			container.animate({ height: "1px", width: "220px" }, function() {
				form.animate({ opacity: 1 });
				container.animate({ opacity: 1, height: "15px" });
			});
		} else {
			container.animate({ height: "0px" });
			form.animate({ opacity: 0 }, function() {
				container.animate({ width: "0px" }, function() {
					container.hide();
				});
			});
		}
	});
});

