/***********************************************************
 * AJAX.JS
 * DESCRIPTION: Core Ajax classes and methods.
 *
 * CHANGES:
 * 
 * 09-02-06 nroberts
 * All element-related functions have been modified to support call by object reference or ID string.
 *
 * 09-27-06
 * Refactored to use Broadcaster, AjaxController, and AjaxStatus classes.
 * Updates to the UI can now be handled through event broadcasting.
 *
 ***********************************************************/

var	SCRIPT_URL = window.location.href;
var	SCRIPT_PATH = SCRIPT_URL.substring(0, SCRIPT_URL.lastIndexOf('/')) + '/';

/**
 * CLASS: AjaxController
 * Description: Ajax UI controller class.
 */
var AjaxController = {

	VERSION: '1.0.0',
	
	/** PROPERTIES **/
	isEnabled : (window.ActiveXObject || window.XMLHttpRequest),
	
	// request params
	request 		: null,
	REQUEST_URL 	: '/ajax.php',
	REQUEST_METHOD 	: 'post',
	ACTION_PARAM 	: 'action',
	DATA_PARAM 		: 'data',
	STATUS_PARAM 	: 'status',
	MESSAGE_PARAM 	: 'message',
	MESSAGE_DIV_ID 	: 'ajaxStatus',
	
	// request actions
	LOGIN_ACTION 			: 'login',
	LOGOUT_ACTION 			: 'logout',
	CHECK_USERNAME_ACTION 	: 'check_username',
	ADD_COMMENTS_ACTION		: 'add_comments',
	ADD_FAVORITE_ACTION		: 'add_favorite',
	DELETE_FAVORITE_ACTION	: 'delete_favorite',
	ADD_RATING_ACTION 		: 'add_rating',
	ADD_TAGS_ACTION			: 'add_tags',
	UPDATE_TAGS_ACTION		: 'update_tags',
	DELETE_TAGS_ACTION		: 'delete_tags',
	UPDATE_VIDEO_ACTION 	: 'update_video',
	DELETE_VIDEO_ACTION 	: 'delete_video',
	TRACK_DOWNLOAD_ACTION	: 'track_download',
	PREVIEW_MOVIE_ACTION	: 'preview_movie',
	DEBUG_VARS_ACTION		: 'debug_vars',
	
	// editing properties
	editActive : false,
	editCache  : {},
	
	// ratings handling
	ratingButtonCount : 5,
	ratingCaptions    : ['worthless', 'not so hot', 'decent', 'great', 'essential'],
	ratingButtons     : [],
	
	
	/** METHODS **/
	
	initialize : function(){
		Broadcaster.initialize(this);
		this.addListener = this.addListenerImpl;
	},
	
	addListenerImpl : function(){
		for(var i=0; i<arguments.length; i++){
			var obj = arguments[i];
			if(typeof(obj)==String.TYPE){ obj = $(obj); }
			if(this.listeners.indexOf(obj) == -1){	
				obj.onChange = this.onChange;
				obj.onReset = this.onReset;
				obj.onClear = this.onClear;
				this.listeners.push(obj);
			}
		}
		
	},	
	
	onChange : function(data){
		this.innerHTML = data.content;
	},
	
	onReset : function(){
		this.innerHTML = String.NBSP;
	},
	
	onClear : function(){
		this.innerHTML = String.EMPTY;
	},	
	
	startEdit : function(){
		this.editActive = true;
		this.editCache = {};
	},
	
	resetEdit : function(){
		this.editActive = false;
		this.editCache = {};
	},
	
	sendRequest : function(action, data, successCallback, errorCallback){
		var queryString = this.buildQueryString(action, data);
		var options = new AjaxRequestOptions(AjaxController.REQUEST_METHOD, queryString, successCallback, errorCallback);
		this.request = new Ajax.Request(AjaxController.REQUEST_URL, options);
	},

	buildQueryString : function(action, data){
		var queryString = '';
		queryString += AjaxController.ACTION_PARAM + '=' + action;
		queryString += '&' + AjaxController.DATA_PARAM + '=' + encodeURIComponent(data.toJSONString());
		return queryString;
	},
	
	getJsonData : function(response){
	    var data = eval( '(' + response.responseText + ')' );
	    return data;
	},
	
	setEditValue : function(id, value){
		this.editCache[id] = value;
	},
	
	getEditValue : function(id){
		return this.editCache[id];
	},
	
	getRatingCaption : function(position){
		return (this.ratingCaptions[position]);
	},
	
	// Caches the divs and classNames for restoring rating button values on rollout.
	cacheRating : function(){
		if(this.ratingButtons.length){ return; } 
		for(var i=0; i<this.ratingButtonCount; i++){
			var elem = $('rs_' + (i+1));
			this.ratingButtons[i] = {el: elem, cl: elem.className};
		}
	},
	
	// Clears the cached rating values.
	clearRating : function(){
		this.ratingButtons = [];
	},	
	
	// Displays ratings group on rollover.
	showRating : function(position){
		for(var i=0; i<this.ratingButtonCount; i++){
			var obj = this.ratingButtons[i];
			if(position>=0){
				obj.el.className = (position <= i ? String.EMPTY : 'hilited');
			} else {
				obj.el.className = obj.cl;
			}
		}
	}
	
}

/**
 * CLASS: AjaxStatus
 * Description: Ajax status controller class.
 */
var AjaxStatus = {

	VERSION: '1.0.0',
	
	// status codes
	ERROR       : 0,
	SUCCESS     : 1,
	WARNING     : 2,
	NO_RESPONSE : 3,
	
	// status refresh
	DEFAULT_MESSAGE_DIV : 'status',
	messageDivId : '',
	messageDiv : null,
	messages : [],
	classNames : [],
	
	/** METHODS **/
	
	initialize : function(){
	
		Broadcaster.initialize(this);
		this.addListener = this.addListenerImpl;
		
		this.messages[AjaxStatus.ERROR] = 'Error message.';
		this.messages[AjaxStatus.SUCCESS] = 'Success message.';
		this.messages[AjaxStatus.WARNING] = 'Warning message.';
		this.messages[AjaxStatus.NO_RESPONSE] = 'No response message.';
		
		this.classNames[AjaxStatus.ERROR] = 'error';
		this.classNames[AjaxStatus.SUCCESS] = 'success';
		this.classNames[AjaxStatus.WARNING] = 'warning';
		this.classNames[AjaxStatus.NO_RESPONSE] = 'error';
		
	},
	
	addListenerImpl : function(){
		for(var i=0; i<arguments.length; i++){
			var obj = arguments[i];
			if(typeof(obj)==String.TYPE){ obj = $(obj); }
			if(this.listeners.indexOf(obj) == -1){	
				obj.onChange = this.onChange;
				obj.onReset = this.onReset;
				obj.onClear = this.onClear;
				this.listeners.push(obj);
			}
		}
		
	},
	
	displayStatus : function(data) {
		this.broadcast('onChange', data);
	},
	
	resetStatus : function(el){
		this.broadcast('onReset');
	},
	
	clearStatus : function(){
		this.broadcast('onClear');
	},
	
	onChange : function(data){
		var style = AjaxStatus.classNames[data.status];
		if(!style.length){ style = AjaxStatus.classNames[AjaxStatus.ERROR]; }
		this.innerHTML = '<span class="' + style + '">' + data.message + '</span>';
	},
	
	onReset : function(){
		this.innerHTML = String.NBSP;
	},
	
	onClear : function(){
		this.innerHTML = String.EMPTY;
	}

}

/**
 * CLASS: AjaxRequestOptions
 * Description: Data class for Prototype-formatted request options.
 */
var AjaxRequestOptions = function(method, parameters, successCallback, errorCallback){
	this.method = method;
	this.parameters = parameters;
	this.onSuccess = successCallback;
	this.onFailure = errorCallback;
}


/**
 * CLASS: Broadcaster
 * Description: Provides event listener and broadcast functionality.
 */ 
var Broadcaster = {
	
	VERSION: '1.0.0',
	
	listeners: [],

	initialize: function(){
		for(var i=0; i<arguments.length; i++){
			var obj = arguments[i];
			obj.listeners = [];
			obj.addListener = this.addListener;
			obj.removeListener = this.removeListener;
			obj.sendListener = this.sendListener;
			obj.broadcast = this.broadcast;
			obj.testEvent = this.testEvent;
		}
	},
	
	addListener : function(){
		for(var i=0; i<arguments.length; i++){
			var obj = arguments[i];
			if(typeof(obj)==String.TYPE){ obj = $(obj); }
			if(this.listeners.indexOf(obj) == -1){	
				this.listeners.push(obj);
			}
		}
	},
	
	removeListener : function(obj){
		for(var i=0; i<arguments.length; i++){
			var obj = arguments[i];
			if(typeof(obj)==String.TYPE){ obj = $(obj); }
			if(this.listeners.indexOf(obj) > -1){
				this.listeners = this.listeners.without(obj);
			}
		}				
	},
	
	broadcast : function(event, args){
		for(var i=0; i<this.listeners.length; i++){
			if(this.listeners[i][event]){
				this.listeners[i][event](args);
			}
		}
	},
	
	sendListener : function(id, event, args){
		for(var i=0; i<this.listeners.length; i++){
			var obj = this.listeners[i]; 
			if(obj[event] && obj.id == id){
				obj[event](args);
			}
		}
	},
	
	testEvent : function(event, message){
		this.broadcast(event, message);
	}

}


// Init controllers
AjaxController.initialize();
AjaxStatus.initialize();


/********************** STATUS METHODS *********************************/

function onAjaxSuccess(response){

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	if(data.status == AjaxStatus.SUCCESS){
		AjaxController.broadcast('onChange', data);
	} else {
		AjaxController.broadcast('onReset');
	}
	
	AjaxStatus.broadcast('onChange', data);
	
}

function onAjaxError(response){

	var data = AjaxController.getJsonData(response);
	if(data == null){
		return (onAjaxDataError());
	}
	
	AjaxController.broadcast('onReset');
	AjaxStatus.broadcast('onReset');
	AjaxController.resetEdit();
	alert("An error occurred:" + data.message);
	
}

function onAjaxDataError(){
	AjaxController.resetEdit();
	AjaxController.broadcast('onReset');
	AjaxStatus.broadcast('onReset');
	alert('An error occurred: Data parameter is missing.');
}


/********************** TEST METHODS *********************************/

// This is a unit test for sending and an Ajax data request.
// The returned data response will echo the data paramaters sent.
function testAjaxRequest(data){
	if(data == null){ data = {name: 'fred', age: 30}; }
	AjaxController.sendRequest(AjaxController.DEBUG_VARS_ACTION, data, onAjaxSuccess, onAjaxError); 
}

/********************** UI METHODS *********************************/

/** LOGIN **/

// Checks for a valid registration username.
function checkUsername() {

	if(!AjaxController.isEnabled){ return; }

	AjaxStatus.broadcast('onClear');
	
	var userName = $F('reg_user_name');
	if(!userName.length){
		alert('Please enter a user name.');
		return;
	}
	
	var data = {user_name : userName};
	AjaxController.sendRequest(AjaxController.CHECK_USERNAME_ACTION, data, onCheckUsernameResponse, onAjaxError); 
	
}

// Response callback for checkUserName
function onCheckUsernameResponse(response) {

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
		
	AjaxStatus.broadcast('onChange', data);	
	
}

/** RATINGS **/

// Hilites the rollover rating.
function hiliteRating(rating_value){

	if(!AjaxController.isEnabled){ return; }

	AjaxController.cacheRating();
	
	var caption = 'rating_caption';
	var position = parseInt(rating_value)-1;
	
	if(rating_value == null){
		Element.update(caption, String.EMPTY);
		AjaxController.showRating(-1);
	} else {
		Element.update(caption, AjaxController.getRatingCaption(position));
		AjaxController.showRating(position);
	}
	
}

// Adds the rating.
function addRating(user_id, video_id, rating_value) {

	if(!AjaxController.isEnabled){ return; }

//	if(user_id == ''){
//		alert('You must be logged in to rate videos.');
//		return;
//	}
	
	if(rating_value == '') {
		document.getElementById('rating_box').style.visibility = "visible";
		return;
	}
	
	AjaxController.clearRating();
	AjaxStatus.broadcast('onClear');
	
	var data = {rating_value: rating_value, user_id: user_id, video_id: video_id};
	AjaxController.sendRequest(AjaxController.ADD_RATING_ACTION, data, onAddRatingResponse, onAjaxError); 
		
}

// Response callback for addRating.
function onAddRatingResponse(response) {
	var data = AjaxController.getJsonData(response);
	if(data == null){
		return (onAjaxDataError());
	}
	if(data.status == AjaxStatus.SUCCESS){
		Element.update('avg_rating', data.avg_rating_content);
		Element.update('user_rating', data.user_rating_content);
		document.getElementById('rating_box').style.visibility = "hidden";
	} else {
		alert(data.message);
	}
	
	AjaxController.clearRating();
	
}

/** VIDEOS **/

// Displays the video edit form.
function editVideo(video_id, user_id) {
	
	if(!AjaxController.isEnabled){ return; }

	if(user_id == ''){
		alert('You must be logged in to edit videos.');
		return;
	}	
	
	AjaxStatus.broadcast('onClear');
	
	// turn AjaxController.editActive flag on to prevent other edits
	if(AjaxController.editActive){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);
	
	Element.toggle('videos_display_' + video_id, 'videos_form_' + video_id, 'videos_edit_controls_' + video_id);
	Form.enable('videos_form_' + video_id);
	
	Field.setValue('videos_title_input_' + video_id, Element.getContent('videos_title_' + video_id));	
	Field.setValue('videos_desc_input_' + video_id, Element.getContent('videos_desc_' + video_id));	
	
}

// Cancels the video edit.
function cancelEditVideo(){
	var video_id = AjaxController.getEditValue('video_id');
	Element.toggle('videos_display_' + video_id, 'videos_form_' + video_id, 'videos_edit_controls_' + video_id);
	AjaxController.resetEdit();
}

// Submits the video edit.
function submitVideo() {
	
	if(!AjaxController.isEnabled){ return; }
	
	// Grab the edit values from cache.
	var user_id = AjaxController.getEditValue('user_id');	
	var video_id = AjaxController.getEditValue('video_id');

	var fieldId;
	
	fieldId = 'videos_title_input_' + video_id;
	var title = $F(fieldId).trim();
	
	if(!title.length){
		alert('The Title field is required.'); 
		Field.clear(fieldId);
		Field.focus(fieldId);
		return;
	}
	
	AjaxController.setEditValue('title', title);
	
	fieldId = 'videos_desc_input_' + video_id;
	var description = $F(fieldId).trim();
	
	if(!description.length){
		alert('The Description field is required.'); 
		Field.clear(fieldId);
		Field.focus(fieldId);
		return;
	}
	
	AjaxController.setEditValue('description', description);
	
	Form.disable('videos_form_' + video_id);
	
	var data = {user_id: user_id, video_id: video_id, title: title, description: description};
	AjaxController.sendRequest(AjaxController.UPDATE_VIDEO_ACTION, data, onSubmitVideoResponse, onAjaxError); 
	
}

// Response callback for submitVideo.
function onSubmitVideoResponse(response){

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var video_id = AjaxController.getEditValue('video_id');
	var user_id = AjaxController.getEditValue('user_id');
	var title = AjaxController.getEditValue('title');
	var description = AjaxController.getEditValue('description');
	
	var linkTitle = title;
	if(linkTitle.length > 150){
		linkTitle = linkTitle.substring(0, 150) + "...";
	}	
	
	if(data.status == AjaxStatus.SUCCESS || data.status == AjaxStatus.WARNING){
		Element.update('videos_title_' + video_id, title);
		Element.update('videos_link_' + video_id, linkTitle);
		Element.update('videos_desc_' + video_id, description);
	}
		
	Form.enable('videos_form_' + video_id);
	Field.clear('videos_title_input_' + video_id);
	Field.clear('videos_desc_input_' + video_id);
	
	Element.toggle('videos_display_' + video_id, 'videos_form_' + video_id, 'videos_edit_controls_' + video_id);
	
	AjaxStatus.broadcast('onChange', data);
	AjaxController.resetEdit();
	
}

// Deletes the specified video.
function deleteVideo(video_id, user_id) {

	if(!AjaxController.isEnabled){ return; }
	
	AjaxStatus.broadcast('onClear');

	// if tags are being edited, exit
	if(AjaxController.editActive){ return; }

	if(!confirm('Are you sure you want to delete this video?')){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);

	var data = {user_id: user_id, video_id: video_id};
	AjaxController.sendRequest(AjaxController.DELETE_VIDEO_ACTION, data, onDeleteVideoResponse, onAjaxError); 	
	
}

// Response callback for deleteVideo
function onDeleteVideoResponse(response) {

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var user_id = AjaxController.getEditValue('user_id');
	var video_id = AjaxController.getEditValue('video_id');
	
	var count = parseInt(Element.getContent('item_counter'));
	
	if(data.status == AjaxStatus.SUCCESS){
		Element.remove('videos_edit_' + video_id);
		Element.update('item_counter', String.EMPTY + (count-1));
	}
	
	AjaxStatus.broadcast('onChange', data);
	AjaxController.resetEdit();	
		
}

/** TAGS **/

// Displays the tags add form.
function addTags(user_id, video_id) {

	if(!AjaxController.isEnabled){ return; }

	if(user_id == ''){
		alert('You must be logged in to add tags.');
		return;
	}	
	
	AjaxStatus.broadcast('onClear');
	
	// turn AjaxController.editActive flag on to prevent other edits
	if(AjaxController.editActive){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);
	
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	Form.enable('tags_form_' + video_id);
	
	Field.setValue('tags_input_' + video_id, $F('user_tags_' + video_id));
	
}

// Cancels the tags add.
function cancelAddTags() {
	var video_id = AjaxController.getEditValue('video_id');
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	AjaxController.resetEdit();
}


// Displays the tags edit form.
function editTags(user_id, video_id) {

	if(!AjaxController.isEnabled){ return; }

	if(user_id == ''){
		alert('You must be logged in to edit tags.');
		return;
	}	
	
	AjaxStatus.broadcast('onClear');
	
	// turn AjaxController.editActive flag on to prevent other edits
	if(AjaxController.editActive){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);
	
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	Form.enable('tags_form_' + video_id);
	
	Field.setValue('tags_input_' + video_id, Element.getContent('user_tags_' + video_id));
	
}

// Cancels the tags edit.
function cancelEditTags() {
	var video_id = AjaxController.getEditValue('video_id');
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	AjaxController.resetEdit();
}

// Submits the tags edit.
function submitTags() {
	
	if(!AjaxController.isEnabled){ return; }
	
	// Grab the edit values from cache.
	var user_id = AjaxController.getEditValue('user_id');	
	var video_id = AjaxController.getEditValue('video_id');

	var fieldId = 'tags_input_' + video_id;
	var tags = $F(fieldId).trim();
	
	if(!tags.length){
		alert('The Tags field is required.'); 
		Field.clear(fieldId);
		Field.focus(fieldId);
		return;
	}
	
	Form.disable('tags_form_' + video_id);
	
	var data = {user_id: user_id, video_id: video_id, tags: tags};
	AjaxController.sendRequest(AjaxController.UPDATE_TAGS_ACTION, data, onSubmitTagsResponse, onAjaxError); 
	
}


// Displays the submitTags results.
function onSubmitTagsResponse(response) {
	
	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var video_id = AjaxController.getEditValue('video_id');
	var user_id = AjaxController.getEditValue('user_id');	
		
	if(data.status == AjaxStatus.SUCCESS || data.status == AjaxStatus.WARNING){
		if(data.content.length){
			Element.update('user_tags_' + video_id, data.content);
		}
	}
		
	Form.enable('tags_form_' + video_id);
	Field.clear('tags_input_' + video_id);
	
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	
	AjaxStatus.broadcast('onChange', data);
	AjaxController.resetEdit();
	
}


// Submits the tags edit.
function submitDetailsTags() {
	
	if(!AjaxController.isEnabled){ return; }
	
	// Grab the edit values from cache.
	var user_id = AjaxController.getEditValue('user_id');	
	var video_id = AjaxController.getEditValue('video_id');

	var fieldId = 'tags_input_' + video_id;
	var tags = $F(fieldId).trim();
	
	if(!tags.length){
		alert('The Tags field is required.'); 
		Field.clear(fieldId);
		Field.focus(fieldId);
		return;
	}
	
	Form.disable('tags_form_' + video_id);
	
	var data = {user_id: user_id, video_id: video_id, tags: tags};
	AjaxController.sendRequest(AjaxController.ADD_TAGS_ACTION, data, onSubmitDetailsTagsResponse, onAjaxError); 
	
}

// Details tags response callback.
function onSubmitDetailsTagsResponse(response) {
	
	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var video_id = AjaxController.getEditValue('video_id');
	var user_id = AjaxController.getEditValue('user_id');	
		
	if(data.status == AjaxStatus.SUCCESS || data.status == AjaxStatus.WARNING){
		if(data.content.length){
			Element.update('tags_display_' + video_id, data.content);
		}
	}
		
	Form.enable('tags_form_' + video_id);
	Field.clear('tags_input_' + video_id);
	Field.setValue('user_tags_' + video_id, data.user_tags);
	
	Element.toggle('tags_display_' + video_id, 'tags_form_' + video_id, 'tags_edit_controls_' + video_id);
	
	AjaxStatus.sendListener('tagsStatus', 'onChange', data);
	AjaxController.resetEdit();
	
}

// Deletes tags for the specified video.
function deleteTags(user_id, video_id) {
	
	if(!AjaxController.isEnabled){ return; }
	
	AjaxStatus.broadcast('onClear');

	// if tags are being edited, exit
	if(AjaxController.editActive){ return; }

	if(!confirm('Are you sure you want to remove all tags for this video?')){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);

	var data = {user_id: user_id, video_id: video_id};
	AjaxController.sendRequest(AjaxController.DELETE_TAGS_ACTION, data, onDeleteTagsResponse, onAjaxError); 

}

// Response callback for deleteTags
function onDeleteTagsResponse(response) {

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var user_id = AjaxController.getEditValue('user_id');	
	var video_id = AjaxController.getEditValue('video_id');
	var count = parseInt(Element.getContent('item_counter'));
	
	if(data.status == AjaxStatus.SUCCESS){
		Element.remove('tags_edit_' + video_id);
		Element.update('item_counter', String.EMPTY + (count-1));
	}
	
	AjaxStatus.broadcast('onChange', data);
	AjaxController.resetEdit();	
	
}

/** FAVORITES **/

// Adds a favorite.
function addFavorite(user_id, video_id) {

	if(!AjaxController.isEnabled){ return; }

	AjaxStatus.broadcast('onClear');
	
	if(user_id == ''){
		alert('You must be logged in to add favorites.');
		return;
	}	
	
	var data = {user_id: user_id, video_id: video_id};
	AjaxController.sendRequest(AjaxController.ADD_FAVORITE_ACTION, data, onAddFavoriteResponse, onAjaxError); 
	
}

// Response callback for addFavorite
function onAddFavoriteResponse(response) {

	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}

	alert(data.message);
	
}

// Deletes the favorite.
function deleteFavorite(favorite_id){

	if(!AjaxController.isEnabled){ return; }
	
	AjaxStatus.broadcast('onClear');
	
	if(!confirm('Are you sure you want to remove this video from your favorites?')){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('favorite_id', favorite_id);
	
	var data = {favorite_id: favorite_id};
	AjaxController.sendRequest(AjaxController.DELETE_FAVORITE_ACTION, data, onDeleteFavoriteResponse, onAjaxError); 
	
}

// Response callback for deleteFavorite.
function onDeleteFavoriteResponse(response) {
	
	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var favorite_id = AjaxController.getEditValue('favorite_id');
	var count = parseInt(Element.getContent('item_counter'));
	
	if(data.status == AjaxStatus.SUCCESS){
		Element.remove('favorite_item_' + favorite_id);
		Element.update('item_counter', String.EMPTY + (count-1));
	}
	
	AjaxStatus.broadcast('onChange', data);
	AjaxController.resetEdit();
	
}

/** COMMENTS **/

// Displays the addComments form.
function addComments(user_id, video_id){

	if(!AjaxController.isEnabled){ return; }
	
	if(user_id == ''){
//		alert('You must be logged in to add comments.');
		return;
	}
	
	AjaxStatus.broadcast('onClear');
	
	// turn AjaxController.editActive flag on to prevent other edits
	if(AjaxController.editActive){ return; }
	
	AjaxController.startEdit();
	AjaxController.setEditValue('video_id', video_id);
	AjaxController.setEditValue('user_id', user_id);
	
	Field.clear('comments_input_' + video_id);
	Form.enable('comments_form_' + video_id);
	document.getElementById('comments_form').style.visibility = "visible";
//	Element.toggle('comments_form_' + video_id, 'comments_edit_controls_' + video_id);

}

// Cancels the addComments form.
function cancelAddComments() {
	var video_id = AjaxController.getEditValue('video_id');
	document.getElementById('comments_form').style.visibility = "hidden";
//	Element.toggle('comments_form_' + video_id, 'comments_edit_controls_' + video_id);
	AjaxController.resetEdit();
}

// Submits the comments edit.
function submitComments() {
	
	if(!AjaxController.isEnabled){ return; }
	
	var user_id = AjaxController.getEditValue('user_id');
	var video_id = AjaxController.getEditValue('video_id');
	
	var fieldId = 'comments_input_' + video_id;
	var description = $F(fieldId).trim();
	
	if(!description.length){
		alert('The Comments field is required.'); 
		Field.clear(fieldId);
		Field.focus(fieldId);
		return;
	}

	document.getElementById('comments_form').style.visibility = "hidden";
	Form.disable('comments_form_' + video_id);
	
	var data = {user_id: user_id, video_id: video_id, description: description};
	AjaxController.sendRequest(AjaxController.ADD_COMMENTS_ACTION, data, onSubmitCommentsResponse, onAjaxError); 
	
}

// Response callback for submitComments
function onSubmitCommentsResponse(response){
	
	var data = AjaxController.getJsonData(response);
	
	if(data == null){
		return (onAjaxDataError());
	}
	
	var video_id = AjaxController.getEditValue('video_id');
	var user_id = AjaxController.getEditValue('user_id');	
		
	if(data.status != AjaxStatus.ERROR){
		Element.update('comments_display_' + video_id, data.content);
	}
		
//	Element.toggle('comments_form_' + video_id, 'comments_edit_controls_' + video_id);
	
	AjaxStatus.sendListener('commentsStatus', 'onChange', data);
	AjaxController.resetEdit();
	
}

/** TRACKING **/

// Tracks download
function trackDownload(video_id) {
	if(!AjaxController.isEnabled){ return; }
	var data = {video_id : video_id};
	AjaxController.sendRequest(AjaxController.TRACK_DOWNLOAD_ACTION, data, onTrackDownloadResponse, onAjaxError); 
}

// Response callback for trackDownload
function onTrackDownloadResponse(response) {
	var data = AjaxController.getJsonData(response);
	if(data == null){
		return (onAjaxDataError());
	}
	if(data.status == AjaxStatus.ERROR){
		alert(data.message);
	}
}

/** PREVIEW MOVIE CHANGE **/

/* Video load is now being handled through the ExternalInterface Flash callback method. */
function previewMovie(video_url) {
	var fo = getFlashObj('player');
	if(fo){
		fo.loadVideoUrl(video_url);
	}
	/*
	if(!AjaxController.isEnabled){ return; }
	var data = {video_id : video_id};
	AjaxController.sendRequest(AjaxController.PREVIEW_MOVIE_ACTION, data, onPreviewMovieResponse, onAjaxError); 
	*/
}

// Response callback for previewMovie
/* DEPRECATED */
function onPreviewMovieResponse(response) {
	var data = AjaxController.getJsonData(response);
	if(data == null){
		return (onAjaxDataError());
	}
	alert(data.content);
	if(data.status == AjaxStatus.SUCCESS){
		//Element.update('video_'+data.video_id, data.content);
		document.getElementById('video_'+data.video_id).innerHTML = data.content;
	} else {
		alert(data.message);
	}
}
