

/**
 * @author David Irving
 * @version 1.0
 * @copyright 2010 BondView
 **/

Ext.namespace('BondNews');

BondNews = Ext.extend(Ext.util.Observable, {

	_config: {
		bondId: null,
		closeable: true,
		dataUrl: null,
		destroyOnClose: true,
		draggable: false,
		height: 400,
		modal: true,
		position: null,
		showFooter: true,
		title: 'Bond News',
		width: 400
	},

	_dv: null,

	_highlighted: { },

	_newsStore: null,

	_newsTemplate: new Ext.XTemplate(
		'<tpl for=".">',
			'<div class="news-item-wrapper {oddEven}" id="article-{article_id}">',
				'<input type="hidden" value="{url}" />',
				'<div class="news-item">',
					'<div class="title">{title}</div>',
					'<div class="date">Posted: {dateFormatted}</div>',
					'<div class="weight">Weight: {weight}</div>',
					'<div class="x-clear"></div>',
				'</div>',
			'</div>',
		'</tpl>',
		'<div class="x-clear"></div>'
	),

	_visible: false,

	_window: null,

	/**
 	 * Constructor for the BondNews object. You may pass a configuration object
	 * which can contain any of the following properties:
	 *	int		bondId		The bonds_id of the bond to display
	 *
	 *	boolean		closeable	True to allow the user to close the panel
	 *
	 *	string		dataUrl		The URL to retrieve bond news from
	 *
	 *	boolean		destroyOnClose	True to destroy the window when closed or false
	 * 					to keep the window in memory (useful to prevent
	 *					polling the server each time the window is displayed
	 *					with the same bonds)
	 *
	 *	boolean		draggable	True to allow the user to drag the window around the screen
	 *
	 *	int		height		The height of the window
	 *
	 * 	boolean		modal		Whether or not to make this window a modal
	 *
	 *	array		position	Array containing the X position (as a percentage), Y position,
	 *					X padding and Y padding for the window
	 *
	 *	boolean		showFooter	True to show the footer
	 *
	 *	string		title		The title of the map window
	 *
	 *	int		width		The width of the window (including the sidebar)
	 *
	 * @returns BondMap
	 **/
        constructor: function(config) {
		if (!typeof(config) == 'object') {
			throw 'You must pass an object to the constructor';
		}

		if (!config.bondId) {
			throw 'You must specify a bond ID in the configuration object';
		}

		Ext.apply(this._config, config);
	},

	/**
	 * Hide the window
	 * @return void
	 **/
	hide: function() {
		this._visible = false;
		this._window.hide();
	},

	/* Private */
	_onBeforeShow: function() {
		this._setPosition();
	},

	/* Private */
	_onClose: function() {
		this._visible = false;
		if (this._config.destroyOnClose) {
			if (this._newsStore) this._newsStore.destroy();
			if (this._dv) this._dv.destroy();
			if (this._window) this._window.destroy();
		}
	},

	/* Private */
	_onShow: function() {
		this._window.getEl().mask('Loading Articles');
		this._newsStore.load();
	},

	/* Private */
	_onWindowResize: function() {
		if (this._visible) {
			this._setPosition();
		}
	},

	/* Private */
	_processHighlights: function() {
		for (var i=0;i<this._newsStore.getCount();i++) {
			var rec = this._newsStore.getAt(i);
			var keywords = rec.get('keywords');
			var aNode = Ext.get('article-' + rec.get('article_id'));
			if (aNode) {
				for (var j=0;j<keywords.length;j++) {
					if (this._highlighted[keywords[j]]) {
						// Highlight
						aNode.addClass('highlighted-'+rec.get('oddEven'));
					} else {
						// Remove Highlight
						aNode.removeClass('highlighted-odd');
						aNode.removeClass('highlighted-even');
					}
				}
			}
		}
	},

	/* Private */
	_setPosition: function() {
		if (!this._config.position || !(this._config.position instanceof Array) || this._config.position.length < 2) {
			this._window.center();
			return;
		}

		var maxX = Ext.lib.Dom.getViewWidth() - this._config.width;
		var maxY = Ext.lib.Dom.getViewHeight() - this._config.height;

		var cX = parseFloat(this._config.position[0]);
		if (cX < 0) { cX = 0; }
		if (cX > 1) { cX = 1; }

		var cY = parseFloat(this._config.position[1]);
		if (cY < 0) { cY = 0; }
		if (cY > 1) { cY = 1; }

		var xA = (this._config.position.length >= 3) ? parseFloat(this._config.position[2]) : 0;
		var yA = (this._config.position.length >= 4) ? parseFloat(this._config.position[3]) : 0;

		var x = (maxX * cX) + xA;
		var y = (maxY * cY) + yA;

		this._window.setPosition(x, y);
	},

	/**
	 * Displays the window (if it isn't already)
	 * @return void
	 **/
	show: function() {

		if (this._visible) {
			return;
		}

		if (!this._window) {

			var fbar = null;

			if (this._config.showFooter) {
				fbar = new Ext.Toolbar({
					items: [{
						xtype: 'tbfill'
					}, {
						xtype: 'tbtext',
						text: '<div class="news-footer-label">Total News Articles:</div> '
					}, {
						xtype: 'tbtext',
						text: 'TBD',
						id: 'newsCount'
					}]
				})
			}

			this._newsStore = new Ext.data.JsonStore({
				autoDestroy: true,
				baseParams: {
					bondId: this._config.bondId
				},
				url: this._config.dataUrl,
				storeId: 'newsStore',
				root: 'articles',
				idProperty: 'article_id',
				fields: [
					'article_id', 
					'title',
					'url',
					{name: 'weight', type: 'float'},
					'date',
					'keywords'
				]
			});

			this._newsStore.on('load', function(store) {
				var el = Ext.get('newsCount');
				if (el) {
					el.dom.innerHTML = store.getCount();
				}
				var distinct = { };
				for (var i=0;i<store.getCount();i++) {
					var r = store.getAt(i);
					var keywords = r.get('keywords');
					for (var j=0;j<keywords.length;j++) {
						distinct[keywords[j]] = true;
					}
				}

				var menu = Ext.ComponentMgr.get('keywordMenu');
				for (var keyword in distinct) {
					if (!distinct.hasOwnProperty(keyword)) {
						continue;
					}
					menu.add(new Ext.menu.CheckItem({
						text: keyword.charAt(0).toUpperCase() + keyword.slice(1),
						handler: function(item) {
							if (!item.checked) {
								this._highlighted[item.bvValue] = true;
							} else {
								delete(this._highlighted[item.bvValue]);
							}
							this._processHighlights();
						},
						bvValue: keyword,
						scope: this
					}));
				}

				if (!menu || !menu.items || menu.items.length == 0) {
					Ext.ComponentMgr.get('highlightBtn').disable();
				}

				this._window.getEl().unmask();
			}, this);

			this._dv = new Ext.DataView({
				store: this._newsStore,
				tpl: this._newsTemplate,
				id: 'newsList',
				multiSelect: false,
				overClass: 'news-over',
				itemSelector: 'div.news-item-wrapper',
				singleSelect: false,
				emptyText: 'There are no news articles related to this bond',
				deferEmptyText: false
			});

			this._dv.on('click', function(dv, index, node) {
				var url = Ext.DomQuery.selectNode('input', node);
				window.open(url.value);
			}, this);

			this._dv.prepareData = function(data, index, record) {
				data.oddEven = (index%2 == 0 ? "even" : "odd");
				var date = Date.parseDate(data.date, 'U');
				data.dateFormatted = date.format('m/d/Y h:ia');
				return data;
			};

			this._window = new Ext.Window({
				closeAction: 'hide',
				title: this._config.title,
				width: this._config.width,
				height: this._config.height,
				modal: this._config.modal,
				resizable: false,
				closeable: this._config.closeable,
				draggable: this._config.draggable,
				layout: 'fit',
				items: [{
					autoScroll: true,
					xtype: 'panel',
					fbar: fbar,
					tbar: new Ext.Toolbar({
						items: [{
							xtype: 'button',
							text: 'Sort By',
							cls: 'x-btn-text-icon',
							icon: '/images/bondnews/sort.png',
							menu: new Ext.menu.Menu({
								items: [{
									text: 'Date',
									cls: 'x-btn-text-icon',
									icon: '/images/bondnews/date.png',
									handler: function() {
										this._newsStore.singleSort('date', 'desc');
										this._processHighlights();
									},
									scope: this
								}, {
									text: 'Title',
									cls: 'x-btn-text-icon',
									icon: '/images/bondnews/title.png',
									handler: function() {
										this._newsStore.singleSort('title');
										this._processHighlights();
									},
									scope: this
								}, {
									text: 'Weight',
									cls: 'x-btn-text-icon',
									icon: '/images/bondnews/weight.png',
									handler: function() {
										this._newsStore.singleSort('weight');
										this._processHighlights();
									},
									scope: this
								}]
							})
						}, {
							xtype: 'button',
							text: 'Highlight Articles Containing',
							cls: 'x-btn-text-icon',
							icon: '/images/bondnews/highlight.png',
							id: 'highlightBtn',
							menu: new Ext.menu.Menu({
								id: 'keywordMenu'
							})
						}]
					}),
					items: [this._dv]
				}]
			});

			Ext.EventManager.onWindowResize(this._onWindowResize, this);
			this._window.on('beforeshow', this._onBeforeShow, this);
			this._window.on('show', this._onShow, this);
			this._window.on('close', this._onClose, this);
			this._window.on('hide', this._onClose, this);
		}

		this._visible = true;

		this._window.show();
	}

});

