/**
 *  Pre-Order call
 */
function preSaleOmniLinkCall()
{
	omniLinkCall('this', 'preorder_link_click');
	loadCommerceBox();
}

/**
 *	Create EA namepsace
 */
var EA = {};

/**
 *  Global Calls
 */
(function()
{
	/**
	*  Fix IE background image flicker
	*  http://www.mister-pixel.com/
	*/
	try
	{
	document.execCommand('BackgroundImageCache', false, true);
	}
	catch(e) {}
	
	/**
	 *  String methods (from Prototype JS framework)
	 */
	String.implement({
        stripTags: function()
        {
            return this.replace(/<\/?[^>]+>/gi, '');
        },
        
        escapeHTML: function()
        {
            var self = arguments.callee;
            self.text.data = this;
            return self.div.innerHTML;
        },
        
        unescapeHTML: function()
        {
            var div = new Element('div');
            div.innerHTML = this.stripTags();
            return div.childNodes[0] ? (div.childNodes.length > 1 ? 
            $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
            div.childNodes[0].nodeValue) : '';
        }
    });
})();

/**
 * 
 * 
 * remove extra space if required
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 *	EA.DantesInferno
 */
EA.DantesInferno = {
    // set site wide variables
    _territoryGateCookieName: 'di_lang',
    _territoryGateLocationCookieName: 'di_location',
    _ageGateCookieName: 'di_birthdate',
    _gateContentUrl: '/'+regionLocator+'/gate.html',
    
    _videoCarouselDataUrl: '/'+regionLocator+videoJsonFeedURL,
	_imageSlideShowDataUrl: '/'+regionLocator+'/media!jsonimages',
	_wallpaperCarouselDataUrl: '/'+regionLocator+'/media!jsonwallpapers',
	_buddyIconCarouselDataUrl: '/'+regionLocator+'/media!jsonbuddyicons',
	_iPhoneCarouselDataUrl: '/'+regionLocator+'/media!jsoniphoneskins',
	_socialSkinDataUrl: '/'+regionLocator+'/media!jsonsocialnetworkskins',
	_screenSaverCarouselDataUrl: '/'+regionLocator+'/media!jsonscreensavers',
	_goToHellDataUrl: 'http://gotohell.dantesinferno.com/souls.aspx',
	_mediaDataUrl: '/'+regionLocator+'/media!jsonsearchmedia',
	_commentDataUrl: '',
	
	_rateContentUrl: '/'+regionLocator+'/rate.html',
	_shareContentUrl: '/'+regionLocator+'/share.html',
	_commentContentUrl: '/'+regionLocator+'/comment.html',
	_flagContentUrl: '/'+regionLocator+'/flag.html',
	_newsletterContentUrl: '/'+regionLocator+'/newsletter.html',
	_newsletterAPIUrl: '/ajaxservlet!index',
	
	init: function()
	{
		// newsletter sign up (needs to go before territory/age gate init b/c of birthdate requirement)
		var newsletter = $('newsletterSignup');
		if (newsletter) new EA.DantesInferno.Newsletter(newsletter, this._newsletterContentUrl, this._newsletterAPIUrl);
		
		// latest newsletter lightbox
		var latestNewsletter = $('newsletterLatest');
		if (latestNewsletter) latestNewsletter.addEvent('click', function(event){
			if(event) event.preventDefault();
			
			Shadowbox.open({
				'content': this.href,
				'player': 'img',
				'handleOversize': 'drag'
			});
			
			return false;
		}.bind(latestNewsletter));
		
		// sound control
	    new EA.DantesInferno.Sound();
		
		// territory/age gate
		new EA.DantesInferno.Gate(this._gateContentUrl, this._territoryGateCookieName, this._territoryGateLocationCookieName, this._ageGateCookieName);
		
		// theme/circle switcher
		var themeSwitcher = $('themeSwitcher');
		if (themeSwitcher) new EA.DantesInferno.ThemeSwitcher(themeSwitcher.getElement('.themeOptions'));		
		
		// main nav
		new EA.DantesInferno.Nav($('header').getElement('ul'));
		
        // home page smoke
		var smoke = $('smoke');
        if (smoke) new Swiff('/flash/head.swf', {id: 'head', container: 'smoke', width: 960, height: 200, params: {wmode: 'transparent', loop: (Browser.Engine.trident && Browser.Engine.version < 5) ? 'false' : 'true', allowscriptaccess: 'sameDomain', allowfullscreen: 'false'}});
        
        // preorder callout
        var preorder = $('preorder');
		if(preorder) this.preOrderLoader = new EA.DantesInferno.PreOrderLoader();
		
		// user generated (rate, comment view/entry, flag, share, download)
		new EA.DantesInferno.UserGenerated(this._rateContentUrl, this._commentDataUrl, this._commentContentUrl, this._flagContentUrl, this._shareContentUrl, this._territoryGateCookieName);
		
		// video carousel
		var videoCarousel = $('videoCarousel');
		if (videoCarousel) new EA.DantesInferno.VideoCarousel(videoCarousel, this._videoCarouselDataUrl);
		
		// image slideshow
		var imageSlideShow = $('imageCarousel');
		if (imageSlideShow) new EA.DantesInferno.ImageSlideShow(imageSlideShow, $('imagePlayer'), this._imageSlideShowDataUrl);
		
		// Go to Hell Facebook module
		var gotohellText = $('goToHellCount');
		if (gotohellText) new EA.DantesInferno.GoToHellFeed(gotohellText, this._goToHellDataUrl);
		
		// wallpaper carousel
		var wallpaperCarousel = $('wallpaperCarousel');
		if (wallpaperCarousel) new EA.DantesInferno.WallpaperCarousel(wallpaperCarousel, this._wallpaperCarouselDataUrl);
		
		// buddy icon carousel
		var buddyIconCarousel = $('buddyIconCarousel');
		if (buddyIconCarousel) new EA.DantesInferno.BuddyIconCarousel(buddyIconCarousel, this._buddyIconCarouselDataUrl);
		
		// iphone carousel
		var iPhoneCarousel = $('iPhoneCarousel');
		if (iPhoneCarousel) new EA.DantesInferno.IPhoneCarousel(iPhoneCarousel, this._iPhoneCarouselDataUrl);
		
		// social media skins
		var socialSkins = $('socialNetworksContent');
		if(socialSkins) new EA.DantesInferno.SocialSkin(socialSkins, this._socialSkinDataUrl);
		
		// screensaver carousel
		var screenSaverCarousel = $('screenSaverCarousel');
		if (screenSaverCarousel) new EA.DantesInferno.ScreenSaverCarousel(screenSaverCarousel, this._screenSaverCarouselDataUrl);
		
		
		// social media tabs
		var socialMedia = $('socialMediaContainerOuter');
		if (socialMedia) new EA.DantesInferno.Tabs(socialMedia, {cookieName: 'di_mediaTab'});
		
		// media page
		var media = $('media');
		if (media) new EA.DantesInferno.Media(media, this._mediaDataUrl);
		
		// explore hell
		var explore = $('explore');
		if (explore) EA.DantesInferno.exploreHell = new EA.DantesInferno.ExploreHell();
		
		// blog tabs
		var popularPosts = $('popularPostsOuter');
		if (popularPosts) new EA.DantesInferno.Tabs(popularPosts, {cookieName: 'di_popularPostsTab'});
		
		// blog archive slider
		var blogArchiveSlide = $('blogArchive');
		if (blogArchiveSlide) new EA.DantesInferno.BlogArchiveSlide(blogArchiveSlide, 'archiveMonth');
		
		// vote results
		var vote = $('voteOuter');
		if (vote) new EA.DantesInferno.Vote(vote, 137);
		
		var gallery = $('gallery');
	    if (gallery) new EA.DantesInferno.Gallery(gallery);
	}
};

/**
 *	EA.DantesInferno.Nav
 */
EA.DantesInferno.Nav = new Class({
	Implements: Options,
	
	options: {
		onStateClassName: 'on'
	},
	
	// Constructor
	initialize: function(nav, options)
	{
		this.container = nav;
		this.setOptions(options);
		
		// set up methods
		if (this.container.getElement('li.on'))
		{
			this.buildOnState();
		}
		this.buildSubNav();
		this.buildNonLinkedNavItems();
	},
	
	buildOnState: function()
	{
		this.activeNavLink = this.container.getElement('li.on a');
		this.activeNavWrapper = new Element('strong');
		this.activeNavWrapper.wraps(this.activeNavLink);
	},
	
	buildSubNav: function()
	{
		this.container.getChildren('li').each(function(navItem, i){
			var subNav = navItem.getElement('ul');
			if (!subNav) return; // only continue for items with a sub nav
			
			if (navItem.hasClass('on')) return; // only continue on "off" state
			
			// show/hide functionality
			new HoverGroup({
				elements: [navItem, subNav],
				delay: 200,
				onEnter: function(){
					subNav.show();
				},
				onLeave: function(){
					subNav.hide();
				}
			});
		}.bind(this));
	},
	
	buildNonLinkedNavItems: function()
	{
		this.container.getElements('a[href=#]').each(function(link){
			link.addEvent('click', function(event){
				event.stop(); // prevent browser default
			});
		});
	}
});

/**
 *	EA.DantesInferno.Sound
 */
EA.DantesInferno.Sound = new Class({
	_flashID: 'soundControl',
	_pagesWithOwnSoundtrack: ['about', 'thePoem', 'exploreHell'], // About, Poem, and Explore Hell pages have their own sound functionality so pause ambient sound so it doesn't interfere
	
   	// Constructor
	initialize: function()
	{
		this.buildCache();
		this.attachEvents();
	},
	
	// Private Methods
	buildCache: function()
	{
		this.pageType = $(document.body).className;
	},
	
	attachEvents: function()
	{
		document.addEvent('setAge', this.build.bind(this));
		document.addEvent('toggleSound', this.toggleSound.bind(this));
	},
	
	build: function()
	{
		var shouldPause = true;
		
		if (this.doesNotHavePageLevelSoundtrack())
		{
			shouldPause = false;
		}
		
		this.soundPlayer = new Swiff('/flash/sound.swf', {id: this._flashID, container: 'sound', width: 50, height: 50, vars: {sourceXML: '/'+regionLocator+'/sound.xml', pauseAnyway: shouldPause}});
		this.flash = $(this._flashID);
	},
	
	doesNotHavePageLevelSoundtrack: function()
	{
		return (this._pagesWithOwnSoundtrack.indexOf(this.pageType) == -1) ? true : false;
	},
	
	toggleSound: function()
	{
		this.flash.toggleSound();
	}
});

/**
 *	EA.DantesInferno.ThemeSwitcher
 */
EA.DantesInferno.ThemeSwitcher = new Class({
	//theme: aka 'level', 'circle'
	_defaultLevel: 'treachery',
	_pathToTheme: "/styles/",
	_themeCookieName: 'di_themeCookieName',
	
	initialize: function(container)
	{
		this.container = container;
		this.cacheMenuElements();
		this.initializeTheme();
		this.configMenu();
		this.buildMenu();
		},
	
	cacheMenuElements: function()
	{
		this.trigger = this.container.getElement('.trigger');
		this.menu = this.container.getElement('.menu');
		this.menuEffect = new Fx.Slide(this.menu, {duration: 300, transition: Fx.Transitions.Cubic.easeIn} );
	},
	
	initializeTheme: function() 
	{
		this.cookie = this.readCookie(this._themeCookieName);
		this.switchStyleSheet(this.cookie);
		this.highlightCurrentSelection(this.cookie);
	},

	configMenu: function()
	{
		this.menu.style.visibility = 'visible';
		this.menu.style.zIndex = '400';
		this.menu.marginBottom = '0';
		this.menu.style.display = 'block';	
	},
	
	buildMenu: function()
	{
		this.menuEffect.hide();
		this.attachEvents();
	},
	
	attachEvents: function()
	{
		this.trigger.addEvent('click', this.toogleMenu.bind(this));
		this.menu.addEvent('click', this.onSwitchStyles.bind(this));
		this.menu.addEvent('click', this.toogleMenu.bind(this));
		this.menu.addEvent('click', this.switchPreOrder.bind(this));
	},
	
	toogleMenu: function(event)
	{
		event.stop();
		var target = event.target;
		var themeReleased = !($(target).hasClass('notreleased'));
		if(themeReleased) this.menuEffect.toggle();
	},

	onSwitchStyles: function(event)
	{
		event.stop();
		var level = event.target.title;
		var target = event.target;
		var themeReleased = !($(target).hasClass('notreleased'));
		if(level && themeReleased)
		{
			this.switchStyleSheet(level);			
			this.setCookie(this._themeCookieName, level);
			this.highlightCurrentSelection(level);
		}
	},

	switchPreOrder: function(event)
	{
		event.stop();
		var level = event.target.title;
		var target = event.target;
		var themeReleased = !($(target).hasClass('notreleased'));
		if(level && themeReleased)
		{
			EA.DantesInferno.preOrderLoader.loadSwf(level);	
		}
	},
	
	readCookie: function(cookie)
	{
		return Cookie.read(cookie);
	},

	setCookie: function(cookie, value)
	{
		Cookie.write(cookie, value, {duration: 365}); // set site theme cookie
	},

	switchStyleSheet: function(level)
	{
		var path = this._pathToTheme;
		var level = (level) ? level : this._defaultLevel;
		if(level)
		{
			path += level;
			var currentStyleSheet = $('theme');
			var newStyleSheet = new Element('link', {type: 'text/css', rel: 'stylesheet', media: 'screen', id: 'theme', href: path + '.css'});
			newStyleSheet.replaces(currentStyleSheet);
		}
	},
		
	highlightCurrentSelection: function(level)
	{
		var level = (level) ? level : this._defaultLevel;
		this.menu.getChildren('li').each(function(item){ 
			if(!item.hasClass('last')) item.getElement('a').removeClass('on');
		});
		this.menu.getElement('a[title='+level+']').addClass('on');
	}
});


/**
 *	EA.DantesInferno.PreOrderLoader
 */
EA.DantesInferno.PreOrderLoader = new Class({
   	_defaultLevel: 'treachery',
	_pathToFlash: '/flash/preOrder_',
	_themeCookieName: 'di_themeCookieName', 
		
	// Constructor
	initialize: function(level)
	{
		this.preorder = $('preorder');
		this.level = (level) ? level : this.getLevel();
		this.loadSwf(this.level);
	},
	
	getLevel: function()
	{
		return this.readCookie(this._themeCookieName);
	},

	readCookie: function(cookie)
	{
		return Cookie.read(cookie);
	},		

	loadSwf: function(level)
	{
		var level = (level) ? level : this._defaultLevel;
		var swf = this._pathToFlash + level + '.swf';
		new Swiff(swf, {id: 'preOrderCallout', container: this.preorder, width: 200, height: 120, params: {allowFullScreen: 'false', allowScriptAccess: 'sameDomain', wMode: 'transparent'}, vars: {link: preOrderVariable, target: '_blank'}});        
	}
});


/**
 *	EA.DantesInferno.Gate
 */
EA.DantesInferno.Gate = new Class({
    Implements: Chain,
    
    _requiredAge: 17,
    _currentDate: new Date(),
    
    // Constructor
	initialize: function(contentUrl, territoryGateCookieName, territoryGateLocationCookieName, ageGateCookieName)
	{
		this.contentUrl = contentUrl;
		this.territoryGateCookieName = territoryGateCookieName;
		this.territoryGateLocationCookieName = territoryGateLocationCookieName;
		this.ageGateCookieName = ageGateCookieName;
		
		// set up methods
		this.buildCache();
		this.checkForCookiesAndSetFlags();
		this.configure();
	},
	
	buildCache: function()
	{
	    // cache elements
	    this.container = new Element('div', {'id': 'gate'});
	},
	
	checkForCookiesAndSetFlags: function()
	{
	    // get cookie values
	    this.territoryCookie = Cookie.read(this.territoryGateCookieName);
	    this.birthdateCookie = Cookie.read(this.ageGateCookieName);
	    this.locationCookie = Cookie.read(this.territoryGateLocationCookieName);
	    // set flags
	    this.hasSelectedTerritory = false;
	    this.hasEnteredBirthdate = false;
	    this.hasValidBirthdate = null;

        if (this.territoryCookie)
        {
            this.hasSelectedTerritory = true; // has cookie
        }
        
        if(this.locationCookie){
        	this.location = unescape(this.locationCookie);
        }
        
        if (this.birthdateCookie)
        {
            this.hasEnteredBirthdate = true; // has cookie
            this.hasValidBirthdate = this.isOfReguiredAge(); // need to also have a valid birthdate
        }
    },
    
    isOfReguiredAge: function() 
	{
	    this.birthdate = new Date(unescape(this.birthdateCookie));
	    var age = this._currentDate.getFullYear() - this.birthdate.getFullYear();

		if ((this._currentDate.getMonth() < this.birthdate.getMonth()) || (this._currentDate.getMonth() == this.birthdate.getMonth() && this._currentDate.getDate() < this.birthdate.getDate()))
		{
		    age--;
		}
		
		return (age < this._requiredAge) ? false : true;
	},
    
    configure: function()
    {
        if (this.hasSelectedTerritory && this.hasEnteredBirthdate && this.hasValidBirthdate) 
        {
            this.broadcastAgeAndTerritory();
            return; // don't show Gate HTML
        }
        
        this.getHTML(); // show Gate HTML
	},
	
	broadcastAgeAndTerritory: function()
    {
        document.fireEvent('setAge', [this.birthdate]);
        document.fireEvent('setLocation', [this.location]);
    },
	
	getHTML: function()
	{
		this.req = new Request.HTML({
			url: this.contentUrl,
			method: 'GET',
			onSuccess: this.build.bind(this),
			onFailure: this.error.bind(this)
		}).send();
	},
	
	build: function(html)
	{
		this.container.adopt(html);
		this.container.inject(document.body); // insert HTML data at bottom of page
		this.showLightbox();
	},
	
	error: $empty, // do nothing if unavailable or error
	
	showLightbox: function()
	{
	    Shadowbox.open({
		    player: 'inline',
		    title: ' ',
		    content: '#gate',
		    width: 748,
		    height: 480,
		    options: {
		        overlayOpacity: 0.99999,
		        displayNav: false, // don't show close button
		        enableKeys: false, // don't enable "esc" key to close
		        modal: true, // don't enable overlay click to close
		        onFinish: function(){
		            this.cacheHTML();
		            this.configureChainOfEvents();
	            }.bind(this)
		    }
        });
	},
	
	hideLightbox: function()
	{
	    Shadowbox.close();
	},
	
	cacheHTML: function()
	{
	    this.territoryGate = $('territoryGate');
	    this.ageGate = $('ageGate');
	},
	
	configureChainOfEvents: function()
	{
	    this.configure = new Chain();
		this.configure.chain(this.configureTerritoryGate.bind(this), this.configureAgeSelector.bind(this), this.configureUnderAgeMessage.bind(this), this.hideLightbox.bind(this));
		this.configure.callChain(); // call first method on chain
	},
	
	configureHTML: function(flag, listOfMethods)
	{
	    if (flag)
        {
            this.configure.callChain(); // call next method on chain
            return
        }
        
        listOfMethods.each(function(method){
            this[method]();
        }.bind(this));
	},
	
    configureTerritoryGate: function()
    {
        this.configureHTML(this.hasSelectedTerritory, ['hideAgeGate', 'showTerritoryGate']);
    },
    
    configureAgeSelector: function()
    {
        this.configureHTML(this.hasEnteredBirthdate, ['hideTerritoryGate', 'showAgeGate', 'displayAgeSelector']);
    },
	
	configureUnderAgeMessage: function()
	{
	    this.configureHTML(this.hasValidBirthdate, ['hideTerritoryGate', 'showAgeGate', 'displayUnderAgeMessage']);
	},
	
	showTerritoryGate: function()
	{
	    this.territoryGate.setStyle("display", "block");
	    
	    $('gateInner').getElement('.langCan').addEvent('click', this.makeTerritoryBinding('CA').bind(this));
        $('gateInner').getElement('.langUsa').addEvent('click', this.makeTerritoryBinding('US').bind(this));
	},
	
	hideTerritoryGate: function()
	{
	    this.territoryGate.setStyle("display", "none");
	},
	
	makeTerritoryBinding: function(location){
		return function(event){
			event.stop(); // prevent browser default
		    
	    	Cookie.write(this.territoryGateCookieName, 'en', {duration: 365}); // set Territory Gate cookie
	    	Cookie.write(this.territoryGateLocationCookieName, location, {duration: 365}) //set Territory Gate location cookie
	    	this.location = location;
	    	
	    	this.configure.callChain(); // call next method on chain
		};
	},
	
	showAgeGate: function()
	{
	    this.ageGate.setStyle("display", "block");
	},
	
	hideAgeGate: function()
	{
	    this.ageGate.setStyle("display", "none");
	},
	
	displayAgeSelector: function()
	{
	    // create container
        this.birthdate = new Element('div', {'id': 'birthdate'});
	    // create generic select to clone
	    this.select = new Element('select', {'id': ''}).addEvent('change', this.changeAge.bind(this));
	    // create generic option to clone
	    this.option = new Element('option', {'value': '0'});
	    
        // create month dropdown
        this.selectMonth = this.select.clone().cloneEvents(this.select).set('id', 'birthdateMonth');
        var defaultOption = this.option.clone().set('text', 'Month');
        defaultOption.inject(this.selectMonth);
        this.monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        var option;
        this.monthNames.each(function(month, i){
            option = this.option.clone().set({'value': i+1, 'text': month});
            option.inject(this.selectMonth);
        }.bind(this));
	    
		// create days per month object
		this.daysPerMonth = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31};
		
        // create day dropdown
        this.selectDay = this.select.clone().cloneEvents(this.select).set('id', 'birthdateDay');
		defaultOption = this.option.clone().set('text', 'Day');
		defaultOption.inject(this.selectDay);
		for (var i = 1; i <= 31; i++)
	    {
		    option = this.option.clone().set({'value': i, 'text': i});
			option.inject(this.selectDay);
	    }
        
		// create year dropdown
        this.selectYear = this.select.clone().cloneEvents(this.select).set('id', 'birthdateYear');
        defaultOption = this.option.clone().set('text', 'Year');
        defaultOption.inject(this.selectYear);
        for (var i = this._currentDate.getFullYear(); i >= 1900; i--)
	    {
		    option = this.option.clone().set({'value': i, 'text': i});
            option.inject(this.selectYear);
	    }
	    var before1900Option = this.option.clone().set({'value': '1900', 'text': 'Before 1900'});
        before1900Option.inject(this.selectYear);
		
        // insert date dropdowns into age gate
        this.selectMonth.inject(this.birthdate);
        this.selectDay.inject(this.birthdate);
		this.selectDay.disabled = true;
        this.selectYear.inject(this.birthdate);
        this.birthdate.inject(this.ageGate);
	},
	
	resetDayDropDown: function(maxDays)
	{
		var option, options = this.selectDay.getElements('option'), len = options.length, norm = maxDays + 1;
		if (len == norm) return; // old month and new month have same number of days 
		else if (len > norm) // old month has more days than new month
		{
			for (var i = len - 1; i > maxDays; i--)
			{
				options[i].dispose();
			}
		}
		else // old month doesn't have enough days
		{
			for (var i = len; i <= maxDays; i++)
		    {
			    option = this.option.clone().set({'value': i, 'text': i});
				option.inject(this.selectDay);
		    }
		}
	},
	
	displayUnderAgeMessage: function() 
	{
        this.underageMessage = new Element('div', {'id': 'underage'});
	    this.underageMessage.set('html', '<p>Sorry, you do not meet requirements for viewing this site.</p>');
	    this.underageMessage.inject(this.ageGate);
	},
	
	changeAge: function(event)
	{
		// assemble the birthdate 
		var month = this.selectMonth.value;
		var day = this.selectDay.value;
		var year = this.selectYear.value;
		
		if (event.target.id == 'birthdateMonth')
		{
			if (month > 0)
			{
				this.resetDayDropDown(this.daysPerMonth[month]);
				this.selectDay.disabled = false;
				
				if (this.selectDay.value > this.daysPerMonth[month]) this.selectDay.value = 0;
			}
			
			if (month == 0)
			{
				this.selectDay.disabled = true;
				this.selectDay.value = 0;
			}
		}
		
		if (day == 0 || month == 0 || year == 0) return;
		
	    // set the cookie with birthdate info; make cookie expire in 3 years
        this.birthdateCookie = escape(month + '/' + day + '/' + year);
        Cookie.write(this.ageGateCookieName, this.birthdateCookie, {duration: (365*3)});

	    this.birthdate.setStyle('display', 'none'); // hide the selector
        this.hasValidBirthdate = this.isOfReguiredAge(); // set valid birthdate flag
        this.broadcastAgeAndTerritory(); // broadcast age globally
        this.configure.callChain(); // call next method on chain
	}
});

/**
 *	EA.DantesInferno.Carousel
 */
EA.DantesInferno.Carousel = new Class({
	Implements: Options,
	
	options: {
		mode: 'horizontal', // set carousel scroll direction (default is horizontal)
		visible: 0, // total number of fully visible slides
		navID: '', // ID of carousel nav (no default)
		width: 0, // thumbnail image width (no default)
		height: 0, // thumbnail image height (no default)
		margin: 0, // combined horizontal (left + right) or vertical (top + bottom) margin of thumbnail list item
		duration: 750 // time of Fx
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
		this.carousel = carousel;
		this.data = data;
		this.setOptions(options);
		
		// set up methods
		this.getData();
	},
	
	// Private Methods
	getData: function()
	{
		// make request for JSON slides data
		this.req = new Request.JSON({
		    noCache: true,
			url: this.data,
			method: 'GET',
			onSuccess: this.success.bind(this),
			onFailure: this.error.bind(this)
		}).send();
	},
	
	error: function()
	{
		//alert('Error accessing data.');
	},
	
	success: function(data)
	{
		this.data = data.slides;
		
		this.build();
	},
	
	build: function()
	{
	    this.buildCache();
		this.insert();
		this.setModeBasedProperties();
		this.setNav();
		this.action();
	},
	
	buildCache: function()
	{
	    // cache parent
	    this.container = this.carousel.getParent('div');
	    
		// create and cache controls
		this.prevButton = new Element('div', {'class': 'button prev'});
		this.nextButton = new Element('div', {'class': 'button next'});
		
		// create carousel
		this.nav = new Element('div', {'id': this.options.navID, 'class': 'nav'});
		this.list = new Element('ul');
		this.numberOfItems = 0;
		this.items = [];
		this.buildHTML(); // separated out into it's own method for classes to override since data is different
		this.currentItem = this.items[0];
	},
	
	buildHTML: function()
	{
	    var img;
		this.data.each(function(item, i){
			this.items[i] = new Element('li');
			this.items[i].addEvent('click', this.onCarouselItemClick.bind(this)).setStyle('filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=60)');
			img = new Element('img', {'alt': '', 'src': item.image, 'width': this.options.width, 'height': this.options.height});
			img.inject(this.items[i]);
			this.items[i].inject(this.list);
			this.items[i].store('data', item);
			this.numberOfItems++;
		}.bind(this));
	},
	
	insert: function()
	{
	    this.prevButton.inject(this.carousel);
		this.list.inject(this.nav);
		this.nav.inject(this.carousel);
		this.nextButton.inject(this.carousel);
	},
	
	setModeBasedProperties: function()
	{
	    if (this.options.mode == 'vertical')
		{
		    this.options.cssProperty = 'marginTop';
			this.options.navDimension = this.nav.getStyle('height').toInt();
			this.options.itemDimension = this.options.height;
			this.options.coordinateCssProperty = 'top';
			this.options.slideOffset = 2;
			
			return;
		}
		this.options.cssProperty = 'marginLeft';
		this.options.navDimension = this.nav.getStyle('width').toInt();
		this.options.itemDimension = this.options.width;
		this.options.coordinateCssProperty = 'left';
		this.options.slideOffset = 2;
	},
	
	setNav: function()
	{
	    this.setNavProperties();
	    
	    this[(this.doesNotHaveMinimum()) ? 'setStaticNav' : 'setRotatingNav']();
	},
	
	setNavProperties: function()
	{
	    this.delta = this.options.itemDimension + this.options.margin; // size in px of combined slide width/height + margins (used for scrolling, etc)
	    this.totalPartialSlideSize = this.options.navDimension - (this.options.visible * this.delta); // size in px of combined visible partial slide
	    this.hasPartialSlides = (this.totalPartialSlideSize == 0) ? false : true; // flag
	    this.totalVisibleSlides = (this.hasPartialSlides) ? this.options.visible + 2 : this.options.visible; // counts partials as a whole
	    this.numberOfSlideOptions = Math.floor(this.totalVisibleSlides / 2); // number on either side of centered slide
	},
	
	setStaticNav: function()
	{
	    this.highlightItem();
		// show off state and change cursor of buttons since they're disabled
		this.prevButton.addClass('off').setStyle('cursor', 'default');
		this.nextButton.addClass('off').setStyle('cursor', 'default');
	},
	
	setRotatingNav: function()
	{
	    this.cloneNavItems();
	    this.setRotatingNavPosition();
		this.cacheFx();
		this.highlightItem();
		this.attachEvents();
	},
	
	cacheFx: function()
	{
		this.fx = new Fx.Morph(this.list, {
			duration: this.options.duration,
			transition: Fx.Transitions.Quad.easeInOut,
			onStart: this.fxStart.bind(this),
			onComplete: this.fxComplete.bind(this)
		});
	},
	
	cloneNavItems: function()
	{
	    var numItems = this.numberOfItems; // cache value b/c we'll be adding to it
	    this.numberOfClonedItemsForBeginning = (this.options.visible == 1) ? 1 : this.totalVisibleSlides - 1;
	    this.numberOfClonedItemsForEnd = this.numberOfItems - this.numberOfClonedItemsForBeginning;
	    
	    // clone end items and add to beginning so nav is centered at first data item
		var item, data, copy;
		var clonedItemsForBeginning = [];
		for (var i = 1; i <= this.numberOfClonedItemsForBeginning; i++)
		{
		    item = this.items[numItems - i];
		    data = item.retrieve('data');
		    copy = item.clone().cloneEvents(item).store('data', data);
			clonedItemsForBeginning[this.numberOfClonedItemsForBeginning - i] = copy;
			copy.inject(this.list, 'top');
			this.numberOfItems++;
		}
		
		// clone rest of items and add to end so rotation is seamless and in order
		var clonedItemsForEnd = [];
		for (var i = 0; i < this.numberOfClonedItemsForEnd; i++)
		{
		    item = this.items[i];
		    data = item.retrieve('data');
		    copy = item.clone().cloneEvents(item).store('data', data);
			clonedItemsForEnd[i] = copy;
			copy.inject(this.list, 'bottom');
			this.numberOfItems++;
		}
		
		// create master list of items
		this.items = clonedItemsForBeginning.extend(this.items);
		this.items = this.items.extend(clonedItemsForEnd);
	},
	
	setRotatingNavPosition: function()
	{
	    // NOTE: make sure enough slides are off view in both directions so pop/push is not visible to user
		var oneSideMargin = this.options.margin / 2;
		var fullsizeSlideOffset = this.numberOfSlideOptions * this.delta;
		var visiblePortionOfPartialSlide = (this.hasPartialSlides) ? (this.totalPartialSlideSize / 2) - oneSideMargin : 0;
		var noPartialSlidesOffset = this.options.itemDimension + this.options.margin; // width/height + full margins
		var partialSlideOffset = oneSideMargin + this.options.itemDimension - visiblePortionOfPartialSlide; // margin + width/height - visible portion of slide
		var finalOffset = (this.hasPartialSlides) ? partialSlideOffset : noPartialSlidesOffset; // margin + width/height - visible portion of slide
		this.position = -(fullsizeSlideOffset + finalOffset);
		this.list.setStyle(this.options.cssProperty, this.position);
	},
	
	highlightItem: function()
	{
	    this.currentItem.addClass('on').setStyle('filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=100)');
	},
	
	unhighlightItem: function()
	{
	    this.list.getElements('li.on').removeClass('on').setStyle('filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=60)');
	},
	
	onCarouselItemClick: function(event)
	{
	    event.stop(); // prevent browser default
	    
	    var target = event.target;
	    var thisItem = (target.tagName == 'LI') ? target : event.target.getParent('li');
	    
	    if (thisItem.hasClass('on')) return; // do nothing if current "active" item is selected again
	    
	    this[(this.doesNotHaveMinimum()) ? 'setItemForStaticNav' : 'setItemForRotatingNav'](thisItem);
	},
	
	setItemForStaticNav: function(thisItem)
	{
        this.unhighlightItem();
        this.items.each(function(item, i){
            if (thisItem == item)
            {
                this.currentItem = item;
                this.highlightItem();
                return;
            }
        }.bind(this));
        
        this.action();
	},
	
	setItemForRotatingNav: function(thisItem)
	{
	    // calculate step
        var items = this.list.getElements('li');
        var currentItem = items[this.numberOfClonedItemsForBeginning];
	    
        var previousItems = currentItem.getAllPrevious('li');
        previousItems.each(function(previousItem, i){
            i++;
            if (i > this.numberOfSlideOptions) return;
	        
            if (thisItem == previousItem)
            {
                this.step = i;
                return;
            }
        }.bind(this));
	    
        var nextItems = currentItem.getAllNext('li');
        nextItems.each(function(nextItem, i){
            i++;
            if (i > this.numberOfSlideOptions) return;
	        
            if (thisItem == nextItem)
            {
                this.step = -1 * i;
                return;
            }
        }.bind(this));
	    
	    this.itemWasClicked = true;
        this.scroll();
	},
	
	attachEvents: function()
	{
		this.prevButton.addEvent('click', this.onPrevButtonClick.bind(this));
		this.nextButton.addEvent('click', this.onNextButtonClick.bind(this));
		
		if (!(Browser.Engine.trident && Browser.Engine.version < 5))
	    {
	        // add mouseover/out methods to buttons
	        this.prevButton.addEvents({
	            'mouseover': function() {this.addClass('hover')},
	            'mouseout': function() {this.removeClass('hover')}
	        });
	        this.nextButton.addEvents({
	            'mouseover': function() {this.addClass('hover')},
	            'mouseout': function() {this.removeClass('hover')}
	        });
        }
	},
	
	onPrevButtonClick: function()
	{
	    this.step = 1;
		this.scroll();
	},
	
	onNextButtonClick: function()
	{
	    this.step = -1;
		this.scroll();
	},
	
	doesNotHaveMinimum: function()
	{
	    // set display flag
		if (this.numberOfItems <= this.totalVisibleSlides && !this.hasPartialSlides)
		{
			return true;
		}
		return false;
	},
	
	scroll: function()
	{
	    // calculate position
	    this.newPosition = this.position + (this.step * this.delta);
		// scroll
		var obj = {};
		obj[this.options.cssProperty] = this.newPosition;
		this.fx.start(obj);
	},
	
	fxStart: function()
	{
	    this.unhighlightItem();
	},
	
	fxComplete: function()
	{
		this.resetNav();
		this.setCurrentItem();
		this.highlightItem();
		this.action();
	},
	
	resetNav: function()
	{
		// get all items
	    var items = this.list.getElements('li');
		
		if (this.step > 0) // prev items
		{
			for (var i = 1; i <= this.step; i++)
			{
			    // pop off end
			    var item = items[this.numberOfItems - i].dispose(); // account for zero based array
			    // inject to front
			    item.inject(this.list, 'top');
            }
		}
		else // next items
		{
		    for (var i = 0, n = (-1 * this.step); i < n; i++)
			{
			    // pop off front
			    var item = items[i].dispose();
			    // inject to end
			    item.inject(this.list, 'bottom');
		    }
		}
		
		// calculate position
		this.position = this.newPosition - (this.step * this.delta);
		// reset margin
		var obj = {};
		obj[this.options.cssProperty] = this.position;
		this.fx.set(obj);
	},
	
	setCurrentItem: function()
	{
	    var currentIndex = this.items.indexOf(this.currentItem);
        currentIndex = currentIndex - this.step;
        if (currentIndex < 0)
		{
			currentIndex = this.numberOfItems - 1;
		}
		if (currentIndex >= this.numberOfItems)
		{
			currentIndex = 0;
		}
		
		this.currentItem = this.items[currentIndex];
	},
	
	action: $empty
});

/**
 *	EA.DantesInferno.VideoCarousel
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.VideoCarousel = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
	    visible: 5,
		navID: 'videoNav',
		width: 90,
		height: 47,
		margin: 10
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
	    // call parent method
		this.parent(carousel, data, options);
	},
	
	// Private methods
	buildCache: function()
	{
	    // cache elements
		this.title = new Element('div', {'class': 'titleOuter'});
		this.gradientPrev = new Element('div', {'class': 'gradient gradient-prev'});
		this.gradientNext = new Element('div', {'class': 'gradient gradient-next'});
		
	    // call parent method
	    this.parent();
	},
	
	buildHTML: function()
	{
		this.data.each(function(item, i){
			this.items[i] = new Element('li');
			this.items[i].addEvents({'click': this.onCarouselItemClick.bind(this), 'mouseover': this.onCarouselItemMouseOver.bind(this), 'mouseout': this.onCarouselItemMouseOut.bind(this)}).setStyle('filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=60)');
			img = new Element('img', {'alt': '', 'src': item.thumb, 'width': 84, 'height': this.options.height});
			img.inject(this.items[i]);
			this.items[i].inject(this.list);
			this.items[i].store('data', item);
			this.numberOfItems++;
		}.bind(this));
	},
	
	insert: function()
	{
	    this.title.inject(this.carousel).addEvents({'mouseover': function(){this.show()}, 'mouseout': function(){this.hide()}});
	    
	    // call parent method
	    this.parent();
	},
	
	setNavProperties: function()
	{
	    this.titleCoordinates =this.title.getStyles('width', 'height');
	    this.title.setStyle('top', this.list.getCoordinates(this.container).top - this.titleCoordinates.height.toInt()); // set top position
	    
	    // call parent method
	    this.parent();
	},
	
	setRotatingNav: function()
	{
	    this.gradientPrev.inject(this.carousel);
	    this.gradientNext.inject(this.carousel);
	    
	    // call parent
	    this.parent();
	},
	
	onCarouselItemMouseOver: function(event)
	{
	    var item, target = event.target;
	    if (target.hasClass('selected'))
	    {
	        item = this.list.getElement('li.on');
	    }
	    else
	    {
	        item = (target.tagName == 'LI') ? target : event.target.getParent('li');
        }
	    var data = item.retrieve('data'); // get stored data
	    
	    this.title.set('html', '<div class="titleInner">' + data.title + '</div>'); // set title
	    var itemCoordinates = item.getCoordinates(this.container); // get list item coordinates
	    var titleHorizontalPosition = itemCoordinates.left - ((this.titleCoordinates.width.toInt() - itemCoordinates.width)/2);
	    this.title.setStyle('left', titleHorizontalPosition); // set horizontal position
	    this.title.show(); // show title
	},
	
	onCarouselItemMouseOut: function(event)
	{
	    this.title.hide(); // hide title
	},
	
	fxStart: function()
	{
	    if (this.itemWasClicked)
		{
		    this.unhighlightItem();
	    }
	},
	
	fxComplete: function()
	{
		this.resetNav();
		this.setCurrentItem();
		
		if (this.itemWasClicked)
		{
		    this.action();
		    this.highlightItem();
	    }
		this.itemWasClicked = false;
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data');  // get data from current item
		
		document.fireEvent('updateScreen');
		document.fireEvent('updatePlayer', [dataset]); // update video player
		document.fireEvent('updateUserGenerated', [dataset.id]); // update user generated items (rate, comment, share) with ID to store data
	    document.fireEvent('updateComments', [dataset.id]); // update comments
	    document.fireEvent('updateRating', [dataset.rating]); // update rating
	    document.fireEvent('updateDownload', [dataset]); // update download
	    loadMediaComments([dataset.id],1,3,regionLocator); //added by ORC - loads comments list for asset
	    setViewCounts([dataset.id]);
	}
});

/**
 *	EA.DantesInferno.ImageSlideShow
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.ImageSlideShow = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
		mode: 'vertical',
		visible: 3,
		navID: 'imageNav',
		width: 55,
		height: 48,
		margin: 12,
		auto: true, // set auto rotation flag (default is false)
		delay: 5000 // set auto rotation delay in milliseconds (no default)
	},
	
	// Constructor
	initialize: function(carousel, player, data, options)
	{
		this.player = player;
		
		// call parent method
		this.parent(carousel, data, options);
	},
	
	// Private methods
	success: function(data)
	{
		this.parent(data);
		
		this.startAutoRotation();
	},
	
	buildCache: function()
	{
		this.caption = new Element('div', {'id': 'imageCaption'});
		this.selected = new Element('div', {'class': 'selected'});
		
		// call parent method
		this.parent();
	},
	
	buildHTML: function()
	{
	    var img, caption;
		this.data.each(function(item, i){
			this.items[i] = new Element('li');
			this.items[i].addEvent('click', this.onCarouselItemClick.bind(this)).setStyle('filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=60)');
			img = new Element('img', {'alt': '', 'src': item.thumb, 'width': this.options.width, 'height': this.options.height});
			img.inject(this.items[i]);
			this.items[i].inject(this.list);
			if (item.title == '' && item.copy == '')
			{
			    this.items[i].store('data', {'item': item});
			}
			else
			{
			    caption = '<h5><a href="' + item.link + '" target="_blank">' + item.title + '</a></h5> ' + '<p><a href="' + item.link + '" target="_blank">' + item.copy + '</a></p>';
			    this.items[i].store('data', {'caption': caption, 'item': item});
			}
			this.numberOfItems++;
		}.bind(this));
	},
	
	insert: function()
	{
	    this.selected.inject(this.container);
		this.caption.inject(this.player);
		
		// call parent method
		this.parent();
	},
	
	setStaticNav: function()
	{
	    // set "selected" bg around first item
		var newCoordinate = this.items[0].getCoordinates(this.carousel)[this.options.coordinateCssProperty];
		this.selected.setStyle(this.options.coordinateCssProperty, newCoordinate + this.options.slideOffset);
        
        // call parent
        this.parent();
	},
	
	onCarouselItemClick: function(event)
	{
	    this.stopAutoRotation();
	    
	    // call parent method
		this.parent(event);
	},
	
	setItemForStaticNav: function(thisItem)
	{
        var newCoordinate = thisItem.getCoordinates(this.carousel)[this.options.coordinateCssProperty];
        this.selected.setStyle(this.options.coordinateCssProperty, newCoordinate + this.options.slideOffset);
        
        // call parent
        this.parent(thisItem);
	},
	
	attachEvents: function()
	{
	    // call parent method
		this.parent();
		
		this.player.addEvents({
			'mouseover': function(){
				$clear(this.autoRotate);
			}.bind(this),
			'mouseout': function(){
				this.startAutoRotation();
			}.bind(this)
		});
	},
	
	onPrevButtonClick: function()
	{
	    this.stopAutoRotation();
			
	    // call parent method
		this.parent();
	},
	
	onNextButtonClick: function()
	{
	   this.stopAutoRotation();
			
	    // call parent method
		this.parent();
	},
	
	onAutoRotate: function()
	{
	    this.step = -1;
	    this.scroll();
	},
	
	startAutoRotation: function()
	{
		if (this.doesNotHaveMinimum() || !this.options.auto) return;
		
		this.autoRotate = this.onAutoRotate.periodical(this.options.delay, this);
	},
	
	stopAutoRotation: function()
	{
	    $clear(this.autoRotate);
		this.player.removeEvents();
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data'); // get data from current item
		
		// change full size image and caption
		if (dataset.caption) this.caption.set('html', dataset.caption);
		var omnitureKey = dataset.item.image.match(/(\w+)(.jpg|.gif)/)[1];
		if (this.fullsizeImage) // elements already exist so update data
		{
			this.fullsizeImage.setProperty('src', dataset.item.image);
			this.fullsizeLink.setProperties({'href': dataset.item.link, 'target': '_blank', 'onclick': "omniLinkCall(this, '" + omnitureKey + "_promo_link_click')"});
			return;
		}
		// create and insert elements first time around
		this.fullsizeLink = new Element('a', {'href': dataset.item.link, 'target': '_blank', 'onclick': "omniLinkCall(this, '" + omnitureKey + "_promo_link_click')"});
		this.fullsizeImage = new Element('img', {'alt': '', 'src': dataset.item.image, 'width': '246', 'height': '287'});
		this.fullsizeImage.inject(this.fullsizeLink);
		this.fullsizeLink.inject(this.player);
	}
});

/**
 *	EA.DantesInferno.WallpaperCarousel
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.WallpaperCarousel = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
	    visible: 1,
		navID: 'wallpaperNav',
		width: 342,
		height: 219,
		margin: 0
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
		this.parent(carousel, data, options);
	},
	
	buildCache: function()
	{
	    this.downloadLinks = {};
	    this.downloadLinks['1024 x 768'] = this.carousel.getElements('div.download a')[0];
	    this.downloadLinks['1280 x 960'] = this.carousel.getElements('div.download a')[1];
	    this.downloadLinks['1440 x 900'] = this.carousel.getElements('div.download a')[2];
	    
		// call parent method
		this.parent();
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data');  // get data from current item
	    
		// update Download links
		this.downloadLinks['1024 x 768'].href = dataset['1024 x 768'];
		this.downloadLinks['1280 x 960'].href = dataset['1280 x 960'];
		this.downloadLinks['1440 x 900'].href = dataset['1440 x 900'];
	}
});

/**
 *	EA.DantesInferno.ScreenSaverCarousel
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.ScreenSaverCarousel = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
	    visible: 1,
		navID: 'screenSaverNav',
		width: 120,
		height: 75,
		margin: 0
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
		this.parent(carousel, data, options);
	},
	
	buildHTML: function()
	{
	    var link, img, imageName;
		this.data.each(function(item, i){
			this.items[i] = new Element('li');
			imageName = item.image.match(/(\w+[-]?\s?)+\.jpg/)[0].split('.jpg')[0];
			link = new Element('a', {'href': item.link, 'target':  '_blank', 'onclick': 'omniLinkCall(this,\'DOWNLOAD_SCREENSAVERS_' + imageName + '_link_click\');'});
			img = new Element('img', {'alt': '', 'src': item.image, 'width': this.options.width, 'height': this.options.height});
			img.inject(link);
			link.inject(this.items[i]);
			this.items[i].inject(this.list);
			this.items[i].store('data', item);
			this.numberOfItems++;
		}.bind(this));
	},
	
	setStaticNav: function()
	{
	    // show off state and change cursor of buttons since they're disabled
		this.prevButton.addClass('off').setStyle('cursor', 'default');
		this.nextButton.addClass('off').setStyle('cursor', 'default');
	},
	
	setRotatingNav: function()
	{
	    this.cloneNavItems();
	    this.setRotatingNavPosition();
		this.cacheFx();
		this.attachEvents();
	},
	
	fxComplete: function()
	{
		this.resetNav();
		this.setCurrentItem();
		this.action();
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data');  // get data from current item
	}
});

/**
 *	EA.DantesInferno.BuddyIconCarousel
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.BuddyIconCarousel = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
	    visible: 6,
		navID: 'buddyIconNav',
		width: 48,
		height: 48,
		margin: 20
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
		this.parent(carousel, data, options);
	},
	
	buildHTML: function()
	{
	    var link, img, imageName;
		this.data.each(function(item, i){
			this.items[i] = new Element('li');
			imageName = item.image.match(/(\w+[-]?\s?)+\.jpg/)[0].split('.jpg')[0];
			link = new Element('a', {'href': item.image, 'target':  '_blank', 'onclick': 'omniLinkCall(this,\'DOWNLOAD_BUDDYICONS_' + imageName + '_link_click\');'});
			img = new Element('img', {'alt': '', 'src': item.image, 'width': this.options.width, 'height': this.options.height});
			img.inject(link);
			link.inject(this.items[i]);
			this.items[i].inject(this.list);
			this.items[i].store('data', item);
			this.numberOfItems++;
		}.bind(this));
	},
	
	setStaticNav: function()
	{
	    // show off state and change cursor of buttons since they're disabled
		this.prevButton.addClass('off').setStyle('cursor', 'default');
		this.nextButton.addClass('off').setStyle('cursor', 'default');
	},
	
	setRotatingNav: function()
	{
	    this.cloneNavItems();
	    this.setRotatingNavPosition();
		this.cacheFx();
		this.attachEvents();
	},
	
	fxComplete: function()
	{
		this.resetNav();
		this.setCurrentItem();
		this.action();
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data');  // get data from current item
	}
});

/**
 *	EA.DantesInferno.IPhoneCarousel
 *		extends EA.DantesInferno.Carousel
 */
EA.DantesInferno.IPhoneCarousel = new Class({
	Extends: EA.DantesInferno.Carousel,
	Implements: Options,
	
	options: {
	    visible: 3,
		navID: 'iPhoneNav',
		width: 99,
		height: 148,
		margin: 38
	},
	
	// Constructor
	initialize: function(carousel, data, options)
	{
		this.parent(carousel, data, options);
	},
	
	buildCache: function()
	{
		this.selected = new Element('a', {'class': 'selected'});
		
		// call parent method
		this.parent();
	},
	
	insert: function()
	{
	    this.selected.inject(this.container);
	    this.downloadLink = this.selected;
	    this.downloadLink.target="_blank";
	    
		// call parent method
		this.parent();
	},
	
	setStaticNav: function()
	{
	    // set "selected" bg around first item
		var newCoordinate = this.items[0].getCoordinates(this.carousel)[this.options.coordinateCssProperty];
		this.selected.setStyle(this.options.coordinateCssProperty, newCoordinate + this.options.slideOffset);
        
        // call parent
        this.parent();
	},
	
	setItemForStaticNav: function(thisItem)
	{
        var newCoordinate = thisItem.getCoordinates(this.carousel)[this.options.coordinateCssProperty];
        this.selected.setStyle(this.options.coordinateCssProperty, newCoordinate + this.options.slideOffset);
        
        // call parent
        this.parent(thisItem);
	},
	
	action: function()
	{
	    var dataset = this.currentItem.retrieve('data');  // get data from current item
	    
		this.downloadLink.href = dataset.link; // update Download link
	}
});

/**
 *	EA.DantesInferno.ScrollingBox (implements and extends MooScroller)
 */
EA.DantesInferno.ScrollingBox = new Class({
	Implements: Options,
	
	options: {
		viewportClassName: 'scrollingboxViewport',
		controlsContainerClassName: 'scrollingboxControls',
		scrollbarContainerClassName: 'scrollBarContainer',
		scrollbarPadding: 22
	},
	
	// Constructor
	initialize: function(container, options)
	{
		this.container = container;
		this.setOptions(options);
		
		// set up methods
		this.buildChrome();
		this.buildControls();
		this.buildScroller();
		this.attachEvents();
	},
	
	// Private Methods
	buildChrome: function()
	{
	    // cache size
		this.viewportDimensions = this.container.getSize(); // get the viewports dimensions based off DEFAULT styles
		
		// cache viewport
		this.viewport = new Element('div', {'class': this.options.viewportClassName});
		
		// insert viewport and set dimensions
		this.viewport.wraps(this.container).setStyles({'width': this.viewportDimensions.x, 'height': this.viewportDimensions.y});
		
		// reset content styles
		this.container.setStyles({'width': this.viewportDimensions.x - this.options.scrollbarPadding, 'height': this.viewportDimensions.y});
	},
	
	buildControls: function()
	{
		// cache control items
		this.controlsContainer = new Element('div', {'class': this.options.controlsContainerClassName});
		this.upButton = new Element('div', {'class': 'button up'});
		this.downButton = new Element('div', {'class': 'button down'});
		this.scrollbarContainer = new Element('div', {'class': this.options.scrollbarContainerClassName});
		this.scrollknob = new Element('div', {'class': 'scrollknob'});
		
		// insert into container
		this.upButton.inject(this.controlsContainer);
		this.scrollknob.inject(this.scrollbarContainer);
		this.scrollbarContainer.inject(this.controlsContainer);
		this.downButton.inject(this.controlsContainer);
		
		// insert into DOM
		this.controlsContainer.inject(this.container, 'after');
		
		// set control container dimensions based off viewport
		this.controlsContainer.setStyle('height', this.viewportDimensions.y);
		
		// set scrollbar container dimensions basaed off controls
		this.scrollbarContainer.setStyle('height', this.viewportDimensions.y - this.upButton.getSize().y - this.downButton.getSize().y - 1);
	},
	
	buildScroller: function()
	{
	    this.scroller = new MooScroller(this.container, this.scrollknob, {
			scrollLinks: {
				forward: this.downButton,
				back: this.upButton
			}
		});
	},
	
	attachEvents: function()
	{
	    if (!(Browser.Engine.trident && Browser.Engine.version < 5))
	    {
	        this.upButton.addEvents({ // do NOT clone events b/c other events are added in MooScroller
		        'mouseover': function() {this.addClass('hover')},
		        'mouseout': function() {this.removeClass('hover')}
		    });
		    this.downButton.addEvents({ // do NOT clone events b/c other events are added in MooScroller
		        'mouseover': function() {this.addClass('hover')},
		        'mouseout': function() {this.removeClass('hover')}
		    });
        }
	},
	
	refresh: function()
	{
	    this.scroller.update();
		if (this.scrollbarContainer.getStyle('visibility') == 'hidden')
		{
		    this.upButton.addClass('off');
		    this.downButton.addClass('off');
		}
		else
		{
		    this.upButton.removeClass('off');
		    this.downButton.removeClass('off');
		}
	}
});

/**
 *	EA.DantesInferno.UserGenerated
 */
EA.DantesInferno.UserGenerated = new Class({
    // Constructor
    initialize: function(rateContentUrl, commentDataUrl, commentContentUrl, flagContentUrl, shareContentUrl, territoryGateCookieName)
	{
	    this.contentUrl = {};
	    this.contentUrl.ratings = rateContentUrl;
	    this.contentUrl.comment = commentContentUrl;
	    this.contentUrl.flag = flagContentUrl;
	    this.contentUrl.share = shareContentUrl;
	    this.commentDataUrl = commentDataUrl;
	    this.territoryGateCookieName = territoryGateCookieName;
		
		// set up methods
		this.buildCache();
		this.setup();
	},
	
	// Private methods
	buildCache: function()
	{
	    // elements
	    this.pageType = $(document.body).className;
	    // containers
	    this.container = $('userGenerated');
	    this.titleContainer = $$('li.title');
	    this.rateContainer = $$('li.ratings');
	    this.commentContainer = $$('li.comment');
	    this.shareContainer = $$('li.share');
	    this.downloadContainer = $$('li.download');
	    this.flagContainer = $$('li.flag');
	    this.commentViewContainer = $('comments');
	},
	
	setup: function()
	{
		if (this.pageType != 'exploreHell' && this.titleContainer == 0 && this.rateContainer.length == 0 && this.commentContainer.length == 0 && this.shareContainer.length == 0 && this.downloadContainer.length == 0 && this.flagContainer.length == 0 && this.commentViewContainer == null) return;
	    
	    this.buildInstances();
        this.buildHTMLCache();
		this.attachEvents();
	},
	
	buildInstances: function()
	{
		if (this.titleContainer.length > 0) this.title = new EA.DantesInferno.UserGenerated.Title(this, this.titleContainer[0]);
	    if (this.rateContainer.length > 0) this.rate = new EA.DantesInferno.UserGenerated.Rate(this, this.rateContainer[0], this.pageType);
	    if (this.commentContainer.length > 0) this.commentContainer.each(function(container){ new EA.DantesInferno.UserGenerated.Comment(this, container, this.territoryGateCookieName) }.bind(this));
	    if (this.shareContainer.length > 0) this.shareContainer.each(function(container){ new EA.DantesInferno.UserGenerated.Share(this, container, this.pageType) }.bind(this));
	    if (this.downloadContainer.length > 0) this.download = new EA.DantesInferno.UserGenerated.Download(this, this.downloadContainer[0]);
	    if (this.flagContainer.length > 0) this.flagContainer.each(function(container){ new EA.DantesInferno.UserGenerated.Flag(this, container) }.bind(this));
	    if (this.commentViewContainer) this.commentView = new EA.DantesInferno.UserGenerated.CommentView(this, this.commentViewContainer, this.commentDataUrl);
		
		if (this.pageType == 'exploreHell') new EA.DantesInferno.UserGenerated.Share(this, $('explore'), this.pageType);
	},
	
	buildHTMLCache: function()
	{
	    this.togglebox = new Element('div', {'class': 'toggleBox'});
	    this.errorbox = this.togglebox.clone(false).addClass('error').set('html', '<div class="errorOuter"><div class="errorInner"><ul><li><h3>Error</h3></li><li><a href="#" class="close">X</a></li></ul><p>Sorry, this service is currently unavailable.</p></div></div>');
	},
	
	attachEvents: function()
	{
	    document.addEvent('updateUserGenerated', this.setAssetIdFromService.bind(this));
	},
	
	setAssetIdFromService: function(assetId)
	{
	    this.assetId = assetId;
	    setAssetId(assetId);
	},
	
	/*
	setAssetIdFromPost: function(container)
	{
	    var assetId;
	    if ($(document.body).id == 'blogPost')
	    {
	        assetId = $('content').className.split('guid-')[1];
	    }
	    else
	    {
	        assetId = container.getParent('li').className.split(' first')[0].split('guid-')[1];
	    }
	    
	    setAssetId(assetId);
	    return assetId;
	},
	*/
	
	setAssetIdFromPost: function(container)
	{
	    //var assetId;
	    if ($(document.body).id == 'blogPost')
	    {
	        this.assetId = $('content').className.split('guid-')[1];
	    }
	    else
	    {
	        this.assetId = container.getParent('li').className.split(' first')[0].split('guid-')[1];
	    }
	    
	    //setAssetId(assetId);
	    return this.assetId;
	},
	
	setIdFromCommentFlag: function(container)
	{
	    var id = container.getElement('a').hash.substr(1);
	    
	    setCommentId(id);
	    return id;
	},
	
	// Public Methods
	getData: function(toggleClass, type)
	{
		// make request for HTML data
	    this.req = new Request({
			url: this.contentUrl[type],
			method: 'GET',
			onSuccess: toggleClass.success.bind(toggleClass),
			onFailure: toggleClass.error.bind(toggleClass)
		}).send();
	},
	
	getToggleBox: function(type, html)
	{
		var box = this.togglebox.clone(false).addClass(type);
	    if (typeof html == 'object')
	    {
	         box.adopt(html);
	    }
	    else
	    {
	         box.set('html', html);
	    }
	    box.inject($(document.body));
        return box;
	},
	
	getErrorBox: function()
	{
	    this.errorbox.inject($(document.body));
	    return this.errorbox;
	},
	
	getAssetId: function(type, container)
	{
	    if (this.pageType == 'blog') return this.setAssetIdFromPost(container);
	    if (type == 'flag') return this.setIdFromCommentFlag(container);
	    
	    return this.assetId;
	},
	
	getLoggedInUserId: function()
	{
	    return localDiUserId;
	},
	
	getLoggedInUserEmail: function()
	{
	    return localDiUserEmail;
	},
	
	isSignedIn: function()
	{
	    return (localDiLoggedIn == null || localDiLoggedIn == 'false') ? false : true;
	}
});

/**
 *	EA.DantesInferno.UserGenerated.ToggleBox
 */
EA.DantesInferno.UserGenerated.ToggleBox = new Class({
    _signedOutContentId: 'signedOut',
    _signedInContentId: 'signedIn',
    
    // Constructor
	initialize: function(manager, container)
	{
		this.manager = manager;
		this.container = container;
		
		// set up methods
		this.buildCache();
		this.attachGlobalEvents();
	},
	
	// Private Methods
	buildCache: function()
	{
	    this.type = this.container.getProperty('class');
	    this.link = this.container.getElement('a');
	    // bound function calls
	    this.bOnCloseClick = this.onCloseClick.bind(this);
	    this.bOnKeydown = this.onKeydown.bind(this);
	},
	
	attachGlobalEvents: function()
	{
	    this.link.addEvent('click', this.onLinkClick.bind(this));
		document.addEvent('displayUserGenerated', this.setVisibility.bind(this));
		document.addEvent('updateScreen', this.setVisibilityToHidden.bind(this));
	},
	
	onLinkClick: function(event)
	{
		if (event) event.stop(); // prevent browser default
	    
	    if (this.box)
        {
            this[(this.isOpen) ? 'hide' : 'show']();
        }
        else
        {
            this.manager.getData(this, this.type);
        }
	},
	
	setVisibility: function(box)
	{
	    if (this.box == box || this.box == null || this.box == 'undefined') return;
	    
	    this.hide();
	},
	
	setVisibilityToHidden: function()
	{
	    if (this.box == null || this.box == 'undefined') return;
	    
	    this.hide();
	},
	
	success: function(html)
	{
		this.hasError = false;
	    this.box = this.manager.getToggleBox(this.type, html);
	    this.show();
	},
	
	error: function()
	{
	    this.hasError = true;
	    this.box = this.manager.getErrorBox();
	    this.show();
	},
	
	show: function()
	{
	    this.isOpen = true;
	    this.buildContent();
	    this.setCoordinates();
	    document.fireEvent('displayUserGenerated', [this.box]);
	    this.box.show();
	},
	
	hide: function()
	{
	    this.isOpen = false;
	    this.destroyContent();
        this.box.hide();
	},
	
	buildContent: function()
	{
	    this.attachContentEvents();
	    
	    if (this.hasError) return;
	    
	    if (this.manager.isSignedIn()) // signed in
        {
            this.box.getElement('div.' + this._signedOutContentId).hide();
            this.box.getElement('div.' + this._signedInContentId).show();
            
            this.buildSignedInContent();
        }
        else // signed out
        {
            this.box.getElement('div.' + this._signedInContentId).hide();
            this.box.getElement('div.' + this._signedOutContentId).show();
        
            this.buildSignedOutContent();
        }
	},
	
	attachContentEvents: function()
	{
	    this.closeLink = this.box.getElement('a.close');
	    this.closeLink.addEvent('click', this.bOnCloseClick);
	    document.addEvent('keydown', this.bOnKeydown);
	},
	
	onCloseClick: function(event)
	{
	    event.stop(); // prevent browser default
	    this.hide();
	},
	
	onKeydown: function(event)
	{
	    if (event.key != 'esc') return;
	    this.hide();
	},
	
    buildSignedOutContent: function()
	{
	    // add GUS redirect to login and register links
	    this.box.getElements('div.' + this._signedOutContentId + ' a').each(function(link){
            link.addEvent('click', function(){
                if (link.hasClass('login'))
                {
                    loginRedirect();
                    return false;
                }
                registerRedirect();
                return false;
            });
            
        });
	},
	
	buildSignedInContent: function()
	{
	    this.box.getElement('input[name=assetId]').setProperty('value', this.manager.getAssetId(this.type, this.container)); // set asset ID
	    this.box.getElement('input[name=userId]').setProperty('value', this.manager.getLoggedInUserId()); // set user ID
	    this.box.getElement('form').setProperty('action','/'+regionLocator+'/'+contentType+'/'+this.manager.getAssetId(this.type, this.container)+'/comment');	    
	    this.box.getElement('input[name=contentId]').setProperty('value',this.manager.getAssetId(this.type, this.container));
	    this.box.getElement('input[name=region]').setProperty('value',regionLocator);
	    this.box.getElement('input[name=pageLabel]').setProperty('value',pageLabel);
	    this.box.getElement('input[name=pageType]').setProperty('value',contentType);
	    this.box.getElement('input[name=currentPage]').setProperty('value',pageIndex);
	    this.box.getElement('textarea[name=comment]').setProperty('value', '');
	},
	
	setCoordinates: function()
	{
	    this.box.setStyles({'visibility': 'hidden', 'display': 'block'}); // set visibility and display styles to get dimensions
	    
		var boxCoordinates = this.box.getCoordinates();
		var containerCoordinates = this.container.getCoordinates(document);
		var containerCenter = containerCoordinates.left + (containerCoordinates.width / 2);
		var computedLeft, computedTop;
		
		if (this.pageType == 'exploreHell')
		{
			computedLeft = containerCoordinates.left + 19;
			computedTop = containerCoordinates.height - boxCoordinates.height - 13;
		}
		else
		{
			computedLeft = containerCenter - (boxCoordinates.width / 2);
			if (computedLeft < 0) computedLeft = 0;
			computedTop = containerCoordinates.top - boxCoordinates.height;
		}
		
		this.box.addClass('toggleBox');
	    this.box.setStyles({'position': 'absolute', 'left': computedLeft, 'top': computedTop, 'visibility': 'visible', 'display': 'none'}); // make sure to reset visibility and display
	},
	
	destroyContent: function()
	{
	    this.closeLink.removeEvent('click', this.bOnCloseClick);
	    document.removeEvent('keydown', this.bOnKeydown);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Title
 */
EA.DantesInferno.UserGenerated.Title = new Class({
    // Constructor
	initialize: function(manager, container)
	{
		this.manager = manager;
		this.container = container;
		
		// set up methods
		this.attachEvents();
	},
	
	attachEvents: function()
	{
	    document.addEvent('updatePlayer', this.update.bind(this));
	},
	
	update: function(data)
	{
	    this.container.set('text', data.title);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Rate (extends ToggleBox)
 */
EA.DantesInferno.UserGenerated.Rate = new Class({
    Extends: EA.DantesInferno.UserGenerated.ToggleBox,
    
    // Constructor
	initialize: function(manager, container, pageType)
	{
	    this.pageType = pageType;
	    
		// call parent
		this.parent(manager, container);
		
		this.build();
	},
	
	// Private methods
	buildCache: function()
	{
	    this.list = this.container.getElement('ul');
	    this.count = 0;
	    
	    this.rateReq = new Request({
	        method: 'GET',
		    onSuccess: this.setGlobalRating.bind(this),
			onFailure: $empty
        });
	    
	    // call parent method
	    this.parent();
	},
	
	build: function()
	{
	    this.list.getChildren('li').each(function(option, i){
	        // store count
			option.store('data', {'count': i + 1});
			
			// star click event
			option.addEvents({
			    'click': this.onClick.bind(this),
			    'mouseover': this.onMouseHover.bind(this),
			    'mouseout': this.onMouseHover.bind(this)
		    });
		}.bind(this));
	},
	
	attachGlobalEvents: function()
	{
	    document.addEvent('updateRating', this.update.bind(this));
	    document.addEvent('displayUserGenerated', this.setVisibility.bind(this));
	},
	
	onMouseHover: function(event)
	{
	    var target = event.target;
	    var data = target.retrieve('data');
	    
	    if (this.currentRatingClass == null)
	    {
	        this.currentRatingClass = this.list.className;
	    }
	    
	    this.list.className = 'on'+data.count;
	    if (event.type == 'mouseout')
	    {
	        this.list.className = this.currentRatingClass;
	    }
	},
	
	onClick: function(event)
	{
	    var target = event.target;
		var data = target.retrieve('data');
		this.count = data.count;

        if (this.manager.isSignedIn())
	    {
	        this.setData();
	        return;
	    }
	    
        if (this.box)
        {
            this.show();
        }
        else
        {
            this.manager.getData(this, this.type);
        }
	},
	
	setData: function()
	{
	    this.assetId = this.manager.getAssetId();
	    
	    this.rateReq.send({url: '/'+regionLocator+'/'+((this.pageType == 'blog') ? 'blog' : 'media')+'/'+this.assetId+'/star?stars='+this.count});
	},
	
	buildContent: function()
	{
	    this.attachContentEvents();
	    this.buildSignedOutContent();
	},
	
	update: function(rating)
	{
	    this.count = rating;
	    this.currentRatingClass = 'on' + this.count;
	    var prevRatingClass = this.list.getProperty('class');
	    
	    if (prevRatingClass)
	    {
            this.list.removeClass(prevRatingClass);
	    }
	    this.list.addClass(this.currentRatingClass);
	},
	
	setGlobalRating: function(rating)
	{
	    this.count = rating;
	    this.currentRatingClass = 'on' + this.count;
	    this.list.addClass(this.currentRatingClass);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Comment (extends ToggleBox)
 */
EA.DantesInferno.UserGenerated.Comment = new Class({
    Extends: EA.DantesInferno.UserGenerated.ToggleBox,
    
    // Constructor
	initialize: function(manager, container, territoryGateCookieName)
	{
	    this.territoryGateCookieName = territoryGateCookieName;
	    
		// call parent
		this.parent(manager, container);
	},
	
	// Private methods
	buildCache: function()
	{
	    // call parent
	    this.parent();
	    
	    // bound function calls
	    this.bOnSubmitClick = this.onSubmitClick.bind(this);
	},
	
	buildSignedInContent: function()
	{
	    // add language parameter to terms of service link
        var termsOfServiceLink = this.box.getElement('div.' + this._signedInContentId).getElement('a');
        termsOfServiceLink.setProperty('href', termsOfServiceLink.getProperty('href') + '?language=' + Cookie.read(this.territoryGateCookieName));
        
        // add button event to close box
        this.box.getElement('button[type=submit]').addEvent('click', this.bOnSubmitClick);
        
        // call parent
        this.parent();
	},
	
	onSubmitClick: function(event)
	{
	    this.hide();
	},
	
	destroyContent: function()
	{
	    // call parent
	    this.parent();
	    
	    this.box.getElement('button[type=submit]').removeEvent('click', this.bOnSubmitClick);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Share (extends ToggleBox)
 */
EA.DantesInferno.UserGenerated.Share = new Class({
    Extends: EA.DantesInferno.UserGenerated.ToggleBox,
    
     // Constructor
	initialize: function(manager, container, pageType)
	{
	    this.pageType = pageType;
	    
		// call parent
		this.parent(manager, container);
	},
	
	buildCache: function()
	{
		// call parent
		this.parent();
		
		this.type = 'share';
	    
	    // bound function calls
	    this.bOnFieldClick = this.onFieldClick.bind(this);
	    this.bOnSubmitClick = this.onSubmitClick.bind(this);
	},
	
	attachGlobalEvents: function()
	{
		// call parent
		if (this.pageType != 'exploreHell') this.parent();
	    
	    document.addEvent('updatePlayer', this.updateData.bind(this));
		document.addEvent('toggleExploreHellShare', this.onLinkClick.bind(this));
		document.addEvent('closeExploreHellShare', this.setVisibilityToHidden.bind(this));
	},
	
	// Private methods
	onLinkClick: function(level)
	{
		this.levelOfHell = level;
		
		// call parent
		this.parent();
		return false;
	},
	
	updateData: function(data)
	{
	    this.data = data;
	},
	
	buildContent: function()
	{
	    this.buildURL();
	    this.buildEmbed();
	    this.buildPostToSocialNetwork();
	    
	    // call parent
	    this.parent();
	},
	
	attachContentEvents: function()
	{
	    // call parent
	    this.parent();
	    
	    this.embedField.addEvent('click', this.bOnFieldClick);
	    this.urlField.addEvent('click', this.bOnFieldClick);
	},
	
	buildSignedInContent: function()
	{
	    this.box.getElement('input[name=accountId]').setProperty('value', this.manager.getLoggedInUserId()); // set user ID
	    this.box.getElement('input[name=accountEmail]').setProperty('value', this.manager.getLoggedInUserEmail()); // set sender of email
	    this.box.getElement('input[name=assetUrl]').setProperty('value', this.displayUrl); // set external ID of the asset
	    this.box.getElement('button[type=submit]').addEvent('click', this.bOnSubmitClick);
	    this.buildEmail();
	},
	
	onSubmitClick: function(event)
	{
	    this.hide();
	},
	
	buildEmail: function()
	{
	    // get fields
	    this.form = this.box.getElement('form');
	    this.emailField = this.box.getElement('input#toEmail');
	    
	    // create validator
	    this.validator = new FormValidator(this.form, {
	        evaluateFieldsOnBlur: false,
	        errorPrefix: '',
	        onFormValidate: this.setData.bind(this)
	    });
	    
	    // add error container
	    this.errorContainer = this.box.getElement('div#shareErrors');
	    if (!this.errorContainer)
	    {
	        this.errorContainer = new Element('div', {'id': 'shareErrors'});
	        this.errorContainer.inject(this.emailField.getParent('fieldset'), 'before');
        }
        
        // add class to show erros in error container
	    this.emailField.addClass("msgPos:'shareErrors'");
	},
	
	buildEmbed: function()
	{
	    // get field
	    this.embedField = this.box.getElement('input[name=shareEmbed]');	    
	    
	    // set value if type is video, hide if img
	    if (this.data == null || this.data.type == 'image' || this.pageType == 'blog' || this.pageType == 'exploreHell')
	    {
	        this.box.getElement('label[for=shareEmbed]').hide();
            this.embedField.hide();
            return;
        }
		
        this.externalEmbedCode = '<object width="656" height="369"><param name="movie" value="http://www.dantesinferno.com/flash/editorialPod.swf" /><param name="wmode" value="opaque" /><param name="scale" value="noscale" /><param name="salign" value="tl" /><param name="bgcolor" value="#000000" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="flashvars" value="configFile=http://www.dantesinferno.com/'+regionLocator+'/media!xmlfeed?id=' + assetId + '&amp;singleVideoEmbedCode=http://www.dantesinferno.com/'+regionLocator+'/media!xmlfeed?id=' + assetId + '&amp;epItemDelay=4500&amp;loopVideo=false&amp;textColor=#ffffff&amp;btnOutColor=#ffffff&amp;btnOverColor=#2d83f7&amp;btnDownColor=#155eca&amp;controlsBGColor=#000000" /><embed src="http://www.dantesinferno.com/flash/editorialPod.swf" width="656" height="369" flashvars="configFile=http://www.dantesinferno.com/'+regionLocator+'/media!xmlfeed?id=' + assetId + '&amp;singleVideoEmbedCode=http://www.dantesinferno.com/'+regionLocator+'/media!xmlfeed?id=' + assetId + '&amp;epItemDelay=4500&amp;loopVideo=false&amp;textColor=#ffffff&amp;btnOutColor=#ffffff&amp;btnOverColor=#2d83f7&amp;btnDownColor=#155eca&amp;controlsBGColor=#000000" wmode="opaque" scale="noscale" salign="tl" bgcolor="#000000" allowscriptaccess="always" allowfullscreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"></embed></object>';
        
        this.embedField.value = this.externalEmbedCode;
	},
	
	buildURL: function()
	{
	    // get field
	    this.urlField = this.box.getElement('input[name=shareUrl]');
	    // build value
	    var currentUrl = document.location.toString();
	    var anchor='';
	    var anchorIndex = currentUrl.indexOf('#');
	    
	    // Is an anchor (# and more) present?
	    if(anchorIndex != -1){
	    	anchor = currentUrl.substring(anchorIndex);
	    	currentUrl = currentUrl.substring(0,anchorIndex);
	    }
	    
		if (this.pageType == 'home' || this.pageType == 'blog')
	    {
	        this.displayUrl = currentUrl;
	    }
		else if (this.pageType == 'exploreHell')
		{
			this.displayUrl = currentUrl + '?level=' + this.levelOfHell;
		}
	    else
	    {
	        var querystring = '?id=' + this.data.id;
	        this.displayUrl = (document.location.search == '' || document.location.search == null) ? currentUrl + querystring : currentUrl.replace(/\?(id)\=\d+/, querystring);
	    }
	    
	    // set value
	    this.urlField.value = this.displayUrl + anchor;
	},
	
	buildPostToSocialNetwork: function()
	{
	    if (this.pageType == 'blog')
	    {
	        var postToSocialNetworkContainer = this.box.getElement('div.gigya');
	        postToSocialNetworkContainer.hide();
	        postToSocialNetworkContainer.getPrevious('h3').hide();
	        return;
	    }
	    
		var gigyaShareControl;
		if (this.pageType == 'exploreHell')
		{
			gigyaShareControl = new Swiff('/flash/share.swf', {id: 'quickPost', container: $('postToSocialNetwork'), width: 160, height: 160, vars: {}});
			return;
		}
	    var imageEmbed = '<img alt="'+this.data.title+'" src="'+this.data.image+'" />';
	    gigyaShareControl = new Swiff('/flash/share.swf', {id: 'quickPost', container: $('postToSocialNetwork'), width: 160, height: 160, vars: {mediaType: this.data.type, mediaLink: this.displayUrl, mediaId: (this.data.type == 'video') ? this.externalEmbedCode : imageEmbed, previewUrl: this.data.thumb}});
	},
	
	onFieldClick: function(event)
	{
	    var target = event.target;
	    target.focus();
	    target.select();
	},
	
	setData: function(passed, form, event)
	{
	    if (passed) this.parent(event);
	},
	
	destroyContent: function()
	{
	    // call parent
	    this.parent();
	    
	    this.embedField.removeEvent('click', this.bOnFieldClick);
	    this.urlField.removeEvent('click', this.bOnFieldClick);
	    this.box.getElement('button[type=submit]').removeEvent('click', this.bOnSubmitClick);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Download
 */
EA.DantesInferno.UserGenerated.Download = new Class({
    // Constructor
	initialize: function(manager, container)
	{
	    this.manager = manager;
	    this.container = container;
	    
	    // set up methods
	    this.buildCache();
	    this.attachEvents();
	},
	
	// Private methods
	buildCache: function()
	{
	    this.link = this.container.getElement('a');
	    this.bOnLinkClick = this.onLinkClick.bind(this);
	},
	
	attachEvents: function()
	{
	    document.addEvent('updateDownload', this.update.bind(this));
	},
	
	update: function(data)
	{
	    this.data = data;
	    
	    if (this.data.type == 'image')
	    {
	        this.link.href = this.data.downloadImage;
	        this.link.target = '_blank';
	        this.link.removeClass('disabled');
	        this.link.removeEvent('click', this.bOnLinkClick);
	        return;
	    }
	    this.link.href = '';
	    this.link.addClass('disabled');
	    this.link.addEvent('click', this.bOnLinkClick);
	},
	
	onLinkClick: function(event)
	{
	    event.stop(); // prevent browser default
	}
});

/**
 *	EA.DantesInferno.UserGenerated.Flag (extends ToggleBox)
 */
EA.DantesInferno.UserGenerated.Flag = new Class({
    Extends: EA.DantesInferno.UserGenerated.ToggleBox,
    
    // Constructor
	initialize: function(manager, container)
	{
		// call parent
		this.parent(manager, container);
	}
});

/**
 *	EA.DantesInferno.UserGenerated.CommentView (extends ScrollingBox)
 */
EA.DantesInferno.UserGenerated.CommentView = new Class({
    Extends: EA.DantesInferno.ScrollingBox,
    
	// Constructor
	initialize: function(manager, container, dataUrl)
	{
	    this.manager = manager;
		this.container = container;
		this.dataUrl = dataUrl;
		
		// set up methods
		this.buildCache();
		
		// call parent method
		this.parent(this.container);
	},
	
	// Public methods
	buildCache: function()
	{
	    // comment cache
	    this.cache = {};
		this.cache.list = new Element('ol');
		this.cache.item = new Element('li');
		this.cache.controlsList = new Element('ul');
		this.cache.timestamp = new Element('li', {'class': 'timestamp'});
		this.cache.author = new Element('li', {'class': 'author'});
		this.cache.flag = new Element('li', {'class': 'flag'});
		this.cache.flagLink = new Element('a', {'href': '#'}).set('text', 'Flag It');
		this.cache.copy = new Element('p');
		
		// request cache
		this.req = new Request.JSON({
		    headers: {'Content-Type': 'application/json; charset=utf-8'},
		    method: 'GET',
		    onSuccess: this.success.bind(this),
			onFailure: this.error.bind(this)
	    });
	},
	
	attachEvents: function()
	{
	    // call parent
	    this.parent();
	    
	    document.addEvent('updateComments', this.build.bind(this));
	},
	
	build: function(mediaId)
	{
	    this.mediaId = mediaId;
	    
	    this.getData();
	},
	
	getData: function()
	{
	    this.req.send({url: this.dataUrl + '?mediaid=' + this.mediaId});
	},
	
	success: function(data)
	{
		this.data = data.comments;
		
		this.destroyHTML();
		this.buildHTML();
		this.refresh(); // refresh scrolling box
	},
	
	error: function()
	{
	    this.container.set('html', '<p class="error">This content is currently unavailable.</p>');
	    this.refresh(); // refresh scrolling box
	},
	
	destroyHTML: function()
	{
	    var list = this.container.getElement('ol');
		if (list) list.destroy(); // clear out old results if they exist
		this.flags = null;
	},
	
	buildHTML: function()
	{
	    var item, controlsList, timestamp, author, flag, flagLink, copy;
	    this.flags = [];
		this.data.each(function(comment, i){
		    // create
			item = this.cache.item.clone(false);
			if (i == 0) item.set('class', 'start'); // first item has a unique class
			controlsList = this.cache.controlsList.clone(false);
			timestamp = this.cache.timestamp.clone().set('text', comment.date);
			author = this.cache.author.clone().set('text', comment.author);
			flagLink = this.cache.flagLink.clone().set('href', '#' + comment.id);
			flag = this.cache.flag.clone();
			copy = this.cache.copy.clone().set('text', comment.copy);
			
			// inject
			timestamp.inject(controlsList);
			author.inject(controlsList);
			flagLink.inject(flag);
			flag.inject(controlsList);
			controlsList.inject(item);
			copy.inject(item);
			item.inject(this.cache.list);
			
			// create flag instance
			this.flags[i] = new EA.DantesInferno.UserGenerated.Flag(this.manager, flag);
		}.bind(this));
		this.cache.list.inject(this.container);
	}
});

/**
 *	EA.DantesInferno.Tabs (implements Clientcide TabSwapper class)
 */
EA.DantesInferno.Tabs = new Class({
	Implements: Options,
	
	options: {
		selectedClass: 'on',
		tabs: 'ul.tab-controls li',
		clickers: 'ul.tab-controls li a',
		sections: 'div.tab',
		cookieName: null // remember what the last tab the user clicked when leaving and returning to page
	},
	
	// Constructor
	initialize: function(container, options)
	{
		this.container = container;
		this.setOptions(options);
		
		// set up methods
		this.build();
	},
	
	// Private Methods
	build: function()
	{
	    $$(this.options.tabs).each(function(tab, i){
		    tab.getElement('a').adopt(new Element('div', {'class': 'tabControl'}));
        });
        
		new TabSwapper({
			selectedClass: this.options.selectedClass,
			tabs: $$(this.options.tabs),
			clickers: $$(this.options.clickers),
			sections: $$(this.options.sections),
			cookieName: this.options.cookieName,
			smooth: this.options.smooth,
			smoothSize: this.options.smoothSize
		});
	}
});

/**
 *	EA.DantesInferno.VideoPlayer (implements Ooyala video player)
 */
EA.DantesInferno.VideoPlayer = new Class({
    // Constructor
	initialize: function(container)
	{
	    this.container = container;
		this.containerOverlay = $('videoPlayerOverlay');
		this.isApiAvailable = false;
		this.containerOverlay.setStyle('visibility', 'hidden');
		// set up methods
		this.attachEvents();
	},
	
	// Public Methods (used for Ooyala API)
	setVideoEvent: function(id, eventName, params)
	{
	    this.player = $(id);
	    this.eventName = eventName;
	    this.params = params;
	    
	    this.eventChanged();
	},
	
	// Private Methods
	attachEvents: function()
	{
	    document.addEvent('updatePlayer', this.build.bind(this));
	},
	
	build: function(data)
	{
	    this.data = data;
	   
	    if (this.data.type == 'video')
		{
			//this.show();
			this.update();
			
			return;
		}
		//this.hide();
	},
	
	update: function()
	{
	    if (this.player == null)
	    {
	        this.containerOverlay.setStyle('visibility', 'hidden');
	        this.isVideoInQueue = true;
	        return;
        }
        this.isVideoInQueue = false;
        this.isApiAvailable = true;
        this.player.setEmbedCode(this.data.flv)
	},
	
	/*
	show: function()
	{
	    this.container.show();
	},
	
	hide: function()
	{
	    this.container.hide();
	},
	*/
	
	eventChanged: function()
	{
	    if (this.eventName == 'embedCodeChanged')
	    {
	        this.containerOverlay.setStyle('visibility', (this.isApiAvailable) ? 'hidden' : 'hidden');
	        return;
	    }
	    
	    if (this.eventName == 'apiReady' && this.isVideoInQueue)
	    {
	        this.update();
	        return;
	    }
	    
	    if (this.params.state == null || this.eventName != 'stateChanged' || this.params.state != 'buffering') return;
	    document.fireEvent('toggleSound');
	}
});

/**
 *	EA.DantesInferno.ImagePlayer
 */
EA.DantesInferno.ImagePlayer = new Class({
    // Constructor
	initialize: function(container)
	{
		this.container = container;
		
		// set up methods
		this.buildCache();
		this.attachEvents();
	},
	
	buildCache: function()
	{
	    this.image = new Element('img', {'alt': '', 'src': '', 'width': '602', 'height': '336'});
	    this.image.inject(this.container);
	},
	
	attachEvents: function()
	{
	    document.addEvent('updatePlayer', this.build.bind(this));
	},
	
	build: function(data)
	{
	    this.data = data;
	    
	    if (this.data.type == 'image')
		{
			this.show();
			this.update();
			
			return;
		}
		this.hide();
	},
	
	update: function()
	{
	    this.image.set('src', this.data.image);
	},
	
	show: function()
	{
	    this.container.show();
	},
	
	hide: function()
	{
	    this.container.hide();
	}
});

/**
 *	EA.DantesInferno.Media
 */
EA.DantesInferno.Media = new Class({
    // Constructor
	initialize: function(container, dataUrl)
	{
		this.container = container;
		this.dataUrl = dataUrl;
		
		// set up methods
		this.buildCache();
		this.buildRequest();
		this.getFormFields();
		this.attachEvents();
		this.setCriteria();
		this.getData();
	},
	
	// Private methods
	buildCache: function()
	{
	    this.criteria = {};
	    this.searchquery = '';
	    this.isInitialLoad = true;
		// cache references
		this.results = new EA.DantesInferno.Media.Results(this.container.getElement('div#mediaResults'));
		this.imagePlayer = new EA.DantesInferno.ImagePlayer($('imagePlayer'));
		this.imagePlayer.hide();
	},
	
	buildRequest: function()
	{
	    this.req = new Request.JSON({
		    headers: {'Content-Type': 'application/json; charset=utf-8'},
		    method: 'GET',
		    onSuccess: this.success.bind(this),
			onFailure: this.error.bind(this)
	    });
	},
	
	getFormFields: function()
	{
	    this.allFilters = this.container.getElements('input');
		this.filters = this.container.getElements('#filter input');
		this.sortByFilters = this.container.getElements('input[name=sortby]');
	},
	
	attachEvents: function()
	{
	    document.addEvent('updateScreen', this.update.bind(this));
	    
	    this.allFilters.each(function(filter){
			var label = filter.getNext('label');
			label.addEvent('click', this.onFilterClick.bind(this));
			filter.addEvent('click', this.onFilterClick.bind(this));
		}.bind(this));
	},
	
	onFilterClick: function(event)
	{
		this.setCriteria();
		this.getData();
	},
	
	setCriteria: function()
	{
	    this.getFilterCriteria();
	    this.getSortByValue();
	},
	
	getFilterCriteria: function()
	{
	    this.filters.each(function(filter){
		    this.criteria[filter.value] = (filter.checked) ? 1 : 0;
		}.bind(this));
	},
	
	getSortByValue: function()
	{
	    this.sortByFilters.each(function(filter){
	        if (filter.checked)
	        {
	            this.criteria['sortby'] = filter.value;
	            return;
	        }
	    }.bind(this));
	    
	    if (this.criteria['sortby'] == null || this.criteria['sortby'] == 'undefined') this.criteria['sortby'] = 0;
	},
	
	getData: function()
	{
	    if (this.searchquery == Hash.toQueryString(this.criteria)) return; // only send request if criteria is different
	    
	    this.searchquery = Hash.toQueryString(this.criteria);
	    if (this.isInitialLoad)
	    {
	        this.itemquery = this.getItemFromQueryString();
	        this.query = '?' + this.searchquery + ((this.itemquery == '') ? '' : '&id=' + this.itemquery);
	    }
	    else
	    {
	        this.query = '?' + this.searchquery;
	    }
	    this.isInitialLoad = false;
	    this.req.send({url: this.dataUrl + this.query});
	},
	
	getItemFromQueryString: function()
	{
	    var querystring = document.location.search;
	    if (querystring != '')
	    {
	        return querystring.split('=')[1];
	    }
	    var currentLocation = document.location.toString();
	    var openingIndex = currentLocation.lastIndexOf('/');
	    var closingIndex = currentLocation.lastIndexOf('!show');
	    if (closingIndex > 0)
	    {
	        return currentLocation.substring(openingIndex + 1, closingIndex);
	    }
	    return '';
	},
	
	success: function(data)
	{
		this.data = data.content;
        
		document.fireEvent('updateResults', [this.data, this.itemquery]);
	},
	
	error: function()
	{
	    document.fireEvent('updateResults', 'error');
	},
	
	update: function(data)
	{
	    var currentItemNumber = data.currentItemNumber;
	    var dataset = this.data[currentItemNumber]; // get appropriate dataset based of current item
	    
	    document.fireEvent('updatePlayer', [dataset]); // update video and image players
	    document.fireEvent('updateUserGenerated', [dataset.id]); // update user generated items (rate, comment, share) with ID to store data
	    document.fireEvent('updateComments', [dataset.id]); // update comments
	    document.fireEvent('updateRating', [dataset.rating]); // update rating
	    document.fireEvent('updateDownload', [dataset]); // update download
	}
});

/**
 *	EA.DantesInferno.Media.Results (extends EA.DantesInferno.ScrollingBox)
 */
EA.DantesInferno.Media.Results = new Class({
    Extends: EA.DantesInferno.ScrollingBox,
    
	// Constructor
	initialize: function(container)
	{
	    this.container = container;
		this.defaultItemNumber =  0;
		
		// set up methods
		this.buildCache();
		
		// call parent method
		this.parent(this.container);
	},
	
	// Public methods
	buildCache: function()
	{
	    this.cache = {};
		this.cache.list = new Element('ul');
		this.cache.item = new Element('li');
		this.cache.link = new Element('a', {'href': '#'});
		this.cache.thumbContainer = new Element('div', {'class': 'thumb'});
		this.cache.video = new Element('div', {'class': 'type video'});
		this.cache.image = new Element('div', {'class': 'type image'});
		this.cache.thumb = new Element('img', {'class': 'thumb', 'alt': '', 'src': '', 'width': 84, 'height': 47});
		this.cache.title = new Element('h4');
		this.cache.copy = new Element('p');
		this.cache.ratingsContainer = new Element('div', {'class': 'ratings'});
		this.cache.ratingsList = this.cache.list.clone(false);
		var item;
		for (var i = 1; i <= 5; i++)
		{
			item = this.cache.item.clone(false).set('class', 'star' + i);
			item.inject(this.cache.ratingsList);
		}
	},
	
	attachEvents: function()
	{
	    // call parent
	    this.parent();
	    
	    document.addEvents({
            'updateResults': this.build.bind(this),
            'updateScreen': this.highlight.bind(this)
        });
	},
	
	build: function(results, deepLinkedItemId)
	{
	    this.data = results;
	    this.currentItemNumber = this.defaultItemNumber;
	    
	    this.destroyHTML(); // clear previous
	    
	    if (this.data == 'error')
	    {
	        this.buildErrorHTML();
	    }
	    else
	    {
	        if (this.data.length > 0)
	        {
	            this.buildResultsHTML(deepLinkedItemId);
	            document.fireEvent('updateScreen', {'currentItemNumber': this.currentItemNumber}); // refresh screen by firing custom event
	        }
	        else
	        {
	            this.buildNoResultsHTML();
	        }
	    }
	    
		this.refresh(); // refresh scrolling box
	},
	
	destroyHTML: function()
	{
	    var list = this.container.getElement('ul');
		if (list) list.destroy(); // clear out old results if they exist
		var altCopy = this.container.getElement('p.error');
		if (altCopy) altCopy.destroy(); // clear out old "error" copy if it exists
	},
	
	buildResultsHTML: function(deepLinkedItemId)
	{
	    // build results list
		this.items = [];
		var item, titleLink, thumbContainer, type, thumbLink, thumb, title, rating, ratingsList, copy;
		this.data.each(function(data, i){
		    // get current item number if deeped linked
		    if (deepLinkedItemId && data.id == deepLinkedItemId) this.currentItemNumber = i;
	        
		    // create
			item = this.cache.item.clone(false);
			titleLink = this.cache.link.clone(false).set('href', '#' + data.id).set('onclick', "omniLinkCall(this, '" + data.title + "MediaLink')").addEvent('click', this.onResultClick.bind(this)).store('itemnumber', i);
			thumbContainer = this.cache.thumbContainer.clone(false);
			type = this.cache[data.type].clone();
			thumbLink = titleLink.clone().cloneEvents(titleLink).store('itemnumber', i);
			thumb = this.cache.thumb.clone().set({'src': data.thumb});
			titleLink.set('text', data.title);
			title = this.cache.title.clone();
			rating = this.cache.ratingsContainer.clone();
			ratingsList = this.cache.ratingsList.clone().set('class', 'on' + data.rating);
			copy = this.cache.copy.clone().set('text', data.copy.unescapeHTML().stripTags());
			
			// insert
			thumb.inject(thumbLink);
			type.inject(thumbLink);
			thumbLink.inject(thumbContainer);
			thumbContainer.inject(item);
			titleLink.inject(title);
			title.inject(item);
			ratingsList.inject(rating);
			rating.inject(item);
			copy.inject(item);
			item.inject(this.cache.list);
			this.items[i] = item;
		}.bind(this));
		this.cache.list.inject(this.container);
	},
	
	buildNoResultsHTML: function()
	{
	    this.container.set('html', '<p class="error">Sorry, there are no results that match the current search criteria.</p>');
	},
	
	buildErrorHTML: function()
	{
	    this.container.set('html', '<p class="error">Sorry, this content is currently unavailable.</p>');
	},
	
	onResultClick: function(event)
	{
	    // prevent browser default
	    event.stop();
	    
	    // get correct target of event
		var target = event.target;
		if (target.tagName != 'A') target = target.getParent('a');
		
	    // retrieve item number from "storage"
		this.currentItemNumber = target.retrieve('itemnumber');
		
		// return to top of page
        window.scrollTo(0, 0);
		
		document.fireEvent('updateScreen', {'currentItemNumber': this.currentItemNumber});
	},
	
	highlight: function()
	{
	    var prevOnImg = this.container.getElement('img.on');
	    if (prevOnImg) prevOnImg.removeClass('on'); // remove highlight from prev img if it exists
	    var prevOnTitle = this.container.getElement('h4.on');
	    if (prevOnTitle) prevOnTitle.removeClass('on'); // remove highlight from prev title if it exists
	    this.items[this.currentItemNumber].getElement('img').addClass('on');
	    this.items[this.currentItemNumber].getElement('h4').addClass('on');
	}
});

/**
 *	EA.DantesInferno.ExploreHell
 */
EA.DantesInferno.ExploreHell = new Class({
	_defaultLevel: 'treachery',
	_flashID: 'exploreHell',
	
    // Constructor
	initialize: function()
	{
		// set up methods
		this.buildCache();
		this.checkUrlForDeepLinking();
		this.buildFlash();
		this.setLevel(this._defaultLevel);
	},
	
	// Private methods
	buildCache: function()
	{
		// vars
		this.externalLink = true;
		this.externalLevel = this._defaultLevel;
	},
	
	checkUrlForDeepLinking: function()
	{
		var querystring = document.location.search;
		if (querystring == '') return;
	    
		this.externalLink = true;
		this.externalLevel = querystring.split('=')[1];
	},
	
	buildFlash: function()
	{
		var playerVersion = swfobject.getFlashPlayerVersion();
        if(playerVersion.major > 9 || playerVersion.major ==9 && playerVersion.release >= 115){
			new Swiff('/flash/dantes_preloader.swf', {id: this._flashID, container: 'explore', width: 990, height: 768, params: {quality: 'high', align: 'middle', play: 'true', loop: 'true', scale: 'showall', wmode: 'window', bgcolor: '#000000', menu: 'true', allowFullScreen: 'true', allowScriptAccess: 'always', base: '.'}, vars: {dantesPath: '/flash/', omniSuite: 'eaeacomdev', externalLink: this.externalLink, externalLevel: this.externalLevel}});
			this.flash = $(this._flashID);
        }else{
        	var att = { data:"/swf/expressinstall.swf", width:"990", height:"300" };
            var par = { bgcolor:"#000000", allowScriptAccess: 'always'};
            var id = "explore";
            
            swfobject.showExpressInstall(att, par, id, function(){});
        }
		//<p><a href="http://www.adobe.com/go/getflashplayer" target="_blank">This content requires Adobe Flash Player 10</a>.</p>
	},
	
	// Public methods (called from Flash)
	setLevel: function(level)
	{
		this.level = level.toLowerCase();
	},
	
	toggleShare: function()
	{
		document.fireEvent('toggleExploreHellShare', [this.level]);
	},
	
	closeShare: function()
	{
		document.fireEvent('closeExploreHellShare');
	},
	
	getShortenedUrl: function()
	{
		this.flash.trimURLFromJS(shortenedUrls[this.level]);
	}
});
EA.DantesInferno.exploreHell = {};

/**
 *	EA.DantesInferno.Vote
 */
EA.DantesInferno.Vote = new Class({
    // Constructor
	initialize: function(container, percentBar)
	{
		this.container = container;
		this.percentBar = percentBar;
		
		// set up methods
		this.getAllFormItems();
		this.attachEvents();
	},
	
	getAllFormItems: function()
	{
	    this.form = this.container.getElement('form');
	    this.voteFields = this.container.getElements('input');
	},
	
	attachEvents: function()
	{
   	    this.container.getElement('.submit').addEvent('click', this.onVoteSubmit.bind(this));
   	    this.container.getElement('.viewAll').addEvent('click', this.onViewResultsClick.bind(this));
	},
	
	onVoteSubmit: function(event)
	{
	    event.stop(); // prevent browser default

        var voted = false;
	    this.voteFields.each(function(voteField) { // check for checked radio button
            if (voteField.checked)
            {
                voted = true;
            }
        })

        if (voted)
        {
       	    this.buildHeader(event);
        }
        else
        {
            if (!$('voteError'))
            {
    	        this.errorContainer = new Element('div', {'id': 'voteError'});
	            this.errorContainer.inject(this.container.getElement('fieldset'), 'before');
	        }
	        this.errorContainer.set('text', 'Please select an item to cast your vote.');
        }
   	},
	
	onViewResultsClick: function(event)
	{
	    event.stop(); // prevent browser default
   	    this.buildHeader(event);
   	},
	
	buildHeader: function(event)
	{
	    this.message = new Element('h4')
	    this.message.inject( $('voteResults'), 'top');
	    if (event.target == this.container.getElement('button'))
	    {
	        this.message.set('text', 'Your vote was recorded');
	        // TODO: process poll vote submission
	    }
	    else
	    {
	        this.message.set('text', 'Poll results');
	    }
	    this.calculateGraphs();
	},
	
	calculateGraphs: function()
	{
        var onePercent = this.percentBar/100; // width of 1% of graph (289px)
        var votes = new Array(25, 50, 25); // set percentage of total votes
	    $('voteResults').getElements('.graph img').each(function(graphCnt, i){
            graphCnt.setStyle('width', onePercent * votes[i]+'px');
	    });
	    this.showResults();
	},
	
	showResults: function()
	{
	    $('voteResults').show();
	    $('voteForm').hide();

	    return false;
	}
});

/**
 *	EA.DantesInferno.BlogArchiveSlide
 */
EA.DantesInferno.BlogArchiveSlide = new Class({    
    // Constructor
	initialize: function(container, sliderClass)
	{
	    this.container = container;
	    this.slider = sliderClass;
		
		// set up methods
		this.build();
		this.attachEvents();
	},
	
	build: function()
	{
	    $$('.archiveMonth').each(function(month, i){
            var toggler = new Element('div', {'class': 'toggled'});
    	    toggler.inject(month.getElement('p'), 'after');
	    });
	},
	
	attachEvents: function()
	{
	    new Accordion($$('.archiveMonth div'), $$('.archiveMonth ol'), {
	        onActive: function() {
	            this.togglers.addClass('on').removeClass('off');
	            this.togglers[this.previous].addClass('off').removeClass('on');
	        }
	    });
	}
});

/**
 *	EA.DantesInferno.Newsletter
 */
EA.DantesInferno.Newsletter = new Class({
	
	_currentDate: new Date(),
	
    // Constructor
	initialize: function(button, contentUrl, apiURL)
	{
		button.addEvent('click', this.showLightbox.bind(this));
		this.contentUrl = contentUrl;
		this.apiURL = apiURL
		
		// set up methods
		this.buildCache();
		
		//Get the newsletter form HTML.
		this.getHTML();
		
		// Listen for the age & location.
		document.addEvent('setAge', this.getBirthdateFromAgeGateCookie.bind(this));
		document.addEvent('setLocation', this.getLocationFromGateCookie.bind(this));
	},
	
	getLocationFromGateCookie: function(location){
		this.location = location;
	},
	
	getHTML: function()
	{
		this.req = new Request.HTML({
			url: this.contentUrl,
			method: 'GET',
			onSuccess: this.build.bind(this)
		}).send();
	},
	
	build: function(html)
	{
		this.container.adopt(html);
		this.container.inject(document.body); // insert HTML data at bottom of page
	    
	    //this.showLightbox();
	},
	
	showLightbox: function(){
		Shadowbox.open({
		    player: 'inline',
		    title: ' ',
		    content: '#newsletter',
		    width: 488-12,
		    height: 469,
		    options: {
		        overlayOpacity: 0.65,
		        displayNav: true,
		        enableKeys: false, //Do not enable; doing so will disable typing into the form.
		        modal: false,
		        onFinish: this.buildForm.bind(this)
		    }
        });
	},
	
	buildCache: function()
	{
		this.container = new Element('div', {'id': 'newsletter'});
	},
	
	setInitialDisplay: function()
	{
	    //this.formContainer.hide();
	    this.successContainer.hide();
	    this.failureContainer.hide();
	},
	
	buildForm: function()
	{
	    var sb = $('sb-content');
	    this.formContainer = sb.getElement('div#newsletterForm');
	    this.successContainer = sb.getElement('div#newsletterSuccess');
	    this.failureContainer = sb.getElement('div#newsletterFailure');
	    
	    this.formContainer.show();
	    this.successContainer.hide();
	    this.failureContainer.hide();
	    
	    this.displayAgeSelector();
	    this.getAllFormItems();
		this.attachEvents();
	},
	
	buildSuccess: function(text, xml)
	{
		this.errorArea.innerHTML = "";
		
		var root = xml.documentElement;
		
		if(root.tagName == "error"){
			//Error.
			for(var i in root.childNodes){
				item = root.childNodes[i];
			
				if(item.tagName && item.tagName == "failure"){
					switch(item.attributes.getNamedItem('cause').value){
						case "INVALID_VALUE":
						case "INVALID_EMAIL_DOMAIN":
							switch(item.attributes.getNamedItem('field').value){
								case "emailAddress":	
									this.errorArea.innerHTML += "Please enter a valid email address. ";
									break;
								case "country":	
									this.errorArea.innerHTML += "Please select a valid country. ";
									break;
								case "birthDate":	
									this.errorArea.innerHTML += "Please select a valid birthdate. ";
									break;
								default:
									this.buildFailure();
							}
							break;
						
						case "EMAIL_ADDRESS_TOO_LONG":
							this.errorArea.innerHTML += "Your email address is too long (more than 256 characters). Please use a shorter address. ";
							break;
						
						case "MISSING_VALUE":
							switch(item.attributes.getNamedItem('field').value){
								case "emailAddress":	
									this.errorArea.innerHTML += "Please enter an email address. ";
									break;
								case "country":	
									this.errorArea.innerHTML += "Please select your country. ";
									break;
								case "birthDate":	
									this.errorArea.innerHTML += "Please select your birthdate. ";
									break;
								default:
									this.buildFailure();
							}
							break;
						
						case "TOO_YOUNG":
							this.errorArea.innerHTML += "Sorry, you are too young to sign up for this newsletter. ";
							break;
						
						default: 
							this.buildFailure();
					}
				}
			}
		}else{
			this.formContainer.hide();
		    this.successContainer.show();
		}
		
	},
	
	buildFailure: function()
	{
		this.formContainer.hide();
	    this.failureContainer.show();
	},
	
	getAllFormItems: function()
	{
		var sb = $('sb-content');
	    this.form = sb.getElement('form');
	    this.emailField = sb.getElement('input#email');
	    this.countryField = sb.getElement('select#country');

	    sb.getElements("select#country option").each(function(item, i){
	    	if(item.value == this.location){
	    		item.set({'selected':'selected'});
	    	}
	    }.bind(this));
	    this.submitButton = sb.getElement('input#submit');
	    this.optinField = sb.getElement("input#optin");
	    this.errorArea = sb.getElement("div.errors");
	},
	
	getBirthdateFromAgeGateCookie: function(birthdate)
	{
	    this.month = birthdate.getMonth() + 1;
	    this.day = birthdate.getDate();
	    this.year = birthdate.getFullYear();
	},
	
	convertToTwoDigits: function(num)
	{
	    num = String(num);
	    return (num.length < 2) ? '0' + num : num;
	},
	
	attachEvents: function()
	{
		this.submitButton.addEvent('click', this.submitForm.bind(this));
		this.form.addEvent('submit', this.submitForm.bind(this));
	},
	
	submitForm: function(event){
		if (event) event.stop();
		
		if(!this.emailField.value || this.emailField.value==''){
			this.errorArea.innerHTML = "Please enter your email.";
			return false;
		}
		
		if(!this.countryField.value){
			this.errorArea.innerHTML = "Please select your country.";
			return false;
		}
		
		if (!this.selectYear.value || this.selectYear.value == 0 ||
			!this.selectMonth.value || this.selectMonth.value == 0 ||
			!this.selectDay.value || this.selectDay.value == 0
		){
			this.errorArea.innerHTML = "Please select your birthdate.";
			return false;
		}
		
		this.errorArea.innerHTML = "";
		
		// Gather the form fields.
		var submission = {
			'emailAddress': this.emailField.value,
			'country': this.countryField.value,
			'birthDate': this.selectYear.value + '-' + this.convertToTwoDigits(this.selectMonth.value) + '-' + this.convertToTwoDigits(this.selectDay.value),
			'preferenceName': 'New-IP-Internal-Tracking-franchise-DantesInferno',
			'thirdPartyOptin': (this.optinField.checked ? "true" : "false")
		};
		
		// Send the data.
		var qs = "";
		for(var k in submission){
			if(qs != ""){
				qs += "&";
			}
			qs += k+"="+escape(submission[k]);
		}
		new Request({
			'url': this.apiURL,
			'method': 'get',
			'data':qs,
			'onSuccess': this.buildSuccess.bind(this),
			'onFailure': this.buildFailure.bind(this)
		}).send();
		
		return false; // Cancel bubble
	},
	
	displayAgeSelector: function()
	{
	    // create container
	    this.ageArea = $('sb-content').getElement("div#newsletterAge");
        this.birthdate = new Element('div', {'id': 'birthdate'});
	    // create generic select to clone
	    this.select = new Element('select', {'id': ''}).addEvent('change', this.changeAge.bind(this));
	    // create generic option to clone
	    this.option = new Element('option', {'value': '0'});
	    
        // create month dropdown
        this.selectMonth = this.select.clone().cloneEvents(this.select).set('id', 'birthdateMonth');
        var defaultOption = this.option.clone().set('text', 'Month');
        defaultOption.inject(this.selectMonth);
        this.monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        var option;
        this.monthNames.each(function(month, i){
            option = this.option.clone().set({'value': i+1, 'text': month});
            if(this.month == i+1) {
            	option.set({'selected':'selected'});
            }
            option.inject(this.selectMonth);
        }.bind(this));
	    
		// create days per month object
		this.daysPerMonth = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31};
		
        // create day dropdown
        this.selectDay = this.select.clone().cloneEvents(this.select).set('id', 'birthdateDay');
		defaultOption = this.option.clone().set('text', 'Day');
		defaultOption.inject(this.selectDay);
		for (var i = 1; i <= 31; i++)
	    {
		    option = this.option.clone().set({'value': i, 'text': i});
		    if(this.day == i) {
            	option.set({'selected':'selected'});
            }
			option.inject(this.selectDay);
	    }
        
		// create year dropdown
        this.selectYear = this.select.clone().cloneEvents(this.select).set('id', 'birthdateYear');
        defaultOption = this.option.clone().set('text', 'Year');
        defaultOption.inject(this.selectYear);
        for (var i = this._currentDate.getFullYear(); i >= 1900; i--)
	    {
		    option = this.option.clone().set({'value': i, 'text': i});
		    if(this.year == i) {
            	option.set({'selected':'selected'});
            }
		    option.inject(this.selectYear);
	    }
	    var before1900Option = this.option.clone().set({'value': '1900', 'text': 'Before 1900'});
        before1900Option.inject(this.selectYear);
		
        // insert date dropdowns into age gate
        this.selectMonth.inject(this.birthdate);
        this.selectDay.inject(this.birthdate);
		//this.selectDay.disabled = true; // day shouldn't be disabled. We'll deal with leap if it becomes an issue.
        this.selectYear.inject(this.birthdate);
        this.birthdate.inject(this.ageArea);
	},
	
	resetDayDropDown: function(maxDays)
	{
		var option, options = this.selectDay.getElements('option'), len = options.length, norm = maxDays + 1;
		if (len == norm) return; // old month and new month have same number of days 
		else if (len > norm) // old month has more days than new month
		{
			for (var i = len - 1; i > maxDays; i--)
			{
				options[i].dispose();
			}
		}
		else // old month doesn't have enough days
		{
			for (var i = len; i <= maxDays; i++)
		    {
			    option = this.option.clone().set({'value': i, 'text': i});
				option.inject(this.selectDay);
		    }
		}
	},
	
	changeAge: function(event)
	{
		// assemble the birthdate 
		var month = this.selectMonth.value;
		var day = this.selectDay.value;
		var year = this.selectYear.value;
		
		if (event.target.id == 'birthdateMonth' || event.target.id == 'birthdateYear')
		{
			if (month > 0)
			{
				this.resetDayDropDown(this.daysPerMonth[month]);
				this.selectDay.disabled = false;
				
				if (this.selectDay.value > this.daysPerMonth[month]) this.selectDay.value = 0;
			}
			
			if (month == 0 || year == 0)
			{
				this.selectDay.disabled = true;
				this.selectDay.value = 0;
			}
		}
	}
	
});

/**
 *	EA.DantesInferno.Gallery
 */
EA.DantesInferno.Gallery = new Class({
    // Constructor
	initialize: function(container)
	{
	    this.container = container;
	    
	    // set up methods
	    this.buildCache();
	    this.build();
	    this.buildLightbox();
	},
	
	buildCache: function()
	{
	    this.type = new Element('div', {'class': ''});
	},
	
	build: function()
	{
	    this.links = [];
	    var link, typeContainer;
	    this.container.getElements('li').each(function(item, i){
	        link = item.getElement('a');
	        this.links[i] = link;
	        
	        if (item.hasClass('video'))
	        {
	            link.set('rel', 'width=602;height=336');
                typeContainer = this.type.clone().set('class', 'type video');
	        }
	        else
	        {
	            typeContainer = this.type.clone().set('class', 'type image');
	        }
	        typeContainer.inject(link, 'top');
	    }.bind(this));
	},
	
	buildLightbox: function()
	{
	    Shadowbox.setup(this.links, {
	        continuous: true,
            gallery: 'Gallery'
        });
	}
});

/**
 *	EA.DantesInferno.SocialSkin
 */
EA.DantesInferno.SocialSkin = new Class({
	initialize: function(container, data)
	{
		this.container = container;
		this.data = data;
		
		// set up methods
		this.getData();
	},
	
	getData: function(){
		this.req = new Request.JSON({
		    noCache: true,
			url: this.data,
			method: 'GET',
			onSuccess: this.success.bind(this),
			onFailure: this.error.bind(this)
		}).send();
	},
	
	error: function()
	{
		alert('Error accessing data.');
	},
	
	success: function(data)
	{
		this.data = data.slides;
		
		this.build();
	},
	
	build: function()
	{
		var el = new Element("img", {src: this.data[0].image});
		el.inject(this.container, "top");
		
		var link = this.container.getElement('a');
		link.addEvent('click', this.showCode.bind(this));
	},
	
	showCode: function()
	{
		// Set the innerHTML (not the value) so that Shadowbox will pick up the code.
		$('myspaceLayoutPopupCode').innerHTML=this.data[0].code;
		
		Shadowbox.open({
		    player: 'inline',
		    content: '#myspaceLayoutPopup',
		    width: 748,
		    height: 480,
		    options: {
		        overlayOpacity: 0.8,
		        displayNav: true,
		        enableKeys: true,
		        modal: true
		    }
	    });
		
		return false;
	}	
});

/**
 *	EA.DantesInferno.GoToHellFeed
 */
EA.DantesInferno.GoToHellFeed = new Class({
	initialize: function(container, data)
	{
		this.container = container;
		this.data = data;
		
		// set up methods
		this.getData();
	},
	
	getData: function(){
		this.req = new Request.JSONP({
		    noCache: true,
			url: this.data,
			method: 'GET',
			onComplete: this.success.bind(this),
			onFailure: this.error.bind(this)
		}).send();
	},
	
	error: function()
	{
		//Couldn't fetch the feed.
	},
	
	success: function(data)
	{
		try{
			this.data = data.TotalSouls;
			this.container.set('html', this.data+' souls currently in Hell.');
		}catch(e){}
	}
});

/**
 *	Load functionality (on domready)
 */
window.addEvent('domready', EA.DantesInferno.init.bind(EA.DantesInferno));