//ŠTim Zwicker

// Parameters and defaults
var showImage	= true;
var showGenre	= true;
var showRating	= true;
var showRDate	= true;
var showFormat	= true;
var showStudio	= false;
var showAspect	= true;
var showRelease	= false;
var showScore	= true;
var showOwner	= false;
var showPDate	= true;

var loadImg 	= true;
var unkD	= 0;
var unkS	= -1;

// Binary bit-map; by addition; more space efficient than above prime (multiplication) method for large sets
var bits = new Array(1,	
2,	4,	8,	16,	32,	64,	128,	256,	
512,	1024,	2048,	4096,	8192,	16384,	32768,	65536,	
131072,		262144,		524288,		1048576,	
2097152,	4194304,	8388608,	16777216,	
33554432,	67108864,	134217728,	268435456);

var i;

// Format, Grenre, and Aspect are sets of tags
i=0;
var formats = new Array();
var bd	= bits[i++]; formats.push("<NOBR>Blu-ray</NOBR>");
var hd	= bits[i++]; formats.push("<NOBR>HD DVD</NOBR>");
var dvd	= bits[i++]; formats.push("DVD");
var umd	= bits[i++]; formats.push("UMD");
var ld	= bits[i++]; formats.push("LaserDisc");
var vhs	= bits[i++]; formats.push("VHS");

i=0;
var genres = new Array();
var in3d	= bits[i++]; genres.push("3D");
var act		= bits[i++]; genres.push("Action");
var anim	= bits[i++]; genres.push("Animation");
var artsy	= bits[i++]; genres.push("Artsy");
var broad	= bits[i++]; genres.push("Broadway");
var bolly	= bits[i++]; genres.push("Bollywood");
var com		= bits[i++]; genres.push("Comedy");
var comic	= bits[i++]; genres.push("Comic");
var spoof	= bits[i++]; genres.push("Spoof");
var dance	= bits[i++]; genres.push("Dance");
var docu	= bits[i++]; genres.push("Documentary");
var drama	= bits[i++]; genres.push("Drama");
var epic	= bits[i++]; genres.push("Epic");
var fant	= bits[i++]; genres.push("Fantasy");
var frgn	= bits[i++]; genres.push("Foreign");
var head	= bits[i++]; genres.push("Head");
var hero	= bits[i++]; genres.push("Hero");
var hist	= bits[i++]; genres.push("History");
var hor		= bits[i++]; genres.push("Horror");
var kids	= bits[i++]; genres.push("Kids");
var mart	= bits[i++]; genres.push("Martial-Arts");
var mus		= bits[i++]; genres.push("Musical");
var nature	= bits[i++]; genres.push("Nature");
var rom		= bits[i++]; genres.push("Romance");
var relig	= bits[i++]; genres.push("Religious");
var scen	= bits[i++]; genres.push("Scenic");
var scf		= bits[i++]; genres.push("Sci-Fi");
var se		= bits[i++]; genres.push("Special-Effects");
var susp	= bits[i++]; genres.push("Suspense");
var trag	= bits[i++]; genres.push("Tragedy");
var war		= bits[i++]; genres.push("War");
var west	= bits[i++]; genres.push("Western");

i=0;
var aspects = new Array();
var ws255	= bits[i++]; aspects.push("2.55:1");
var ws240	= bits[i++]; aspects.push("2.40:1");
var ws235	= bits[i++]; aspects.push("2.35:1");
var ws220	= bits[i++]; aspects.push("2.20:1");
var ws185	= bits[i++]; aspects.push("1.85:1");
var ws178	= bits[i++]; aspects.push("1.78:1");
var ws177	= ws178; //bits[i++]; aspects.push("1.77:1");
var ws166	= bits[i++]; aspects.push("1.66:1");
var fs133	= bits[i++]; aspects.push("1.33:1");
var da177	= fs133|ws177;
var da178	= fs133|ws178;
var da185	= fs133|ws185;
var da235	= fs133|ws235;


// Relase Rating, Date, and Score are all numeric

i=0;
var releases = new Array();
var movie	= i++; releases.push("Movie");
var tv		= i++; releases.push("TV");
var dv_rel	= i++; releases.push("DVD");
var it_rel	= i++; releases.push("Internet");

var ratings = new Array();
i = 0;
var nr 		= i++;	ratings.push("NR");
var tvy 	= i++;	ratings.push("TV-Y");
var tv7 	= i++;	ratings.push("TV-7");
var tvg 	= i++;	ratings.push("TV-G");
var g 		= i++;	ratings.push("G");
var tvpg 	= i++;	ratings.push("TV-PG");
var pg 		= i++;	ratings.push("PG");
var tv14 	= i++;	ratings.push("TV-14");
var pg13 	= i++;	ratings.push("PG-13");
var tvma	= i++;	ratings.push("TV-MA");
var r 		= i++;	ratings.push("R");
var ur 		= i++;	ratings.push("Unrated");
var nc17 	= i++;	ratings.push("NC-17");
var x 		= i++;	ratings.push("X");

// Studios
i=0;
var studios = new Array();
var otherS	= i++; studios.push("Other");
var ae		= i++; studios.push("A&E");
var bbc		= i++; studios.push("BBC");
var enter2	= i++; studios.push("BBC: 2 Entertain Video");
var bigi	= i++; studios.push("Big Idea");
var discov	= i++; studios.push("Discovery Channel");
var disney	= i++; studios.push("Disney: Walt Disney");
var buena	= i++; studios.push("Disney: Buena Vista");
var touch	= i++; studios.push("Disney: Touchstone");
var miram	= i++; studios.push("Disney: Miramax");
var fox		= i++; studios.push("20th Century Fox");
var hallm	= i++; studios.push("Hallmark");
var hollyw	= i++; studios.push("Hollywood Pictures");
var image	= i++; studios.push("Image Entertainment");
var lions	= i++; studios.push("Lionsgate");
var artis	= i++; studios.push("Lionsgate: Artisan");
var param	= i++; studios.push("Paramount");
var dream	= i++; studios.push("Paramount: Dreamworks");
var dreama	= i++; studios.push("Pmt: DrmWks Anim SKG");
var sony	= i++; studios.push("Sony");
var columb	= i++; studios.push("Sony: Columbia Tristar");
var mgm		= i++; studios.push("Sony: MGM");
var sgems	= i++; studios.push("Sony: Screen Gems");
var univ	= i++; studios.push("Universal");
var focus	= i++; studios.push("Univ: Focus Features");
var dreamu	= i++; studios.push("Univ: DrmWks Anim SKG");
var warner	= i++; studios.push("Warner");
var hbo		= i++; studios.push("Warner: HBO");
var newln	= i++; studios.push("Warner: New Line");

/**
 *	constructor Movie
 *	Returns a Movie with given attributes.
 **/
function Movie(format, studio, aspect, release, rating, genre, rdate, owner, pdate, asin, score, title, num)
{
	this.title	= title;
	this.asin	= asin;
        this.num	= num;
	this.format	= format;
	this.genre	= genre;
	this.studio	= studio;
	this.aspect	= aspect;
	this.rdate	= rdate;
	this.release	= release;
	this.rating	= rating;
	this.owner	= owner;
	this.score	= score;
	this.pdate	= pdate;

	// functions
	this.header	= header;
	this.tabulate	= tabulate;
	
	return this;
}

/**
 *	funciton makeTable
 *	Returns a string of HTML code to generate the table from the movies Array.
 **/
function makeTable(moviesArray, cat)
{
	str="<BR><TABLE BORDER=5 BGCOLOR='#FFFFFF'>";
	topRow=new Movie( 
		"<A HREF='javascript:displayBy(\"format\")'>Format</A>",
		"<A HREF='javascript:displayBy(\"studio\")'>Studio</A>",
		"<A HREF='javascript:displayBy(\"aspect\")'>Aspect</A>",
		"<A HREF='javascript:displayBy(\"release\")'>Release</A>",
		"<A HREF='javascript:displayBy(\"rating\")'>Rating</A>",
		"<A HREF='javascript:displayBy(\"genre\")'>Genre</A>",
		"<A HREF='javascript:displayBy(\"rdate\")'>Date Released</A>",
		"<A HREF='javascript:displayBy(\"owner\")'>Owner</A>",
		"<A HREF='javascript:displayBy(\"pdate\")'>Date Purchased</A>",
		"<A HREF='javascript:displayBy(\"asin\")'>Image [num]</A>",
		"<A HREF='javascript:displayBy(\"score\")'>Score</A>",
		"<A HREF='javascript:displayBy(\"title\")'>Title</A>", 0);
	str+=topRow.header(cat);
	if(cat!=null)	moviesArray.sort(getSort(cat));
	if(cat=="asin")	loadImg = !loadImg;
	for(i=0; i<moviesArray.length; i++)
	{
		str+=moviesArray[i].tabulate(i + 1);
	}
	str+="</TABLE><BR>";
	return str;
}

/**
 *	function header
 *	Generates the Header HTML
 **/
function header(cat)
{
	str="";
	str+="<TH>";
	str+="<TR ALIGN='center' VALIGN='top' BGCOLOR='#DDDDDD'>";
	if(showImage)
	{
		str+="<TD>"+(cat=="asin"  ?"<B>":"")+this.asin  +(cat=="asin"  ?"</B>":"")+filter("asin")  +"</TD>";
	}

	str+="<TD>";
	str+=(cat=="title" ?"<B>":"")+this.title +(cat=="title" ?"</B>":"")+" (Click links to sort)<BR><INPUT TYPE='button' VALUE='Reset filters' onClick='restore()'>";
	if(!showImage | !showGenre | !showRating | !showRDate | !showFormat | !showStudio | !showAspect | !showRelease | !showScore | !showOwner | !showPDate)
	{
		str+="<BR>Click buttons to show: <INPUT TYPE='button' VALUE='All' onClick='showImage=true; showGenre=true; showRating=true; showRDate=true; showFormat=true; showStudio=true; showAspect=true; showRelease=true; showScore=true; showOwner=true; showPDate=true; displayBy();'>";		
		if(!showImage)
		{
			str+="<INPUT TYPE='button' VALUE='Image' onClick='showImage=true; displayBy();'>";
		}
		if(!showGenre)
		{
			str+="<INPUT TYPE='button' VALUE='Genre' onClick='showGenre=true; displayBy();'>";
		}
		if(!showRating)
		{
			str+="<INPUT TYPE='button' VALUE='Rating' onClick='showRating=true; displayBy();'>";
		}
		if(!showRDate)
		{
			str+="<INPUT TYPE='button' VALUE='Date Released' onClick='showRDate=true; displayBy();'>";
		}
		if(!showFormat)
		{
			str+="<INPUT TYPE='button' VALUE='Format' onClick='showFormat=true; displayBy();'>";
		}
		if(!showStudio)
		{
			str+="<INPUT TYPE='button' VALUE='Studio' onClick='showStudio=true; displayBy();'>";
		}
		if(!showAspect)
		{
			str+="<INPUT TYPE='button' VALUE='Aspect' onClick='showAspect=true; displayBy();'>";
		}
		if(!showRelease)
		{
			str+="<INPUT TYPE='button' VALUE='Release' onClick='showRelease=true; displayBy();'>";
		}
		if(!showScore)
		{
			str+="<INPUT TYPE='button' VALUE='Score' onClick='showScore=true; displayBy();'>";
		}
		if(!showOwner)
		{
			str+="<INPUT TYPE='button' VALUE='Owner' onClick='showOwner=true; displayBy();'>";
		}
		if(!showPDate)
		{
			str+="<INPUT TYPE='button' VALUE='Date Purchased' onClick='showPDate=true; displayBy();'>";
		}
	}
	str+="</TD>";
	
	if(showGenre)
	{
		str+="<TD>"+(cat=="genre"  ?"<B>":"")+this.genre  +(cat=="genre"  ?"</B>":"")+filter("genre")  +"</TD>";
	}
	if(showRating)
	{
		str+="<TD>"+(cat=="rating" ?"<B>":"")+this.rating +(cat=="rating" ?"</B>":"")+filter("rating") +"</TD>";
	}
	if(showRDate)
	{
		str+="<TD>"+(cat=="rdate"   ?"<B>":"")+this.rdate   +(cat=="rdate"   ?"</B>":"")+filter("rdate")   +"</TD>";
	}
	if(showFormat)
	{
		str+="<TD>"+(cat=="format" ?"<B>":"")+this.format +(cat=="format" ?"</B>":"")+filter("format") +"</TD>";
	}
	if(showStudio)
	{
		str+="<TD>"+(cat=="studio" ?"<B>":"")+this.studio +(cat=="studio" ?"</B>":"")+filter("studio") +"</TD>";
	}
	if(showAspect)
	{
		str+="<TD>"+(cat=="aspect" ?"<B>":"")+this.aspect +(cat=="aspect" ?"</B>":"")+filter("aspect") +"</TD>";
	}
	if(showRelease)
	{
		str+="<TD>"+(cat=="release"?"<B>":"")+this.release+(cat=="release"?"</B>":"")+filter("release")+"</TD>";
	}
	if(showScore)
	{
		str+="<TD>"+(cat=="score"  ?"<B>":"")+this.score  +(cat=="score"  ?"</B>":"")+filter("score")  +"</TD>";
	}
	if(showOwner)
	{
		str+="<TD>"+(cat=="owner"  ?"<B>":"")+this.owner  +(cat=="owner"  ?"</B>":"")+filter("owner")  +"</TD>";
	}
	if(showPDate)
	{
		str+="<TD>"+(cat=="pdate"  ?"<B>":"")+this.pdate  +(cat=="pdate"  ?"</B>":"")+filter("pdate")  +"</TD>";
	}
	str+="</TR>";
	
	var columns = 0;
	str+="<TR ALIGN='center' VALIGN='top' BGCOLOR='#DDDDDD'>";
	if(showImage)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showImage=false; displayBy();' /></TD>";
		++columns;
	}
	// Title
	str+="<TD><INPUT TYPE='button' VALUE='Add...' onClick=\"document.getElementById('add_item').style.display='inline';\"/></TD>";
	++columns;
	if(showGenre)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showGenre=false; displayBy();' /></TD>";
		++columns;
	}
	if(showRating)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showRating=false; displayBy();'></TD>";
		++columns;
	}
	if(showRDate)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showRDate=false; displayBy();'></TD>";
		++columns;
	}
	if(showFormat)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showFormat=false; displayBy();'></TD>";
		++columns;
	}
	if(showStudio)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showStudio=false; displayBy();'></TD>";
		++columns;
	}
	if(showAspect)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showAspect=false; displayBy();'></TD>";
		++columns;
	}
	if(showRelease)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showRelease=false; displayBy();'></TD>";
		++columns;
	}
	if(showScore)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showScore=false; displayBy();'></TD>";
		++columns;
	}
	if(showOwner)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showOwner=false; displayBy();'></TD>";
		++columns;
	}
	if(showPDate)
	{
		str+="<TD><INPUT TYPE='button' VALUE='Hide' onClick='showPDate=false; displayBy();'></TD>";
		++columns;
	}
	
	str+="</TR>";
	str+="<TR STYLE='display:none;' ID='add_item'>";
	str+="<TD COLSPAN='"+columns+"'>";
	str+="&nbsp;"
	str+="</TD>";
	str+="</TR>";
	str+="</TH>";
	return str;
}

/**
 *	function tabulate
 *	Returns an HTML string to generate a row for this movie.
 **/
function tabulate(index)
{
	str="";
	str+="<TR ALIGN='center'";
	if(this.format == dvd)
	{
		str+=" BGCOLOR='#FFFFFF'";
	}
	else if(this.format & bd)
	{
		str+=" BGCOLOR='#DDDDFF'";
	}
	else if(this.format & hd)
	{
		str+=" BGCOLOR='#FFDDDD'";
	}
	else if(this.format & umd)
	{
		str+=" BGCOLOR='#DDFFDD'";
	}
	else if(this.format & vhs)
	{
		str+=" BGCOLOR='#DDDDDD'";
	}
	str+=">";
	if(showImage)
	{
		if(loadImg && this.asin.length!=0)
		{
			str+=("<TD><A HREF='http://www.amazon.com/exec/obidos/ASIN/"+this.asin+"/"+"timzwickespage"+"' TARGET='_blank'><IMG SRC=\"http://images.amazon.com/images/P/"+this.asin+".01.THUMBZZZ.jpg\" HEIGHT=30 BORDER=0 ALT='["+index+"]' TITLE='"+index+"'></A></TD>");
		}
		else
		{
			str+=("<TD>["+index+"]</TD>");
		}
	}

	// Title
	str+=("<TD ALIGN='left'>"+this.title.substring(0,this.num)+"<U>"+this.title.charAt(this.num)+"</U>"+this.title.substring(this.num+1,this.title.length)+"</TD>");

	// Genre
	if(showGenre)
	{
		str+=("<TD>");
		var first = true;
		for(var b=0; b<bits.length; b++)
		{
			if(bits[b] & this.genre)
			{
				if(first)
				{
					first = false;
				}
				else
				{
					str += " ";
				}
				str+=("<NOBR>"+genres[b]+"</NOBR>");
			}
		}
	}

	// Rating
	if(showRating)
	{
		str+=("<TD><NOBR>"+ ratings[this.rating] +"</NOBR></TD>");
	}

	if(showRDate)
	{
		str+=("<TD>"+this.rdate   +"</TD>");
	}
	
	// Format
	if(showFormat)
	{
		str+=("<TD>");
		var first = true;
		for(var b=0; b<bits.length; b++)
		{
			if(bits[b] & this.format)
			{
				if(first)
				{
					first = false;
				}
				else
				{
					str += " ";
				}
				str+=formats[b];
			}
		}
		str+=("</TD>");
	}

	// Studio
	if(showStudio)
	{
		str+=("<TD>"+studios[this.studio]+"</TD>");
	}

	// Aspect
	if(showAspect)
	{
		str+=("<TD>");
		var first = true;
		for(var b=0; b<bits.length; b++)
		{
			if(bits[b] & this.aspect)
			{
				if(first)
				{
					first = false;
				}
				else
				{
					str += " ";
				}
				str+=aspects[b];
			}
		}
		str+=("</TD>");
	}

	// Release
	if(showRelease)
	{
		str+=("<TD><NOBR>"+ releases[this.release] +"</NOBR></TD>");
	}
	
	// Score
	if(showScore)
	{
		str+=("<TD ALIGN='left'>"+numToStars(this.score)  +"</TD>");
	}
	
	// Owner
	if(showOwner)
	{
		str+=("<TD><NOBR>"+this.owner  +"</NOBR></TD>");
	}
	
	// Purchase Date
	if(showPDate)
	{
		if(this.pdate == unkD)
		{
			str+=("<TD BGCOLOR='#DDDDDD'>"+"Unknown"	+"</TD>");
		}
		else
		{
			str+=("<TD>"+this.pdate	+"</TD>");
		}
	}
	
	str+=("</TR>");
	return str;
}

/**
 *	function numToStars
 *	Returns a string with the number of stars passed into the function
 **/
function numToStars(num)
{
	if(num == unkS)
	{
		return " -N/A-";
	}
	var str = "&nbsp;";
	for(var i=0; i<num; i++)
	{
		str+="*";
	}
	return str;
}


/**
 *	Returns a positive number if a>b, negative if a<b, zero if a==b
 **/
function numSort(a, b)
{
	return a-b;
}
function bitSetSort(a, b)
{
	for(var c=0; c<bits.length; c++)
	{
		if((a&bits[c]) != (b&bits[c]))
		{
			return (b&bits[c]) - (a&bits[c]);
		}
	}
	return 0;
}
function alphaSort(a, b)
{
        if(a.toLowerCase()==b.toLowerCase()) return 0;
        return a.toLowerCase()>b.toLowerCase()?1:-1;
}
function nameSort(a, b)
{
	lastA=a.lastIndexOf(" ")+1;
	lastB=b.lastIndexOf(" ")+1;
	return alphaSort(
		a.substring(lastA, a.length)+","+a.substring(0, lastA),
		b.substring(lastB, b.length)+","+b.substring(0, lastB));
}

/**
 *	function sortFormat, sortRating, sortRDate, sortGenre, sortTitle, sortOwner, sortScore
 *	sorts a and b by the appropriate attribute.  To be used with Array.sort(function sort)
 **/
function sortFormat(a, b)
{
	return bitSetSort(a.format, b.format);
}
function sortRelease(a, b)
{
	return numSort(a.release, b.release);
}
function sortAspect(a, b)
{
	return bitSetSort(a.aspect, b.aspect);
}
function sortRating(a, b)
{
	return numSort(a.rating, b.rating);
}
function sortRDate(a, b)
{
	return numSort(a.rdate, b.rdate);
}
function sortPDate(a, b)
{
	return numSort(b.pdate, a.pdate);
}
function sortGenre(a, b)
{
	return bitSetSort(a.genre, b.genre);
}
function sortStudio(a, b)
{
	return numSort(a.studio, b.studio);
}
function sortTitle(a, b)
{
	return alphaSort(
		a.title.substring(a.num, a.title.length)+", "+a.title.substring(0, a.num),
		b.title.substring(b.num, b.title.length)+", "+b.title.substring(0, b.num));
}
function sortOwner(a, b)
{
	lastA=a.owner.lastIndexOf(" ")+1;
	lastB=b.owner.lastIndexOf(" ")+1;
	return alphaSort(
		a.owner.substring(lastA, a.owner.length)+", "+a.owner.substring(0, lastA),
		b.owner.substring(lastB, b.owner.length)+", "+b.owner.substring(0, lastB));
}
function sortScore(a, b)
{
	return -1 * numSort(a.score, b.score);
}

function sortASIN(a, b)
{
	return 0;
}

/**
 *	function getSort(cat)
 *	returns the proper sort function to use with Array.sort(funciton sort).
 **/
function getSort(cat)
{
	cat=cat.toLowerCase();
	if(cat=="title")	return sortTitle;
	if(cat=="rating")	return sortRating;
	if(cat=="genre")	return sortGenre;
	if(cat=="rdate")	return sortRDate;
	if(cat=="format")	return sortFormat;
	if(cat=="studio")	return sortStudio;
	if(cat=="aspect")	return sortAspect;
	if(cat=="release")	return sortRelease;
	if(cat=="owner")	return sortOwner;
	if(cat=="pdate")	return sortPDate;
	if(cat=="asin")		return sortASIN;
	if(cat=="score")	return sortScore;
	alert("Invalid sort cat: ", cat);
	return alphaSort;
}

/**
 *	function filter(cat)
 *	Returns the HTML in the form of a string to set up drop-down menus to filter
 * 	the given category.
 **/
function filter(cat)
{
	str="<BR>";
	vals=new Array();
	if(cat=="rating")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].rating==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].rating);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION VALUE='"+vals[0]+"'>"+ratings[vals[0]]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='rating' onChange='doFilter(\"rating\",document.form.rating.value, true)'>";
			str+="<OPTION SELECTED>[>=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+ratings[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='ratingRemove' onChange='doFilter(\"rating\",document.form.ratingRemove.value, false)'>";
		str+="<OPTION SELECTED>[<=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+ratings[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="genre")
	{
		var allGenres = 0;
		for(i=0; i<movies.length; i++)
		{
			allGenres |= movies[i].genre;
		}
		for(i=0; i<bits.length; i++)
		{
			if((bits[i] & allGenres) != 0)
			{
				vals.push(i);
			}
		}

		str+="<SELECT NAME='genre' onChange='doFilter(\"genre\",document.form.genre.value, true, false)'>";
		str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+genres[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='genreDisregard' onChange='doFilter(\"genre\",document.form.genreDisregard.value, false, true)'>";
		str+="<OPTION SELECTED>[x]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+genres[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='genreRemove' onChange='doFilter(\"genre\",document.form.genreRemove.value, false, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+genres[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="rdate")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].rdate==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].rdate);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION>"+vals[0]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='rdate' onChange='doFilter(\"rdate\",document.form.rdate.value, true)'>";
			str+="<OPTION SELECTED>[>=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='rdateRemove' onChange='doFilter(\"rdate\",document.form.rdateRemove.value, false)'>";
		str+="<OPTION SELECTED>[<=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="pdate")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].pdate==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].pdate);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION>"+vals[0]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='pdate' onChange='doFilter(\"pdate\",document.form.pdate.value, true)'>";
			str+="<OPTION SELECTED>[>=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='pdateRemove' onChange='doFilter(\"pdate\",document.form.pdateRemove.value, false)'>";
		str+="<OPTION SELECTED>[<=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="format")
	{
		var allFormats = 0;
		for(i=0; i<movies.length; i++)
		{
			allFormats |= movies[i].format;
		}
		for(i=0; i<bits.length; i++)
		{
			if((bits[i] & allFormats) != 0)
			{
				vals.push(i);
			}
		}

		str+="<SELECT NAME='format' onChange='doFilter(\"format\",document.form.format.value, true, false)'>";
		str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+formats[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='formatDisregard' onChange='doFilter(\"format\",document.form.formatDisregard.value, false, true)'>";
		str+="<OPTION SELECTED>[x]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+formats[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='formatRemove' onChange='doFilter(\"format\",document.form.formatRemove.value, false, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+formats[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="aspect")
	{
		var allAspects = 0;
		for(i=0; i<movies.length; i++)
		{
			allAspects |= movies[i].aspect;
		}
		for(i=0; i<bits.length; i++)
		{
			if((bits[i] & allAspects) != 0)
			{
				vals.push(i);
			}
		}

		str+="<SELECT NAME='aspect' onChange='doFilter(\"aspect\",document.form.aspect.value, true, false)'>";
		str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+aspects[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='aspectDisregard' onChange='doFilter(\"aspect\",document.form.aspectDisregard.value, false, true)'>";
		str+="<OPTION SELECTED>[x]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+aspects[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='aspectRemove' onChange='doFilter(\"aspect\",document.form.aspectRemove.value, false, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+aspects[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="release")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].release==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].release);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION VALUE='"+vals[0]+"'>"+releases[vals[0]]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='release' onChange='doFilter(\"release\",document.form.release.value, true)'>";
			str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+releases[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='releaseRemove' onChange='doFilter(\"release\",document.form.releaseRemove.value, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+releases[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="studio")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].studio==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].studio);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION VALUE='"+vals[0]+"'>"+studios[vals[0]]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='studio' onChange='doFilter(\"studio\",document.form.studio.value, true)'>";
			str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+studios[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='studioRemove' onChange='doFilter(\"studio\",document.form.studioRemove.value, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+studios[vals[i]]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="owner")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].owner==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].owner);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION>"+vals[0]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(nameSort);
		str+="<SELECT NAME='owner' onChange='doFilter(\"owner\",document.form.owner.value, true)'>";
		str+="<OPTION SELECTED>[+]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='ownerRemove' onChange='doFilter(\"owner\",document.form.ownerRemove.value, false)'>";
		str+="<OPTION SELECTED>[-]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	if(cat=="title")
	{
		return(str);
	}
	if(cat=="asin")
	{
		return(str);
	}
	if(cat=="score")
	{
		for(i=0; i<movies.length; i++)
		{
			alreadyThere=false;
			for(j=0; j<vals.length; j++)
			{
				if(movies[i].score==vals[j])	alreadyThere=true;
			}
			if(!alreadyThere)	vals.push(movies[i].score);
		}
		if(vals.length==1)
		{
			str+="<SELECT><OPTION>"+vals[0]+"</OPTION></SELECT>";
			return str;
		}
		vals.sort(numSort);
		str+="<SELECT NAME='score' onChange='doFilter(\"score\",document.form.score.value, true)'>";
			str+="<OPTION SELECTED>[>=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		str+="<BR>";
		str+="<SELECT NAME='scoreRemove' onChange='doFilter(\"score\",document.form.scoreRemove.value, false)'>";
		str+="<OPTION SELECTED>[<=]...</OPTION>";
		for(i=0; i<vals.length; i++)
		{
			str+="<OPTION VALUE='"+vals[i]+"'>"+vals[i]+"</OPTION>";
		}
		str+="</SELECT>";
		return str;
	}
	return str+"Filter error: "+cat;
}


/**
 *	function doFilter
 *	Filters the movies array by keeping only those elements i for 
 *	which (movies[i].cat==value)==keep.
 **/
function doFilter(cat, value, keep, disregard)
{
	movies1=new Array();
	if(value=="[+]..." || value=="[-]..." || value=="[>=]..." || value == "[<=]..." || value == "[x]...")	return;
	if(cat=="rating")
	{
		i=0;
		while(i<movies.length)
		{
		if(movies[i].rating == value || (movies[i].rating >= value)==keep)	movies1.push(movies[i]);
			i++;
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="genre")
	{
		for(i=0; i<movies.length; i++)
		{
			if(disregard)
			{
				if(movies[i].genre & bits[value])
				{
					if(movies[i].genre ^ bits[value])
					{
						// Don't modify the original
						movies1.push(new Movie(
						movies[i].format,
						movies[i].studio,
						movies[i].aspect,
						movies[i].release,
						movies[i].rating,
						movies[i].genre ^ bits[value],
						movies[i].rdate,
						movies[i].owner,
						movies[i].pdate,
						movies[i].asin,
						movies[i].score,
						movies[i].title,
						movies[i].num));
					}
				}
				else
				{
					movies1.push(movies[i]);
				}
			}
			else
			{
				if(((movies[i].genre & bits[value])?true:false) == keep)
				{
					movies1.push(movies[i]);
				}
			}
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="format")
	{
		for(i=0; i<movies.length; i++)
		{
			if(disregard)
			{
				if(movies[i].format & bits[value])
				{
					if(movies[i].format ^ bits[value])
					{
						// Don't modify the original
						movies1.push(new Movie(
						movies[i].format ^ bits[value],
						movies[i].studio,
						movies[i].aspect,
						movies[i].release,
						movies[i].rating,
						movies[i].genre,
						movies[i].rdate,
						movies[i].owner,
						movies[i].pdate,
						movies[i].asin,
						movies[i].score,
						movies[i].title,
						movies[i].num));
					}
				}
				else
				{
					movies1.push(movies[i]);
				}
			}
			else
			{
				if(((movies[i].format & bits[value])?true:false) == keep)
				{
					movies1.push(movies[i]);
				}
			}
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="aspect")
	{
		for(i=0; i<movies.length; i++)
		{
			if(disregard)
			{
				if(movies[i].aspect & bits[value])
				{
					if(movies[i].aspect ^ bits[value])
					{
						// Don't modify the original
						movies1.push(new Movie(
						movies[i].format,
						movies[i].studio,
						movies[i].aspect ^ bits[value],
						movies[i].release,
						movies[i].rating,
						movies[i].genre,
						movies[i].rdate,
						movies[i].owner,
						movies[i].pdate,
						movies[i].asin,
						movies[i].score,
						movies[i].title,
						movies[i].num));
					}
				}
				else
				{
					movies1.push(movies[i]);
				}
			}
			else
			{
				if(((movies[i].aspect & bits[value])?true:false) == keep)
				{
					movies1.push(movies[i]);
				}
			}
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="studio")
	{
		for(i=0; i<movies.length; i++)
		{
			if((movies[i].studio == value)==keep)	movies1.push(movies[i]);
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="release")
	{
		for(i=0; i<movies.length; i++)
		{
			if((movies[i].release == value)==keep)	movies1.push(movies[i]);
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="rdate")
	{
		i=0;
		while(i<movies.length)
		{
			if((movies[i].rdate == value) || (movies[i].rdate > value)==keep)	movies1.push(movies[i]);
			i++;
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="pdate")
	{
		i=0;
		while(i<movies.length)
		{
			if((movies[i].pdate == value) || (movies[i].pdate > value)==keep)	movies1.push(movies[i]);
			i++;
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="score")
	{
		i=0;
		while(i<movies.length)
		{
			if((movies[i].score == value) || (movies[i].score > value)==keep)	movies1.push(movies[i]);
			i++;
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="owner")
	{
		i=0;
		while(i<movies.length)
		{
			if((movies[i].owner == value)==keep)	movies1.push(movies[i]);
			i++;
		}
		movies=movies1;
		displayBy(null);
		return;
	}
	if(cat=="asin")
	{
		displayBy(null);
		return;
	}
	alert("Cannot filter by: "+cat+" : "+value);
	return;
}

/**
 *	function displayBy
 *	Updates the web page to reflect the movies array, sorts by cat element
 **/
function displayBy(cat)
{
	document.getElementById("main").innerHTML=makeTable(movies, cat);
}

/**
 *	funciton restore
 *	Restores the movies Array to its original form.
 **/
function restore()
{
	for(i=0; i<movies0.length; i++)
	{
		movies[i]=movies0[i];
	}
	displayBy("title");
}

