/*

	217church
	Javascript Bootstrap

*/

/*
 * Add existence handler to jQuery
 */
$.fn.exists = function() {
	return this.is('*');
};

/*
 * Add highlight animation to jQuery
 */
$.fn.highlight = function() {
	return this
		.fadeTo(150, 0.1)
		.fadeTo(150, 1)
		.fadeTo(150, 0.1)
		.fadeTo(150, 1)
		.fadeTo(150, 0.1)
		.fadeTo(150, 1);
};

/*
 * Add forEach method
 */
if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(fn /*, _this*/) {
		var len = this.length >>> 0;
		if (typeof fn != 'function') {
			throw new TypeError();
		}
		var _this = arguments[1];
		for (var i = 0; i < len; i++) {
			if (i in this) {
				fn.call(_this, this[i], i, this);
			}
		}
	};
}

/*
 * Init jQuery Validation plugin
 */
$.validator.setDefaults({
	debug: false,
	focusInvalid: true,
	focusCleanup: false,
	errorElement: 'span',
	errorPlacement: function(error, element) {
		error.insertAfter(element.parent().children(':last')).hide().slideDown(250);
	}
/*
	invalidHandler: function(form, validator) {
		var el, elLeft;
		for (name in validator.invalid) {
			el = $('input[name="' + name +'"], textarea[name="' + name +'"], select[name="' + name +'"]');
			elLeft = el.css('marginLeft') || '';			// this separation prevents validation from failing in case
			elLeft = elLeft.pxToInt();						// el is not found, or el has no 'margin-left' value
			el
				.animate({ marginLeft: elLeft + 5 }, 40)
				.animate({ marginLeft: elLeft - 5 }, 40)
				.animate({ marginLeft: elLeft + 5 }, 40)
				.animate({ marginLeft: elLeft }, 40);
		}
	}
*/
});

/*
 * Remove 'px' suffix and convert string to integer
 */
if (!String.prototype.pxToInt) {
	String.prototype.pxToInt = function() {
		return parseInt(this.substr(0, this.lastIndexOf('px'))) || 0;
	};
}

/**
 * Launch new browser window, if approved by user
 *
 * @param {String} url URL for new window
 * @param {String} id DOM ID for new window  
 * @param {Boolean} silent Don't prompt user to open new window if true
 * @param {String} prompt Prompt message  
 * @param {String} failure Failure message  
 * @param {Boolean} respawn Always respawn open windows if true
 * @param {Object} die Window object to close
 * @return {Boolean} True if window was successfully opened; false otherwise 
 */
var spawned = [];
function spawn(url, id, silent, features, prompt, failure, respawn, die) {
	id = (typeof(id) != 'undefined' && id) ? id : '_blank';
	features = (typeof(features) != 'undefined' && features) ? features : '';
	prompt = (typeof(prompt) != 'undefined' && prompt) ? prompt : 'Would you like to open a new window?'; 
	failure = (typeof(failure) != 'undefined' && failure) ? failure : 'Your browser did not let the new window open.\nPlease disable your popup blocker or add this site to the safe list, then try again.';

	if (silent || confirm(prompt)) {
		if (respawn && spawned[id] != null && !spawned[id].closed) {
			spawned[id].close();
		} else if (typeof(die) == 'object' && die) {
			die.close();
		}
		if (respawn || spawned[id] == null || spawned[id].closed) {
			return (spawned[id] = window.open(url, id, features)) ? true : alert(failure);
		} else {
			spawned[id].location = url;
			spawned[id].focus();
			return true;
		}
	}

	return false;
}

/**
 * Modify anchor tag behaviour:
 *
 * "rel" Attribute		Behaviour
 *
 * external				launch in new window, if allowed by global preference
 * external force		launch in new window, always
 * external die			launch in new window, closing referring window in process
 * 						note: referring window will only be closed if it was opened by spawn()
 * external force die	same as [external force] and [external die]
 */
function initAnchors() {

	// XHTML 1.1 deprecated the <a>'s target attribute (with fairly good reason);
	// but sometimes we still want to open new windows in new windows...
	var extLinks = $('a[rel="external"], a[rel="external die"], a[rel="external force"], a[rel="external force die"]').not('[href=""]');
	var extLinkHandler = function() {
		return !spawn(
			this.href,
			this.id,
			true,
			null,
			null,
			null,
			null,
			($(this).is('a[rel="external die"], a[rel="external force die"]')) ? window : null
		);
	};
	if (CONFIG.spawnOnExternalURL) {
		extLinks.bind('click', extLinkHandler);
	} else {
		extLinks.filter('a[rel="external force"], a[rel="external force die"]').bind('click', extLinkHandler);
	}
	extLinks.not('.implicit').addClass('extlink');

	// disable the disabled
	// note: these links will remain working when JS is disabled
	$('.disabled > a').bind('click', function() {
		return false;
	});

}

/**
 * Entry Point
 * Wait for DOM to load
 */
$(document).ready(function() {

	// init anchor tags
	initAnchors();

	// warn about crimes against humanity
	if ($.browser.msie && $.browser.version <= 6) {
		$('body').prepend(
			'<div id="notice"><p class="error">' +
				'You appear to be using an outdated version of Internet Explorer.<br />' +
				'Please visit <a href="http://update.microsoft.com/" rel="external force die">Microsoft Update</a> to upgrade your browser.<br />' +
				'<span class="smallprint">IE version: ' + $.browser.version + '</span>' +
			'</p></div>'
		);
	}

	// fix IE 6 flickering bug by forcing caching of background images
	// based on recommendation from http://support.microsoft.com/kb/823727/
	if ($.browser.msie && $.browser.version == 6) {
		try {
			document.execCommand('BackgroundImageCache', false, true);
		} catch(ex) { /* swallow errors */ }
	}

	// simulate :before and :after in IE
	if ($.browser.msie) {
		$('q')
			.prepend('<span class="before">&#x201c;</span>')
			.append('<span class="after">&#x201d;</span>');
	}

	// simulate :focus and :blur on form elements in IE
	if ($.browser.msie) {
		$('input, select, textarea')
			.bind('focus', function() {
				$(this).addClass('focus');
			})
			.bind('blur', function() {
				$(this).removeClass('focus');
			})
	}

	// check for current version of Flash Player
	if (!swfobject.hasFlashPlayerVersion('12') && !$.cookie('217flashwarning')) {

		// bake cookie so that notice is only displayed once
		$.cookie('217flashwarning', true, {path: '/'});

		if (!swfobject.hasFlashPlayerVersion('1')) {
			// missing
			$('body').prepend(
				'<div id="notice"><p class="warning">' +
					'You need Adobe Flash Player to view the media on this site.<br />' +
					'Visit <a href="http://www.adobe.com/go/getflashplayer" rel="external force die">Adobe\'s site</a> for more information.' +
				'</p></div>'
			);
		} else if (!swfobject.hasFlashPlayerVersion(CONFIG.flashMinVersion)) {
			// outdated
			$('body').prepend(
				'<div id="notice"><p class="warning">' +
					'You need to upgrade Adobe Flash Player to view the media on this site.<br />' +
					'Visit <a href="http://www.adobe.com/go/getflashplayer" rel="external force die">Adobe\'s site</a> for more information.<br />' +
					'<span class="smallprint">Installed version: ' + swfobject.getFlashPlayerVersion().major + (typeof(swfobject.getFlashPlayerVersion().minor) != 'undefined' ? '.' + swfobject.getFlashPlayerVersion().minor : '') + (typeof(swfobject.getFlashPlayerVersion().build) != 'undefined' ? '.' + swfobject.getFlashPlayerVersion().build : '') + '</span>' +
				'</p></div>'
			);
		}

	}

	// animate notices
	$('#notice')
		.hide()
		.slideDown(400);
/*
		.slideDown(400, function() {
			setTimeout(function() {
				$('#notice').slideUp(400, function() {
					$(this).remove();
				});
			}, 10000)
		});
*/

	// call local handler
	if (typeof(handler) != 'undefined' && handler && typeof(handler) == 'function') {
		handler.call(this);
	}

});

// [EOF]