(function(doc) {

	var
		pollute = true,
		api, vendor,
		apis = {
			// http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
			w3: {
				enabled: "fullscreenEnabled",
				element: "fullscreenElement",
				request: "requestFullscreen",
				exit:    "exitFullscreen",
				events: {
					change: "fullscreenchange",
					error:  "fullscreenerror"
				}
			},
			webkit: {
				enabled: "webkitIsFullScreen",
				element: "webkitCurrentFullScreenElement",
				request: "webkitRequestFullScreen",
				exit:    "webkitCancelFullScreen",
				events: {
					change: "webkitfullscreenchange",
					error:  "webkitfullscreenerror"
				}
			},
			moz: {
				enabled: "mozFullScreen",
				element: "mozFullScreenElement",
				request: "mozRequestFullScreen",
				exit:    "mozCancelFullScreen",
				events: {
					change: "mozfullscreenchange",
					error:  "mozfullscreenerror"
				}
			}
		},
		w3 = apis.w3;

	// Loop through each vendor's specific API
	for (vendor in apis) {
		// Check if document has the "enabled" property
		if (apis[vendor].enabled in doc) {
			// It seems this browser support the fullscreen API
			api = apis[vendor];
			break;
		}
	}

	function dispatch(type, target) {
		var event = doc.createEvent("Event");
		event.initEvent(type, true, false);
		target.dispatchEvent(event);
	} // end of dispatch()

	function handleChange(e) {
		// Recopy the enabled and element values
		doc[w3.enabled] = doc[api.enabled];
		doc[w3.element] = doc[api.element];

		dispatch(w3.events.change, e.target);
	} // end of handleChange()

	function handleError(e) {
		dispatch(w3.events.error, e.target);
	} // end of handleError()

	if (pollute && api && vendor !== "w3") {
		// Add listeners for fullscreen events
		doc.addEventListener(api.events.change, handleChange, false);
		doc.addEventListener(api.events.error,  handleError,  false);

		// Copy the default value
		doc[w3.enabled] = doc[api.enabled];
		doc[w3.element] = doc[api.element];

		// Match the reference for exitFullscreen
		doc[w3.exit] = doc[api.exit];

		// Add the request method to the Element's prototype
		Element.prototype[w3.request] = function() {
			return this[api.request].apply(this, arguments);
		};
	}

	// Return the API found (or undefined if the Fullscreen API is unavailable)
	return api;

}(document));