
/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/chart/InteractiveChart.js
*/

var InteractiveChart = function(args) {
	this.init(args);
	InteractiveChart.Super(this);
}

InteractiveChart.Extend(Chart);

InteractiveChart.prototype.init = function(args) {
	if (!args) {
		return;
	}
	
	this.upperIndicators = this.getAvailableUpperIndicators();
	this.lowerIndicators = this.getAvailableLowerIndicators();
	this.initializeColors();
	
	//constants
	this.maxUpperIndicators = 5;
	this.maxLowerIndicators = 3;
	this.maxComparisons = 3;
	this.maxSaves = 10;
	
	InteractiveChart.Super(this, "init", arguments);
	
	this.chartImage.URL = SiteRules.getURL("/chart/getInteractiveChart.asp");
}

InteractiveChart.prototype.attachInteractiveLinks = function(parent, defaultChart) {
	parent = parent || WSDOM.Element.get("WSOD");
	
	var links = WSDOM.Element.parseSelector(this.CSS_LINK, parent);
	
	this.eventManager.add(elLinks, 'click', function(e, el) {
		e.cancel();
		
		if (this.initBaseChart) {
			this.initBaseChart(defaultChart);
		}
		
		var symbol = el.getAttribute(wsodInteractiveChart.ATTR_SYMBOL);
		var issueName = el.getAttribute(wsodInteractiveChart.ATTR_ISSUE_NAME);
		
		this.showInteractiveChart(symbol, issueName);
		
	});
}

InteractiveChart.prototype.buildContent = function() {
	
	var frame = this.getFrame();
	
	frame.id = "interactiveChart";
	
	this.setTitleText("INTERACTIVE CHARTING");
	
	this.flyouts = {};
	
	WSDOM.Element.create("div", {id: "interactiveChartContent"}, [
		WSDOM.Element.create("div", {id: "interactiveChartContainer"}, [
			this.buildTimeframeControls(),
			this.buildParamControls(),
			WSDOM.Element.create("div", {id: "chartKeyContainer"}),
			this.buildChartContainer(),
			
			this.buildToolbar()
		]),
		this.buildCalendar()
	], this.getContent());
	
	this.formatIndexComparisonFlyout();
};

InteractiveChart.prototype.buildTimeframeControls = function() {
	var items = [];
	
	for (var i in this.interactiveChartTimeframes) {
		items.push(WSDOM.Element.create("li", {timeframe: this.interactiveChartTimeframes[i]}, i));
	}
	
	items.push(WSDOM.Element.create("li", {"class": "customRange"}, "Custom Range"));
	
	return WSDOM.Element.create("div", {id: "timeframeControlsContainer", "class":"glossy"}, [
		WSDOM.Element.create("ul", {"class": "timeframeControls"}, items)
	]);
};

InteractiveChart.prototype.buildFlyout = function(id, title, items) {
	//var select = this.buildSelectBox(id, title);
	
	var target = WSDOM.Element.create("div", { id: id, "class": "icon icon-flyout"},
		WSDOM.Element.create("div", null, title)
	);
	
	var flyout = new Flyout();
	
	flyout.setParent(WSDOM.Element.get("interactiveChart"));
	flyout.addTarget(target);
	flyout.setData(items);
	
	WSDOM.Element.addClass(flyout.getFrame(), id);
	
	// need to get back to some of these later
	this.flyouts[id] = flyout;
	
	return target;
};

InteractiveChart.prototype.buildSelectOption = function(value, label, parent) {
	return WSDOM.Element.create("option", {value: (undefined !== value)?value:""}, unescape(label), parent)
};

InteractiveChart.prototype.buildSelectBox = function(id, title, items) {
	var elSelect = WSDOM.Element.create("select", {id: id}, [
		this.buildSelectOption(null, title)
	]);
	
	if (items instanceof Array) {
		for (var i=0, group; i<items.length; i++) {
			group = items[i];
			
			var elGroup = WSDOM.Element.create("optgroup", {label: group.title}, null, elSelect);
			
			for (var j in group.items) {
				this.buildSelectOption(j, group.items[j].title, elGroup);
			}
		}
	}
	else if (items) {
		for (var i in items)  {
			this.buildSelectOption(items[i].value, items[i].label, elSelect);
		}
	}
	
	return elSelect;
};

InteractiveChart.prototype.convertToFlyoutChildren = function(o) {
	var children = [];
	for (var i in o) {
		children.push({
			label: o[i].title,
			value: i
		});
	}
	return children;
};

InteractiveChart.prototype.buildParamControls = function() {
	var upper = this.getAvailableUpperIndicators();
	var lower = this.getAvailableLowerIndicators();
	//console.log(this.getAvailableComparisons());
	//console.log(this.convertToFlyoutChildren(this.getAvailableUpperIndicators()));
	return WSDOM.Element.create("div", {id: "interactiveChartControls", "class": "chartControls"}, [
		WSDOM.Element.create("div", {"class": "chartParamControls"}, [
			this.buildFlyout("selectIndicators", "Add Indicators", [{ 
					label: "Upper Indicators", children: this.convertToFlyoutChildren(this.getAvailableUpperIndicators())
				}, {
					label: "Lower Indicators", children: this.convertToFlyoutChildren(this.getAvailableLowerIndicators())
			}]),
			this.buildFlyout("selectEvents", "Add Events", this.getEventTypes()),
			this.buildFlyout("selectComparisons", "Compare To", this.getAvailableComparisons()),
			this.buildFlyout("selectStyles", "Chart Style", this.getChartStyles())
		]),
		WSDOM.Element.create("div", {"class": "newChartControls"}, [
			WSDOM.Element.create("form", {id: "newChart"}, [
				WSDOM.Element.create("label", null, "New Chart"),
				WSDOM.Element.create("input", { "name": "query", "autocomplete": "off"}),
				//WSDOM.Element.create("input", { "type": "hidden", name: "time", value: new Date().getTime() }),
				WSDOM.Element.create("a", {href: "#" }, [
					WSDOM.Element.create("span", {}, "Go")
				]),
			])
		])
		//this.buildNewsControls()
	]);
};

InteractiveChart.prototype.buildToolbar = function() {
	var elToolbar,
		elButtonInvested,
		elButtonAlerts,
		elButtonTrendlines,
		elButtonFTNews,
		elButtonICNews,
		elButtonTransactions;

	elToolbar = WSDOM.Element.create("div", {"class":"toolbar contain"}, [
		WSDOM.Element.create("div", {"class":"buttonPanel"}, [
			WSDOM.Element.create("label", {}, "Tools"),
			WSDOM.Element.create("div", {"class":"buttonGroup"}, [
				elButtonInvested = WSDOM.Element.create("div", {"class":"basicButtonGray"}, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-help"}, "What if I had invested?")
					])
				]),

				elButtonAlerts = WSDOM.Element.create("div", {"id":"toggleSetAlerts", "class":"basicButtonGray", "data-alert-add-edit":"Company", "data-alert-key":'' }, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-alert-sent"}, "Set alerts")
					])
				]),

				elButtonTrendlines = WSDOM.Element.create("div", {"id":"toggleTrendlines", "class":"basicButtonGray"}, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-edit"}, "Trend lines")
					])
				])
			])
		]),
		WSDOM.Element.create("div", {"class":"buttonPanel"}, [
			WSDOM.Element.create("label", {}, "Overlays"),
			WSDOM.Element.create("div", {"class":"buttonGroup"}, [
				elButtonFTNews = WSDOM.Element.create("div", {"id":"icToggleNews", "class":"basicButtonGray"}, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-chart-ftNews"}, "View News")
					])
				]),
				elButtonICNews = WSDOM.Element.create("div", {"id":"icToggleNewsIC", "class":"basicButtonGray"}, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-chart-icNews"}, "View News")
					])
				]),
				elButtonTransactions = WSDOM.Element.create("div", {"id":"icToggleTransactions", "class":"basicButtonGray"}, [
					WSDOM.Element.create("div", {}, [
						WSDOM.Element.create("em", {"class":"icon icon-transaction"}, "View my transactions")
					])
				])
			])
		]),
		WSDOM.Element.create("div", {"class":"buttonPanel noBorder"}, [
			WSDOM.Element.create("label", {}, "Chart Settings"),
			WSDOM.Element.create("div", {"class":"buttonGroup"}, [
				WSDOM.Element.create("div", {"id":"loadSettings", "class":"basicButtonSmall"}, [
					WSDOM.Element.create("div", {}, "Load")
				]),
				WSDOM.Element.create("div", {"id":"saveSettings", "class":"basicButtonSmall"}, [
					WSDOM.Element.create("div", {}, "Save")
				])
			])
		]),
		WSDOM.Element.create("div", {"class":"buttonPanel noBorder"}, [
			WSDOM.Element.create("label", {}, "Saved Charts"),
			WSDOM.Element.create("div", {"class":"buttonGroup"}, [
				WSDOM.Element.create("div", {"id":"loadChart", "class":"basicButtonSmall"}, [
					WSDOM.Element.create("div", {}, "Load")
				]),
				WSDOM.Element.create("div", {"id":"saveChart", "class":"basicButtonSmall"}, [
					WSDOM.Element.create("div", {}, "Save")
				])
			])
		])
	]);
	
	Events.add(elButtonInvested, "click", this.toggleHypotheticalsOverlay, this);
	Events.add(elButtonTrendlines, "click", this.toggleTrendlines, this);
	
	Events.add(elButtonFTNews, "click", this.toggleEvent, this, {"event":"ftNews"});
	Events.add(elButtonICNews, "click", this.toggleEvent, this, {"event":"icNews"});
	Events.add(elButtonTransactions, "click", this.togglePortfolioTransactions, this, {"event":"viewTransactions"});

	if (SiteRules.isFinancialTimes()) {
		Element.remove(elButtonICNews);
	}
	
//	this.btnSetAlert = elButtonAlerts;
	
	return elToolbar;
	
	return WSDOM.Element.create("div", {"class":"toolbar"}, [
		WSDOM.Element.create("span", {"class":"label"}, "Tools"),
		this.buildButton("icon-help", "What if I had invested?", this.toggleHypotheticalsOverlay),
//		this.btnSetAlert = this.buildButton("icon-alert-sent wsodHidden", "Set Alerts", this.toggleAlertsOverlay),
		WSDOM.Element.create("span", {"class":"label"}, "Overlays"),			
		this.buildButton("icon-transaction wsodHidden", "View My Transactions", function(e, el) {
			this.togglePortfolioTransactions(e, el, {event:"viewTransactions"});
		}, 'icToggleTransactions', true),
		SiteRules.isInvestorsChronicle() ? this.buildButton("icon-chart-icNews", "View News", function(e, el) {
			this.toggleEvent(e, el, {event:"icNews"});
		}, 'icToggleNewsIC') : WSDOM.Element.create('span'),
		this.buildButton("icon-chart-ftNews", "View News", function(e, el) {
			this.toggleEvent(e, el, {event:"ftNews"});
		}, 'icToggleNews')
	])
}

InteractiveChart.prototype.updateToolbar = function(transactionsOn, newsOn, hasTransactions, icNewsOn){	
	(hasTransactions)
		? WSDOM.Element.removeClass(WSDOM.Element.parseSelector('em', WSDOM.Element.get('icToggleTransactions')), 'wsodHidden')
		: WSDOM.Element.addClass(WSDOM.Element.parseSelector('em', WSDOM.Element.get('icToggleTransactions')), 'wsodHidden');		
	(transactionsOn)
		? WSDOM.Element.addClass(WSDOM.Element.get('icToggleTransactions'), 'selectedButtonGray')
		: WSDOM.Element.removeClass(WSDOM.Element.get('icToggleTransactions'), 'selectedButtonGray');
	(newsOn)
		? WSDOM.Element.addClass(WSDOM.Element.get('icToggleNews'), 'selectedButtonGray')
		: WSDOM.Element.removeClass(WSDOM.Element.get('icToggleNews'), 'selectedButtonGray');	
	
	if (WSDOM.Element.get('icToggleNewsIC')) {
		(icNewsOn)
			? WSDOM.Element.addClass(WSDOM.Element.get('icToggleNewsIC'), 'selectedButtonGray')
			: WSDOM.Element.removeClass(WSDOM.Element.get('icToggleNewsIC'), 'selectedButtonGray');
	}

	if (this.chartImage.settings) {
		var toolbar = WSDOM.Element.parseSelector('DIV.toolbar', 'wsodPop', 'first');

		if (!this.chartImage.settings.isCommodity && !this.chartImage.settings.isCurrency) {
//			WSDOM.Element.removeClass(WSDOM.Element.parseSelector('em.icon-alert-sent', toolbar), 'wsodHidden');
		}

		if (this.chartImage.settings.FTStandard) {
			var self = this;

			$ws('#toggleSetAlerts').attr('data-alert-key', self.chartImage.settings.FTStandard);

			var alertsHub = new AlertsHub_class();
				alertsHub.init();
		}
	}
}

InteractiveChart.prototype.buildButton = function(cssIcon, text, callback, id, isHidden) {
	var btn = WSDOM.Element.create("div", 
		(id) 
		? {"id": id, "class": "basicButtonGray"}
		: {"class": "basicButtonGray"}, [
		WSDOM.Element.create("div", null, [
			WSDOM.Element.create("em", {"class": "icon " + cssIcon}, text)
		])
	]);
	
	if(isHidden){ 
		WSDOM.Element.replaceClass('basicButton', 'wsodHidden')
	}
	
	if (callback) {
		this.eventManager.add(btn, "click", function(e, el) {
			
			WSDOM.Element.toggleClass(el, "selectedButtonGray");
			callback.call(this, e, el);
			
		}, this);
	}
	
	return btn;
}

InteractiveChart.prototype.buildChartContainer = function() {
	return WSDOM.Element.create("div", {id: "interactiveChartImageContainer"}, [
		WSDOM.Element.create("img", {"class":"chartImage", src:"/gif/x.gif"}),
		this.buildLoadingOverlay()
	])
};

InteractiveChart.prototype.buildLoadingOverlay = function() {
	return WSDOM.Element.create("div", {"class":"chartLoading wsodHidden" }, [
		WSDOM.Element.create("div", {"class": "loadingImageContainer"}, [
			WSDOM.Element.create("img", {src:"/ft/resources/image/loading.gif"})
		])
	]);
};

InteractiveChart.prototype.buildCalendar = function() {
	return WSDOM.Element.create("div", {id: "div-CustomTimeframe"}, [
		WSDOM.Element.create("div", {className: "contentModule"},[
			WSDOM.Element.create("h2",{}, ["Create a Custom Timeframe"]),
			WSDOM.Element.create("a",{className: "customTimeframe closeLink", href: "javascript:void(0)", Events: 
				{type: "click", context: this, handler: this.popZoomControls}
			}, SiteRules.isFinancialTimes() ? ["Close"] : [" "]),
		]),
		WSDOM.Element.create("div", {className: "calendarHolder"},[
			WSDOM.Element.create("div", {id: "div-CalendarBegin"}),
			WSDOM.Element.create("div", {id: "div-CalendarEnd"}),
		]),
		WSDOM.Element.create("div", {"class": "applySettings"}, [
			WSDOM.Element.create("div", {id: "applyButton", "class": "basicButton", "style": "float: left"}, "<span>Apply Date Range</span>")
		])
	]);
};

InteractiveChart.prototype.initializeInteractiveChart = function() {
	this.buildContent();
	
	this.eventManager.add({element: WSDOM.Element.parseSelector("li[timeframe]", "timeframeControlsContainer"), type: "click", context: this, handler: this.setTimeframe, data: {}});
	this.eventManager.add({element: WSDOM.Element.parseSelector("li.customRange", "timeframeControlsContainer"), type: "click", context: this, handler: this.popZoomControls})
	
	this.eventManager.add({element: WSDOM.Element.get("saveSettings"), type: "click", context: this, handler: this.popDialog, data: {type:'saveSetting'}});
	this.eventManager.add({element: WSDOM.Element.get("loadSettings"), type: "click", context: this, handler: this.loadDialog, data: {type:'loadSettings', label: 'Load settings'}});	
	this.eventManager.add({element: WSDOM.Element.get("saveChart"), type: "click", context: this, handler: this.popDialog, data: {type:'saveChart'}});
	this.eventManager.add({element: WSDOM.Element.get("loadChart"), type: "click", context: this, handler: this.loadDialog, data: {type:'loadChart', label: 'Load chart'}});		
	
	//this.eventManager.add({element: WSDOM.Element.parseSelector("div.ftNewsButton", this.settings.type+"ChartControls"), type: "click", context: this, handler: this.toggleEvent, data: {event:"ftNews"}});
	
	this.attachFlyoutHandlers();
	
	this.onDragStop().addListener(this.offset, this);
	
	this.initSymbolSearch();

	this.initializeInteractiveChart = function() {
		// overwrite so this can only be run once.
		return;
	}
};

InteractiveChart.prototype.loadDialog = function(e, el, data) {

    if (window.INFOID && window.INFOID == 3) { //Check to see if the user is logged in...

        this.subscribePopup();
        
    } else {

        var p = this.getLoadPopup(data);
        p.clearContent();
        p.setTitleText(data.label);
        p.sizeShim();
        if (!this.userStoredData) {
            this.userStoredData = this.getUserStoredData();
        }
        var content = WSDOM.Element.create('div', { id: 'chartSettingsPopup' });
        var options = (data.type == 'loadSettings') ? this.userStoredData.settings : this.userStoredData.charts;
        var count = 0;

        for (var item in options) {
            count++;
            var el = WSDOM.Element.create('div',
			{ className: (options[item].value.indexOf('manage') != -1) ? 'managesetting' : 'loadoption' },
				WSDOM.Element.create('a', { href: '#',
				    value: options[item].value
				},
					unescape(options[item].label)),
				content);
            this.eventManager.add({
                element: el,
                type: "click",
                context: this,
                handler: this.loadSettings,
                data: { id: options[item].value, type: (data.type == 'loadSettings') ? 'saveChartParams' : 'saveChartSettings' }
            });
        }

        if (count == 1) {
            //Element.remove(el, content);
            Element.create("p", { className: "noDataMessage" }, [
			(data.type == 'loadSettings') ? 'You have no saved chart settings' : 'You have no saved charts'
		], content);
        }

        WSDOM.Element.addChild(p.getContent(), content);
        p.draw();
    }
}

InteractiveChart.prototype.loadSettings = function(e, el, data){
	e.cancel();
	var p = this.getLoadPopup();
	if(data.id != 'manageSetting' && data.id != 'manageChart'){
		p.close();
		p.clearContent();
	}	
	this.loadSave(e, el, data);
}

InteractiveChart.prototype.getLoadPopup = function(){
	var p = new Popup();		
	
	p.allowOthers(true);
	
	// todo, use generic classname
//	WSDOM.Element.addClass(p.getFrame(), "setAlertsErrorPopup");
	
	this.getLoadPopup = function() {
		return p;
	}
	
	return this.getLoadPopup();		
}

InteractiveChart.prototype.attachFlyoutHandlers = function() {
	
	this.flyouts["selectIndicators"].onSelect().addListener({
		context: this,
		handler: function(e, item) {
			if (!item.getValue()) {
				return;
			}
			this.addIndicator(item.getValue(), item.getLabel());	
			
		}
		
	});
	
	this.flyouts["selectEvents"].onSelect().addListener({
		context: this,
		handler: function(e, item) {
			this.addEvent(item.getValue(), item.getLabel());	
		}
		
	});
	
	var self = this;
	
	$ws("div.selectComparisons").bind("click", function(e) {
		var elTarget = $ws(e.target).attr("data-value") ? $ws(e.target) : $ws(e.target).parents("[data-value]");
	
		if (!elTarget || !elTarget.size()) { return; }
	
		if (elTarget.attr("data-value") == "addPortfolioHoldings") {
			self.addPortfolioHoldings();
		} else if (elTarget.attr("data-value") == "addOtherSecurities") {
			self.addOtherSecurity();
		} else {
			self.addComparison(elTarget.attr("data-value"), elTarget.find(".compareName").html());
		}
	});
	
	this.flyouts["selectStyles"].onSelect().addListener({
		context: this,
		handler: function(e, item) {
			this.setStyle(item.getValue(), item.getLabel());	
		}
		
	});
	
}

InteractiveChart.prototype.initSymbolSearch = function() {
	var theChart = this;
	var s = new SymbolSearch();
	s.moreResultsPopupMode(true);
	s.moreResultsHandlerCallback(
		function(popup, parent) {
			var elLinks = WSDOM.Element.parseSelector('.interactiveChartLink', parent || WSDOM.Element.get('wsod'));
			
			WSDOM.Events.add(elLinks, 'click', function(e, el) {
				e.cancel();
				
				var symbol = el.getAttribute(wsodInteractiveChart.ATTR_SYMBOL);
				var issueName = el.getAttribute(wsodInteractiveChart.ATTR_ISSUE_NAME);
				
				wsodInteractiveChart.showInteractiveChart(symbol, issueName);
				
				popup.close();
			});		
		}
	);
	s.setForm(WSDOM.Element.get('newChart'));
	s.setRequestor(new ContentBuffer());
		
	s.go = function(symbol) {
		this.clearResults();
		this.query = symbol;
		this.elInput.value = symbol;
		theChart.settings.symbol = symbol;
		//theChart.validateSymbol = true;
		theChart.getAdvancedChart(null, true);
	};
	
	s.eventManager.add(s.elForm, "submit", function(e) {
		e.cancel();
		this.go(this.elInput.value);
	}, this);
};


InteractiveChart.prototype.showInteractiveChart = function(symbol, issueName) 
{
	this.initializeInteractiveChart();
	
	this.draw();
	this.offset(null, WSDOM.Element.getXY(this.getFrame()));
	
	this.setSymbol(symbol);
	this.setIssueName(issueName);
	
	this.getAdvancedChart("init", true);
	
	this.setTimeframe(null, null, {timeframe: this.params.timeframe, preventUpdate: true});
	
	if (window["dcsMultiTrack"] instanceof Function) {
		window["dcsMultiTrack"](
			"WT.ti", "Interactive Charting"
		);
	}	
}

InteractiveChart.prototype.offset = function(e, value) {
	if (value) {
		this._offset = value;
	}
	
	return this._offset;
}

InteractiveChart.prototype.rolloverChart = function(e, el, data) 
{
	var x0 = e.nativeEvent.clientX - this.offset().x;

	this.coordPt = this.rolloverCoords[x0];

	if (
			(this.coordPt || this.coordPt === 0)/* && 
			(!this.lastCoordPt || (this.lastCoordPt && this.lastCoordPt != this.coordPt))*/
		) { 
		this.updateInfoBar(this.chartImage.coords[this.coordPt], e);
	}
	
	this.lastCoordPt = this.coordPt
}

InteractiveChart.prototype.rolloutChart = function(e, el, data) 
{
//	console.info(this.chartImage.coords)
}

InteractiveChart.prototype.updateInfoBar = function(obj, e) 
{
	if (obj) {	
		if (!this.rolloverLine) {
			var rolloverOffset = 18,
				baseChartHeight = this.settings.yAxisHeightUpper + this.settings.upperChartPadding + this.settings.chartOffset,
				lowerChartHeight = this.settings.yAxisHeightLower * this.params.lower.length,
				baseChartRolloverHeight = baseChartHeight - this.settings.xAxisHeight - rolloverOffset,
				lowerChartTop = baseChartHeight + this.params.lower.length;
		
			var chartImageContainer = WSDOM.Element.get(this.settings.type+"ChartImageContainer");
			this.rollover = WSDOM.Element.create("div", {'class':'rollover'}, null, chartImageContainer);
			this.rolloverText = WSDOM.Element.create("div", {'class':'rolloverText'}, null, chartImageContainer);
			this.rolloverLine = []
			this.rolloverLine.push(WSDOM.Element.create("div", {'class':'rolloverLine'}, null, this.rollover));
			WSDOM.Element.setHeight(this.rolloverLine, baseChartRolloverHeight);
			WSDOM.Element.setXY(this.rolloverLine, null, rolloverOffset);
			
			if (this.params.lower.length) {
				lowerLine = WSDOM.Element.create("div", {'class':'rolloverLine'}, null, this.rollover);
				WSDOM.Element.setHeight(lowerLine, lowerChartHeight);
				WSDOM.Element.setXY(lowerLine, null, lowerChartTop);
				this.rolloverLine.push(lowerLine);
			}
			
			this.crossHair = WSDOM.Element.create("div", {'class':'crossHair'}, null, this.rollover);
			WSDOM.Element.setWidth(this.crossHair, this.settings.width);
			
			this.crossHairBarrier = {
				upperTop: rolloverOffset,
				upperBottom: baseChartRolloverHeight + rolloverOffset,
				lowerTop: lowerChartTop
			};
		}
		
		WSDOM.Element.setHTML(this.rolloverText, [
			"<div>",
				"<span class=\"value\">", obj.date, "</span>",
				"<span class=\"label\">Close</span>",
				"<span class=\"value\">", obj.close, "</span>",
				"<span class=\"label\">Open</span>",
				"<span class=\"value\">", obj.open, "</span>",
				"<span class=\"label\">High</span>",
				"<span class=\"value\">", obj.high, "</span>",
				"<span class=\"label\">Low</span>",
				"<span class=\"value\">", obj.low, "</span>",
				"<span class=\"label\">Volume</span>",
				"<span class=\"value\">", obj.volume, "</span>",
			"</div>"
		].join(""));
		
		var pageY = e.nativeEvent.pageY ? e.nativeEvent.pageY : e.nativeEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop,
			crossHairY = pageY - Element.getXY("interactiveChartImageContainer").y - 5;

		WSDOM.Element.setXY(this.rolloverLine, obj.x0, null);
		
		if (
			crossHairY >= this.crossHairBarrier.upperTop &&
			(crossHairY <= this.crossHairBarrier.upperBottom || crossHairY >= this.crossHairBarrier.lowerTop)
		) {
			WSDOM.Element.setXY(this.crossHair, null, crossHairY);
		}
	}
}

InteractiveChart.prototype.getAdvancedChart = function(type, getSupplementalData) {
	//cancel previous upper chart request
	this.setLoadingState(true);
	this.closeDialog();
//	this.getAlertsOverlay().clearAll();
	this.disableTrendlines();
	this.disableRollover();
	this.chartImage.portfolioTransactions = null;
	if(WSDOM.Element.get('transEventContainer')){
		WSDOM.Element.remove(WSDOM.Element.get('transEventContainer'));
	}
	
	this.chartImage.contentBuffer.abortRequests();

	this.settings.height = (this.settings.yAxisHeightUpper + this.settings.upperChartPadding) + (this.params.lower.length * this.settings.yAxisHeightLower) + (this.params.lower.length * this.settings.chartOffset) + 1;

	var returns = [
		"fileName:File.Name", 
		"eventPoints:eventPoints", 
		"rangeExport:rangeExport", 
		"datesExport:datesExport", 
		"chartCoords:chartCoords", 
		"timeStamp:timeStamp", 
		"timezoneDelta:timezoneDelta",
		"priceRange:priceRange",
		"portfolioTransactions:portfolioTransactions",
		"currencyCode:currencyCode"
	];
/*	if(this.params.transactions){
		returns.push('portfolioTransactions:portfolioTransactions');
	}*/
	this.chartImage.load({
		type: this.settings.type, 
		settings: this.settings, 
		params: this.params, 
		returns: returns.join(","), 
		callback: this.setupAdvancedChart,
		getSupplementalData: getSupplementalData,
		context: this//,
		//validateSymbol: this.validateSymbol 
	});
}

InteractiveChart.prototype.setupAdvancedChart = function() 
{
	InteractiveChart.Super(this, "setupAdvancedChart", arguments);
	
	this.updateComparisons(this.chartImage.updatedComparisons);
	this.updatePeers(this.chartImage.peers, this.chartImage.settings.FTStandard);
	
	this.updatePriceRange(this.chartImage.priceRange);
	var response = this.serializer.deserialize(this.chartImage.portfolioTransactions);
	if(this.params.drawTransactions){
		
		this.getTransactionsOverlay().updatePortfolioTransactions(response.transactions, response.summary);
	}
	
//	this.addAlerts(this.chartImage.alerts);
	this.drawIndicatorHeaders();	
	this.updateToolbar(this.params.drawTransactions, this.params.ftNews, response.transactions ? response.transactions.length : false, this.params.icNews)	
	this.sizeShim();
	
	this.loadChartLoadEvents();
}

InteractiveChart.prototype.addChartLoadEvent = function(handler, context) {
	this._chartLoadEvents = this._chartLoadEvents || [];
	this._chartLoadEvents.push({handler: handler, context: context});
}

InteractiveChart.prototype.removeChartLoadEvent = function(event) {
	if (this._chartLoadEvents) {
		var loadEvents = [];
		for (var i = 0; i < this._chartLoadEvents.length; i++) {
			if (this._chartLoadEvents[i].handler != event) {
				loadWSDOM.Events.push(this._chartLoadEvents[i]);
			}
		}
		this._chartLoadEvents = loadEvents;
	}
}

InteractiveChart.prototype.removeAllChartLoadEvents = function() {
	this._chartLoadEvents = [];
}

InteractiveChart.prototype.loadChartLoadEvents = function() {
	if (this._chartLoadEvents) {
		for (var i = 0; i < this._chartLoadEvents.length; i++) {
			this._chartLoadEvents[i].handler.Context(this._chartLoadEvents[i].context)();
		}
	}
}

InteractiveChart.prototype.showEvent = function(e, el, data) {
	var theChart = this;
	
	if (this.rolloverActive) {
		this.rolloverChart(e, el);
	}

	if (el.dialogEventOut) {
		el.dialogEventOut.clearDelayTimeouts();
		el.dialogEventOut.removeAllElements();
		el.dialogEventOver.removeAllElements();
	}
	else {
		if (('ftNews' == data.type || 'icNews' == data.type) && this.settings.type == 'interactive') {
			el.dialogEventOut		= false;
			el.dialogEventOver	= false;
		}
		else {
			el.dialogEventOut		= this.eventManager.add({element: null, type: "mouseout", context: this, handler: function(e) { this.hideEvent(e, el); }, delay: 100 });
			el.dialogEventOver	= this.eventManager.add({element: null, type: "mouseover", context: el.dialogEventOut, handler: el.dialogEventOut.clearDelayTimeouts });
		}
	}

	WSDOM.Element.addClass(el, "active");

	if (!el.eventDialogBubble) {		
		var dialogContent = [];

		if (this.settings.type != 'performance') {
			if ("ftNews" != data.type && "icNews" != data.type) {
				dialogContent.push(WSDOM.Element.create("div", {'class':'eventDialogContent'}, data.date));
			}
		}

		if ('ftNews' == data.type || 'icNews' == data.type) {
			var headlines = data.value.split("@@");
			var urls = data.url.split("@@"); 
			var time = data.time.split("@@");
			var h;

			if (this.settings.type == 'performance') {
				for (var i = 0, h, words; i < Math.min(headlines.length, 2); i++) {
					h = theChart.treatHeadline(headlines[i], data.width);

					if (urls[i]) {
						dialogContent.push(WSDOM.Element.create('a', { 'class':'eventDialogContent storyLink', 'href':urls[i], 'Events':[ { type:'click', handler:popNewsStory } ]}, h));
					}
					else {
						dialogContent.push(WSDOM.Element.create('div', { 'class':'eventDialogContent storyLink' }, h));
					}
				}
			}
			else {
				// Interactive Chart
				if (this.hover) {					
					this.hover.clearContent();
	
					var innerContent = WSDOM.Element.create('div', { 'class':'innerContent' }, null, this.hover.getContent());
					WSDOM.Element.create('div', { 'class':'newsDate' }, data.date, innerContent);
	
					var tBody = WSDOM.Element.create('tbody', {}, null);
					WSDOM.Element.create('table', { 'class':'newsTimesAndHeadlines' }, tBody, innerContent);
	
					for (var i = 0, h, words; i < headlines.length; i++) {
						h = theChart.treatHeadline(headlines[i], data.width);
						var finalHeadline = h;
						if (urls[i]) {
							finalHeadline = WSDOM.Element.create('a', { 'href':urls[i], 'Events':[ {type: 'click', handler: popNewsStory } ]}, h);
						}
	
						WSDOM.Element.create('tr', {}, [ WSDOM.Element.create('td', { 'class':'newsTime' }, time[i]), WSDOM.Element.create('td', { 'class':'storyLink' }, finalHeadline) ], tBody);
					}
				}
			}
		}
		else if('dividends' == data.type){
			dialogContent.push(WSDOM.Element.create("div", {'class':'eventDialogContent'}, data.value + ' ' + data.currency));
		}
		else {
			dialogContent.push(WSDOM.Element.create("div", {'class':'eventDialogContent'}, data.value));
		}

		if (dialogContent.length) {
			el.eventDialogBubble = WSDOM.Element.create("div", {'class': 'eventDialogBubble ' + data.type}, dialogContent, WSDOM.Element.get(this.settings.type+"ChartEvents"));
		}
	}

	if (el.dialogEventOut) {
		el.dialogEventOut.addElement([el.eventDialogBubble, el]);
	}

	if (el.dialogEventOver) {
		el.dialogEventOver.addElement([el.eventDialogBubble, el]);
	}

	if (el.eventDialogBubble) {
		WSDOM.Element.setXY(el.eventDialogBubble, data.x0 - 5, data.y0 - 5)
		WSDOM.Element.removeClass(el.eventDialogBubble, "narrowEventBubble")

		if (data.width) {
			WSDOM.Element.setWidth(el.eventDialogBubble, Math.min(data.width - 5, 200));

			if (data.width < 80) {
				WSDOM.Element.addClass(el.eventDialogBubble, "narrowEventBubble");
			}		
		}
	}
}

InteractiveChart.prototype.updateFlyoutItemComparisons = function(item, showSymbol) {
	var container = item.getContainer();
	var country = container.getAttribute("data.country");
	//var country = item.data.extra.country;
	
	var label = container.innerHTML;
	WSDOM.Element.removeChildNodes(container);
	
	var compareTo = WSDOM.Element.create("div", { "class": "compareTo"}, [
		WSDOM.Element.create("div", {"class": "compareName"}, item.getLabel())
	]);
	
	if (country) {		
		WSDOM.Element.create("div", { 
			"class": "wsod-flag flag-" + String(country).toLowerCase() 
		}, null, compareTo);
	}
	
	if (showSymbol) {
		var symbol = container.getAttribute("data.displaysymbol") || item.getValue();
		WSDOM.Element.create("div",  {"class": "symbol"}, symbol, compareTo)
	}
	
	WSDOM.Element.addChild(container, compareTo);
}

InteractiveChart.prototype.formatIndexComparisonFlyout = function() {
	var indexFlyout = this.flyouts["selectComparisons"].itemsById["indices"];
	
	for (var i=0; i<indexFlyout.child.items.length; i++) {
		this.updateFlyoutItemComparisons(indexFlyout.child.items[i]);
	}
};

InteractiveChart.prototype.updatePeers = function(peers, symbol) {
	var peersFlyout = this.flyouts["selectComparisons"].itemsById["peers"];
	
	if (!peers || !peers.length) {
		peersFlyout.setLabel("Peers not available");
		peersFlyout.setData({});
		return;
	}
	
	peersFlyout.setLabel("Peers of " + symbol);
	peersFlyout.setData({ children: peers });
	
	for (var i=0; i<peersFlyout.child.items.length; i++) {
		this.updateFlyoutItemComparisons(peersFlyout.child.items[i], true);
	}
};

InteractiveChart.prototype.updateComparisons = function(updated) {
	if (updated && updated.length) {
		for (var i=0, comparison; i<updated.length; i++) {
			comparison = updated[i];
			
			if (!this.params.index[comparison.position]) {
				continue;
			}
			
			this.params.index[comparison.position] = comparison.data;
		}
	}
}

InteractiveChart.prototype.getPortfolioHoldingsPopup = function() {
	var ph = new PortfolioHoldings();
	
	//ph.setParent(WSDOM.Element.get("interactiveChart"));
	
	ph.onSelectHolding().addListener({
		context: this,
		handler: function(e, holding) {
			this.addComparison(holding.wsodIssue, holding.name, "wsodIssue");
		}		
	})
	
	this.getPortfolioHoldingsPopup = function() {
		return ph;
	};
	return this.getPortfolioHoldingsPopup();
}

InteractiveChart.prototype.getAlertsOverlay = function(btn) {
	var alertsOverlay = new AlertsOverlay(WSDOM.Element.get(this.settings.type+"ChartImageContainer"), this);
	
	// this is weird, clean it up
	var theChart = this;
	var _hide = alertsOverlay.hide;
	alertsOverlay.hide = function(e, el) {
		_hide.call(this, e, el);
		
/*
		if (theChart.btnSetAlert) {
			
			WSDOM.Element.removeClass(theChart.btnSetAlert, "selectedButton");
		}
*/
	}
	
	//this.toggleAlertsOverlay
	
	this.getAlertsOverlay = function() {
		return alertsOverlay;
	}
	return this.getAlertsOverlay();

};

InteractiveChart.prototype.updatePriceRange = function(priceRange) {
	priceRange = this.serializer.deserialize(priceRange);
	var alertsOverlay = this.getAlertsOverlay();
	alertsOverlay.setPriceRange(priceRange);
};

InteractiveChart.prototype.addAlerts = function(alerts) {
	
	// can't show alerts on percent comparisons right now
	if (this.params.index.length) {
		return;
	}
	
	this.getAlertsOverlay().addAlerts(alerts);	
};

InteractiveChart.prototype.toggleAlertsOverlay = function(e, el) {
	var alertsOverlay = this.getAlertsOverlay();
	
	WSDOM.Element.toggleClass(el, "selectedButtonGray");
	
	if (alertsOverlay.isVisible()) {
		
		alertsOverlay.hide();
		//this.enableRollover();
		
	}
	else {
		
		if (this.params.index.length) {
			alertsOverlay.showComparisonError();
		}
		else {
			alertsOverlay.draw();
		}
	}
};

InteractiveChart.prototype.getHypotheticalsOverlay = function(btn) {
	var hypotheticalsOverlay = new HypotheticalsOverlay(WSDOM.Element.get(this.settings.type+"ChartImageContainer"), this);
	
	this.getHypotheticalsOverlay = function() {
		return hypotheticalsOverlay;
	}
	
	return this.getHypotheticalsOverlay();
};

InteractiveChart.prototype.toggleHypotheticalsOverlay = function(e, el) {
	var hypotheticalsOverlay = this.getHypotheticalsOverlay();
	
	if (this.getLoadingState()) { return; }
	
	WSDOM.Element.toggleClass(el, "selectedButtonGray");
	
	if (hypotheticalsOverlay.isVisible()) {
		hypotheticalsOverlay.hide();
	} else {
		hypotheticalsOverlay.draw();
	}	
}

InteractiveChart.prototype.togglePortfolioTransactions = function(e, el, event) {
	WSDOM.Element.toggleClass(el, "selectedButtonGray");

	var elClass = el.getAttribute("class");
	elClass = elClass ? elClass : el.getAttribute("classname");
	
	if (elClass.indexOf('selectedButton') > -1) {
		this.params.drawTransactions = true;
		this.getAdvancedChart("addPortfolioTransactions")
	} else {
		this.params.drawTransactions = false;
		WSDOM.Element.remove('transEventContainer');
		this.getAdvancedChart('init');
	}
}

InteractiveChart.prototype.toggleTrendlines = function(e, el) {
	WSDOM.Element.toggleClass(el, "selectedButtonGray");
	
	var elClass = el.getAttribute("class");
	elClass = elClass ? elClass : el.getAttribute("classname");
	
	if (elClass.indexOf('selectedButton') > -1) {
		this.enableTrendlines();
	} else {
		this.disableTrendlines();
	}
}

InteractiveChart.prototype.disableTrendlines = function() {
	this.enableRollover();
	
	if(WSDOM.Element.get("toggleTrendlines")){
		WSDOM.Element.removeClass("toggleTrendlines", "selectedButtonGray");
	};
	
	if (this.trendlines) {
		this.trendlines.clearLines();
		this.trendlines.disableCanvas();
	}
}

InteractiveChart.prototype.enableTrendlines = function() {
	if (!this.trendlines) {
		var rRanges = this.chartImage.rangeExport ? this.chartImage.rangeExport.split(',') : [],
			elChartContainer = Element.get("interactiveChartImageContainer"),
			oChartPos = Element.getXY(elChartContainer),
			oChartSize = Element.getSize(elChartContainer);
	
		// A bit of an ugly logic check here, but this is how the chart was built to return its position and value ranges, if the array doesn't have more than 6 elements, something went wrong so we shouldn't allow trendlines
		if (rRanges.length > 6) {
			this.trendlines = new TrendLineCanvas(elChartContainer);
			this.trendlines.setBounds(0, oChartSize.width, 0, oChartSize.height);
			this.trendlines.setAxes(Number(rRanges[0]), Number(rRanges[2]), Number(rRanges[4]), Number(rRanges[6]));
		}
	}

	this.disableRollover();
	
	this.trendlines.enableCanvas();
}

InteractiveChart.prototype.getTransactionsOverlay = function(btn) {
	var transactionsOverlay = new PortfolioTransactions(this);	
	this.getTransactionsOverlay = function() {
		return transactionsOverlay;
	}	
	return this.getTransactionsOverlay();
};

InteractiveChart.prototype.addOtherSecurity = function() {
	// done in haste, apologies
	this._addOtherPopup = new Popup();
	var p = this._addOtherPopup;
	p.allowOthers(true);
	
	WSDOM.Element.addClass(p.getFrame(), "compareToOther");
	
	var form, link;
	WSDOM.Element.create("div", null, [
		
		WSDOM.Element.create("label", { "for": "symbolCompareTo"}, "Enter symbol, name, or partial name of the security you would like to compare."),
		form = WSDOM.Element.create("form", null, [
			WSDOM.Element.create("input", { id: "symbolCompareTo", "name": "query" }),
			//WSDOM.Element.create("input", { "type": "hidden", name: "time", value: new Date().getTime() }),
			link = WSDOM.Element.create("a", { href: "#" }, "Add to chart")
		])
	], p.getContent())
	
	var theChart = this;
	var s = new SymbolSearch();
	s.moreResultsPopupMode(true);
	s.moreResultsHandlerCallback(
		function(popup, parent) {
			var elLinks = WSDOM.Element.parseSelector('.interactiveChartLink', parent || WSDOM.Element.get('wsod'));
			
			WSDOM.Events.add(elLinks, 'click', function(e, el) {
				e.cancel();
				
				var symbol = el.getAttribute(wsodInteractiveChart.ATTR_SYMBOL);
				var issueName = el.getAttribute(wsodInteractiveChart.ATTR_ISSUE_NAME);
				
				wsodInteractiveChart.addComparison(symbol, symbol, "FTStandard");
				
				popup.close();
				this._addOtherPopup.close();
			}.Context(this));		
		}, this
	);	
	
	s.setForm(form);
	s.setRequestor(new ContentBuffer());
	
	var interactiveChart = this;	
	s.go = function(symbol) {
		this.requestor.abortRequests();
		
		if (!symbol) {
			return;
		}
		
		this.clearResults();
		this.query = symbol;
		this.elInput.value = symbol;
		
		interactiveChart.addComparison(symbol, symbol, "FTStandard"); //this will force a serverside xref to get us back to wsodissue
		p.close();
	};
	
	s.submitHandler = function(e) {
		e.cancel();
		this.go(this.elInput.value);
	};
	
	s.eventManager.add(s.elForm, "submit", s.submitHandler, s);
	s.eventManager.add(link, "click", s.submitHander, s);
	
	this.addOtherSecurity = function() {
		p.setTitleText("Compare " + this.settings.symbol + " to another share");
		p.draw();
		
		s.elInput.value = "";
		s.elInput.focus();
	}
	
	this.addOtherSecurity();
};

InteractiveChart.prototype.addPortfolioHoldings = function() {
	var ph = this.getPortfolioHoldingsPopup();
	
	ph.draw();
};

InteractiveChart.prototype.addComparison = function(symbol, name, symbolSet) {

	if (this.params.index.length < this.maxComparisons) {	
	
		this.params.index.push({
			index: symbol, 
			title: name, 
			color: this.indexIndicatorColors.splice(0,1),
			symbolSet: symbolSet || "WSODIssue"
		});
		this.getAdvancedChart("comparisonAdd");
		
	} else {
		
		alert("Maximum number of comparisons reached.");
//		this.popDialog(null, null, {title: "Chart Error", errorText: "You are limited to " + this.maxComparisons + " comparisons. To view an additional comparison, please remove one comparison from the price performance chart."});

	}
	
};

InteractiveChart.prototype.addEvent = function(value) {
	this.params[value] = true;
	this.getAdvancedChart("eventAdd");
};


InteractiveChart.prototype.addIndicator = function(value) {
	if (this.upperIndicators[value]) {
		this.addUpperIndicator(value);
	} else {
		this.addLowerIndicator(value);
	}
};

InteractiveChart.prototype.setStyle = function(value) {
	this.params.style = value;
	this.getAdvancedChart("style");
};

// ----------------------------------------------------------------------------------------
//	Massive data structures here
// ----------------------------------------------------------------------------------------

InteractiveChart.prototype.getAvailableUpperIndicators = function() {
	var upperIndicators = {
		'sma': {
			name: 'sma'
			,title: 'Simple Moving Average'
			,color: []
			,text: 'Simple Moving Average is calculated by adding the closing prices for a number of time intervals and dividing by that number, giving equal weight to each bar.'
			,options: {
				labels: ['Period']
				,values: [50]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'ema': {
			name: 'ema'
			,title: 'Exponential Moving Average'
			,color: []
			,text: 'Exponential Moving Average is weighted in favor of recent price movement, thus providing a more reactive view of price changes than SMA.'
			,options: {
				labels: ['Period']
				,values: [50]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'boll': {
			name: 'boll'
			,title: 'Bollinger Bands'
			,color: []
			,text: 'Bollinger Bands provide a view of the current trading range.'
			,options: {
				labels: ['Period', 'Deviations']
				,values: [20, 2]
				,minValues: [1, 1]
				,maxValues: [200, 10]
			}		
		}
		,'psar': {
			name: 'psar'
			,title: 'Parabolic SAR'
			,color: []
			,text: 'Parabolic Time/Price System is used to set price stops.'
			,options: {
				labels: ['Step', 'Maximum']
				,values: [.02, .2]
				,minValues: [.01, .01]
				,maxValues: [1, 1]
			}			
		}
		,'pc': {
			name: 'pc'
			,title: 'Price Channel'
			,color: []
			,text: 'Price channels form boundaries above and below a price line and can be used to measure volatility.'
			,options: {
				labels: ['Period']
				,values: [20]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'tsf': {
			name: 'tsf'
			,title: 'Time Series Forecast'
			,color: []
			,text: 'The Time Series Forecast displays the statistical trend of a security\'s price based on analysis of linear regression.'
			,options: {
				labels: ['Period']
				,values: [15]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'lr': {
			name: 'lr'
			,title: 'Linear Regression'
			,color: []
			,text: 'The linear regression indicator uses trend lines to plot a straight line through prices that minimize the distances between the prices.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'mae': {
			name: 'mae'
			,title: 'Moving Average Envelope'
			,color: []
			,text: 'MA (Moving Average) Envelopes show the average value of a security\'s price over a period of time.'
			,options: {
				labels: ['Period', 'Percent']
				,values: [20, 6]
				,minValues: [1, 1]
				,maxValues: [200, 20]
			}			
		}
	};
	
	return upperIndicators;
};

InteractiveChart.prototype.getAvailableLowerIndicators = function() {
	var lowerIndicators = {
		'ad': {
			name: 'ad'
			,title: 'Accumulation Distribution'
			,text: 'A momentum indicator that relates price changes to the amount of buying and selling associated with those changes.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'adlnasdaq': {
			name: 'adlnasdaq'
			,title: 'Advance Decline Line (NASDAQ)'
			,text: 'The A/D Line tracks the breadth of the overall market by adding or subtracting the difference between the number of stocks that closed higher and the number of stocks that closed lower to a cumulative total.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'adlnyse': {
			name: 'adlnyse'
			,title: 'Advance Decline Line (NYSE)'
			,text: 'The A/D Line tracks the breadth of the overall market by adding or subtracting the difference between the number of stocks that closed higher and the number of stocks that closed lower to a cumulative total.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'arms': {
			name: 'arms'
			,title: 'Arms Index'
			,text: 'The Arms index measures market breadth and depth and is often referred to as the TRIN.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'cv': {
			name: 'cv'
			,title: 'Chaikin\'s Volatility'
			,text: 'Chaikin\'s Volatility indicator relays information about the daily dispersion of prices.'
			,options: {
				labels: ['EMA', 'Difference']
				,values: [10, 10]
				,minValues: [1, 1]
				,maxValues: [200, 200]
			}
		}
		,'dmi': {
			name: 'dmi'
			,title: 'Directional Movement Index'
			,text: 'The Directional Movement Index was developed by Welles Wilder and is used to measure the strength of a trend.'
			,options: {
				labels: ['Period']
				,values: [14]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'divyield': {
			name: 'divyield'
			,title: 'Dividend Yield'
			,text: 'Dividend Yield is the dividend per share divided by the price per share.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'eps': {
			name: 'eps'
			,title: 'Rolling EPS'
			,text: 'Earnings Per Share is an important measure of the health of a company.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'mi': {
			name: 'mi'
			,title: 'Mass Index'
			,text: 'The Mass Index is a tool used to identify reversals of trend by measuring the spread between high and low prices.'
			,options: {
				labels: ['Period']
				,values: [25]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'macd': {
			name: 'macd'
			,title: 'MACD'
			,text: 'The MACD shows the difference between a fast and a slow exponential moving average and is plotted around 0.'
			,options: {
				labels: ['Smoothing', 'Fast', 'Slow']
				,values: [9, 12, 26]
				,minValues: [1, 1, 1]
				,maxValues: [10, 100, 100]
			}
		}
		,'mfi': {
			name: 'mfi'
			,title: 'Money Flow Index'
			,text: 'The Money Flow Index describes the rate at which money is flowing into or out of a security and uses as inputs both price change and volume.'
			,options: {
				labels: ['Period']
				,values: [14]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'momentum': {
			name: 'momentum'
			,title: 'Momentum'
			,text: 'The Momentum Indicator examines the rate with which a security\'s price changes.'
			,options: {
				labels: ['Period']
				,values: [12]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'roc': {
			name: 'roc'
			,title: 'Rate of Change'
			,text: 'Rate of Change measures the amount that a stock\'s price changed compared to a number of periods in the past.'
			,options: {
				labels: ['Period']
				,values: [10]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'rsi': {
			name: 'rsi'
			,title: 'Relative Strength Index'
			,text: 'The Relative Strength Index was developed by Welles Wilder and examines the strength of a security\'s price action relative to other price changes incurred by that security.'
			,options: {
				labels: ['Period']
				,values: [14]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'obv': {
			name: 'obv'
			,title: 'On Balance Volume'
			,text: 'On Balance Volume measures the strength of buying or selling pressure on a security.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'ud': {
			name: 'ud'
			,title: 'Up/Down Ratio'
			,text: 'The Up/Down Ratio shows the relationship between trading volume for advancing stocks and trading volume for declining stocks.'
			,options: {
				labels: []
				,values: []
			}
		}
		,'williams': {
			name: 'williams'
			,title: 'Williams %R'
			,text: 'The Williams %R is a momentum indicator that attempts to measure overbought and oversold levels.'
			,options: {
				labels: ['Period']
				,values: [10]
				,minValues: [1]
				,maxValues: [200]
			}
		}
		,'fs': {
			name: 'fs'
			,title: 'Fast Stochastic'
			,text: 'Stochastics show periods when a stock is overbought or oversold.'
			,options: {
				labels: ['Period 1', 'Period 2']
				,values: [14, 3]
				,minValues: [1, 1]
				,maxValues: [200, 200]
			}
		}
		,'ss': {
			name: 'ss'
			,title: 'Slow Stochastic'
			,text: 'Stochastics show periods when a stock is overbought or oversold.'
			,options: {
				labels: ['Period 1', 'Period 2']
				,values: [14, 3]
				,minValues: [1, 1]
				,maxValues: [200, 200]
			}
		}
		,'ultimate': {
			name: 'ultimate'
			,title: 'Ultimate Oscillator'
			,text: 'The ultimate oscillator combines a stock\'s action during three periods into one oscillator.'
			,options: {
				labels: ['Period 1', 'Period 2', 'Period 3']
				,values: [7, 14, 28]
				,minValues: [1, 1, 1]
				,maxValues: [200, 200, 200]
			}
		}
		,'volume': {
			name: 'volume'
			,title: 'Volume'
			,text: 'Tracks a stock\'s volume and displays a Exponential Moving Average of volume for a given period.'
			,options: {
				labels: ['Period']
				,values: [14]
				,minValues: [1]
				,maxValues: [200]
			}
		}
	};

	if (!SiteRules.showInternationalData()) {
		delete lowerIndicators.adlnasdaq;
		delete lowerIndicators.adlnyse;
		delete lowerIndicators.arms;
		delete lowerIndicators.ud;
	}
	
	return lowerIndicators;
}


InteractiveChart.prototype.getEventTypes = function() {
	return [
		{ label: "Earnings", value: "earnings" },
		{ label: "Dividends", value: "dividends" },
		{ label: "Splits", value: "splits" }
	];
};

InteractiveChart.prototype.getChartStyles = function() {
	return [
		{ label: "OHLC", value: "ohlc" },
		{ label: "Candle", value: "candlestick" },
		{ label: "Line", value: "line" },
		{ label:"Mountain", value: "mountain" },
		{ label: "Dot", value: "dot" }
	];
};

InteractiveChart.prototype.interactiveChartTimeframes = {
	"1 Day":1
	,"5 Days":5
	,"10 Days":10
	,"1 Month":30
	,"3 Months":90
	,"6 Months":180
	,"9 Months":270
	,"YTD": "ytd"
	,"1 Year":365
	,"3 Years":1095
	,"5 Years":1825
	,"10 Years":3650
	,"Max":36500
};

/*
FILE CONCAT ADD FILE
PATH: /ft/resources/client/DataDefinitions.js
*/
function DataDefinitions () {
	DataDefinitions.Super(this);
	this.definitions = null;
};
DataDefinitions.Extend(Popup);

DataDefinitions.prototype.getBuffer = function() {
	var cb = new ContentBuffer();
	this.getBuffer = function() { return cb; };
	
	return this.getBuffer();
};

DataDefinitions.prototype.setDefinitionSet = function(set) {
	this.definitionSet = set;
};

DataDefinitions.prototype.requestURL = "/ft/resources/buffer/getDataDefinitions.asp";

DataDefinitions.prototype.getDefinitions = function() {
	this.getBuffer().load({
		url: this.requestURL,
		data: {
			view: this.definitionSet
		},
		onload: this.updateContent,
		context: this
	})
};

DataDefinitions.prototype.draw = function() {
	
	if (this.isVisible()) {		
		return;
	}
	
	if (!this.definitions) {
		this.setTitleText("Data Definitions - " + this.definitionSet);
		Element.addClass(this.getFrame(), "dataDefinitions");
		this.getDefinitions();
		Element.addChild(this.getContent(), Element.create("p", null, "Loading definitions for data items displayed on this page."));
	}
	
	DataDefinitions.Super(this, "draw");
};

DataDefinitions.prototype.updateContent = function(response) {
	this.clearContent();
	this.definitions = response.getResult();
	this.getContent().innerHTML = this.definitions;
};