
// JSON Content
var JSONContent = Class.create();
Object.extend(JSONContent.prototype, {

	_view: null,
	viewId: null,
	_initialized: false,
	_lastResult: null,
	newIds: [],
	
	initialize: function(view,source) {
		if (typeof view === 'string') {
			this.setValueForKey(view,'viewId');
			this.setValueForKey($(view),'_view');
		} else {
			this.setValueForKey(view,'_view');
			this.setValueForKey(view.id,'viewId');
		}
		// set values
		this.setValueForKey(0,'currentFirstId');
		this.setValueForKey([],'currentIds');
		this.setValueForKey(source,'source');
		this.setValueForKey([],'_animatedResultIds');
		
		this.setMonthArray();
		this.setDayArray();
	},

	setDelegate: function(delegate) {
		this.delegate = delegate;
	},
	
	setValueForKey: function(value,key) {
		this[key] = value;
	},
	
	getJSON: function() {
		// send the request for the JSON
		var fileName = '/scripts/get_json_content.php';
		var send = new Ajax.Request(fileName, {
			method: 'POST',
			parameters: {'source':this.source},
			onComplete: this.acknowledgeComplete.bind(this)
		});
	},

	acknowledgeComplete: function(request) {
		var jsonText = request.responseText;
		var results = new Function("return"+jsonText)();
		if (results) {
			this.results = results;
			
			// check to see if results should change
			var shouldShowResults = this.shouldShowResults();
			if (shouldShowResults === true) {
				this.showResults(this.displayCount);
			}
		}
	},
	
	shouldShowResults: function() {
		if (this.delegate && typeof this.delegate.shouldShowResults === 'function') {
			return this.delegate.shouldShowResults(this,this.results);
		}
		
		var idsMatched = true;
		this.newIds = [];

		for (var i=0; i < this.displayCount; i++) {
			var resultId = this.results.results[i].id;

			if (resultId !== this.currentIds[i]) {
				idsMatched = false;
				this.newIds.push(resultId);
			}
		}
		
		return (idsMatched) ? false : true;
	},

	willShowResults: function(displayCount) {
		if (this.results && this.results !== null) {		
			this.result = this.results.results;
		} else {
			this.displayCount = displayCount;
			this.getJSON();
		}
		
	},
	
	showResults: function(displayCount) {		
		// will show the results
		if (this.delegate && typeof this.delegate.willShowResults === 'function') {
			this.delegate.willShowResults(this,displayCount);
		} else {
			this.willShowResults(displayCount);
		}
		
		// show the results
		if (this.results && this.results !== null) {
			this._lastResult = null;
			for (var i=(this.displayCount-1); i>=0; i--) {
				var result = this.result[i] || this.result;
				var formattedResult = this.getFormattedResult(result,i);

				if (!Element.descendantOf(formattedResult, this._view)) {
					this.animateResult(formattedResult,i);
				}
				
				this._lastResult = formattedResult;
			}

		}

	},

	didShowResults: function() {
		this._initialized = true;
		this._interval = window.setInterval(this.getJSON.bind(this), 120000);
	},
	
	getFormattedResult: function(result,index) {
		if (this.delegate && typeof this.delegate.getFormattedResult === 'function') {
			return this.delegate.getFormattedResult(this,result,index);
		}
		
		var id = result.id;
		
		this.currentIds[index] = id;
		
		var displayId = this.viewId+'_'+id;
		
		var alreadyInView = this._view.down('#'+displayId);
		
		if (alreadyInView) {
			return $(displayId)
		}
	
		var fromUser = result.from_user;
		var text = result.text;
		
		this.currentFirstId = id;
		
		var displayContent = new Element('span', { className:this.viewId+'_content'}).update(text);
		var displayFromUser = new Element('a', { className:this.viewId+'_user', href:'http://twitter.com/'+fromUser, title:fromUser }).update(fromUser);
		var displayDelimiter = document.createTextNode(': ');
		var displayResult = new Element('div', { id:displayId, className:this.viewId+'_result feed_result' });
		
		var containerDiv = new Element('div');
		
		containerDiv.appendChild(displayFromUser);
		containerDiv.appendChild(displayDelimiter);
		containerDiv.appendChild(displayContent);
		
		displayResult.appendChild(containerDiv);
		
		return displayResult;
	},
	
	setMonthArray: function() {
		this.months = new Array(
			'January',
			'February',
			'March',
			'April',
			'May',
			'June',
			'July',
			'August',
			'September',
			'October',
			'November',
			'December'
		);
	},
	
	setDayArray: function() {
		this.days = new Array(
			'Sunday',
			'Monday',
			'Tuesday',
			'Wednesday',
			'Thursday',
			'Friday',
			'Saturday'
		);
	},
	
	getFormattedDate: function(date) {
		var day = this.days[date.getDay()];
		var month = this.months[date.getMonth()];
		var number = date.getDate();
		var year = date.getFullYear();
		
		return day + ', ' + month + ' ' + number + ', ' + year;
	},
	
	willAnimateResult: function(result) {
		// Thank you to Andrew Dupont for this...
		var USERNAMES = /@([A-Za-z0-9_]*)\b/;
		var URLS = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?/;
  
  		var html = result.innerHTML;
  		var text = (result.innerText && !window.opera) ? result.innerText : result.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, '');
  		
  		text.scan(URLS, function(match) {
  			html = html.sub(match[0], '<a href="#{0}">#{0}</a>');
  		});
  		html = html.gsub(USERNAMES, '<a href="http://twitter.com/#{1}/" title="#{1}">#{0}</a>');
  		
  		result.update(html);
	},

	animateResult: function(formattedResult,index) {
	
		formattedResult.hide();
		
		if (this.delegate && typeof this.delegate.willAnimateResult === 'function') {
			this.delegate.willAnimateResult(this,formattedResult);
		} else {
			this.willAnimateResult(formattedResult);
		}
		
		if (this._lastResult) {
			this._lastResult.insert({ 'before':formattedResult });
		} else {
			this._view.appendChild(formattedResult);
		}
		
		var containerWidth = this._view.getWidth();
		
		formattedResult.setStyle({
			position:'absolute',
			top:'-9999px',
			left:'-9999px',
			width:containerWidth+'px',
			display:'block'
		});
		var resultHeight = formattedResult.getHeight();
		formattedResult.setStyle({
			position:'relative',
			top:'0',
			left:'0',
			display:'none',
			//width:containerWidth+'px',
			//height:resultHeight+'px'
		});
		
		var currentId = formattedResult.id;

		if (this._initialized === true) {
			var lastId = $$('#'+this.viewId+' .'+this.viewId+'_result')[this.displayCount].id;

			new Effect.Parallel([
				new Effect.SlideDown(currentId, {sync:true}),
				new Effect.Fade(lastId, {sync:true}),
				new Effect.SlideUp(lastId, {sync:true})], {
					duration:0.8,
					afterFinish: function(effect) {
						this.didAnimateResult(currentId);
					}.bind(this)
				});
		} else {
			new Effect.SlideDown(currentId, {
				duration:0.8,
				beforeStart: function(effect) {
					effect.element.up().makeClipping();
				}.bind(this),
				afterFinish: function(effect) {
					effect.element.up().undoClipping();
					this.didAnimateResult(currentId);
				}.bind(this)
			});
		}
	},

	didAnimateResult: function(id) {
		this._animatedResultIds[this._animatedResultIds.length] = id;
		
		if (this._initialized === true) {
			new Effect.Highlight(id, {
				startcolor:'#E7A7CA',
				endcolor:'#777777'
			});
		}
		
		var results = $$('#'+this.viewId+' .'+this.viewId+'_result');
		
		results.each(function(result, index) {
			if (index === this.displayCount) {
				result.remove();
			}
		}.bind(this));
		
		// did show the results
		if (this._animatedResultIds.length === this.displayCount) {
			if (this.delegate && typeof this.delegate.didShowResults === 'function') {
				this.delegate.didShowResults(this);
			} else {
				this.didShowResults();
			}
		}

	}
});
