// ==UserScript==
// @name            YouTube Highest Possible Video Quality
// @description     Detects and shows the highest quality video available on YouTube.  It can also add a link to download a video that is being watched.
// @author          HoppyToad75	
// @version         1.1
// @include         *youtube.com/*v=*
// ==/UserScript==

// Uses modified code from the "YouTubeHD" script by Yansky and the "Download Video From YouTube" script by the IE7pro Team.

/*
The following four variables can be modifed by the user to change the way the script works.  Set each one to true or false.  Be sure to use lower case letters since javascript is case sensitive and also be sure to leave the semicolon (;) at the end of the line.  Here's a description of what these variables do:

EnableQualityChange - set this to true to show videos in a higher quality format if available.  Set it to false to allow YouTube to determine which format is shown.

EnableVideoDownloading - set this to true to enable a link to download the video that is currently being watched.  Set it to false to not allow downloading of videos.

UseHD - set this to true to watch videos in 720p HD if available.  Set it to false to watch videos in one of the other formats.

UseHQflv - set this to true to watch videos in the higher quality flv format if available.  Set it to false to watch videos in mp4 format.

Not all videos are available in these formats and in that case will default to the mp4 format.  In some rare instances older videos or very poorly encoded videos may not even be available in that format and will then play in a lower quality flv format.
*/

// ONLY MODIFY THE FOLLOWING FOUR VARIABLES!

var EnableQualityChange = true;
var EnableVideoDownloading = true;    
var UseHD = true;
var UseHQflv = true;

// ONLY MODIFY THE ABOVE FOUR VARIABLES!

var HDformat = 22,
    HQflv = 35,
    mp4Format = 18,        
    EncodedFormat = swfArgs.fmt_map.match(/\d+/),
    SelectedFormat;

if (EnableQualityChange)
{
	ChangeQuality();
}

if (EnableVideoDownloading)
{
	CreateDownloadLink();
}

function ChangeQuality()
{
	var dURL = document.URL,
	    newURL;
/*
The following checks the format value found in the video's web page against the conditions set by the user.  Depending on what the format value is and whether the user set the UseHD and UseHQflv variables to true or false determines which video quality is played
*/
	
	if (UseHD && EncodedFormat == HDformat)
	{
		if (dURL.match('&hd=1'))
		{
			return;  // If '&hd=1' is in the URL it will display in HD automatically so there's no need to change format.
		}
		else
		{
			SelectedFormat = SetupFormat(HDformat);
		}
	}
	else if (UseHQflv)
	{
		if (EncodedFormat == HQflv || EncodedFormat == HDformat)
		{
			SelectedFormat = SetupFormat(HQflv);
		}
		else
		{
			SelectedFormat = SetupFormat(mp4Format);
		}
	}
	else
	{
		SelectedFormat = SetupFormat(mp4Format);
	}
	
	if (!dURL.match(SelectedFormat))
	{		
		if (dURL.match(/&fmt=\d+/gi))
		{
			newURL = dURL.replace(/&fmt=\d+/gi, SelectedFormat);
		}
		else
		{
			newURL = dURL + SelectedFormat;
		}
		window.location.replace(newURL);
	}
}

function CreateDownloadLink()
{

/*
The following generates a link that will allow the user to download the video that is currently being watched.  The link will be placed above the title of the video.  The link will download the format that is currently being watched so it may or may not be the best quality available.
*/

	if (EncodedFormat != HDformat && EncodedFormat != HQflv) 
	{                        
		SelectedFormat = SetupFormat(mp4Format);
	}
	else
	{
		SelectedFormat = SetupFormat(EncodedFormat);
	}
	
	var DownloadLink = 'http://youtube.com/get_video?video_id=' + pageVideoId + '&t=' + swfArgs.t + SelectedFormat, 
	    VideoTitleElem = document.getElementById('watch-vid-title');

	if(VideoTitleElem)
	{
	var div = document.createElement('div');
	VideoTitleElem.parentNode.insertBefore(div, VideoTitleElem);
	div.innerHTML = '<style>#download{text-align:left;margin: 0 10px 0 20px;}.downloadImg{border: 0;float:left;}h2.downloadVid{font-size: 22px;display:inline;}</style><div id="download"><a href="'+DownloadLink+'"><img src="data:image/gif;base64,R0lGODlhFAAUAOYAAP///3jJrvTl4+r38sjp3se0q67i0V2Wd9Xz6gCZZv3+/k2YdgCUX2rDpgCSW3HGqgCZZ2vEpvr9/ACQWf7//v7+/gCWYe/49W7FqPf8+nLGqq3i0Z3YxGPAoVS7mOT07gSXY9Xz62C/oHfJrVG5l02Yde349KXWxI3Ru5XUv4TNtf3z9PT6+QCOVXvLsMayqQCTXt3x6/D59hygcJbVwACVYcrv5HiWfVuUddr17c68tPz+/WrDpQCTXfX8+k6Ydtzx6ur383KSd6/h0uzo5KTayBqicyCmeQCQWK/j0tDs4gCOVvv6+UyXdUyWc5nWwVe8mo/SvAKXYwCWYvX7+eDz7ZHTvWbCo9Hv5tHt5JTVv2rCpJLTvvzy8m3Fp2zEpsbo3VGaeDesgkO0j8fo3fH692WihcLm2gCVX3rKr8Szqdjv6FyWd2m2mPDk4kK0jjethACXZACYZBijdO/59Rykd6aWh1e7mRyebVi8nOr28tHHv9Tu5SSne4TIsAAAACH5BAAAAAAALAAAAAAUABQAAAfygACCg4SFhoIyA4qLjHomFYQZKh08DQ1eD5kYllsRTz6DSh4fCqUZF3QXVKUKZVong2RphBwzdXguhENmK4IEAYQoEzUtV4QGOAK+wINWDAkOEccHygC/hFzPDl/T1dcUginaGILgBtTLAEFQYkdyCXFzcG9AAOfewApRE2gQCRAWkASQYA+dNWYSSMBIwLDHGBaC7qUTtKYPA4BGsgySeJBQERBTpNDoNlHQDhFL8igglIRNNTAjCsW4U6XQBoN8NGBBwBNBCBs5evL0c8ONoApn2jhpsmDBjzBNo5YQYocIoS46XhTYyrWrmj1MDok1FAgAOw==" class="downloadImg"><span class="downloadVid">Download Video</span></a></b></div>';	
	}
}

function SetupFormat(Format)
{
	return '&fmt=' + Format;  // Adds '&fmt=' before the format value
}	