// ==UserScript==
// @name           Video Full Sizer
// @namespace      http://arantius.com/misc/greasemonkey/
// @description    Add a control to tiny embedded videos to make them full screen, or to open the site they belong to.
// @include        *
// @exclude        http://video.google.com/*
// @exclude        http://www.youtube.com/*
// @exclude        http://youtube.com/*
// ==/UserScript==

var vids=[];
var vidI=0;

(function(){
var srcTipoffs=[
	// common video sharing sites
	'video.google.com', 'youtube.com', 'metacafe.com', 'yimg.com',
	'dailymotion.com', 'embed.break.com',
	// common "player" names
	'player.swf', 'player/', 'video',
	// if it's an FLV, it's a video!
	'.flv'
];

var flashvarsTipoffs=[
	'video'
];

//find the video(s)
var vids=xpath(
	"//embed[contains(@src, '"+srcTipoffs.join("') or contains(@src, '")+"')] |" +
	"//object[contains(@data, '"+srcTipoffs.join("') or contains(@data, '")+"')] |" +
	"//embed[contains(@flashvars, '"+flashvarsTipoffs.join("') or contains(@flashvars, '")+"')]"
);
for (var i=0, vid=null; vid=vids[i]; i++) {
	addExpandTab(vid);
}
})();

// Functions at the bottom ... I must be insane ...

function xpath(p, context) {
    if (!context) context=document;
    var arr=[];
    var xpr=document.evaluate(
        p, context, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null
    );
    for(i=0;item=xpr.snapshotItem(i);i++){ arr.push(item); }
    return arr;
}

function addExpandTab(vid) {
	// check if this is inside an <object>
	var o=vid.parentNode;
	while (o) {
		if ('OBJECT'==o.tagName) break;
		o=o.parentNode;
	}
	if (o) vid=o;

	if (vid.getAttribute('fullsized')) return;

	vids[++vidI]=vid;

	var top=0;
	var left=0;
	var el=vid;
	do {
		top+=parseInt(el.offsetTop);
		left+=parseInt(el.offsetLeft);
	} while (el=el.offsetParent);
	top+=parseInt(vid.offsetHeight || vid.height);

	var t=createTab(top, left, vidI, 'Expand', expandVid);

	// In compatible cases, add "open" link.
	var doc='';
	// Find the "source" value.
	var src=vid.src;
	if (!src) {
		try {
			var d=xpath('param[@name="movie"]/@value | embed/@src', vid)[0];
			src=d.value;
		} catch (e) { }
	}
	if (src.match(/video.google.com/)) {
		var m=decodeURIComponent(src).match(/docid=(.*?)(&|$)/i);
		if (m[1]) doc='http://video.google.com/videoplay?docid='+m[1];
	} else if (src.match(/youtube.com/)) {
		var m=src.match(/[^\/]+$/);
		if (m) doc='http://www.youtube.com/watch?v='+m;
	} else if (src.match(/video.yahoo.com/)) {
		var m=unescape(src).match(/vid=([0-9a-f.]+)&/);
		if (m) doc='http://video.yahoo.com/video/play?vid='+m[1];
	} else if (src.match(/metacafe.com/)) {
		var m=unescape(src).match(/fplayer\/(.+)\.swf/);
		if (m) doc='http://www.metacafe.com/watch/'+m[1]+'/';
	}
	if (doc) {
		t=createTab(top, left+75, vidI, 'Open', function() {
			document.location.assign(doc);
		});
	}

	vid.setAttribute('fullsized', 1)
}

function createTab(top, left, vidI, label, listener) {
	var t=document.createElement('div');
	t.setAttribute('style',
		'border: 2px solid black;'+
		'border-top: none;'+
		'background: white;'+
		'cursor: pointer;'+
		'position: absolute;'+
		'padding: 2px;'+
		'background: lightgray;'+
		'opacity: 0.5;'+
		'top: '+top+'px;'+
		'left: '+left+'px;'+
		'width: 66px;'+
		'text-align: center;'+
		'z-index: 9999;'
	);
	t.appendChild(document.createTextNode(label));
	t.setAttribute('vidI', vidI);
	t.addEventListener('click', listener, true);

	document.body.appendChild(t);

	return t;
}

function expandVid(event) {
	var t=event.target;

	var s=document.createElement('div');
	s.setAttribute('style',
		'position: fixed;'+
		'top: 0;'+
		'left: 0;'+
		'width: 100%;'+
		'height: 100%;'+
		'padding: 0 1em;'+
		'background: lightgray;'+
		'text-align: center;'+
		'cursor: no-drop;'+
		'z-index: 10000;'
	);

	var vid=vids[t.getAttribute('vidI')];
	var v=vid.cloneNode(true);
	var vidW=parseInt(v.width);
	var vidH=parseInt(v.height);
	var sizeRatio=window.innerHeight/vidH;
	vidW=parseInt(vidW*sizeRatio);
	vidH=parseInt(vidH*sizeRatio);
	v.width=String(vidW);
	v.height=String(vidH);

	// if there's an embed inside, resize it, too
	var e=v.getElementsByTagName('embed');
	if (e[0]) {
		e[0].width=String(vidW);
		e[0].height=String(vidH);
	}

	s.appendChild(v);
	s.addEventListener('click', collapseVid, true);

	document.body.appendChild(s);
}

function collapseVid(event) {
	var s=event.target;
	document.body.removeChild(s);
}
