(function($) {
//Miscellaneous utility functions and jQuery extensions


//Create firebug stubs if it's not present so we don't get errors
if(!('console' in window))
	window.console = { log: function() {}, dir: function() {} };


//Fade out, then reduce height to 0
$.fn.mmsFadeHide = function(speed, callback) {
	return this.animate({opacity: 0}, speed / 2).slideUp(speed / 2, callback);
};


//Returns true if this is Safari 2
$.mmsIsSafari2 = function() {
    return $.browser.safari && $.browser.version.substring(0, 1);
};


//Runs a function on each item in an array, putting small timeouts every n
//iterations, in order to give the browser a chance to update and accept input.
$.mmsEachAsync = function(object, callback, args, pauseEvery, pause, after, i) {
    pauseEvery = pauseEvery || 5;
    pause = pause || 20;
    i = i || 0;
    
    for( ; i < object.length; ) {
        if(callback.apply(object[i++], args || []) === false)
            break;
        if(i == object.length && after) after();
        if(i % pauseEvery == pauseEvery - 1) {
            setTimeout(function() {
                $.mmsEachAsync(object, callback, args, pauseEvery, pause, after, i);
            }, pause);
            break;
        }
    }
};


//Restore height, then fade in
$.fn.mmsFadeShow = function(speed, callback) {
	return this.slideDown(speed / 2).css('opacity','0')
	    .animate({opacity: 1}, speed / 2, function() {
            //If we're in IE, remove the opacity
            if($.browser.msie) {
                var re = /alpha\(opacity=100\)/g;
                var filter = $(this).css('filter').replace(re, '');
                $(this).css('filter', filter);
            }
               
            //Run the callback if necessary 
            if(callback) callback();
        });
};


//Fade background from one color to another
$.fn.mmsFadeBg = function(from, to, speed, callback) {
    return this.css({ backgroundColor: from })
        .animate({ backgroundColor: to }, speed, callback);
};


//Parse an 8601 UTC date into a Date object
//See http://www.json.com/2007/10/24/lossless-json-dates/
$.mmsJsonDate = function(dateString) {
    var k = dateString.match(/(\d*)-(\d*)-(\d*)T(\d*):(\d*):(\d*)Z/);
    return new Date(Date.UTC(k[1], k[2]-1, k[3], k[4], k[5], k[6]));
};


//Parse an 8601 UTC date into a Date object
//See http://www.json.com/2007/10/24/lossless-json-dates/
$.mmsMediumDate = function(d) {
    var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 
        'Sep', 'Oct', 'Nov', 'Dec'];
        
    return months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();
};


//Read the content attribute of the meta tag with the specified name
$.mmsMetaContent = function(name) {
    return jQuery('meta[name="' + name + '"]').attr('content');
};


//Returns a count of the properties in the object (similar to Array length)
$.mmsPropertyCount = function(x) {
    var i = 0;
    for(var property in x) i++;  
    return i;
};

})(jQuery);