<?xml version="1.0" encoding="UTF-8"?>
<Module>
	<ModulePrefs title="ContentZ" author="Zachary “Gamer_Z.” Yaro" author_email="zmyaro@gmail.com">
		<Require feature="wave"/>
		<Require feature="dynamic-height"/>
	</ModulePrefs>
	<Content type="html">
		<![CDATA[
			<style type="text/css">
				body {
					font-family: Arial, sans-serif;
					font-size: 10pt;
					color: #505050;
					text-align: center;
				}
				p {
					margin: 2em;
				}
				select {
					background-image: #EDEDED;
					filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='white', endColorstr='#DDDDDD', GradientType=0);
					background-image: -webkit-gradient(linear, left top, left bottom, from(white), to(#DDDDDD));
					background-image: -webkit-linear-gradient(white, #DDDDDD);
					background-image:    -moz-linear-gradient(white, #DDDDDD);
					background-image:     -ms-linear-gradient(white, #DDDDDD);
					background-image:      -o-linear-gradient(white, #DDDDDD);
					background-image:         linear-gradient(white, #DDDDDD);
					
					border-style: solid;
					border-width: 1px;
					border-color: rgb(171,171,171);
					        border-radius: 3px;
					   -moz-border-radius: 3px;
					-webkit-border-radius: 3px;
					
					        box-shadow: 1px 1px 0px 0px white, inset 1px 1px 0px 0px white;
					   -moz-box-shadow: 1px 1px 0px 0px white, inset 1px 1px 0px 0px white;
					-webkit-box-shadow: 1px 1px 0px 0px white, inset 1px 1px 0px 0px white;
					
					color: black;
					font-family: Arial, sans-serif;
					font-size: 8.5pt;
					text-align: center;
					vertical-align: middle;
					padding-left: 6px;
					padding-right: 6px;
					padding-top: 3px;
					padding-bottom: 3px;
					
					       user-select: none;
					  -moz-user-select: none;
					-khtml-user-select: none;
					
					display: inline;
					
					cursor: pointer;
				}
				select:active {
					background-color: #C3C3C3;
					filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#AAAAAA', endColorstr='#E5E5E5', GradientType=0);
					background-image: -webkit-gradient(linear, left top, left bottom, from(#AAAAAA), to(#E5E5E5));
					background-image: -webkit-linear-gradient(top, #AAAAAA, #E5E5E5);
					background-image:    -moz-linear-gradient(top, #AAAAAA, #E5E5E5);
					background-image:     -ms-linear-gradient(top, #AAAAAA, #E5E5E5);
					background-image:      -o-linear-gradient(top, #AAAAAA, #E5E5E5);
					background-image:         linear-gradient(top, #AAAAAA, #E5E5E5);
					
					        box-shadow: 1px 1px 0px 0px white;
					   -moz-box-shadow: 1px 1px 0px 0px white;
					-webkit-box-shadow: 1px 1px 0px 0px white;
				}
				#settings {
					min-height: 82px;
				}
				#settings, #content {
					display: none;
				}
				#settings select, #settings input {
					width: 98%;
				}
			</style>
			<script type="text/javascript" src="http://wave-api.appspot.com/public/wave.js"></script>
			<!--<script type="text/javascript" src="http://zmyaro.com/projects/wave/gadgets/embedscript.js"></script>-->
			<script type="text/javascript">
var ERROR_COLOR = "#FFAAAA";
var ERROR_MESSAGE = "<p>No embedded content has been chosen.  Please switch to edit mode and enter a valid URL to embed.</p>";

var contentContainer;
var typeSelect;
var sourceSelect;
var urlInput;
var type = "video";
var source = "youtube";
var url = "";

if(!String.prototype.trim) {
	String.prototype.trim = function() {return this.replace(/^\s+|\s+$/g, "");};
}
var types = {
	default: "video",
	audio: {
		name: "Audio",
		default: "soundcloud",
		options: {
			audio: {
				name: "Audio by URL",
				exampleURL: "http://example.com/myaudio.mp3",
				//urlCheck: /https?:\/\/.*\/.*/i,
				getEmbedData: function(url) {
					return "<audio src=\"" + url + "\" width=\"300\" controls>You cannot hear this because your browser does not support HTML5 audio.</audio>";
				},
				oEmbedURL: null,
				defaultWidth: 300,
				defaultHeight: 30
			},
			soundcloud: {
				name: "SoundCloud",
				exampleURL: "https://soundcloud.com/username/sound-name",
				urlCheck: /https?:\/\/(soundcloud\.com\/.*|soundcloud\.com\/.*\/.*|soundcloud\.com\/.*\/sets\/.*|soundcloud\.com\/groups\/.*|snd\.sc\/.*)/i,
				getEmbedData: null,
				oEmbedURL: "https://soundcloud.com/oembed?format=json&url=%u",
				defaultWidth: 550,
				defaultHeight: 300
			}
		}
	},
	video: {
		name: "Video",
		default: "youtube",
		options: {
			collegehumor: {
				name: "CollegeHumor",
				exampleURL: "http://www.collegehumor.com/video/1234567/video-name",
				urlCheck: /https?:\/\/(collegehumor\.com\/video:.*|collegehumor\.com\/video\/.*|www\.collegehumor\.com\/video:.*|www\.collegehumor\.com\/video\/.*)/i,
				oEmbedURL: "http://www.collegehumor.com/oembed.json?url=%u"
			},
			dailymotion: {
				name: "DailyMotion",
				exampleURL: "http://www.dailymotion.com/video/abcdef_video-name",
				urlCheck: /https?:\/\/(.*\.dailymotion\.com\/video\/.*|.*\.dailymotion\.com\/.*\/video\/.*)/i,
				getEmbedData: function(url) {
					var vidIDRegex = /dailymotion\.com\/video\/(\w+)_.*$/i;
					var vidID;
					if(!vidIDRegex.test(url)) {
						return null;
					} else {
						vidID = vidIDRegex.exec(url)[1];
					}
					return "<iframe frameborder=\"0\" width=\"480\" height=\"270\" src=\"http://www.dailymotion.com/embed/video/" + vidID + "\"></iframe>";
				},
				oEmbedURL: "http://www.dailymotion.com/services/oembed?format=json&url=%u",
				defaultWidth: 480,
				defaultHeight: 270
			},
			hulu: {
				name: "Hulu",
				exampleURL: "http://www.hulu.com/watch/12345/video-name",
				urlCheck: /https?:\/\/(www\.hulu\.com\/watch.*|www\.hulu\.com\/w\/.*|www\.hulu\.com\/embed\/.*|hulu\.com\/watch.*|hulu\.com\/w\/.*)/i,
				oEmbedURL: "http://www.hulu.com/api/oembed.json?url=%u"
			},
			metacafe: {
				name: "Metacafe",
				exampleURL: "http://www.metacafe.com/watch/12345678/video_name/",
				urlCheck: /https?:\/\/(www\.metacafe\.com\/watch\/.*|www\.metacafe\.com\/w\/.*)/i,
				getEmbedData: function(url) {
					var vidIDRegex = /metacafe\.com\/watch\/(.*)\/?/i;
					var vidID;
					if(!vidIDRegex.test(url)) {
						return null;
					} else {
						vidID = vidIDRegex.exec(url)[1];
						if(vidID.charAt(vidID.length - 1) === "/") {
							vidID = vidID.substring(0, vidID.length - 1);
						}
					}
					return "<embed flashVars=\"playerVars=autoPlay=no\" src=\"http://www.metacafe.com/fplayer/" + vidID + ".swf\" width=\"540\" height=\"304\" wmode=\"transparent\" allowFullScreen=\"true\" allowScriptAccess=\"always\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\"></embed>";
				},
				defaultWidth: 540,
				defaultHeight: 304
			},
			qik: {
				name: "Qik",
				exampleURL: "http://qik.com/video/123456",
				urlCheck: /https?:\/\/(qik\.com\/video\/.*|qik\.com\/.*|qik\.ly\/.*)/i,
				oEmbedURL: "http://qik.com/api/oembed.json?url=%u"
			},
			ted: {
				name: "TED Talk",
				exampleURL: "http://www.ted.com/talks/video_name.html",
				urlCheck: /https?:\/\/(www\.ted\.com\/talks\/.*\.html.*|www\.ted\.com\/talks\/lang\/.*\/.*\.html.*|www\.ted\.com\/index\.php\/talks\/.*\.html.*|www\.ted\.com\/index\.php\/talks\/lang\/.*\/.*\.html.*)/i,
				getEmbedData: function(url) {
					var embedURL = url.replace("www", "embed");
					return "<iframe src=\"" + embedURL + "\" width=\"560\" height=\"315\" frameborder=\"0\" scrolling=\"no\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>";
				},
				oEmbedURL: null,
				defaultWidth: 560,
				defaultHeight: 315
			},
			twitch: {
				name: "Twitch LiveStream",
				exampleURL: "http://www.twitch.tv/username",
				urlCheck: /https?:\/\/(.*twitch\.tv\/.*|.*twitch\.tv\/.*\/b\/.*)/i,
				getEmbedData: function(url) {
					var channelRegex = /\/(\w+$)/;
					var channel;
					if(!channelRegex.test(url)) {
						return null;
					} else {
						channel = channelRegex.exec(url)[1];
					}
					return "<object type=\"application/x-shockwave-flash\" height=\"378\" width=\"620\" id=\"live_embed_player_flash\" data=\"http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel + "\" bgcolor=\"#000000\"><param name=\"allowFullScreen\" value=\"true\" /><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"allowNetworking\" value=\"all\" /><param name=\"movie\" value=\"http://www.twitch.tv/widgets/live_embed_player.swf\" /><param name=\"flashvars\" value=\"hostname=www.twitch.tv&channel=" + channel + "&start_volume=25\" /></object>";
				},
				oEmbedURL: null,
				defaultWidth: 620,
				defaultHeight: 378
			},
			video: {
				name: "Video by URL",
				exampleURL: "http://example.com/myvideo.webm",
				//urlCheck: /https?:\/\/.*\/.*/i,
				getEmbedData: function(url) {
					return "<video src=\"" + url + "\" width=\"550\" height=\"400\" controls>You cannot see this video because your browser does not support HTML5 video.</video>";
				},
				oEmbedURL: null,
				defaultWidth: 550,
				defaultHeight: 400
			},
			vimeo: {
				name: "Vimeo",
				exampleURL: "http://vimeo.com/12345678",
				urlCheck: /((https?:\/\/(www\.vimeo\.com\/groups\/.*\/videos\/.*|www\.vimeo\.com\/.*|vimeo\.com\/groups\/.*\/videos\/.*|vimeo\.com\/.*|vimeo\.com\/m\/#\/.*|player\.vimeo\.com\/.*))|(https:\/\/(www\.vimeo\.com\/.*|vimeo\.com\/.*|player\.vimeo\.com\/.*)))/i,
				getEmbedData: function(url) {
					var vidIDRegex = /\/(\w+$)/i;
					var vidID;
					if(!vidIDRegex.test(url)) {
						return null;
					} else {
						vidID = vidIDRegex.exec(url)[1];
					}
					//var oembedURL = "http://vimeo.com/api/oembed.json?url=" + encodeURIComponent(url);
					return "<iframe src=\"http://player.vimeo.com/video/" + vidID + "?color=ffffff\" width=\"500\" height=\"213\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>";
				},
				oEmbedURL: "http://vimeo.com/api/oembed.json?url=%u",
				defaultWidth: 500,
				defaultHeight: 281
			},
			youtube: {
				name: "YouTube",
				exampleURL: "https://www.youtube.com/watch?v=ABCDEFGHIJK",
				urlCheck: /((https?:\/\/(.*youtube\.com\/watch.*|.*\.youtube\.com\/v\/.*|youtu\.be\/.*|.*\.youtube\.com\/user\/.*|.*\.youtube\.com\/.*#.*\/.*|m\.youtube\.com\/watch.*|m\.youtube\.com\/index.*|.*\.youtube\.com\/profile.*|.*\.youtube\.com\/view_play_list.*|.*\.youtube\.com\/playlist.*))|(https:\/\/(.*youtube\.com\/watch.*|.*\.youtube\.com\/v\/.*)))/i,
				getEmbedData: function(url) {
					var vidIDRegex = /youtube\.com\/watch\?v=([^&]+)/i;
					var vidID;
					if(!vidIDRegex.test(url)) {
						return null;
					} else {
						vidID = vidIDRegex.exec(url)[1];
					}
					return "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/" + vidID + "?rel=0\" frameborder=\"0\" allowfullscreen></iframe>";
				},
				oEmbedURL: "https://www.youtube.com/oembed?url=%u",
				defaultWidth: 560,
				defaultHeight: 315
			}
		}
	}
};

function init() {
	// confirm gadget is running in wave container
	if(wave && wave.isInWaveContainer()) {
		// get references to HTML elements
		contentContainer = document.getElementById("content");
		typeSelect = document.getElementById("type");
		sourceSelect = document.getElementById("source");
		urlInput = document.getElementById("url");
		
		/*
		// load state
		var state = wave.getState();
		if(state) { // avoid bug in which wave.getState() returns null
			type = typeSelect.value = state.get("type", "video");
			source = sourceSelect.value = state.get("source", "youtube");
			url = urlInput.value = state.get("url", "");
		}
		*/
		// add DOM event listeners
		typeSelect.addEventListener("change", function(e) {
			wave.getState().submitValue("type", e.target.value);
		}, false);
		sourceSelect.addEventListener("change", function(e) {
			wave.getState().submitValue("source", e.target.value);
		}, false);
		urlInput.addEventListener("change", function(e) {
			wave.getState().submitValue("url", e.target.value);
		}, false);
		
		// add wave event listeners
		wave.setModeCallback(modeChanged);
		wave.setStateCallback(stateChanged);
	}
}
gadgets.util.registerOnLoadHandler(init);

function stateChanged() {
	// Update the type.
	var newType = wave.getState().get("type", type);
	if(newType === null || newType === "") {
		newType = types.default;
	}
	typeChanged(newType);
	
	// Update the source.
	var newSource = wave.getState().get("source", source);
	if(newSource === null || newSource === "") {
		newSource = types[type].default;
	}
	sourceChanged(newSource);
	
	// Update the URL.
	var newURL = wave.getState().get("url", url);
	urlChanged(newURL);
	
	typeSelect.disabled = false;
	sourceSelect.disabled = false;
	urlInput.disabled = false;
}
function modeChanged(newMode) {
	if(newMode === wave.Mode.EDIT) {
		document.getElementById("content").style.display = "none";
		document.getElementById("settings").style.display = "block";
	} else {
		document.getElementById("settings").style.display = "none";
		document.getElementById("content").style.display = "block";
	}
}
function typeChanged(newType) {
	// Stop if type has not actually changed.
	if(newType === type || newType === "") {
		return;
	}
	
	// Update the global type and reflect the change in the UI.
	type = newType;
	typeSelect.value = newType;
	console.log("type has been changed to " + newType); // for debugging
	
	// Update source options.
	sourceSelect.innerHTML = "";
	var srcOptions = types[newType].options;
	for(var srcOption in srcOptions) {
		var newOption = document.createElement("option");
		newOption.value = srcOption;
		newOption.innerHTML = srcOptions[srcOption].name;
		newOption.selected = (srcOption === types[newType].default);
		sourceSelect.appendChild(newOption);
	}
	
	if(!(source in types[newType].options)) {
		wave.getState().submitValue("source", types[newType].default);
	}
}
function sourceChanged(newSource) {
	// Stop if the source has not actually changed or is not valid for the current type.
	if(newSource === source || newSource === "" || !(newSource in types[type].options)) {
		return;
	}

	// Update the global source and reflect the change in the UI.
	source = newSource;
	sourceSelect.value = newSource;
	console.log("source has been changed to " + newSource); // for debugging
	
	var sourceData = types[type].options[newSource];
	// Update the example URL.
	urlInput.placeholder = sourceData.exampleURL || "";
	// update gadget size for new potential contents
	contentContainer.style.width = sourceData.defaultWidth;
	contentContainer.style.height = sourceData.defaultHeight;
	gadgets.window.adjustWidth(sourceData.defaultWidth);
	gadgets.window.adjustHeight(sourceData.defaultHeight < 82 ? 82 : sourceData.defaultHeight);
	
	var currentURL = url;
	url = ""; // Reset the URL so the urlChanged function actually gets run
	urlChanged(currentURL);
}
function urlChanged(newURL) {
	// Trim extra whitespace from the user's input.
	newURL = newURL.trim();
	
	// Stop if the URL has not actually changed.
	if(newURL === url) {
		return;
	}
	
	// If the URL does not begin with "http://" or "https://", add "http://" to the URL.
	if(!(/^https?:\/\/.*/).test(newURL)) {
		newURL = "http://" + newURL;
		// Also update the text field to show the modified URL.
		urlInput.value = newURL;
	}
	
	// Update the global URL and reflect the change in the UI.
	url = newURL;
	urlInput.value = newURL;
	console.log("url has been changed to " + newURL); // for debugging
	
	// Update embed code.
	if(checkURL(url)) {
		if(types[type].options[source].oEmbedURL) {
			var oEmbedURL = types[type].options[source].oEmbedURL.replace("%u", encodeURIComponent(url));
			gadgets.io.makeRequest(oEmbedURL, processOEmbedResponse);
		} else {
			var newEmbedData = types[type].options[source].getEmbedData(url);
			if(!newEmbedData) {
				contentContainer.innerHTML = ERROR_MESSAGE;
				urlInput.style.backgroundColor = ERROR_COLOR;
			} else if(newEmbedData !== contentContainer.innerHTML) {
				contentContainer.innerHTML = newEmbedData;
				urlInput.style.backgroundColor = null;
			}
		}
	} else {
		contentContainer.innerHTML = ERROR_MESSAGE;
		urlInput.style.backgroundColor = ERROR_COLOR;
	}
}

/**
 * Checks if a given URL is valid for the current source type
 * @param {String} url - The URL to check
 * @returns {Boolean} - Whether the URL is valid
 */
function checkURL(url) {
	if(types[type].options[source].urlCheck) {
		return types[type].options[source].urlCheck.test(url);
	}
	return (/^https?:\/\/.*\/.*/i).test(url);
}

/**
 * Processes the response from an asynchronous oEmbed API call
 * @param {Object} response
 */
function processOEmbedResponse(response) {
	if(!response.data) {
		contentContainer.innerHTML = ERROR_MESSAGE;
		urlInput.style.backgroundColor = ERROR_COLOR;
	} else {
		urlInput.style.backgroundColor = null;
		var data = JSON.parse(response.data);
		if(data.html !== contentContainer.innerHTML) {
			contentContainer.innerHTML = data.html;

			if(!data.width) {
				contentContainer.style.width = types[type].options[source].defaultWidth + "px";
				gadgets.window.adjustWidth(types[type].options[source].defaultWidth);
			} else if(data.width === "100%") {
				//contentContainer.style.width = "100%";
				contentContainer.style.width = "600px";
				gadgets.window.adjustWidth();
			} else {
				contentContainer.style.width = data.width + "px";
				gadgets.window.adjustWidth(data.width);
			}

			if(!data.height) {
				contentContainer.style.height = types[type].options[source].defaultHeight + "px";
				gadgets.window.adjustHeight(types[type].options[source].defaultHeight < 82 ? 82 : types[type].options[source].defaultHeight);
			} else if(data.height === "100%") {
				contentContainer.style.height = "100%";
				gadgets.window.adjustHeight();
			} else {
				contentContainer.style.height = data.height + "px";
				gadgets.window.adjustHeight(data.height);
			}
		}
	}
}
			</script>
			<div id="settings">
				<select name="type" id="type">
					<option value="audio">Audio</option>
					<option value="video" selected="selected">Video</option>
				</select>
				<br />
				<select name="source" id="source">
					<option value="collegehumor">CollegeHumor</option>
					<option value="dailymotion">DailyMotion</option>
					<option value="hulu">Hulu</option>
					<option value="metacafe">Metacafe</option>
					<option value="qik">Qik</option>
					<option value="ted">TED Talk</option>
					<option value="twitch">Twitch Livestream</option>
					<option value="video">Video by URL</option>
					<option value="vimeo">Vimeo</option>
					<option value="youtube" selected="selected">YouTube</option>
				</select>
				<br />
				<input type="url" name="url" id="url" placeholder="http://www.youtube.com/watch?v=AAAAAAAAAAA" />
			</div>
			<div id="content" style="width: 560; height: 315">
				<p>No embedded content has been chosen.  Please switch to edit mode and enter a valid URL to embed.</p>
			</div>
		]]>
	</Content>
</Module>