/** NO WIDGETS SHOULD OBTAIN ANY MODEL OBJECTS * */

PLegendContainer = function(jElm) {
	this.jElm = jElm;

	// Setup all events
	this.eventTypes = new Object();
	this.eventTypes.init = 'init';
	this.eventTypes.remove = 'remove';
	this.eventTypes.enable = 'enable';
	this.eventTypes.disable = 'disable';
	this.eventManager = new PEventManager();
}

PLegendContainer.prototype = {
	init : function() {
		this.eventManager.triggerListeners(this.eventTypes.init);
	},
	remove : function() {
		this.jElm.remove();
		this.eventManager.triggerListeners(this.eventTypes.remove);
	},
	hide : function() {
		this.jElm.hide();
	},
	show : function() {
		this.jElm.show();
	},
	addElement : function(elm) {
		this.jElm.append(elm);
	},
	addListener : function(eventId, f, c) {
		this.eventManager.addListener(eventId, f, c);
	},
	enable : function() {
		this.jElm.removeClass("disabled");
		this.jElm.find(":input").removeAttr("disabled");
		this.jElm.find("*").removeClass("disable_pointer");
		this.enabled = true;
		this.eventManager.triggerListeners(this.eventTypes.enable);
	},
	disable : function() {
		this.jElm.addClass("disabled");
		this.jElm.find(":input").attr("disabled", "disabled");
		this.jElm.find("*").addClass("disable_pointer");
		this.enabled = false;
		this.eventManager.triggerListeners(this.eventTypes.disable);
	},
	isEnabled : function() {
		return this.enabled;
	}
}

PIndicatorShadeWidget = function(elm, showShadeByAsString) {
	this.elm = elm;
	this.sourceHref = this.elm.find("#source").attr("href");
	this.shade_by = this.elm.find("#shade_by");
	this.showShadeByAsString = null;
	if (showShadeByAsString) {
		this.showShadeByAsString = showShadeByAsString;
	}

	this.shade_by[0].shadeWidget = this;
	this.shade_by.bind('change', function() {
		this.shadeWidget.changeShade.call(this.shadeWidget);
		if(PEnvironment.pageName == 'widget' && map.widgetRankingsOn) {
			refreshWidgetRankings();
		}
	});
	
	this.current_shade = this.shade_by;
	
	// Setup all events
	this.eventTypes = new Object();
	this.eventTypes.change = 'change';
	this.eventManager = new PEventManager();
}
PIndicatorShadeWidget.prototype = {

	addListener : function(eventId, f, c) {
		this.eventManager.addListener(eventId, f, c);
	},
	clear : function() {
		this.shade_by.empty();
		this.elm.find("#source").empty().removeAttr("href");
	},
	
	changeShade : function(){
		var options = this.shade_by.find("option");
		// commented out the 5 lines below to make this feature public
//		if( isSubscriber() ) {
			var id = this.shade_by.find(":selected").attr("id");

			var useLockOption = false;
			// The lock option only applies to the widget for now. But just because it's set to true doesn't mean it'll be used, only if the widget has that option set in the db then it will allow
			// the locking of a boundary type across all indicators.
			if (PEnvironment.pageName == 'widget')
				useLockOption = true;
			this.eventManager.triggerListeners(this.eventTypes.change, id, useLockOption);
//		} else {
//			this.shade_by.find("option").attr("selected", false);
//			this.shade_by.find("option[defaultSelected=true]").attr("selected", true);
//			subscribeAlert();
//		}
	},
	
	/** Change map.legend references? * */
	update : function(shadeInfo) {
		this.elm.find("#source").html(shadeInfo.indicator.getSourceList(true));

		if (shadeInfo.shadeString) {
			this.current_shade = this.current_shade.replaceWith(shadeInfo.shadeString);
		} else if (this.showShadeByAsString) {
			// If when creating the PIndicatorShadeWidget the showShadeByAsString argument is passed then this will make the string of the
			// current placetype appear in the 'Shaded by' part of the legend. For now this is only used in the embedded dynamic map.
			// There may be a better of way of doing this so if a better way comes along by all means go ahead. The legend was just being a
			// complicated beast that this seemed like the simplest solution for now.
			this.shade_by.html(map.getLegend().getCurrentPlaceType().getName());
		} else {
			var shadeItems = shadeInfo.shadeItems;
			this.shade_by.empty();


			for ( var i = 0; i < shadeItems.length; i++) {
				var option = document.createElement("option");
				option.id = shadeItems[i].id;
				option.selected = shadeItems[i].selected;
				option.innerHTML = shadeItems[i].value;
				option.defaultSelected = shadeItems[i].defaultSelected;
				this.shade_by.append(option);
			}

			if (this.current_shade != this.shade_by){
				this.current_shade = this.current_shade.replaceWith(this.shade_by);
				this.shade_by.hide();
				this.shade_by.fadeIn( 'slow' );
			}
		}
	},
	enable : function() {
		this.elm.find("a").unbind("click");
	},
	disable : function() {
		this.elm.find("a").click( function() {
			return false;
		})
	}
}

PIndicatorInfoWidget = function() {
	this.jElms = [];
	for ( var i = 0; i < arguments.length; i++)
		this.jElms[i] = arguments[i];
}
PIndicatorInfoWidget.prototype = {
	clear : function() {
		for ( var i = 0; i < this.jElms.length; i++)
			this.jElms[i].html("To add another data layer, select from the menu above the map.");
	},
	update : function(ind) {
		if (ind)
			for ( var i = 0; i < this.jElms.length; i++)
				this.jElms[i].html(ind.getFullLabel());
	}
}

PRangeWidget = function(elm, options) {

	this.elm = $(elm);
	options = options || new Object();

	this.min = (options.min == null) ? 0 : options.min;
	this.max = (options.max == null) ? 100 : options.max;
	this.unit = (options.unit == null) ? '' : options.unit;
	this.step = 1;
	this.range = [this.min, this.max];
	this.rangeElms = this.elm.find('input');
	this.rangeElms[0].iControl = this;
	this.rangeElms[1].iControl = this;

	this.sliderElm = this.elm.find("#slider")[0];
	this.sliderElm.rangeWidget = this;
	this.sliderElm = $(this.sliderElm);

	this.eventTypes = {
		update :'update'
	};
	this.eventManager = new PEventManager();

	this.initialized = false;
}

PRangeWidget.prototype = {

	init : function() {

		var change = function() {
			this.iControl.setRange.call(this.iControl, this.iControl.getRange.call(this.iControl));
		}
		$(this.rangeElms[0]).change(change);
		$(this.rangeElms[1]).change(change);

                // temp fix that removes the grey filled bar in the slider in IE which occasionaly causes an error(not sure yet why)
                var showFillBar = true;
                if (version)
                        showFillBar = false;

		this.sliderElm.slider( {
			range :showFillBar,
			min :this.min,
			max :this.max,
			step : this.step,
			values : this.range,
			slide : function(event, ui) {
				this.rangeWidget.setRange.call(this.rangeWidget, ui.values, { noslide :true	});
			},
			stop : function() {
				this.rangeWidget.updated.call(this.rangeWidget);
			}
		});

		this.initialized = true;
	},
	addListener : function(eventId, f, c) {
		this.eventManager.addListener(eventId, f, c);
	},
	disable : function() {
		this.sliderElm.slider("disable");
		this.elm.hide();
		this.rangeElms[0].value = "";
		this.rangeElms[1].value = "";
	},

	enable : function() {
		this.elm.show();
		if (this.initialized == false)
			this.init();
		this.sliderElm.slider("enable");
	},

	updateRange : function(rangeLimits, range, unit) {
		this.min = rangeLimits[0];
		this.max = rangeLimits[1];
		this.sliderElm.slider("option", "min", rangeLimits[0]);
		this.sliderElm.slider("option", "max", rangeLimits[1]);
		
		
		var diff = this.max - this.min;
		this.step = ( diff >= this.sliderElm.parent().width())? 1 : diff/this.sliderElm.parent().width();
		this.sliderElm.slider("option", "step", this.step);
		this.unit = unit;

		this.setRange(range, {update:false});
	},
	
	setRange : function(range, options) {
		options = options || new Object();

		if (range[1] > this.max)
			range[1] = this.max;
		else if(range[1] < this.min)
			range[1] = this.min;

		if (range[0] < this.min)
			range[0] = this.min;
		else if(range[0] > this.max)
			range[0] = this.max;
		
		if (range[0] > range[1])
			range[0] = range[1];
		else if (range[1] < range[0])
			range[1] = range[0];

		this.range = range;
		this.rangeElms[0].value = PWebUtil.formatNumber(range[0], this.unit);
		this.rangeElms[1].value = PWebUtil.formatNumber(range[1], this.unit);

		if (options.noslide != true) {
			this.sliderElm.slider("values", 0, range[0]);
			this.sliderElm.slider("values", 1, range[1]);

			/* if range wasn't set by slide action, then its final */
			if (options.update != false)
				this.updated();
		}
	},

	getRange : function() {
		var range = new Array();
		range[0] = parseFloat(this.rangeElms[0].value.replace(/[^\d&^\.^-]/g, ''));
		range[1] = parseFloat(this.rangeElms[1].value.replace(/[^\d&^\.^-]/g, ''));
		return range;
	},

	resetRange : function() {
		this.setRange( [ this.min, this.max ], {
			update :false
		});
	},

	getElement : function() {
		return this.element;
	},

	updated : function() {
		this.eventManager.triggerListeners(this.eventTypes.update, this.getRange());
	}

}


PValuesWidget = function(jContainer) {
	this.elm = $(document.createElement("div"));
	jContainer.append(this.elm);
	
	this.eventTypes = {update :'update'};
	this.eventManager = new PEventManager();
}

PValuesWidget.prototype = {
	clear : function() {
		this.elm.empty();
		this.values = null;
	},
	refresh : function(values){
		this.values = values;
		
		var html = "<table cellpadding=0 cellspacing=0 border=0>";
		var lblCheck = "$(this).parent().find('input').attr('checked', !$(this).parent().find('input').attr('checked'));";
		for(var i=0; i<values.length; i++){
			html += "<tr><td><input type=\"checkbox\" "+(values[i][1]?"checked":"")+"/></td><td class=\"labels\">" + values[i][0] + "</td></tr>";
		}
		html += "</table>";
		this.elm.html(html);
		var self = this;
		this.elm.find("input").bind('change', function(){ self.changed() });
		this.elm.find(".labels").bind('click', function(){ 
				$(this).parent().find('input').attr('checked', !$(this).parent().find('input').attr('checked'));
				self.changed(); });
	},
	
	changed : function(){
		var checkboxes = this.elm.find("input[type=checkbox]");
		var len = checkboxes.length;
		for(var i=0;i<len&&i<this.values.length;i++)
			this.values[i][1] = (checkboxes[i].checked)?1:0;
		this.eventManager.triggerListeners(this.eventTypes.update, this.values);
	},
	
	enable : function() {
		this.elm.show();
	},

	disable : function() {
		this.elm.hide();
	},
	
	addListener : function(eventId, f, c) {
		this.eventManager.addListener(eventId, f, c);
	}
}


PBreaksWidget = function(jContainer) {
	this.elm = $(document.createElement("div"));
	jContainer.append(this.elm);
	this.showEditRangesLinks = true;
}

PBreaksWidget.prototype = {

	clear : function() {
		this.elm.empty();
	},

	refresh : function(breaks, incrementBreaks, numBreaks, colors, legend ) {
		// show legend div
		var html = "<div class='breakdown'>";

		if (this.showEditRangesLinks) {
			// restore defaults
			html += "<div style='float: left'>";
			if (editState & (PIndicatorBreaks.EDITSTATE.currentlyEditing | PIndicatorBreaks.EDITSTATE.alreadyEdited))
				html += "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().restoreBreaks();return false;'>Restore Defaults</a>";
			else
				html += "<span class='editbreaks'>Restore Defaults</span>";
			html += "</div>";

			// edit ranges link
			html += "<div style='float: right'>";
			if (editState & (PIndicatorBreaks.EDITSTATE.currentlyEditing | PIndicatorBreaks.EDITSTATE.noBoundaryType))
				html += "<span class='editbreaks'>Edit Ranges</span>";
			else {
				html += "<a href='#' class='editbreaks' onclick='displayEditRangesPanel();return false;'>Edit Ranges</a>";
			}
			html += "</div><br clear='both'><br>";
		}

		if (editState & PIndicatorBreaks.EDITSTATE.noBoundaryType)
			html += "<div style='color: #ff0000; font-size: 12px'><i>Zoom in further to see this data.</i></div>";
		else {
			html += "<table cellpadding=0 cellspacing=0 border=0>";

			if (editState & PIndicatorBreaks.EDITSTATE.noData)
				numBreaks += 1;
			var nodata = false;

			// if no breaks exist
			if (breaks == null || breaks[numBreaks - 1] == null) {
				html += "<tr><td><div style='color: #ff0000; font-size: 12px'><i>There is insufficient data to create the current ranges. Try a smaller number.</i><br><br></div></td></tr>";
			} else {
				var mvaLayers = session2.get("mvalayers");
				for (var i = 0; i < numBreaks; i++) {
					var breaksString = "";
					if (editState & PIndicatorBreaks.EDITSTATE.noData && i == 0) {
						html += "<tr><td width=25 style='width: 25px; background-color: #" + colors[i]
							+ "'>&nbsp;</td><td style='background-color:#fff'>";
						// Exact breaks get a checkbox for Insufficient Data.
						if((editState & PIndicatorBreaks.EDITSTATE.currentlyEditing) && (editState & PIndicatorBreaks.EDITSTATE.exactBreaks)) {
							html += "<input id='breakbox0' class='breaksbox' type='checkbox' ";
							// Check the box if Insufficient Data is currently being displayed.
							if(mvaLayers[0])
								html += "checked ";
							html += "/>&nbsp;";
						}
						// The Insufficient Data text displays differently depending on whether or not
						// we are currently editing the breaks, and whether we're currently in exact
						// breaks or ranged breaks.
						if(editState & PIndicatorBreaks.EDITSTATE.exactBreaks) {
							// The Insufficient Data text is never italicized in exact breaks.
							// In addition, we want it to follow the exact break text color
							// scheme when the breaks *aren't* being edited.
							if(!(editState & PIndicatorBreaks.EDITSTATE.currentlyEditing)) {
								// Exact breaks that are being displayed are a dark gray.
								// Exact breaks that are hidden are an italicized light gray.
								// This happens for the remaining layers below as well.
								if(mvaLayers[0])
									html += "</td><td colspan=3 style='color:#878787;padding-left:3px;'>";
								else
									html += "</td><td colspan=3 style='color:#d7d7d7;font-style:italic;padding-left:3px'>";
							}
							else
								html += "</td><td colspan=3 style='padding-left:3px'>";
						} else {
							// We want the Insufficient Data text to to be italicized if we're
							// in ranged breaks, so it keeps looking like it did before.
							html += "</td><td colspan=3 style='padding-left:3px;font-style:italic'>";
						}
						html += legend.getIndicator().nodatalabel + "</td></tr>";
						nodata = true;
					} else if (editState & PIndicatorBreaks.EDITSTATE.currentlyEditing) {
						if(editState & PIndicatorBreaks.EDITSTATE.exactBreaks) {
							// Exact breaks get checkboxes.
							html += "<tr><td width=25 style='width: 25px; background-color: #" + colors[i] + "'>&nbsp;</td>"
								+ "<td style='background-color:#fff'><input id='breakbox" + i + "' class='breaksbox' type='checkbox' ";
							// Check the box if the layer is currently being displayed.
							if(mvaLayers[i])
								html += "checked ";
							html += "/><td align='right' style='padding-left: 3px'>" + breaks[i] + "</td></tr>";
						} else {
							// Ranged breaks get the textboxes.
							var startbreak;
							if (i == 0 || (i == 1 && nodata))
								startbreak = breaks[i];
							else
								startbreak = incrementBreaks[i];
							breaksString = "<td align='right' style='padding-left: 3px'><input onchange='widget.getIndicatorBreaks().checkBreakBoxes(this.id)' id='breakbox"
									+ i + "a' class='breaksbox' type='text' value='" + startbreak 
									+ "'></td><td width=20 align='center'>&ndash;</td><td align='right' style='padding-right: 3px'><input onchange='widget.getIndicatorBreaks().checkBreakBoxes(this.id)' id='breakbox"
									+ i + "b' class='breaksbox' type='text' value='" + breaks[i + 1] + "'></td>";
							html += "<tr><td width=25 style='width: 25px; border: 1px solid #ddd'>&nbsp;</td><td style='background-color:#fff'>&nbsp;</td>"+ breaksString + "</tr>";
						}						
					} else {
						if (editState & PIndicatorBreaks.EDITSTATE.exactBreaks) {
							// Exact breaks that are being displayed are a dark gray.
							// Exact breaks that are hidden are an italicized light gray.
							breaksString = "<td colspan=3 align='center' style='padding-left:3px";
							if(mvaLayers[i])
								breaksString += ";color:#878787";
							else
								breaksString += ";color:#d7d7d7;font-style:italic";
							breaksString += "'>" + breaks[i] + "</td>";
						} else {
							// Display ranged breaks as usual.
							if ((i == 0 || (i == 1 && nodata)) && !legend.compareCustomBreaks(i, ">")) {
								breaksString = "<td colspan='3' align='center' style='padding-left: 3px'>" + breaks[i + 1] + " or less</td>";
							} else if (i == numBreaks - 1 && !legend.compareCustomBreaks(i + 1, "<"))
								breaksString = "<td colspan='3' align='center' style='padding-left: 3px'>" + incrementBreaks[i] + " or more </td>";
							else {
								var startbreak;
								if (i == 0 || (i == 1 && nodata))
									startbreak = breaks[i];
								else
									startbreak = incrementBreaks[i];
								if (startbreak == breaks[i + 1])
									breaksString = "<td align='right' style='padding-left: 3px'>" + startbreak + "</td><td width=20 align='center'></td><td align='right' style='padding-right: 3px'></td>";
								else
									breaksString = "<td align='right' style='padding-left: 3px'>" + startbreak + "</td><td width=20 align='center'>&ndash;</td><td align='right' style='padding-right: 3px'>" + breaks[i + 1] + "</td>";
							}
						}

						// Display the break string we put together above.
						html += "<tr><td width=25 style='width: 25px; background-color: #" + colors[i] + "'>&nbsp;</td><td style='background-color:#fff'>&nbsp;</td>" + breaksString + "</tr>";
					}
					html += "<tr><td colspan=4><div style='font-size:1px'>&nbsp;</div></td></tr>";
				}
			}
			html += "</table><div style='padding-bottom: 3px'>";
// Don't show breaks dropdown for window widget or embedded map
if (!isWidgetOrEmbedMap()) {
			// apply or cancel edit
			if (editState & PIndicatorBreaks.EDITSTATE.currentlyEditing) {
				var cancelLink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().setEditMode(false); return false;'>Cancel</a>";
				var applyLink = "";
				var applyAllLink = "";
				if(!(editState & PIndicatorBreaks.EDITSTATE.nonSubscriber)) {
					applyLink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().applyCustomBreaks(false); return false;'>Apply to Current Time Period</a>";
					applyAllLink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().applyCustomBreaks(true); return false;'>Apply to All Time Periods</a>";
				} else {
					applyLink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().setEditMode(false); return false;'>Apply to Current Time Period</a>";
					applyAllLink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().setEditMode(false); return false;'>Apply to All Time Periods</a>";
				}
				html += "<div align='center' style='padding: 5px 0px'>" + applyLink + "<br />" + applyAllLink + "<br />" + cancelLink + "</div>";
			}

			// Added a bit to the end of the conditional below to check if we're currently in exact breaks.
			// Exact breaks have no use for an option to set the number of breaks.

			if ((!(editState & (PIndicatorBreaks.EDITSTATE.variableNotSupported | PIndicatorBreaks.EDITSTATE.preRendered | PIndicatorBreaks.EDITSTATE.currentlyEditing))) && !(editState & PIndicatorBreaks.EDITSTATE.exactBreaks)) {
				html += '<br/><span>Shade map in: </span> <select style="font-size:10px; color:#7a7a7a" onchange="handleCutPoints(this);">';
				for ( var i = 2; i <= 8; i++) {
					var option = "<option value='" + i + "'";
					if (i == map.getLegend().getNumberOfBreaks())
						option += " selected";
					option += ">" + i + "</option>";
					html += option;
				}
				html += '</select> ranges';
			}
}
			html += "</div>";
			html += "</div>";
		}
		this.elm.html(html);
	},

	removeEditRangesLinks : function() { // requires a refresh of PBreaksWidget
		this.showEditRangesLinks = false;
	},

	showEditRangesLinks : function() { // requires a refresh of PBreaksWidget
		this.showEditRangesLinks = true;
	}
}

PIndicatorToggleWidget = function(elm) {
	this.elm = elm;
	this.elm.show();
	this.years = elm.find("#indicator_years");
	this.quarters = elm.find("#indicator_quarters");
	this.months = elm.find("#indicator_months");
	this.indicators = elm.find("#indicators_additional");
	this.toggleButton = elm.find("#toggle_button");
	this.toggleButton.bind("click", function() {
		$(this).toggleClass('toggle_hide');
		$(this).siblings('#indicator_toggle').toggle();
	});
	this.listeners = [];

	// This is so user can hide pieces of the legend if they want to
	if (isWidgetOrEmbedMap()) {
		this.periodsContainer = elm.find("#periods_container");
		this.variablesContainer = elm.find("#variable_container");
		this.indicatorToggle = elm.find("#indicator_toggle");
	}
}

PIndicatorToggleWidget.prototype = {

	enable : function() {
		this.elm.show();
	},

	disable : function() {
		this.elm.hide();
	},

	clear : function() {
		var l = this.listeners.length;
		for ( var i = 0; i < l; i++)
			PEvent.removeListener(this.listeners[i]);
		this.listeners = [];
		this.years.empty();
		this.quarters.empty();
		this.months.empty();
		this.indicators.empty();
	},

	refresh : function(years, quarters, indicators, months) {

		// Keep track of how many periods are available so on widget page we know if periods section should/shouldn't be displayed
		var yearToggleCount = 0;
		/* Add years */
		for ( var i = 0; i < years.length; i++) {
			var year = null;

			var params = getUrlParams();
			// This allows widgets to have the option of not showing the teaser years
			// The value is set in the db in the user_widget_options table
			var disableTeasers = params['disableTeaserYears'];

			if (years[i].state & PIndicatorToggle.YEAR.selectedYear) {
				year = document.createElement("span");
				year.className = "yearselected";
				yearToggleCount++;
			} else if (years[i].state & PIndicatorToggle.YEAR.availableYear) {
				year = document.createElement("a");
				year.href = "javascript:void(0)";
				for ( var key in years[i].funcParams)
					year[key] = years[i].funcParams[key];
				this.listeners.push(PEvent.addListener(year, 'click', years[i].func));
				yearToggleCount++;
			} else if (years[i].state & PIndicatorToggle.YEAR.mustSubscribe && !disableTeasers) {
				year = document.createElement("a");
				year.href = "javascript:void(0)";
				year.className = "yearteaser";
				this.listeners.push(PEvent.addListener(year, 'click', subscribeAlert));
				year.title = "Subscriber Only";
				yearToggleCount++;
			} else { // state = PIndicatorToggle.YEAR.mustSubscribe - default
				year = document.createElement("span");
				year.className = "notavail";
				year.title = "Not Available";
			}

			if (years[i].state[i] & PIndicatorToggle.YEAR.projection)
				year.style.borderLeft = "1px solid #ccc";

			year.innerHTML = years[i].value.slice(2);

			this.years.append(year);
		}
		var br = document.createElement("br");
		br.className = "clear";
		this.years.append(br);

		// Keep track of how many periods are available so on widget page we know if periods section should/shouldn't be displayed
		var quartToggleCount = 0;
		/* Add quarters if they exist */
		if (!quarters || quarters.length == 0) {
			this.elm.find("#quarters_container").hide();
		} else {

			for ( var i = 0; i < quarters.length; i++) {
				var quarter = null;
				if (quarters[i].state & PIndicatorToggle.QUARTER.selectedQuarter) {
					quarter = document.createElement("span");
					quarter.className = "yearselected";
					quartToggleCount++;
				} else if (quarters[i].state
						& PIndicatorToggle.QUARTER.availableQuarter) {
					quarter = document.createElement("a");
					quarter.href = "javascript:void(0)";
					for ( var key in quarters[i].funcParams) {
						quarter[key] = quarters[i].funcParams[key];
					}
					this.listeners.push(PEvent.addListener(quarter, 'click',quarters[i].func));
					quartToggleCount++;
				} else { // state = PIndicatorToggle.YEAR.mustSubscribe - default
					quarter = document.createElement("span");
					quarter.className = "notavail";
					quarter.title = "Not Available";
				}

				quarter.innerHTML = quarters[i].value;
				this.quarters.append(quarter);
			}
			var br = document.createElement("br");
			br.className = "clear";
			this.quarters.append(br);

			this.elm.find("#quarters_container").show();
		}

		// Keep track of how many periods are available so on widget page we know if periods section should/shouldn't be displayed
		var monthToggleCount = 0;
		/* Add months if they exist */
		if (!months || months.length == 0) {
			this.elm.find("#months_container").hide();
		} else {

			for ( var i = 0; i < months.length; i++) {
				var month = null;
				if (months[i].state & PIndicatorToggle.MONTH.selectedMonth) {
					month = document.createElement("span");
					month.className = "yearselected";
					monthToggleCount++;
				} else if (months[i].state & PIndicatorToggle.MONTH.availableMonth) {
					month = document.createElement("a");
					month.href = "javascript:void(0)";
					for ( var key in months[i].funcParams) {
						month[key] = months[i].funcParams[key];
					}
					this.listeners.push(PEvent.addListener(month, 'click', months[i].func));
					monthToggleCount++;
				} else { // state = PIndicatorToggle.YEAR.mustSubscribe - default
					month = document.createElement("span");
					month.className = "notavail";
					month.title = "Not Available";
				}

				month.innerHTML = months[i].value;
				this.months.append(month);
			}
			var br = document.createElement("br");
			br.className = "clear";
			this.months.append(br);

			this.elm.find("#months_container").show();
		}

		/* Add other indicators tab */
		if (indicators && indicators.length > 0) {
			for ( var i = 0; i < indicators.length; i++) {
				var indicator = null;
				if (indicators[i].state & PIndicatorToggle.INDICATOR.selectedIndicator) {
					indicator = document.createElement("span");
					indicator.className = "yearselected";
					indicator.innerHTML = indicators[i].value;
					indicator.title = indicators[i].title;
				} else {
					indicator = document.createElement("a");
					indicator.href = "javascript:void(0)";
					indicator.innerHTML = indicators[i].value;
					indicator.title = indicators[i].title;
					for ( var key in indicators[i].funcParams)
						indicator[key] = indicators[i].funcParams[key];
					this.listeners.push(PEvent.addListener(indicator, 'click', indicators[i].func));
				}
				this.indicators.append(indicator)
			}
			var br = document.createElement("br");
			br.className = "clear";
			this.indicators.append(br);
		}

		if (PEnvironment.pageName == 'widget') {
			if (yearToggleCount <= 1) {
				if (quartToggleCount <= 1 && monthToggleCount <= 1)
					this.hidePeriods();
			}
			else
				this.showPeriods();

			// if only one type of indicator is available hide the "Change Variable" section
			if (indicators && indicators.length <= 1)
				this.hideVariables();
			else
				this.showVariables();
		}
	},

	hidePeriods : function() {
		this.periodsContainer.hide();
		// if periods and variables are hidden then hide the container to fix the layout
		if (this.variablesContainer.css('display') == "none")
			this.indicatorToggle.hide();
	},
	showPeriods : function() {
		this.periodsContainer.show();
		this.indicatorToggle.show();
	},
	hideVariables : function() {
		this.variablesContainer.hide();
		// if periods and variables are hidden then hide the container to fix the layout
		if (this.periodsContainer.css('display') == "none")
			this.indicatorToggle.hide();
	},
	showVariables : function() {
		this.variablesContainer.show();
		this.indicatorToggle.show();
	}
}

