$.namespace('globe.common');

globe.common.MarketDataBox = function(containerId, layoutId, showTicker)
{
	var templateUrl = globe.conf.templateUrl,
		eventPrefix = 'marketdatabox-'
		;
	
	//
	// Config variables
	//
	this.urls = {
		tabs				: templateUrl + '/ajax/summaryTabs.jsp?symbols=TSX-I,COMP-I,SPX-I,DJIA-I,CL-FT,GC-FT,CAD/USD-I',
		chart				: templateUrl + '/ajax/medium.jsp?type=indices&range={RANGE}&symbols={SYMBOLS}',
//		watchlistSummary	: templateUrl + '/ajax/watchlist-summary.jsp',
//		watchlistData		: templateUrl + '/ajax/watchlist.jsp?watchlistId={WATCHLISTID}&type={TYPE}',
		watchlistSummary	: '/InvestorServices/WatchlistService/watchlist/summary?userId=',
		watchlistData		: '/InvestorServices/WatchlistService/watchlist/{TYPE}?userId=&watchlistId={WATCHLISTID}'
	};
	
	this.events = {
		tabs				: eventPrefix + 'tabs',
		chart				: eventPrefix + 'chart',
		watchlistSummary	: eventPrefix + 'watchlist-list',
		watchlistStocksData	: eventPrefix + 'watchlist-funds-data',
		watchlistFundsData	: eventPrefix + 'watchlist-stocks-data'
	};
	
	this.delays = {
		tabs		: 60000,
		watchlist	: 60000,
		chart		: 30000
	};
	
	this.intervals = {
		watchlist	: 0,
		tabs		: 0,
		chart		: 0
	};
	
	// insure to boolean
	this.showTicker = showTicker == true;
	this.containerId = containerId;
	
	this.width = 630;
	this.tickerHeight = 40;
	this.boxHeightCollapsed = 81;
	this.boxHeightExpanded = 186;
	
	this.expandedHeight = this.boxHeightExpanded + (this.showTicker ? this.tickerHeight : 0);
	this.collapsedHeight = this.boxHeightCollapsed + (this.showTicker ? this.tickerHeight : 0);
	
	// runtime variables
	this.watchlistType = 'gainers';
	this.watchlistId = null;
	this.isExpanded = true;
	this.chartSymbol = '';
	this.chartRange = '5d';
	this.watchlistData = null;
	this.isLoggedIn = false;
	this.watchlistInviteVisible = false;
	
	this.containerDiv = $('#' + containerId);
	this.layoutDiv = $('#' + layoutId);
	this.layoutDiv.height(this.expandedHeight);
	
	$.subscribe('relogin-success', this, 'onReloginSuccess');
	$.subscribe('login-success', this, 'onLoginSuccess');
	
	this.currency = globe.common.ChartData.currency;
};

globe.common.MarketDataBox.prototype =
{
	number : function (value) 
	{
		return globe.common.util.Number.format(value, { decimals: 0, separateThousands: true }); 
	},

	percent : function (value) 
	{ 
		return value != 0
			? globe.common.util.Number.format(value, { decimals: 2 })
			: "--"
			; 
	},
	
	delegate : function(callback)
	{
		var ref = this;
		return function() { callback.apply(ref); }
	},
	
	/** Determines if current time falls within trading hours. */
	isTradingTime : function()
	{
		return true;
	},
	
	init : function()
	{
		var templateUrl = globe.conf.templateUrl,
			swfUrl = templateUrl + '/gfx/marketdatabox',
			so = new SWFObject(
				swfUrl + '/MarketDataBox.swf', 
				'marketDataBoxMovie', 
				this.width, 
				this.expandedHeight, 
				'8.0.0',
				'#A3A2A2'
			)
		;
		
		so.addParam('allowscriptaccess', 'always');
		so.addParam('scale', 'noscale');
		so.addParam('salign', 'TL');
		so.addParam('wmode', 'transparent');
		so.addVariable('chartSwfUrl', swfUrl + '/amstock_marketbox.swf');
		so.addVariable('chartPathUrl', swfUrl);
		so.addVariable('chartSettingsUrl', swfUrl + '/amstock_settings.xml');
		so.addVariable('live', '1');
		
		if (this.showTicker)
			so.addVariable('showTicker', '1');
			
		so.write(this.containerId);
		
		this.swf = $("> *:first-child", this.containerDiv).get(0);
		this.toggleArrow = $('#group-a-toggle a');
	
		var s = '-success',
			e = '-error',
			watchlistCallback = 'showWatchlistInviteView'
			;
		
		$.subscribe(this.events.tabs + s, this, 'onTabsData');
		$.subscribe(this.events.chart + s, this, 'onChartData');
		
		$.subscribe(this.events.watchlistStocksData + s, this, 'onWatchlistStocksData');
		$.subscribe(this.events.watchlistFundsData + s, this, 'onWatchlistFundsData');
		$.subscribe(this.events.watchlistSummary + s, this, 'onWatchlistSummary');

		$.subscribe(this.events.watchlistStocksData + e, this, watchlistCallback);
		$.subscribe(this.events.watchlistFundsData + e, this, watchlistCallback);
		$.subscribe(this.events.watchlistSummary + e, this, watchlistCallback);
	},
	
	onLoginSuccess : function()
	{
		this.isLoggedIn = true;
		this.hideWatchlistInviteView();
	},
	
	onReloginSuccess : function()
	{
		this.isLoggedIn = true;
	},
	
	getIsLoggedIn : function()
	{
		return this.isLoggedIn;
	},
	
	login : function()
	{
		globe.common.register.openLoginWindow();
	},
	
	setupWatchlist : function()
	{
		var profileCookie = $.cookie('OLD_PROFILE');
		
		if (profileCookie == 'Y' || profileCookie == 'P')
		{
			globe.common.register.showConversion();
			$.subscribe('old-profile-converted-success', this, 'openMyWatchlist');
		}
		else
		{
			this.openMyWatchlist();
		}
	},
	
	openMyWatchlist : function()
	{
		window.location = '/globe-investor/my-watchlist/';
	},
	
	/** Called from flash to perform DOM side portion of expanding. */
	expandView : function()
	{
		var height = this.expandedHeight;
		
		$(this.swf).height(height);
		this.layoutDiv.height(height);
		this.isExpanded = true;
		this.toggleArrow.removeClass('close');
	},
	
	/** Called from flash to perform DOM side portion of collapsing. */
	collapseView : function()
	{
		var height = this.collapsedHeight;
		
		$(this.swf).height(height);
		this.layoutDiv.height(height);
		this.isExpanded = false;
		this.stopUpdatingChart();
		this.updateWatchlist();
		this.toggleArrow.addClass('close');
		
	},
	
	/** Toggles the view. Triggered by user on the DOM side. */
	toggleView : function()
	{
		this.swf[this.isExpanded ? 'collapseView' : 'expandView']();
	},

	/** Activates a specific page by name. */
	setChartSymbol : function(symbol) 
	{
		this.chartSymbol = symbol;
	},
	
	setChartRange : function(range) 
	{
		this.chartRange = range;
	},
	
	setWatchlistType : function(type)
	{
		this.watchlistType = type;
	},
	
	updateTabs : function()
	{
		clearInterval(this.intervals.tabs);
		
		if (this.isTradingTime())
			this.intervals.tabs = setInterval(this.delegate(this.updateTabs), this.delays.tabs);
		
		$.publish('invoke-request', this.events.tabs, { url: this.urls.tabs });
	},
	
	updateWatchlist : function()
	{
		var url;
		
		if (this.watchlistId == null)
		{
			url = this.urls.watchlistSummary;
			$.publish('invoke-request', this.events.watchlistSummary, { url: url });
			return;
		}
		
		this.stopUpdatingWatchlist();
		this.stopUpdatingChart();

		if (this.isTradingTime())
			this.intervals.watchlist = setInterval(this.delegate(this.updateWatchlist), this.delays.watchlist);

		this.watchlistData = { stocks : null, funds : null };
		
		url = this.urls.watchlistData.replace('{WATCHLISTID}', this.watchlistId);
			
		$.publish('invoke-request', this.events.watchlistStocksData, { url: url.replace('{TYPE}', 'stocks') });
		$.publish('invoke-request', this.events.watchlistFundsData, { url: url.replace('{TYPE}', 'funds') });
	},
	
	updateChart : function()
	{
		this.stopUpdatingWatchlist();
		this.stopUpdatingChart();

		if (this.isTradingTime())
			this.intervals.chart = setInterval(this.delegate(this.updateChart), this.delays.chart);
		
		var url = this.urls.chart
			.replace('{RANGE}', this.chartRange)
			.replace('{SYMBOLS}', this.chartSymbol)
			;
			
		$.publish('invoke-request', this.events.chart, { url: url });
	},
	
	stopUpdatingChart : function()
	{
		clearInterval(this.intervals.chart);
		this.intervals.chart = 0;
	},
	
	stopUpdatingWatchlist : function()
	{
		clearInterval(this.intervals.watchlist);
		this.intervals.watchlist = 0;
	},
	
	showWatchlistInviteView : function()
	{
		this.swf.showWatchlistInviteView();
		this.watchlistInviteVisible = true;
		$.subscribe('login-success', this, 'hideWatchlistInviteView');
	},
	
	hideWatchlistInviteView : function()
	{
		if (this.watchlistInviteVisible == false)
			return;
			
		this.swf.hideWatchlistInviteView();
		this.updateWatchlist();
		this.watchlistInviteVisible = false;
	},
	
	onWatchlistSummary : function(json)
	{
		if (json == null || json.data == null || json.data.length == 0)
		{
			this.showWatchlistInviteView();
			return;
		}
		
		//var data = json.data[0];
		var data = this.getCurrentWatchlist(json.data);
		
		this.watchlistName = data.watchlistName;
		this.watchlistId = data.watchlistId;
		this.updateWatchlist();
	},
	
	getCurrentWatchlist : function(data)
	{
		var currentIndex = 0;
		var currentDate = data[0].lastModifiedDate;
		
		for (var i=1; i < data.length; i++)
		{
			var nextDate = data[i].lastModifiedDate;
			
			if( currentDate < nextDate){
				currentIndex = i;
				currentDate = nextDate;
			}
		}

		return data[currentIndex];
	},
	
	getStockUrl : function(symbol, exchange)
	{
		return '/globe-investor/markets/stocks/summary/?q=' + symbol + '-' + exchange;
	},

	getFundUrl : function(securityId)
	{
		return '/globe-investor/funds-and-etfs/funds/summary/?id=' + securityId;
	},
	
	onWatchlistStocksData : function(json)
	{
		if (json == null || json.data == null)
			return;
		
		var watchlistItems =  json.data.length > 0 ? json.data[0].watchlistItems || [] : [],
			data = []
			;
		
		for (var i = 0; i < watchlistItems.length; i++)
		{
			var row = watchlistItems[i];

			data.push({
				name			: row.companyName, 
				symbol			: row.symbol,
				country			: row.currency,
				last			: this.currency(row.lastPrice),
				change			: this.currency(row.priceChange),
				changePercent	: this.percent(row.percentChange),
				url				: this.getStockUrl(row.symbol, row.exchangeCode),
				__change		: row.percentChange,
				__volume		: row.volume
			});
		}
		
		this.watchlistData.stocks = data;
		
		if (this.watchlistData.funds != null)
		{
			this.passWatchlistData();
			return;
		}
	},
	
	onWatchlistFundsData : function(json)
	{
		if (json == null || json.data == null)
			return;
			
		var watchlistItems =  json.data.length > 0 ? json.data[0].watchlistItems || [] : [],
			data = []
			;
		
		for (var i = 0; i < watchlistItems.length; i++)
		{
			var row = watchlistItems[i];

			data.push({
				name			: row.fundName, 
				symbol			: row.fundName,
				country			: "",
				last			: this.currency(row.lastPrice),
				change			: this.currency(row.priceChange),
				changePercent	: this.percent(row.percentChange),
				url				: this.getFundUrl(row.securityId),
				__change		: row.percentChange
			});
		}
		
		this.watchlistData.funds = data;
		
		if (this.watchlistData.stocks != null)
		{
			this.passWatchlistData();
			return;
		}
	},
	
	passWatchlistData : function()
	{
		var sort = {
				gainers : { field : '__change', direction : 1, filter : function(value) { return value > 0; } },
				loosers : { field : '__change', direction : -1, filter : function(value) { return value < 0; } },
				mostActive : { field : '__volume', direction : 1, filter : function(value) { return true; } }
			}[this.watchlistType],
			
			data = this.watchlistData.stocks
				// discard funds if displaying most active
				.concat(this.watchlistType != 'mostActive' ? this.watchlistData.funds : [])
				
				.sort(function(a, b)
				{
					if (a == null || b == null)
						return 0;
					
					a = parseFloat(a[sort.field]);
					b = parseFloat(b[sort.field]);
					
					if (a > b)
						return -1 * sort.direction;
					else if (a < b)
						return 1 * sort.direction;
					
					return 0;
				})
			;
			
		function filter(array, func, field)
		{
			var result = [];
			
			for (var i = 0; i < array.length; i++)
				if (func(array[i][field]))
					result.push(array[i]);
					
			return result;
		};
		
		if (data.length == 0)
			data = null;
		else
			data = filter(data, sort.filter, sort.field);

		this.swf.setWatchlistData(this.watchlistName, data);
	},
	
	onChartData : function(json)
	{
		if (json == null || json.data == null)
		{
			this.swf.setChartData("0");
			return;
		}
		
		var data = json.data[0],
			dataPoints = data.dataPoints,
			eventPoints = globe.common.ChartData.getEventPoints(data.eventPoints)
			;

		this.swf.setChartEvents(eventPoints);
		this.swf.setChartData(globe.common.ChartData.pointsToCsv(
			dataPoints, 
			this.chartRange,
			false
			));
	},
	
	onTabsData : function(json)
	{
		if (json == null || json.meta == null || json.data == null)
			return;
		
		function n(number) { return isNaN(number) ? 0 : number; }
		
		var data = [],
			timestamp = globe.common.util.Date.format(json.meta.timestamp, "mmm dd, yyyy hh:MM:ss TT")
			;
		
		for (var i = 0; i < json.data.length; i++)
		{
			var row = json.data[i];
			
			data.push({
				name: row.symbol + "-" + row.exchangeCode,
				data : {
					change			: this.currency(n(row.priceChange)),
					changePercent	: this.percent(n(row.percentChange)),
					last			: this.currency(n(row.lastPrice)), 
					volume			: this.number(n(row.volume)), 
					timestamp		: timestamp
				}
			})
		}
		
		this.swf.setTabsData(data);
	}
}
