/** 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);
		this.jElm.toggleClass()
	},
	isEnabled : function() {
		return this.enabled;
	}
}

PIndicatorShadeWidget = function(elm) {
	this.elm = elm;
	this.sourceHref = this.elm.find("#source").attr("href");
	this.shade_by = this.elm.find("#shade_by");
	this.shade_by[0].shadeWidget = this;
	this.shade_by.bind('change', function(){ this.shadeWidget.changeShade.call(this.shadeWidget); });
	
	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");
			this.eventManager.triggerListeners(this.eventTypes.change, id);
//		} 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.source).attr("href", this.sourceHref + "#" + shadeInfo.dataDirectory);

		if (shadeInfo.shadeString) {
			this.current_shade = this.current_shade.replaceWith(shadeInfo.shadeString);
		} else if (shadeInfo.windowShadeString) { // display only the string in window widget
			this.shade_by.html(shadeInfo.windowShadeString);
		} 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'><div style='float: left'>";

		if (this.showEditRangesLinks) {
			// restore defaults
			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 += "Insufficient Data</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
if (PAGE_ID != "w_") {
			// 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 = "";
				if(!(editState & PIndicatorBreaks.EDITSTATE.nonSubscriber))
					applylink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().applyCustomBreaks(); return false;'>Apply</a>";
				else
					applylink = "<a href='#' class='editbreaks' onclick='widget.getIndicatorBreaks().setEditMode(false); return false;'>Apply</a>"; 
				
				html += "<div align='center' style='padding: 5px 0px'>" + applylink + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + 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.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 = [];
}

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) {

		/* Add years */
		for ( var i = 0; i < years.length; i++) {
			var year = null;
			if (years[i].state & PIndicatorToggle.YEAR.selectedYear) {
				year = document.createElement("span");
				year.className = "yearselected";
			} 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));
			} else if (years[i].state & PIndicatorToggle.YEAR.mustSubscribe) {
				year = document.createElement("a");
				year.href = "javascript:void(0)";
				year.className = "yearteaser";
				this.listeners.push(PEvent.addListener(year, 'click', subscribeAlert));
				year.title = "Subscriber Only";
			} 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);

		/* 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";
				} 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));
				} 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();
		}

		/* 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";
				} 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));
				} 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);
		}

	}
}
