function syfyGlobalHeader(container, options) {
	/* TODO:
		sort through our jquery rigamorale bs
		promos?
	*/

	// Dependencies
	window['Cufon'] || document.write('\x3Cscript type="text/javascript" src="http://www.syfy.com/_js/cufon-yui.js"/>\x3Cscript type="text/javascript" src="/_js/Syfy_550-Syfy_600.font.js"/>');


	if (options == undefined) { options = {} }

	var self=this;
	this.container = jqN('#'+container);
	this.headerContent = null;
	this.siteContext = null;

	if (/(^www\.syfy\.com|^syfy\.com|.*origin\.syfy\.com)/.test(window.location.hostname)) {
		this.siteContext = 'local';
	} else {
		this.siteContext = 'remote';
	}

	if (options.headerContent) {
		this.buildHeader(options.headerContent);
	} else {
		// grab header content via xhr
		jqN.ajax({
			url: 'http://www.syfy.com/json/globalheader',
			dataType: 'jsonp',
			success: function(json) {
				self.buildHeader(json);
			}
		});
	}

	var self=this;

}

syfyGlobalHeader.prototype.buildHeader = function(content) {
	var self=this;
	this.headerContent = content;
	
	//console.log(this.headerContent);
	
	// create promo
	if (content.backgroundPromo) {
		var promo;
		if (content.backgroundPromo.url != '') {
			promo = jqN('<a href="'+this.generateURL(content.backgroundPromo.url)+'" class="promo"></a>');
			if (content.backgroundPromo.openInNewWindowFlag == 'true') {
				promo.attr('target', '_blank');
			}
		} else {
			promo = jqN('<div class="promo"></div>');			
		}

		// one day i'm going to do this right
		if (typeof(content.backgroundPromo.shortDescription) === 'string' && typeof(content.backgroundPromo.longDescription) === 'string') {
			var textlabel = jqN('<div class="backgroundText"></div>');
			textlabel.append('<div class="title">'+content.backgroundPromo.shortDescription+'</div>');
			textlabel.append('<div class="subtitle">'+content.backgroundPromo.longDescription+'</div>');
			textlabel.appendTo(promo);	
		}

		promo.css('background', 'url('+content.backgroundPromo.baseCoverImageURL+') left top no-repeat');
		this.container.append(promo);

		if (window['Cufon'] != undefined) { Cufon.replace('#syfyGlobalHeader .promo .backgroundText div'); }

	}

	// create logo
	if (this.headerContent.headerLogo) {
		this.createLogo(this.headerContent.headerLogo);
	}

		// tune-in promo
		if (this.headerContent.tuneInPromo) {
			// break this out to its own deal eventually
			var tuneInContainer = jqN('<div id="tuneInContainer"></div>');
			for (pi in this.headerContent.tuneInPromo) {
				var promo = this.headerContent.tuneInPromo[pi];
				var link = jqN('<a class="promo" href="'+this.generateURL(promo.url)+'"></a>');
				link.append('<span>'+promo.shortDescription+'</span>');
				if (promo.title) { link.append('<span class="show">'+promo.title+'</span>'); }
				if (promo.openInNewWindowFlag == "true") { link.attr('target', '_blank'); }
				if (tuneInContainer.children().length > 0) { link.hide(); }
				link.appendTo(tuneInContainer);
				if (promo.linkType) { link.css('background-color', '#'+promo.linkType); }
			}

			self.container.css('margin-top', '30px');
			tuneInContainer.prependTo('BODY');

			Cufon.replace('#tuneInContainer span');

			if (this.headerContent.tuneInPromo.length > 1) {
				window.setInterval(function() {
					var current = tuneInContainer.find('.promo:visible');
					current.css('z-index', '995');
					var next = current.next();
					if (next.length == 0) { next = tuneInContainer.find('.promo:first'); }
					next.css('z-index', '996');
					next.fadeIn('slow', function() {
						current.hide();
					});
				}, 6000);
			}

		}

	// main nav items
	if (this.headerContent.mainNavigation) {
		// debug
		//this.headerContent.mainNavigation.push({openInNewWindowFlag: 'false', shortDescription: {}, title: 'Games', url: null});
		//console.log(this.headerContent.mainNavigation);

		
		var container = jqN('<div class="main_navigation"></div>').appendTo(this.container);	
		var wrapper = jqN('<div class="navitem_wrapper"></div>').appendTo(container);
		for (i=0;i<this.headerContent.mainNavigation.length;i++) {
			var menuItem = this.headerContent.mainNavigation[i];
			wrapper.append(this.createMainNavItem(menuItem));
		}

		if (window['Cufon'] != undefined) { Cufon.replace('#syfyGlobalHeader .main_navigation a'); }

		//social
		jqN(document).ready(function() {
			if (window['gigya'] != undefined) {
				if(typeof conf == 'undefined'){
					var conf = {
						APIKey: '2_847XhCe0zygxwG2Cnki_Jk--UI5FuxDzU5ZQUqr4NIMtMDfYYhu12nOOcfkPyqKI',
						enabledProviders: 'facebook,twitter,yahoo,messenger,google,linkedin,myspace,aol,foursquare'
					}
				}
				gigya.services.socialize.addEventHandlers(conf, {
					onLogin: function() { self.createLogoutButton(); },
					onLogout: function() { self.createLoginButton(); }
				});
	
				gigya.services.socialize.getUserInfo(conf, { callback: function(resp) {
					if (resp.errorCode == "0" && resp.user.isLoggedIn == true) {
						self.createLogoutButton();
					} else {
						self.createLoginButton();
					}
				}});
			}
		});

	}

	// network navigation menu
	if (this.headerContent.networkNavigation) {
		this.container.append('<div class="top_navigation"><div class="navitem_wrapper"></div></div>');
		for(i=0;i<this.headerContent.networkNavigation.length;i++) {
			var menuItem = this.headerContent.networkNavigation[i];
			this.createNetworkNavItem(menuItem);
		}
	}

	// rewrite this pos
	var imagesToCache = new Array();
	imagesToCache.push(this.generateURL('http://www.syfy.com/_images/icons/icon_rewind.png'));

	// dropdown image cache
	if (this.headerContent.showsDropdown.currentShows) {
		for (var i=0;i<this.headerContent.showsDropdown.currentShows.menuItems.length;i++) {
			imagesToCache.push(this.headerContent.showsDropdown.currentShows.menuItems[i].baseCoverImageURL);
		}
	}

	if (this.headerContent.showsDropdown.upcomingShows) {
		for (var i=0;i<this.headerContent.showsDropdown.upcomingShows.menuItems.length;i++) {
			imagesToCache.push(this.headerContent.showsDropdown.upcomingShows.menuItems[i].baseCoverImageURL);
		}
	}
	this.cacheImages(imagesToCache);
	
	this.container.append('<!--[if IE 7]><style>#syfyGlobalHeader .top_navigation .button { margin-right: 1px; } #syfyGlobalHeader .top_navigation .hover { display: none; }</style><![endif]-->');

}

syfyGlobalHeader.prototype.changeButtonTitle = function(button, string) {
	var link = jqN(button).find('a:first');
	link.html(string);
	Cufon.replace(link[0]);
}

syfyGlobalHeader.prototype.cacheImages = function(images) {
	for (var i=0;i<images.length;i++) {
		var cacheImage = new Image();
		cacheImage.src = images[i];
	}
}

syfyGlobalHeader.prototype.createLogo = function(logo) {
	var logoElement = jqN('<img border="0" class="logo" src="'+logo.baseCoverImageURL+'" width="'+logo.imageWidth+'" height="'+logo.imageHeight+'" alt="'+logo.title+'">');

	if (logo.url) {
		linkElement = jqN('<a href="'+logo.url+'"></a>');
		if (logo.openInNewWindowFlag == "true") {
			linkElement.attr('target', '_blank');
		}
		linkElement.append(logoElement);
		logoElement = linkElement;
	}

	this.container.append(logoElement);
}

syfyGlobalHeader.prototype.createPromo = function(pc) {

	
	var promo = jqN('<div id="promo_container" href="#"></div>');
	var plink = jqN('<a href="'+this.generateURL(pc.url)+'"></a>');

	var pimage = jqN('<img src="'+pc.baseCoverImageURL+'" id="promo_image">');
	var ptext = jqN('<div id="promo_text_container"></div>');
	var ptitle = jqN('<div id="promo_title"></div>');
	var ptitletext = jqN('<span></span>');
	var ptunein = jqN('<div id="promo_tunein"></div>');

	if (pc.openInNewWindowFlag == 'true') { plink.attr('target', '_blank'); }

	ptitletext.text(pc.shortDescription);
	ptunein.text(pc.longDescription);

	ptitle.append(ptitletext);
	ptext.append(ptitle);
	ptext.append(ptunein);

	plink.append(pimage);
	plink.append(ptext);

	promo.append(plink);
	
	return(promo);

}

syfyGlobalHeader.prototype.createNetworkNavItem = function(item) {
	var wrapper = this.container.find('.top_navigation .navitem_wrapper');
	var button = jqN('<div class="button shadow"></div>');
	var link = jqN('<a href="'+item.url+'"><img src="'+item.baseCoverImageURL+'" width="'+item.imageWidth+'" height="'+item.imageHeight+'" border="0"></a>');
	if (item.openInNewWindowFlag == "true") { link.attr('target', '_blank'); }
	var hover = jqN('<div class="hover"></div>');
	if (item.imageWidth) {
		button.css('width', item.imageWidth+'px');
		hover.css('width', item.imageWidth+'px');
	}
	if (item.imageHeight) {
		button.css('height', item.imageHeight+'px');
		hover.css('height', item.imageHeight+'px');
	}
	hover.css('opacity', '0.0');
	button.append(link)
	link.append(hover);

	button.mouseenter(function(e) {
		hover.stop(true, true).fadeTo(400, 0.10);
	});
	button.mouseleave(function(e) {
		hover.stop(true, true).fadeTo(400, 0.0);
	});
	wrapper.append(button);
}

syfyGlobalHeader.prototype.createMainNavItem = function(item) {
	var self=this;
	/* TODO:
		 figure out div/a padding so the A can properly be 100% of the button container area
	*/
	
	//var wrapper = this.container.find('.main_navigation .navitem_wrapper');
	var button_container = jqN('<div class="button_container"></div>');
	button_container.attr('id', 'navitem_main_' + item.title.toLowerCase().replace(/ /g, '_'));
	
	var button = jqN('<div class="button shadow"></div>');
	var hover = jqN('<div class="hover"></div>');

	hover.hide();

	var link = jqN('<a href=""></a>');
	if (item.openInNewWindowFlag == "true") { link.attr('target', '_blank'); }

	//if (item.title == 'Shop') { item.url = null; } // debuggery, remove later

	if (typeof(item.url) == 'string') { // sigh.
		link.attr('href', this.generateURL(item.url));
	} else {
		button_container.addClass('dropdown');
	}
	link.text(item.title);
	button.append(hover);
	button.append(link);
	button_container.append(button);
	
	// bind enter/leave
	button_container.mouseenter(function() {
		if (!button.hasClass('selected')) {
			button.stop(true, true).animate({ 'height': '35px', 'marginTop': '-5px' }, 'fast');
			hover.show();
			hover.stop(true, true).fadeIn();
		}

		if (button_container.hasClass('dropdown') && typeof(self[item.title.toLowerCase().replace(/ /g, '_')+'Dropdown']) == 'function') {
			// barfy barf bafr. maybe i should just run a custom create(dropdownName)Dropdown() that then calls the
			// createDropdown() stuff
			self.createDropdown(button_container);

			// visilbility: hidden the div?
			if (jqN('#global_header_ad').length > 0) {
				jqN('#global_header_ad embed').css('visibility', 'hidden');
			}
		}
	});

	button_container.mouseleave(function() {
		// instead of -=5px we should probably set it back to the orig css height? 30px?
		if (!button.hasClass('selected')) {
			button.stop(true, true).animate({ 'height': '30px', 'marginTop': '0px'}, 'fast');
			//button.stop(true, true).animate({ 'height': '-=5px', 'marginTop': '+=5px' }, 'fast');
			hover.stop(true, true).fadeOut();
		}

		if (button_container.find('.dropdown_container')) {
			button_container.find('.dropdown_container').fadeOut('fast', function() {
				jqN(this).remove();
				if (jqN('#global_header_ad').length > 0) {
					jqN('#global_header_ad embed').css('visibility', 'visible');
				}
			});
		}
	});

	return(button_container);

}

syfyGlobalHeader.prototype.createLoginButton = function() {
	var self=this;
	jqN('#navitem_main_logout').remove();
	if (jqN('#navitem_main_login').length) { return false; }
	var wrapper = jqN('#syfyGlobalHeader .main_navigation .navitem_wrapper');
	var button = this.createMainNavItem({ title: 'Login' });
	button.click(function(e) {
		e.preventDefault();
		gigya.services.socialize.showLoginUI(conf, login_params);
	})
	wrapper.append(button);
	Cufon.replace(button.find('a:first')[0]);
}

syfyGlobalHeader.prototype.createLogoutButton = function() {
	var self=this;
	jqN('#navitem_main_login').remove();
	if (jqN('#navitem_main_logout').length) { return false; }
	var wrapper = jqN('#syfyGlobalHeader .main_navigation .navitem_wrapper');
	var button = this.createMainNavItem({ title: 'Logout' });
	button.click(function(e) {
		e.preventDefault();
		gigya.services.socialize.logout(conf);
	});
	wrapper.append(button);
	Cufon.replace(button.find('a:first')[0]);
}


syfyGlobalHeader.prototype.createDropdown = function(t) {
	// TODO
	// maybe bind a click to $t here so that when a dropdown is open, clicking hides it (for mobile safari/ipad)
	
	var dropdownName = t.attr('id').replace(/^navitem_main_/, '');

	var dropdown = jqN('<div id="'+dropdownName+'_dropdown" class="dropdown_container"></div>');

	// create a div to cover up the hovered button so we don't trigger mouseout on the gap
	// get button dimensions + position to know where to put cover
	var coverWidth = t.outerWidth();
	var coverHeight = t.outerHeight();
	var coverLeft = t.position().left;

	var cover = jqN('<div class="dropdown_cover"></div>');
	cover.css('position', 'absolute');
	cover.css('top', '-'+(coverHeight+5)+'px');
	cover.css('left', (coverLeft-5)+'px');
	cover.css('width', coverWidth+'px');
	cover.css('height', (coverHeight+5)+'px');
	dropdown.append(cover);

	cover.click(function(e) { // ipad/iphone/mobile handiness to hide menu
		e.preventDefault();
		t.trigger('mouseleave');
	});
	
	var content = jqN('<div class="dropdown_content"></div>');

	// population
	if (typeof(this[dropdownName+'Dropdown']) == 'function') {
		content.append(this[dropdownName+'Dropdown'].apply(this));
	}

	dropdown.append(content);
	t.append(dropdown);

	// just bein' safe
	dropdown.width(content.width());
	dropdown.height(content.height());

	Cufon.replace('.dropdown_content .tunein');
	Cufon.replace('.dropdown_content h3');

	dropdown.hide();
	dropdown.fadeIn('fast');

}

/*
 *
 SHOWS DROPDOWN
 *
 */

syfyGlobalHeader.prototype.showsDropdown = function() {

	// shows dropdown
	var elements = jqN('<div></div>');
	
	var left = jqN('<div class="left"></div>');
	if (this.headerContent.showsDropdown.currentShows) {
		left.append(this.fancyShowsLists(this.headerContent.showsDropdown.currentShows, { tunein: true }));
	}
	
	if (this.headerContent.showsDropdown.upcomingShows) {
		left.append(this.fancyShowsLists(this.headerContent.showsDropdown.upcomingShows, { tunein: true }));
	}

	if (this.headerContent.showsDropdown.onlineOriginals) {
		left.append(this.fancyShowsLists(this.headerContent.showsDropdown.onlineOriginals));
	}

	elements.append(left);

	if (this.headerContent.showsDropdown.showsList) {
		elements.append(this.showsList(this.headerContent.showsDropdown.showsList));
	}

	return(elements);

}

syfyGlobalHeader.prototype.showsList = function(menuObject) {
	var shows_list = jqN('<div class="shows_list_container"></div>');
	var shows_title = jqN('<div class="title drawfont"><h3>All Shows</h3><div class="rewind_label"><img class="rewind_icon" src="'+this.generateURL('http://www.syfy.com/_images/icons/icon_rewind.png')+'" width="14" height="14"> <span class="divider">|</span> Full Episodes available in Syfy Rewind</div></div>');
	var shows_links = jqN('<div class="shows_list_links"></div>');

	var column = jqN('<div class="list_column"></div>');
	for (i=0;i<Math.round(menuObject.length/2);i++) {
		column.append(this.showLink(menuObject[i]));
	}
	shows_links.append(column);

	column = jqN('<div class="list_column"></div>');
	for (i=Math.round(menuObject.length/2);i<menuObject.length;i++) {
		column.append(this.showLink(menuObject[i]));
	}
	shows_links.append(column);

	shows_list.append(shows_title);
	shows_list.append(shows_links);
	return(shows_list);
}

syfyGlobalHeader.prototype.showLink = function(showObject) {
	var show_link = null;
	if (typeof(showObject.url) == 'string') {
		show_link = jqN('<a class="show_link" href="'+this.generateURL(showObject.url)+'">'+showObject.title+'</a>');
		if (showObject.rewindID) {
			show_link.append('<a target="_blank" href="'+this.generateURL(showObject.rewindURL)+'/"><img class="rewind_icon" src="http://www.syfy.com/_images/icons/icon_rewind.png" width="14" height="14"></a>');
		}
	} else {
		show_link = jqN('<a class="show_link" href="http://www.syfy.com/schedule/?search='+showObject.title+'">'+showObject.title+'</a>');
		//show_link = jqN('<div class="show_link">'+showObject.title+'</div>');
	}
	return(show_link);
}

/* in future, 160x71 default size for buttons but allow huge ones? */
syfyGlobalHeader.prototype.fancyShowsLists = function(menuObject, options) {
	if (options === undefined) { options = {} }
	var current_shows = jqN('<div class="fancy_shows_container"></div>');
	var current_shows_title = jqN('<div class="title drawfont"><h3>'+menuObject.title+'</h3></div>');
	var current_shows_links = jqN('<div class="fancy_shows_links"></div>');

	if (menuObject.menuItems.length > 0) {
		switch(menuObject.menuItems[0].imageWidth) {
			case '117':
				current_shows.addClass('rows4x1');
			break;
			case '160':
				current_shows.addClass('rows3x1');
			break;			
		}
	}

	for (i=0;i<menuObject.menuItems.length;i++) {
		var l = menuObject.menuItems[i];
		var linkElement = jqN('<a href="'+this.generateURL(l.url)+'"></a>');
		var linkImage = jqN('<img border="0" src="'+l.baseCoverImageURL+'" width="'+l.imageWidth+'" height="'+l.imageHeight+'" alt="'+l.title+'" title="'+l.title+'">');

		if (((i+1)%4) == 0 && l.imageWidth == '117') { linkImage.addClass('last'); }
		if (((i+1)%3) == 0 && l.imageWidth == '160') { linkImage.addClass('last'); }

		linkElement.append(linkImage);

		if (options.tunein === true) {
			linkElement.addClass('tall');			
		}

		if (options.tunein === true && typeof(l.shortDescription) != 'object' && typeof(l.shortDescription) != 'undefined') {
			var linkTunein = jqN('<div class="tunein">'+l.shortDescription+'</div>');
			linkElement.append(linkTunein);
		}


		current_shows_links.append(linkElement);
	}

	current_shows.append(current_shows_title);
	current_shows.append(current_shows_links);
	current_shows.append('<div style="clear: both;"></div>');
	return(current_shows);
}


syfyGlobalHeader.prototype.shopDropdown = function() {

	var elements = jqN('<div class="content"></div>');

	elements.append('<div class="title"></div>');

	var products = this.headerContent.shopDropdown.product;
	//console.log(products);
	var pe = jqN('<div class="products_container"></div>');

	for (i=0;i<products.length;i++) {
		var product = jqN('<a href="'+products[i].url+'" class="product"></a>');
		product.append('<img src="'+products[i].thumbnailImg+'">');
		product.append('<div class="product_title">'+products[i].name+'</div>');
		product.append('<div class="product_price">$'+products[i].salePrice+'</div>');
		product.append('<a class="productlink" href="'+products[i].url+'" target="_blank">Buy Now</a>');
		product.appendTo(pe);
	}
	
	elements.append(pe);

	elements.append('<div style="clear: both;"></div>');
	
	elements.append('<a id="button_syfyshop" href="http://www.syfy.com/store/"></a>');
	
	return(elements);

}

syfyGlobalHeader.prototype.gamesDropdown = function() {

	var elements = jqN('<div class="content"></div>');

	/*
	if (typeof(this.headerContent.gamesDropdown.title) == 'string') {
		elements.append('<div class="title"><h3>'+this.headerContent.gamesDropdown.title+'</h3></div>');		
	}
	*/
	elements.append('<div class="title"></div>');
	
	var games = this.headerContent.gamesDropdown.games;

	var ge = jqN('<div class="games_container"></div>');

	for (i=0;i<games.length;i++) {
		var game = jqN('<a href="'+games[i].url+'" class="game"></a>')
					.append('<img src="'+games[i].baseCoverImageURL+'">')
					.append('<div class="game_title">'+games[i].title+'</div>')
					.append('<div class="game_desc">'+games[i].shortDescription+'</div>')
					.append('<span class="game_playnow">Play Now</span>');
		game.appendTo(ge);
	}
	elements.append(ge);

	elements.append('<div style="clear: both;"></div>');
	elements.append('<a id="button_games" href="http://www.syfygames.com/"></a>');
	
	return (elements);

}


/*
 *
 UTILITY METHODS
 *
 */

/* generateURL(string)
 * Check operating context, turn relative links into absolute links to http://www.syfy.com/ if we're on a site other than syfy.com.
 */
syfyGlobalHeader.prototype.generateURL = function(url) {
	// figure out where we are
	if (this.siteContext == 'remote' && !/^http\:\/\//.test(url)) {
		// turn relative links into absolute
		if (!/^\//.test(url)) { url = '/'+url; }
		url = 'http://www.syfy.com'+url;
	}
	return(url);
}

syfyGlobalHeader.prototype.isLoggedIn = function() {
	if (window['gigya'] != 'undefined') {
		gigya.services.socialize.getUserInfo(conf, { callback: function(resp) {
			if (resp.errorCode == "0" && resp.user.isLoggedIn == true) {
				return(true);
			} else {
				return(false);
			}
		}});
	} else {
		return(false);
	}
}

