var superOptions = {};

var MediaTypes = {
	newReleases: {
		name: "New Releases",
		directory: "music/",
		suffix: "newreleases-enhanced.inc",
		genres: new Hash({
			all: { name: "New Music Releases", link: "http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewNewReleases?fcId=290055898&genreIdString=34&mediaTypeString=Music" }
		})
	},
	
	music: {
		name: "Music",
		directory: "music/",
		suffix: "topsongs-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Songs", link:"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=1&popId=1" },
			alternative: { name: "Alternative", link: 20 },
			blues: { name: "Blues", link: 2 },
			childrensmusic: { name: "Children’s Music", link: 4 },
			classical: { name: "Classical", link: 5 },
			country: { name: "Country", link: 6 },
			dance: { name: "Dance", link: 17 },
			electronic: { name: "Electronic", link: 7 },
			folk: { name: "Folk", link: 10 },
			hiphoprap: { name: "Hip-Hop/Rap", link: 18 },
			jazz: { name: "Jazz", link: 11 },
			latinjazz: { name: "Latin", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/iTunesLatino" },
			newage: { name: "New Age", link: 13 },
			pop: { name: "Pop", link: 14 },
			rbsoul: { name: "R&B/Soul", link: 15 },
			rock: { name: "Rock", link: 21 },
			soundtrack: { name: "Soundtrack", link: 16 },
			vocal: { name: "Vocal", link: 23 },
			world: { name: "World", link: 19 }
		})
	},
			
	albums: {
		name: "Albums",
		directory: "music/",
		suffix: "topalbums-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=1&popId=11" },
			alternative: { name: "Alternative Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=21&popId=11" },
			blues: { name: "Blues Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=2&popId=11" },
			childrensmusic: { name: "Children’s Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=4&popId=11" },
			classical: { name: "Classical Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=5&popId=11" },
			country: { name: "Country Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=6&popId=11" },
			dance: { name: "Dance Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=18&popId=11" },
			electronic: { name: "Electronic Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=7&popId=11" },
			folk: { name: "Folk Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=11&popId=11" },
			hiphoprap: { name: "Hip-Hop/Rap Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=19&popId=11" },
			jazz: { name: "Jazz Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=12&popId=11" },
			latinjazz: { name: "Latin Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=13&popId=11" },
			newage: { name: "New Age Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=14&popId=11" },
			pop: { name: "Pop Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=15&popId=11" },
			rbsoul: { name: "R&B/Soul Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=16&popId=11" },
			rock: { name: "Rock Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=24&popId=11" },
			soundtrack: { name: "Soundtrack Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=17&popId=11" },
			vocal: { name: "Vocal Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=26&popId=11" },
			world: { name: "World Albums", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=20&popId=11" }
		})
	},
			
	movies: {
		name: "Movies",
		directory: "movies/",
		suffix: "topmovies-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Films", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=39&popId=15" },
			actionadventure: { name: "Action/Adventure", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=203632744&id=39" },
			classics: { name: "Classics", link: null },
			comedy: { name: "Comedy", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=190873060&id=39" },
			documentary: { name: "Documentary", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=253262688&id=39" },
			drama: { name: "Drama", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=190873058&id=39" },
			holiday: { name: "Holiday", link: null },
			horror: { name: "Horror", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=253262943&id=39" },
			independent: { name: "Indie", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=218375737&id=39" },
			kidsfamily: { name: "Kids/Family", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=190873059&id=39" },
			music: { name: "Music", link: null },
			romance: { name: "Romance", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=253261976&id=39" },
			scififantasy: { name: "Sci-fi/Fantasy", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=212719717&id=39" },
			shortfilms: { name: "Shorts", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewCustomPage?name=pageShorts" },
			sports: { name: "Sports", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=208744051&id=39" },
			thriller: { name: "Thriller", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=250390412&id=39" },
			urban: { name: "Urban", link: null },
			western: { name: "Western", link: null }
		})
	},
			
	tvshows: {
		name: "TV Shows",
		directory: "tvshows/",
		suffix: "toptvepisodes-enhanced.inc",
		genres: new Hash({
			all: { name: "Top TV Shows", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=37&popId=4" },
			actionadventure: { name: "Action/Adventure", link: null },
			classic: { name: "Classic", link: null },
			comedy: { name: "Comedy", link: 4000 },
			drama: { name: "Drama", link: 4001 },
			kids: { name: "Kid’s", link: 4005 },
			nonfiction: { name: "Nonfiction", link: 4006 },
			realitytv: { name: "Reality", link: 4007 },
			scififantasy: { name: "Sci-fi/Fantasy", link: 4008 },
			sports: { name: "Sports", link: 4009 },
			teens: { name: "Teen’s", link: 4010 }
		})
	},
		
	audiobooks: {
		name: "Audiobooks",
		directory: "audiobooks/",
		suffix: "topaudiobooks-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Audiobooks", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=28&popId=8" },
			artsentertainment: { name: "Arts & Entertainment", link: 50000041 },
			audiobooksinspanish: { name: "En Español", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewGrouping?id=25008" },
			biographymemoir: { name: "Biography/Memoirs", link: 50000042 },
			business: { name: "Business", link: 50000043 },
			classics: { name: "Classics", link: 50000045 },
			comedy: { name: "Comedy", link: 50000046 },
			dramapoetry: { name: "Drama/Poetry", link: 50000047 },
			fiction: { name: "Fiction", link: 50000040 },
			history: { name: "History", link: 50000049 },
			kidsyoungadults: { name: "Kids/Young Adults", link: 50000044 },
			languages: { name: "Languages", link: 50000050 },
			mystery: { name: "Mystery", link: 50000051 },
			news: { name: "News", link: 74 },
			nonfiction: { name: "Nonfiction", link: 50000052 },
			religionspirituality: { name: "Religion/Spirituality", link: 50000053 },
			romance: { name: "Romance", link: 50000069 },
			science: { name: "Science", link: 50000054 },
			scififantasy: { name: "Sci-fi/Fantasy", link: 50000055 },
			selfdevelopment: { name: "Self-Development", link: 50000056 },
			showsperiodicals: { name: "Shows Periodical", link: 75 },
			speakersstorytellers: { name: "Speaker/Story Tellers", link: 50000048 },
			sports: { name: "Sports", link: 50000057 },
			technology: { name: "Technology", link: 50000058 },
			traveladventure: { name: "Travel/Adventure", link: 50000059 }
		})
	},
			
	podcasts: {
		name: "Podcasts",
		directory: "podcasts/",
		suffix: "toppodcasts-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Podcasts", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=33&popId=3" },
			arts: { name: "Arts", link: 1301 },
			business: { name: "Business", link: 1321 },
			comedy: { name: "Comedy", link: 1303 },
			education: { name: "Education", link: 1304 },
			gameshobbies: { name: "Games/Hobbies", link: 1323 },
			governmentorganizations: { name: "Government", link: 1325 },
			health: { name: "Health", link: 1307 },
			kidsfamily: { name: "Kids/Family", link: 1305 },
			music: { name: "Music", link: 1310 },
			newspolitics: { name: "News/Politics", link: 1311 },
			religionspirituality: { name: "Religion/Spirituality", link: 1314 },
			sciencemedicine: { name: "Science/Medicine", link: 1315 },
			societyculture: { name: "Society/Culture", link: 1324 },
			sportsrecreation: { name: "Sports/Recreation", link: 1316 },
			technology: { name: "Technology", link: 1318 },
			tvfilm: { name: "TV/Film", link: 1309 }
		})
	},
		
	topapps: {
		name: "App Store",
		directory: "topapps/",
		suffix: "topapplications-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Apps", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewGenre?id=36&mt=8" },
			business: { name: "Business", link: 6000 },
			weather: { name: "Weather", link: 6001 },
			utilities: { name: "Utilities", link: 6002 },
			travel: { name: "Travel", link: 6003 },
			sports: { name: "Sports", link: 6004 },
			socialnetworking: { name: "Social Networking", link: 6005 },
			reference: { name: "Reference", link: 6006 },
			productivity: { name: "Productivity", link: 6007 },
			photography: { name: "Photography", link: 6008 },
			news: { name: "News", link: 6019 },
			navigation: { name: "Navigation", link: 6010 },
			music: { name: "Music", link: 6011 },
			lifestyle: { name: "Lifestyle", link: 6012 },
			healthcarefitness: { name: "Healthcare & Fitness", link: 6013 },
			games: { name: "Games", link: 6014 },
			finance: { name: "Finance", link: 6015 },
			entertainment: { name: "Entertainment", link: 6016 },
			education: { name: "Education", link: 6017 },
			books: { name: "Books", link: 6018 }
		})
	},

	toppaidapps: {
		name: "App Store",
		directory: "topapps/",
		suffix: "toppaidapplications-enhanced.inc",
		genres: new Hash({
			all: { name: "Top Paid Apps", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTop?id=25204&popId=30" }
		})
	},

	newapps: {
		name: "App Store",
		directory: "topapps/",
		suffix: "newapplications-enhanced.inc",
		genres: new Hash({
			all: { name: "New Apps", link: "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewRoom?fcId=285114016&genreIdString=36&mediaTypeString=Mobile+Software+Applications" }
		})
	}
			
};



var iTunesModuleSection = {

	topLists: function() {
		var lists = this.content.select('.toplist');
		lists.each(this.topList.bind(this));
	},

	topList: function(list, i) {
		var media = list.id.replace(/-.*/, '');
		var genre = (list.className.match(/genre-/)) ? list.className.match(/.*genre-([^ ]*).*/)[1] : null;
		var cookie = (list.className.match('nopref')) ? null : list.id.replace('-toplist', '');
		
		var options = Object.extend({}, superOptions);
		options.defaultMedia = media;
		options.defaultGenre = genre;
		options.cookieId = cookie;

		var topList = new TopList(list.id, options);
	}

};

var iTunesModuleDelegate = {

	willShow: function(view, outgoing, incoming) {
		if (outgoing) {
			outgoing.triggers().each(function(trigger) {
				var item = trigger.up('li');
				if (item) item.removeClassName('active');
			});
		}

		if (incoming) {
			incoming.triggers();
			incoming.content.show();
			incoming.triggers().each(function(trigger) {
				var item = trigger.up('li');
				if (item) item.addClassName('active');
			});
		}
	},

	extendSection: function(view, outgoing, incoming) {
		if (!incoming.topLists) {
			Object.extend(incoming, iTunesModuleSection);
			incoming.topLists();
		}
	},

	didShow: function(view, outgoing, incoming) {
		this.willShow(view, outgoing, incoming);
		this.extendSection(view, outgoing, incoming);
		
		this.didShow = this.extendSection;
	}

};

var iTunesModule = Class.create({

	initialize: function(contents, view, triggerClassName, options) {
		var trigger = $$('.'+triggerClassName);
		trigger[0].up('ul').style.display = 'block';
		
		//For IE we need to remove this node before swap view takes over
		//because swap view's innerHTML = '', breaks the splash
		if (Object.isArray(contents)) {
			contents[0].remove();
			document.body.appendChild(contents[0].hide());
		} else if (Object.isElement(contents)) {
			contents = contents.remove();
			document.body.appendChild(contents.hide());
		}

		superOptions = options || {};
		if (superOptions.initialSection) superOptions.initialId = 'itunesmodule-'+superOptions.initialSection;
		if (!superOptions.initialId) superOptions.initialId = 'itunesmodule-music';
		if (!superOptions.shouldAnimateContentChange) superOptions.shouldAnimateContentChange = false;
		if (!superOptions.silentTriggers) superOptions.silentTriggers = true;

		var viewer = new AC.ViewMaster.Viewer(null, view, triggerClassName, superOptions);
		viewer.setDelegate(iTunesModuleDelegate);

	}

});





var TopList = Class.create({

	rootChartPath: window.location.protocol+"//"+window.location.host+'/itunescharts/',
	countryPath: 'ireland/',

	orderedMediaTypes: ['music','movies','tvshows','audiobooks','podcasts','appstore'],

	container: null,
	preferencePanel: null,
	populated: false,
	isCustomized: false,

	initialize: function(container, options) {
		this.container = $(container);
		this.options = options || {};
		
		this.listing = new Element('ul');
		
		var existingListing = this.container.down('.listing');
		if (existingListing) {
			this.listing = existingListing;
			this.populated = true;
		} else {
			this.container.appendChild(this.listing);
		}
		
		this.storeLink = this.container.down('.storelink');
		if (!this.storeLink) {
			this.storeLink = $(document.createElement('a'));
			this.storeLink.setAttribute('href', 'http://phobos.apple.com/WebObjects/MZStore.woa/wa/storeFront');
			this.storeLink.addClassName('storelink');
			this.storeLink.innerHTML = 'View All';
			this.container.appendChild(this.storeLink);
		}
		
		if (this.options.cookieId) {
			this.provideConfigurationTrigger();
		}
		
		this.getInitialConfiguration();
		
		this.render();
	},
	
	provideConfigurationTrigger: function() {
		
		var configureTrigger = $(document.createElement('a'));
		configureTrigger.innerHTML = 'Edit';
		configureTrigger.addClassName('configure-trigger');
		
		configureTrigger.observe('click', function(evt) {
			Event.stop(evt);
			this.showPreferences();
		}.bind(this));
		
		this.container.appendChild(configureTrigger);
		configureTrigger = null;
	},
	
	getInitialConfiguration: function() {
		
		var loadConfiguration = function(cookieId) {
			
			var cookies = document.cookie.split(';');
			
			var foundCookie = null;
			
			for (var i = 0; i < cookies.length; i++) {
				var foundCookie = cookies[i].match('topLists');
				if (foundCookie) {
					var values = cookies[i].toQueryParams();
					
					var media = values[cookieId + '-media'];
					var genre = values[cookieId + '-genre'];
					
					if (media && genre) {
						//toplists cookie had configuration for this list
						return {media: media, genre: genre};
					} else {
						//cookie found, but no configuration for this list
						return null;
					}
				}
			}
		}
		
		var media = this.options.defaultMedia || 'music';
		var genre = this.options.defaultGenre || 'all';
		
		if (this.options.cookieId) {
			var savedConfig = loadConfiguration(this.options.cookieId);
			if(savedConfig) {
				this.isCustomized = true;
				media = savedConfig.media;
				genre = savedConfig.genre;
			}
		}
		
		
		this.setScope(media, genre);
	},
	
	providePreferences: function() {
		
		if (!this.preferencePanel) {
			
			this.preferencePanel = $(document.createElement('div'));
			this.preferencePanel.addClassName('preferences');
			
			var genreSelector = Builder.node('select', { 'class':'genres', 'size':this.options.genreSelectSize || 15 })
			
			var preferenceForm = $(document.createElement('form'));
			this.updateGenreSelector(genreSelector, this.currentMedia);
			preferenceForm.appendChild(genreSelector);
			
			var submit = $(document.createElement('input'));
			submit.setAttribute('type', 'submit');
			submit.addClassName('submit');
			submit.setAttribute('value', 'Done');
			preferenceForm.appendChild(submit);
			
			preferenceForm.observe('submit', function(evt) {
				Event.stop(evt);

				var selects = preferenceForm.getElementsByTagName('select');
				var genre = selects[0].value;
				
				if (genre == '') {
					return;
				}
				
				var changed = this.setScope(this.currentMedia, genre, true);
				this.hidePreferences();
				if (changed) {
					this.render(true);
				}

			}.bind(this));
			
			this.preferencePanel.appendChild(preferenceForm);
		
			this.container.appendChild(this.preferencePanel);
		}
	},
	
	updateGenreSelector: function(selector, media) {
		selector.innerHTML = '';
		
		var genres = MediaTypes[media].genres;
		genres.each(function(genre, i) {
			var prefix = genre[0];
			var name = genre[1].name;
			
			var genreOption = Builder.node('option', { value:prefix }, name);
			if (this.currentGenre == prefix) genreOption.selected = true;

			selector.appendChild(genreOption);
		}.bind(this));
	},
	
	setScope: function(media, genre, save) {
		
		if (media == this.currentMedia && genre == this.currentGenre) {
			return false;
		}

		var saveConfiguration = function(cookieId, media, genre) {
			var d = new Date();
			var expires = 360 * 1000 * 60 * 60 * 24; // 360 days
			var expiresDate = new Date(d.getTime() + (expires));
			
			
			//Write to existing cookie if possible
			var cookies = document.cookie.split(';');
			

			
			var foundCookie = null;
			
			for (var i = 0; i < cookies.length; i++) {
				if (cookies[i].match('topLists')) {
					foundCookie = cookies[i];
				}
			}

			var values = {};
			if (foundCookie) {
				values = foundCookie.toQueryParams();
			}
			
			//create or update entries for this cookie
			values[cookieId + '-media'] = escape(media);
			values[cookieId + '-genre'] = escape(genre);
			
			var cookieData = '';
			for (var key in values) {
				cookieData += key + '=' + values[key] + '&';
			}
			cookieData = cookieData.replace(/&$/, ''); //remove trailing &
			
			document.cookie = 'topLists=?' + cookieData + ';expires=' + expiresDate.toGMTString() +';path=/';
		}
		
		this.currentMedia = media;
		this.currentGenre = genre;
		
		this.updateGenreHeading();
		
		
		if (save && this.options.cookieId) {
			saveConfiguration(this.options.cookieId, this.currentMedia, this.currentGenre);
		}
		
		
		return true;
	},
	
	updateGenreHeading: function() {
		var current = MediaTypes[this.currentMedia].genres.get(this.currentGenre);

		var genreName = current.name;

		var link = current.link;
		if (typeof(link) == 'number') {
			link = 'http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewGenre?id=' + current.link;
		} else if(link === null || typeof(link) == 'undefined') {
			link = 'http://phobos.apple.com/WebObjects/MZStore.woa/wa/storeFront';
		}
		this.storeLink.setAttribute('href', link);

		var genreHeading = this.container.down('.title');
		var truncate = this.options.titleTruncation || 16;
		genreHeading.innerHTML = genreName.truncate(truncate);
	},
	
	hidePreferences: function() {
		this.listing.show();
		this.preferencePanel.hide();
	},
	
	showPreferences: function() {
		this.listing.hide();
		this.providePreferences();
		this.preferencePanel.show();
	},
	
	render: function(forced) {
		
		if (!forced && (this.populated && !this.isCustomized)) {
			//ensure static content is truncated the same as dynamic content
			this.truncateResults();
			return;
		}
		
		this.listing.innerHTML = '';
		
		var display = function(response) {
			this.listing.innerHTML = response.responseText;
			this.truncateResults();
		};
		
		var media = MediaTypes[this.currentMedia];
		
		var url = this.rootChartPath +				// itunescharts/
				this.countryPath + 					// us/
				media.directory + 					// audiobooks/
				this.currentGenre +					// all
				(this.options.resultCount || 5) + 	// 5
				media.suffix;						// topaudiobooks-enhanced.inc
				
		var listingRequest = new Ajax.Request(url, { 
			method: 'get', 
			onSuccess: display.bind(this) });
		},
		
		getTruncationLength: function(element, text) {
			// fixed width of column for testing character limit
			truncWidth = this.options.itunesLanding ? 138 : 128;
				
			var inSpan = document.createElement('span');
			// set same styles as the element for accurate width assessment
			Element.setStyle(inSpan, {
				whiteSpace: 'nowrap',
				fontWeight:'bold'				
			})
			
			// unescape HTML to avoid partial enteties (&amp...)
			var textNode = document.createTextNode(text);
			inSpan.appendChild(textNode);
			element.appendChild(inSpan);

			// if full text width is greater than allowed column width, remove
			// character 1 at a time until it meets the allowed width
			if(inSpan.offsetWidth > truncWidth) {
				while(inSpan.offsetWidth > truncWidth) {
					textNode.deleteData(textNode.length-1,1);
				}
			}
			Element.remove(inSpan);
			
			// return the calculated amount of characters allowed for element
			return textNode.length;
		},

		truncateResults: function() {
			var items = this.listing.select('li>a');
			items.each(function(item, i) {
				var title = item.down('strong');
				
				if (title) {
					// unescape HTML to avoid partial enteties ("&amp...")
					var textData = title.innerHTML.unescapeHTML(),
						truncLength = this.getTruncationLength(item, textData);
					title.innerHTML = title.innerHTML.unescapeHTML().truncate(truncLength);
				}
				var subtitle = item.down('span');
				if (subtitle) subtitle.innerHTML = subtitle.innerHTML.truncate(24);
			}.bind(this));
		}

	})
