HEARST.horoscopes = function() {
	var urlName,
		sectionPrefix,
		sectionRoot,
		sectionPath = function() {
			var sections = document.location.pathname.split('/');
			sectionRoot = sections[1];
			sectionPrefix = sections[sections.length - 2];
			urlName = sections.pop();
			sections.push('');
			return sections.join('/');
		}( ),
		zodiac = ['aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces'],
		// Create an array-like object for elements
		elements = {
			0: { name:'fire', optionText:'Fire (Aries, Leo and Sagittarius)' },
			1: { name:'earth', optionText:'Earth (Taurus, Virgo and Capricorn)' },
			2: { name:'air', optionText:'Air (Gemini, Libra and Aquarius)' },
			3: { name:'water', optionText:'Water (Cancer, Scorpio and Pisces)' },
			length: 4
		},
		/**
		 * Properties of scopeData represent parameters of a horoscope
		 *  affix: unique id component of a horoscope article urlName
		 *  signs: number of signs used by scope
		 *  feed: identifies type of feed, if any
		 *  signList: list used by scope, if not zodiac
		 *  channel: intermediate component of full url path. root and end
		 *           directories are added in createHoroscope
		 *  chooserData: properties pertinent to that scope's chooser dropdown
		 *  chooserData.selects: number of dropdowns used
		 *  chooserData.heading: text used for chooser's heading (on landing pages)
		 */
		scopeData = {
			boss: { affix:'cboss', channel:'career', chooserData:{ heading:'Pick your boss\'s sign' } },
			coworker: { affix:'ccowo', channel:'career', signs:2, chooserData:{ selects:2, heading:'Pick your signs and see how you work together' } },
			money: { affix:'cmone', channel:'career', chooserData:{ heading:'See your money profile!' } },
			recommendations: { affix:'ccare', channel:'career', chooserData:{ heading:'See your career profile &amp; guide!' } },
			extended: { affix:'extended', feed:'daily', channel:'daily' },
			single: { affix:'single', feed:'daily', channel:'daily' },
			couple: { affix:'couple', feed:'daily', channel:'daily' },
			'love-career': { affix:'dyear', channel:'daily' },
			work: { affix:'work', feed:'daily', channel:'daily' },
			'feng-shui': { affix:'feng-shui', channel:'lifestyle', signs:0, signList:['The Feng Shui Story', 'General Guidelines', 'Entrances and Exits', 'The Facilities', 'In the Bedroom', 'Relationships', 'Finances'], chooserData:{ firstOption:'Find out more!', heading:'Find out more' } },
			yoga: { affix:'lyoga', feed:'static', channel:'lifestyle', signList:elements, chooserData:{ firstOption:'Pick an element', heading:'See the best yoga type for you!' } },
			beauty: { affix:'beauty', feed:'daily', channel:'lifestyle' },
			passion: { affix:'spass', channel:'love', chooserData:{ heading:'Enter a sign (yours or theirs) to find out more!' } },
			seduction: { affix:'ssedu', channel:'love', chooserData:{ heading:'Enter the sign of a person you\'d like to seduce' } },
			sex: { chooserData:{ selects:0 } }
		},
		currentScope, currentSign;

	function createChooser(scope) {
		if (scope && scope.chooserData && scope.chooserData.selects) {
			var c = scope.chooserData,
				$chooser = $('<a class="button"><span>Go</span></a>'),
				selectCounter = 0,
				selectTotal = c.selects,
				firstSign = scope.signList[0],
				// Returns a function that gets appropriate sign text
				getSign = function() {
					switch (typeof firstSign) {
						case 'string': return function(i){ return scope.signList[i] };
						case 'object': return function(i){ return scope.signList[i].name };
					}
				}( ),
				// Returns a function that gets appropriate option text
				getText = function() {
					if (firstSign.optionText) {
						return function(i){ return scope.signList[i].optionText }
					} else {
						return function(i){ var t = getSign(i); return t.substr(0,1).toUpperCase() + t.substr(1); };
					}
				}( ),
				// Returns a function that configures option value attributes
				// relative to a scope's number of signs and type of feed.
				// This would be easier if scopes were set up more consistently
				getValue = function(){
					var path = scope.path,
						affix = scope.affix,
						config = [
							{ static:function(i,j){ return [[path, affix, '-', i+1]][j].join('');} },
							{ static:function(i,j){ return [[path, getSign(i), '-', affix]][j].join('');}, daily:function(i,j){ return [[path, affix, '-', getSign(i)]][j].join('');} },
							{ static:function(i,j){ var twoDigitSign = (i<9) ? '0'+(i+1) : i+1 ; return [[path, getSign(i), '-'],[twoDigitSign, '-', affix]][j].join('');} }
						];
	
					return config[scope.signs][scope.feed];
				}( );
	
			function addSelect() {
				var $button = $chooser.filter(':last'),
					html = '<select><option selected="selected" value="">' + c.firstOption + '</option>',
					i, $select;
	
				for (i=0; i<scope.signList.length; i++) {
					html += '<option value="' + getValue(i, selectCounter) + '">' + getText(i) + '</option>';
				}
	
				html += '</select>';
				$select = $(html);
				$select[0].counter = selectCounter;
				
				$select
					.change(function() {
						var counter = this.counter;
	
						if (this.value) {
							$chooser.url[counter] = this.value;
							for (var i=0; i<$chooser.url.length; i++) {
								if ($chooser.url[i]) {
									if (i === $chooser.url.length-1) {
										$button.attr('href', $chooser.url.join(''));
									}
								} else {
									$button.removeAttr('href');
									break;
								}
							}
							
						} else {
							delete $chooser.url[counter];
							$button.removeAttr('href');						
						}
					});
	
				// Insert $select at next-to-last position of $chooser
				$chooser[$chooser.length] = $chooser[$chooser.length - 1];
				$chooser[$chooser.length++ - 1] = $select[0];

				selectCounter++;
			}
	
			while (selectCounter<selectTotal) {
				addSelect();
			}

			// Create a property in $chooser to keep track of url
			// segments provided by one or more select elements
			$chooser.url = [];

			// Create a link back to $chooser's scope
			$chooser.scope = scope;

			return $chooser;
		}
	}

	function createHoroscope(k) {
		var o = scopeData[k],
			// Set default horoscope properties
			scope = {
				feed: 'static',
				signs:1,
				signList: zodiac,
				chooserData: {}
			},
			defaultChooserData = { 
				selects:1,
				firstOption:'Pick a Sign'
			};

		if (o && o.channel) {
			o.path = ['', sectionRoot, o.channel, k, ''].join('/');
			scope = $.extend(scope, o);
			scope.chooserData = $.extend(defaultChooserData, scope.chooserData);
			return scope;
		}
	}

	if (scopeData[sectionPrefix]) {
		
		currentScope = createHoroscope(sectionPrefix);
		
		if (urlName && currentScope.signList === zodiac) {
			// Extracts sign from urlName with scope affix code (e.g. {sign}-dyear)
			switch (scopeData[sectionPrefix].feed) {
				case 'daily':
					currentSign = urlName.split('-')[1];
					break;
				default:
					currentSign = urlName.split('-')[0];
			}
		}
	}
		
	return {
		writeChooser: function($target) {
			if ($target.length) {
				var key = $target[0].id.replace('_chooser',''),
					newScope = createHoroscope(key),
					chooser = createChooser(newScope || currentScope),
					// Display the chooser if createChooser returns an object and if 
					// chooser's scope has at least one sign or we are on a landing page
					displayChooser = (chooser && (chooser.scope.signs || !urlName)),
					heading = function() {
						var defaultHeading = (urlName) ? 'Choose another sign' : 'Pick a sign',
							sd = scopeData[sectionPrefix],
							scopeDataHeading = sd && sd.chooserData && sd.chooserData.heading;

						switch (key) {
							case 'current':
								if (urlName) {
									return defaultHeading;
								} else {
									return scopeDataHeading || defaultHeading;
								}
							case 'extended':
								if (sectionPrefix === 'extended') {
									return defaultHeading;
								} else {
									return 'Daily Horoscope';
								}
							case 'yoga':
								return scopeData['yoga'].chooserData.heading;
						}
					}( );

				if (displayChooser) {
					$target.html(chooser);
					if (heading) {
						$target.prepend('<h4>' + heading + '</h4>');
					}
				}
			}
		},
		writeSignedLinks: function($target) {
			if (currentSign) {
				var $links = $target.find('li a'),
					$heading = $target.find('h4');

				$links.each(function() {
					var feed, affix;

					if (this.className && scopeData[this.className]) {
						feed = scopeData[this.className].feed;
						affix = scopeData[this.className].affix;

						switch (feed) {
							case 'daily':
								this.href += [affix, currentSign].join('-');
								break;
							default:
								this.href += [currentSign, affix].join('-');
								break;
						}
					}
				});

				$heading.append(' for ' + currentSign);
			}
		}
	}
}( );