/* jslint verified 2009.01.20 */
/*jslint browser: true, onevar: true, undef: true, white: false, eqeqeq: true */

var Song = function (id, song, isStem, style) {
	function buildImagePath(name) {
		return 'http://community.mixmatchmusic.com/images/index/' + name + ((style === Song.style.large) ? 'Large' : '') + '.20081023.gif';
	}
	var expandOptions, optionsHolder, pinLink, playIcon, featureLink, radioLink,
		playIconSrc = buildImagePath('playIcon'), stopIconSrc = buildImagePath('stopIcon'),
		loadingIconSrc = buildImagePath('playIconLoading'), playerName = 'smallPlayerHidden',
		classes = {
			song: 'song', stem: 'stem', expandOptions: 'expandOptions', contractOptions: 'contractOptions',
			optionsHolder: 'optionsHolder', optionsSpacer: 'optionsSpacer', avatar: 'songAvatar',
			info: 'songInfo', author: 'songAuthor', mixLink: 'mixLink', purchaseLink: 'purchaseLink',
			playLink: 'playLink', infoHolder: 'infoHolder', stats: 'stats', statHolder: 'statHolder',
			statLabel: 'statLabel', statValue: 'statValue', spacer: 'songSpacer'
		}, msgs = {
			menu: 'menu', profile: 'View profile', comment: 'Comment on this', pin: 'Pin for palette',
			unpin: 'Un-Pin from palette', tree: 'View family tree',
			mix: 'Load this in the MixMaker', mixSequencer: 'Load into your session', mixAlt: 'Mix',
			mixAltSequencer: 'Load', purchase: 'Add to cart', purchaseAlt: 'Buy', purchaseAnon: 'Buy now!'
		};

	function setupDom() {
		if (isStem !== true && isStem !== false) { isStem = song.type === 'stem'; }
		var holderDom = document.createElement('div');
		$(holderDom).addClass(isStem ? classes.stem : classes.song, 'clearfix');
		buildExpandableOptions(holderDom);
		buildAvatar(holderDom);
		buildInfo(holderDom);
		buildIcons(holderDom);
		if (style === Song.style.large) {
			buildSongInfo(holderDom);
			buildSpacer(holderDom);
		}
		if (isStem && style !== Song.style.featured)	{ buildStemInfo(holderDom); }
		if (style === Song.style.featured)				{ $(holderDom).addClass(Song.style.featured); }
		preload();
		holderDom.mmmid = id;
		return holderDom;
	}

	function buildExpandableOptions(holderDom) {
		expandOptions = document.createElement('div');
		$(expandOptions).addClass(classes.expandOptions).text(msgs.menu).click(toggleOptions);
		expandOptions.toggle = toggleOptions;
		expandOptions.showing = false;
		optionsHolder = document.createElement('div');
		$(optionsHolder).addClass(classes.optionsHolder);
		buildOptions(optionsHolder);

		$(holderDom).append(expandOptions).append(optionsHolder);
	}

	function buildOptions(optionsHolder) {
		var profileHref = 'http://community.mixmatchmusic.com/profiles/~' + id;
		$(optionsHolder).append(buildLink(msgs.profile, profileHref)).append(buildLink(msgs.comment, profileHref + "#commentboard"));
	}

	function buildLink(name, href) {
		var a = document.createElement('a');
		$(a).text(name).attr('href', href);
		return a;
	}

	function buildAvatar(holderDom) {
		var img = document.createElement('img');
		img.src = 'http://community.mixmatchmusic.com/viewProfilePic?id=' + id + '&type=thumb';
		img.setAttribute('width', (style === Song.style.large) ? 65 : 34);
		$(img).addClass(classes.avatar);
		img.removeAttribute('height');
		$(holderDom).append(img);
	}
	function buildInfo(holderDom) {
		var infoHolder = document.createElement('div'),
			h4 = document.createElement('h4'),
			author = document.createElement('div'),
			authorLink = buildLink(song.un, 'http://community.mixmatchmusic.com/user/' + song.un);
		$(authorLink).addClass('link_atuser');
		$(author).addClass(classes.author).text('by ').append(authorLink);
		$(infoHolder).addClass(classes.info).append(h4).append(author);
		$(h4).append(buildLink(song.name, 'http://community.mixmatchmusic.com/profiles/~' + id));
		$(holderDom).append(infoHolder);
	}
	function buildIcons(holderDom) {
		var mixLink, mixIcon = document.createElement('img'),
			purchaseLink, purchaseIcon = document.createElement('img');
		if (song.canseq) {
			mixLink = document.createElement('a');
			$(mixLink).addClass(classes.mixLink).attr('href', 'http://community.mixmatchmusic.com/sequencer?id=' + id);
			mixIcon.src = buildImagePath('mixIcon');
			$(mixIcon).attr('alt', msgs.mixAlt).attr('title', msgs.mix);
			$(mixLink).append(mixIcon);
			$(holderDom).append(mixLink);
		} else {
			$(mixIcon).addClass(classes.mixLink).attr('src', buildImagePath('mixIconSad'));
			$(holderDom).append(mixIcon);
		}

		function buildBuyIcon(logged) {
			purchaseLink = document.createElement('a');
			$(purchaseLink).addClass(classes.purchaseLink).attr('href', 'http://community.mixmatchmusic.com/buy/' + id);
			$(purchaseIcon).
				attr('src', buildImagePath('purchaseIcon')).
				attr('alt', msgs.purchaseAlt).
				attr('title', msgs.purchaseAnon);
			$(purchaseLink).append(purchaseIcon);
			$(holderDom).append(purchaseLink);
		}
		buildBuyIcon(false);

		playIcon = document.createElement('img');
		$(playIcon).addClass(classes.playLink);
		if (song.canplay) {
			playIcon.src = buildImagePath('playIcon');
			playIcon.playing = false;
			$(playIcon).click(playPause);
		} else {
			$(playIcon).addClass('arrow').attr('src', buildImagePath('playIconSad'));
		}
		$(holderDom).append(playIcon);
	}

	function playPause() {
		if (playIcon.playing) {
			stop();
		} else {
			play();
		}
	}

	function play() {
		$(playIcon).attr('alt', 'Loading...').attr('title', 'Loading...').attr('src', loadingIconSrc);
		Flash.update(playerName);
		Flash.update(playerName, id);
		Flash.play(playerName);
		Flash.setPlayingCallback(playing);
		Flash.setCallback(stop);
		playIcon.playing = true;
	}

	function playing() {
		$(playIcon).attr('alt', 'Stop').attr('title', 'Stop').attr('src', stopIconSrc);
	}

	function stop() {
		$(playIcon).attr('alt', 'Play').attr('title', 'Play').attr('src', playIconSrc);
		Flash.stop(playerName);
		Flash.update(playerName);
		Flash.update(playerName, id);
		playIcon.playing = false;
	}

	function toggleOptions(e) {
		cancelBubble(e);
		if (!expandOptions.showing) {
			$(optionsHolder).show();
			optionsHolder.style.zIndex = '1000';
			optionsHolder.parentNode.style.zIndex = '1000';	// needed for IE z-index bug
			$(expandOptions).addClass(classes.contractOptions);
			expandOptions.style.zIndex = '1001';
		} else {
			$(optionsHolder).hide();
			optionsHolder.style.zIndex = '';
			optionsHolder.parentNode.style.zIndex = '';
			$(expandOptions).removeClass(classes.contractOptions);
			expandOptions.style.zIndex = '';
		}
		expandOptions.showing = !expandOptions.showing;
	}

	function buildSongInfo(holderDom) {
		var stats = document.createElement('div'),
			i,
			attribs = (isStem) ? 
				[['plays','numplays'],['attributions','numattributions'],['date published', 'date']] :
				[['plays','numplays'],['date created', 'date']];
		$(stats).addClass(classes.stats);
		for (i=0; i<attribs.length; ++i) {
			$(stats).append(buildStat(attribs[i][0], song[attribs[i][1]]));
		}
		$(holderDom).append(stats);
	}

	function buildStat(label, value) {
		var statHolder = document.createElement('div');
		$(statHolder).addClass('classes.statHolder clearfix');
		var statLabel = document.createElement('div');
		$(statLabel).addClass(classes.statLabel).text(label + ':');
		var statValue = document.createElement('div');
		$(statValue).addClass(classes.statValue).text(value);
		$(statHolder).append(statLabel).append(statValue);
		return statHolder;
	}

	function buildSpacer(holderDom) {
		var spacer = document.createElement('div');
		$(spacer).addClass(classes.spacer).text(' ');
		$(holderDom).append(spacer);
	}

	function buildStemInfo(holderDom) {
		var attribs = [['key','key'],['tempo','tempo'],['genre','genre'],['inst','instrument']],
			details = [], i;
		for (i=0; i<attribs.length; i++) {
			if (song[attribs[i][1]]) {
				details.push(buildStemDetail(attribs[i][0], song[attribs[i][1]]));
			}
		}
		if (details.length > 0) {
			var infoHolder = document.createElement('div');
			$(infoHolder).addClass(classes.infoHolder).html(details.join(', '));
			$(holderDom).append(infoHolder);
		}
	}

	function buildStemDetail(type, value) {
		return '<strong>' + type + '</strong> - ' + value;
	}

	function preload() {
		var paths = [buildImagePath('playIcon'), buildImagePath('stopIcon'), buildImagePath('playIconLoading')], i, img;
		for (i=0; i<paths.length; i++) {
			img = new Image();
			img.src = paths[i];
		}
	}

	return setupDom();
};
Song.style = {small: 'small', large: 'large', featured: 'featured'};
