jQuery(function ($) { 
    // signal the body that JS is enabled
    $('body').removeClass('nojs').addClass('js');
    
    detectPortraits();
    setupModal();
    setupComments();
    setupPlaceholders();
    ieFixes();
    
    // setup fluid-width videos
    $('.article-copy').fitVids();

    // set up 'switch' links, which allow links to toggle between sections of 
    // a page.
    $('a.switcher')
        // switcher links should hide all sections in their grouping, and show 
        // their target. The default browser action is allowed to bubble in 
        // order to jump the page to the correct anchored spot and update the 
        // URL appropriately.
        .live('click', function (e) {
            showInScope(this.hash, $(this).data('switch-scope'));
        })
        
        // test the location hash to see if it points to an element that's in 
        // a scope; if so, show it (as if its switcher target was clicked)
        .each(function () {
            var hash  = window.location.hash,
                scope = $(this).data('switch-scope');
            if (hash && $(hash).is(scope)) {
                showInScope(hash, scope);
            }
        });
        
    // setup the mega-menu
    $('.categories')
        
        // add the 'first' class to the first four sections, to allow CSS hooks
        .find('div').each(function () {
            $(this).find('section').slice(0, 4).addClass('first');
        }).end()
        
        // add the 'right' class to the last 3 menu items
        .find('> ul > li').slice(3).addClass('right').end().end()
        
        // add show/hide functionality to the menu items
        .click(function (e) {
            var $tgt = $(e.target),
                off  = $(this).offset(),
                $parent;
            if (off.top === 0 && $tgt.is('a.top')) {
                $parent = $tgt.closest('li');
                hideMenus($parent);
                $parent.toggleClass('active');
                return false;
            }
            return true;
        });
    
    // auto-submit the search sort/filter forms
    $('select#sort, input#sort-asc, input#sort-desc, select#filter, select#author, select#category')
        .live('change', function() {
            $(this).closest('form').submit();
        });
    $('#moderate select')
	.live('change', function() {
	    $(this).closest('form').submit();
        }); 
    // toggle the Top Comment Info blurb on clicking, and window shade it.
    $('.top-comments h1 a').live('click', function() { 
	 $('#topcommentinfo').slideToggle();
        return false;
    });
 
    // close the mega-menu when clicking anywhere, and when hitting <esc>
    $(document)
        .click(function (e) {
            if (!$(e.target).closest('.categories').length) {
                hideMenus();
            }
        })
        .keyup(function (e) {
            if (e.keyCode === 27) {
                hideMenus();
            }
        });
        
    // utility method used by the 'switcher' links to show/hide the right 
    // section of a page based on a given hash and scope
    function showInScope(hash, scope) {
        $(scope).hide();
        $(hash).show().each(function () {
            if ($(this).is('form')) {
                $(this).find('input,textarea').first().focus();
            }
        });
    }
    
    // IE-related fixes
    function ieFixes() {
        var $page = $('html');
        if ($page.is('.ie8,.ie7')) {
            // selectivizr would normally find these, but the combination with 
            // respond.js makes it not function as we want it to
            $('.categories > ul > li:nth-child(3n),.categories div section:nth-child(4n+1)').addClass('last-in-row');
            $('.more-articles li:last-child').addClass('last');
        }
    }
    
    // hide all mega menus, optionally skipping the one specified by $ctxt
    function hideMenus($ctxt) {
        $('.categories > ul > li').not($ctxt).removeClass('active');
    }

    function detectPortraits() {
        var $main = $('section.articles article.main');
        
        // run on both .load() and .each() to ensure that the proper class is 
        // added when navigating back to a cached page (and .load() will not be 
        // called).
        if ($main.length) {
            $main.find('aside img').load(portraitize).each(portraitize);
        }
        function portraitize() {
            $main.removeClass('portrait');
            if (this.width < this.height) {
                $main.addClass('portrait');
            }
        }
    }
    
    // if the browser does not support placeholders, add in fake support for 
    // them
    function setupPlaceholders() {
        if (!('placeholder' in document.createElement('input'))) {
            $('input[type="text"]').each(function () {
                var hint = $(this).attr('placeholder'), $me = $(this), $ghost;
                if (!hint) {
                    return;
                }

                // clone the input, remove its name (to prevent its value from being 
                // submitted), give it a class for styling, and hide it on click
                $ghost = $me.clone()
                    .removeAttr('name')
                    .addClass('hint')
                    .val(hint)
                    .click(function () {
                        $ghost.hide();
                        $me.show().focus();
                    })
                    .insertBefore($me);

                // hide the original input, and tell it to re-hide if it has no value 
                // when it loses focus
                $me.hide().blur(function () {
                    if (!$me.val()) {
                        $ghost.show();
                        $me.hide();
                    }
                });
            });
        }
    }

    function setupModal() {
        if ($.fancybox) {
            $('a.email-subscribe').fancybox({
                'hideOnContentClick': false,
                'autoDimensions' : false,
                'padding' : 0,
                'height' : 230,
                'width'  : 500
            });
            $('#subscribe-popup').find('a.btn-close').click(function (event) {
                event.preventDefault();
                parent.$.fancybox.close();
            });
        }
    }
    
    function setupComments() {
        $('a.comment_reply').live('click', function () {
            $('.comment_reply_form input[name=parent_id]')
                .val($(this).attr('rel'));
            $('#comment_reply')
                .show().insertAfter($(this).closest('.comment-wrapper'));
            return false;
        });
        $('form.load-more button').live('click', function () {
            $('section.comments').load(
                $('form.load-more').attr('action') + '?allcomments=true&js=1'
            );
            $('form.load-more').html('<img src="/images/loading.gif">');
            return false;
        });
        $('button.maketopcomment').live('click', function () {
            $($(this).attr('rel')).removeClass('hidden');
            return false;
        });
        $('a.topcomment_cancel').live('click', function () {
            $($(this).attr('rel')).addClass('hidden');
            return false;
        });
        
        $("form.moderate_comment").live('submit', function (event) {
            event.preventDefault(); 
            var $form   = $(this),
                comment = $form.find('input[name="comment_id"]').val(),
                cstatus = $form.find('input[name="status"]').val(),
                url     = $form.attr('action');
            $.post(url, $form.serialize(), function (data) {
                if (cstatus == 'o') {
                    $form.html("Approved");       
                } 
                else {
                    $form.html("Disapproved");
                }
            });
        });
    }
});

