/*
 * Live Comments Display and Post for WGTE Manager
 */
(function(){
	
	par2str = function(p){
		var str, loop;
	    str = '{';
	    loop = 0;
	    for (var n in p) {
	        if (loop > 0) 
	            str += ','
	        switch (typeof p[n]) {
	            case 'string':
					var search = [{
							replacement: "&#38;",
							search: /\&/g
						},{
							replacement: "&#34;",
							search: /\"/g
						},{
							replacement: "\\\\",
							search: /\\/g
						},{
							replacement: "<br/>",
							search: /\n/g
						},{
							replacement: "&#44;",
							search: /\,/g
						},{
							replacement: "",
							search: /[^\x20-\x7e]/g
						}];
					$.each(search,function(key,value){
						p[n] = p[n].replace(value.search,value.replacement);
					});
	                str += '"' + n + '":"' + p[n] + '"';
	                break;
	            case 'number':
	            case 'boolean':
	                str += '"' + n + '":' + p[n];
	                break;
	            case 'object':
					if(p[n] == null){
						str += '"' + n + '":null';
					}else{
						str += '"' + n + '":' + par2str(p[n]);
					}
	                break;
	            default:
	                str += '"' + n + '":null';
	        }
	        loop = loop + 1;
	    }
	    str += '}';
	    return str;
	};
	
	// SETUP
	var data_to_send = {
		projectId: 1, // n : aeon project id
		results: 5, // -1 : all; 0 : all; n : number
		start: -1, // -1 : dependent on direction but first from associated side; n : uid
		itemId: 0, // n : item id
		userId: -1, // -1 : logged out
		direction: 0, // 0 : reverse; 1 : forward
		deletedIds: -1,
		displayName: false,
		body: false,
		firstId: -1,
		profileUrl: 'http://www.knowledgestream.org/kstream/profile.asp?userid=',
		projectFolder: 'wgte',
		userAdmin: 0
	};
	var config = {
		interval: false,
		loading: false,
		refresh: 1000,
		paused: false,
		element: '#comments',
		loader: '/modules/livecomments_v2/ajax-loader.gif',
		play: '/modules/livecomments_v2/play.png',
		pause: '/modules/livecomments_v2/pause.png',
		url: '/modules/livecomments_v2/backend.php',
		attach: 1, // 0 - Append, 1 - Prepend
		more: false,
		login: function(){
			alert('no login function yet');
		},
		username: false,
		postButtonText: 'Post',
		onPost: false
	}
	var elements = {
		'loading_box': {
			element: 'div',
			attributes: {},
			classes: 'comments_loading_box',
			html: false
		},
		'ajax_box': {
			element: 'img',
			attributes: {
				'src': config.loader,
				'alt': 'Loading ...'
			},
			classes: 'comments_ajax_loader',
			html: false,
			events: {
				onclick: function(){
					action({
						action: 'pause'
					});
				}
			}
		},
		'test_comment': {
			element: 'div',
			attributes: {
				'id': 'comment_0'
			},
			classes: 'live_comment_container',
			html: '<div class="live_info"><div class="live_user"><span>Anonymous</span></div><div class="live_time">Jan 29 1966 10:52am</div><div class="live_body">ugh, good night all</div></div><div class="live_photo"></div><div class="clear"></div>'
		},
		'error': {
			element: 'div',
			attributes: {},
			classes: 'comments_error',
			html: 'No Element Matches That Request.'
		},
		'input': {
			element: 'div',
			attributes: {},
			classes: 'comments_form',
			html: false
		},
		'message': {
			element: 'textarea',
			attrbiutes: {},
			classes: 'comments_input_box expand',
			html: false
		},
		'user': {
			element: 'input',
			attributes: {
				type: 'text',
				value: 'Enter Your Name Here'
			},
			classes: 'comments_input_user',
			html: false,
			events: {
				onclick: function(){
					if($(this).val()==elements.user.attributes.value) $(this).val('');
				}
			}
		},
		'post': {
			element: 'div',
			attributes: {},
			classes: 'comments_input_button comments_post_button',
			html: 'Post',
			events: {
				onclick: function(){
					action({
						action: 'post'
					});
				}
			}
		},
		'clear': {
			element: 'input',
			attributes: {
				type: 'button',
				value: 'Clear'
			},
			classes: 'comments_input_button comments_clear_button',
			html: false
		},
		'login': {
			element: 'div',
			attributes: {},
			classes: 'comments_input_button comments_user_button',
			html: 'Login To Use Your Account',
			events: {
				onclick: function(){
					action({
						action: 'login'
					});
				}
			}
		},
		'more': {
			element: 'div',
			attributes: {},
			classes: 'comments_more_button',
			html: 'Show X Comments',
			events: {
				onclick: function(){
					action({
						action: 'showmore'
					});
				}
			}
		},
		'orDiv': {
			element: 'div',
			attributes: {},
			classes: 'comments_or_div',
			html: 'or'
		}
	};
	eventsList = {'blur':1,'change':1,'click':1,'contextmenu':1,'copy':1,'cut':1,'dblclick':1,'error':1,'focus':1,'keydown':1,'keypress':1,'keyup':1,'mousedown':1,'mousemove':1,'mouseout':1,'mouseover':1,'mouseup':1,'mousewheel':1,'paste':1,'reset':1,'resize':1,'scroll':1,'select':1,'submit':1}
	
	// INITIALIZE
	var initialize = function(options){
		$.each(options,function(key,value){
			if(key in data_to_send)
				data_to_send[key] = value;
			if(key in config)
				config[key] = value;
		});
		action({
			action: 'append',
			element: config.element,
			data: action({
				action: 'form',
				element: 'input'
			})
		});
		action({
			action: 'prepend',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'message'
			})
		});
		action({
			action: 'prepend',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'user'
			})
		});
		action({
			action: 'append',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'login'
			})
		});
		action({
			action: 'append',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'orDiv'
			})
		});
		action({
			action: 'append',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'post'
			})
		});
		action({
			action: 'append',
			element: '.comments_form',
			data: action({
				action: 'form',
				element: 'clear'
			})
		});
		var pb = action({
			action: 'form',
			element: 'ajax_box'
		});
		action({
			action: 'append',
			element: '.comments_form',
			data: pb
		});
		var lb = action({
				action: 'form',
				element: 'loading_box'
			});
		config.loading_area = lb;
		action({
			action: 'append',
			element: config.element,
			data: lb
		});
		if(data_to_send.userId>-1)
			action({
				action: 'newuser',
				userid: data_to_send.userId,
				displayname: config.username,
				userAdmin: data_to_send.userAdmin
			});
		else
			action({
				action: 'load',
				start: -1
			});
		action({
			action: 'refresh',
			length: (test(config.paused))?'pause':false
		});
		$('.comments_input_box').TextAreaExpander();
	};

	// ACTIONS
	var action = function(options){
		if (test(options) && ('action' in options))
			if (options['action'] in action) {
				var key = options['action'];
				var a = action[key](options);
				return test(a)?a:false;
			}
		else
			return false;
	};
	action.pause = function(options){
		if (test(config.interval)) {
			//cl('Trying to pause');
			action({
				action: 'refresh',
				length: 'pause'
			});
			action({
				action: 'ajax_loader',
				display: false
			});
			//cl('Should be paused');
			return 'paused';
		}else{
			//cl('Starting again');
			action({
				action: 'load',
				results: -1,
				queue: 'live',
				direction: 1
			});
			action({
				action: 'refresh'
			});
			//cl('Should be running');
			return 're-start';
		}
	};
	action.refresh = function(options){
		var length = test(options.length)?options.length:config.refresh;
		if(test(length)){
			if(length != 'pause'){
				config.interval = setInterval(function(){
					action({
						action: 'load',
						results: -1,
						queue: 'live',
						direction: 1
					});
				}, length);
			}else{
				if(test(config.interval)) clearInterval(config.interval);
				config.interval = false;
			}
		}else{
			if(test(config.interval)) clearInterval(config.interval);
			config.interval = false;
		}
		return config.interval;
	};
	action.load = function(options){
		var options = test(options)?options:{};
		//cl(options);
		if (!test(config.loading)) {
			var dt = {
				start: (test(options.start)) ? options.start : data_to_send.start,
				results: (test(options.results)) ? options.results : data_to_send.results,
				direction: (test(options.direction)) ? options.direction : data_to_send.direction,
				userId: data_to_send.userId,
				deletedIds: (test(options.deletedIds)) ? options.deletedIds : data_to_send.deletedIds,
				itemId: data_to_send.itemId,
				firstId: data_to_send.firstId,
				projectId: data_to_send.projectId,
				profileUrl: data_to_send.profileUrl,
				projectFolder: data_to_send.projectFolder,
				userAdmin: data_to_send.userAdmin
			};
			/*if(dt.deletedIds!=-1){
				$(dt.deletedIds).remove();
			}*/
			var animate = (typeof options.animate != 'undefined') ? options.animate : true;
			$.ajax({
				url: config.url,
				data: dt,
				type: 'post',
				beforeSend: function(){
					action({
						action: 'ajax_loader',
						display: true
					});
					config.loading = true;
				},
				error: function(){},
				success: function(data){
					$.each(data, function(key, value){
						if (test(value.action) && value.action == 'attach') 
							value.action = (config.attach == dt.direction) ? 'prepend' : 'append';
						if (test(animate)) {
							value.css = {
								'opacity': 0
							};
							value.animate = [{
								actions: {
									'opacity': 1
								},
								options: {
									duration: 400,
									easing: false,
									complete: function(){
									},
									step: false,
									queue: (test(options.queue)) ? options.queue : 'archives',
									specialEasing: false
								},
								delay: false
							}];
						}
						action(value);
					});
				},
				complete: function(){
					action({
						action: 'ajax_loader',
						display: false
					});
					config.loading = false;
				},
				dataType: 'json'
			});
			return true;
		}
	};
	action.ajax_loader = function(options){
		if (options.display) {
			$(config.element).find('.' + elements['ajax_box'].classes).attr({
				'src': config.loader
			}).css({
				'cursor': 'default'
			});
			return 'loading image';
		}
		else {
			$(config.element).find('.' + elements['ajax_box'].classes).attr({
				'src': (test(config.interval)) ? config.pause : config.play
			}).css({
				'cursor': 'pointer'
			});
			return 'play/pause';
		}
	};
	action.append = function(options){
		var element = test(options.element)?options.element:config.loading_area, data = test(options.data)?options.data:false;
		if (element && data) {
			var r = $(data);
			if(options.action == 'append')
				$(element).append(r);
			else
				$(element).prepend(r);
			if (test(options.css))
				r.css(options.css);
			if (options.animate)
				$.each(options.animate, function(key, value){
					queue(r,value);
				});
			if (r.find('.comment_delete').length)
				$.each(r.find('.comment_delete'),function(key, value){
					$(value).click(function(){
						action({
							action: 'load',
							start: data_to_send.start,
							results: -1,
							direction: 1,
							deletedIds: $(this).parent().attr('id')
						})
					})
				});
			var events = r.data('events');
			if (test(events)) {
				$.each(events, function(key, value){
					if(key.substr(2) in eventsList)
						r.bind(key.substr(2), value);
				});
			}
		}
		return r;
	};
	action.prepend = action.append;
	action.del = function(options){
		var element = test(options.element)?options.element:false;
		if(element)
			return $(element).remove();
		return false;
	};
	action.form = function(options){
		var element = test(options.element)?options.element:false, modifiers = test(options.modifiers)?options.modifiers:false, info = {};
		if(test(elements[element]))
			info = elements[element];
		else
			info = elements['error'];
		if (test(modifiers)) {
			if (test(modifiers.attributes)) 
				$.each(modifiers.attributes, function(key, value){
					info.attributes[key] = value;
				});
			if (test(modifiers.classes)) 
				$.each(modifiers.classes, function(key, value){
					info.classes += ' ' + value;
				});
			if (test(modifiers.html)) 
				info.html = modifiers.html;
			if (test(modifiers.text)) 
				info.text = modifiers.text;
		}
		var construct = $('<'+info.element+'/>')
		if(test(info.attributes)) construct.attr(info.attributes);
		if(test(info.classes)) construct.addClass(info.classes);
		if(test(info.html)) construct.html(test(info.html.action)?action(info.html):info.html);
		if(test(info.text)) construct.text(test(info.text.action)?action(info.text):info.text);
		if(test(info.events)) construct.data('events',info.events);
		return (test(options.callback))?options.callback=='html'?$('<div/>').append(construct).html():options.callback=='text'?$('<div/>').append(construct).text():construct:construct;
	};
	action.lastId = function(options){
		var data = test(options.data)?options.data:0;
		if(data!=-1&&data>data_to_send.start) data_to_send.start = data;
	};
	action.deleteIds = function(options){
		if(test(options.data)){
			$.each(options.data,function(key,value){
				$('#'+value).remove();
			});
		}
	};
	action.firstId = function(options){
		var data = test(options.data)?options.data:0;
		if(data!==false) data_to_send.firstId = data;
	};
	action.more = function(options){
		var data = test(options.data)?options.data:false;
		if (!config.more && data) {
			config.more = data;
			action({
				action: (config.attach == 0) ? 'prepend' : 'append',
				data: action({
					action: 'form',
					element: 'more',
					modifiers: {
						html: 'Show All Comments'
					}
				})
			});
		}
		else 
			if (config.more && !data) {
				config.more = data;
			}
	}
	action.showmore = function(options){
		if(test(options)){
			var r = (test(options.results))?options.results:-1;
			if(r==-1) $('.comments_more_button').remove();
			var s = (test(options.start))?options.start:data_to_send.firstId;
			action({
				action: 'load',
				results: r,
				start: s,
				direction: 0,
				animate: false
			});
		}
	};
	action.post = function(options){
		var message = $('.comments_input_box').val(), dn = $('.comments_input_user').val(), animate = true;
		if (test(message) && test(dn)) {
			if (dn == elements.user.attributes.value) {
				alert('Please enter a name and submit your post again.');
				$('.'+elements.user.classes).focus();
			}
			else
				$.ajax({
					url: config.url,
					data: {
						newComment: par2str({
							"body": message,
							"displayName": dn,
							"userId": (data_to_send.userId == -1 ? 0 : data_to_send.userId)
						}),
						start: (test(options.start)) ? options.start : data_to_send.start,
						results: -1,
						direction: 1,
						userId: (data_to_send.userId == -1) ? 0 : data_to_send.userId,
						deletedIds: data_to_send.deletedIds,
						itemId: data_to_send.itemId,
						projectId: data_to_send.projectId,
						profileUrl: data_to_send.profileUrl,
						projectFolder: data_to_send.projectFolder,
						userAdmin: data_to_send.userAdmin
					},
					type: 'post',
					beforeSend: function(){
						action({
							action: 'ajax_loader',
							display: true
						});
						config.loading = true;
					},
					error: function(){
						var e = action({
							action: 'form',
							element: 'error',
							modifiers: {
								html: 'There was an error with loading the comments'
							}
						});
						action({
							action: (config.attach == 0) ? 'append' : 'prepend',
							data: e,
							animate: [{
								actions: {
									'opacity': 0
								},
								options: {
									duration: 2000,
									easing: false,
									complete: function(){
										$(this).remove();
									},
									step: false,
									queue: false,
									specialEasing: false
								},
								delay: 5000
							}]
						});
					},
					success: function(data){
						$('.comments_input_box').val('');
						$('.comments_input_box').height('18px');
						$.each(data, function(key, value){
							if (test(value.action) && value.action == 'attach') 
								value.action = (config.attach == 1) ? 'prepend' : 'append';
							if (test(animate)) {
								value.css = {
									'opacity': 0
								};
								value.animate = [{
									actions: {
										'opacity': 1
									},
									options: {
										duration: 400,
										easing: false,
										complete: function(){
										//cl('finished');
										},
										step: false,
										queue: (test(options.queue)) ? options.queue : 'archives',
										specialEasing: false
									},
									delay: false
								}];
							}
							action(value);
						});
						if(config.onPost) config.onPost();
					},
					complete: function(){
						action({
							action: 'ajax_loader',
							display: false
						});
						config.loading = false;
					},
					dataType: 'json'
				});
		} else
			if (dn == '') {
				alert('Please enter a name and submit your post again.');
				$('.'+elements.message.classes).focus();
			} else
				if (message == '') {
					alert('Please enter a message and submit your post again.');
					$('.'+elements.message.classes).focus();
				}
	};
	action.login = function(options){
		action({
			action: 'pause'
		});
		config.login(options);
	};
	action.newuser = function(options){
		if(test(options)&&test(options.userid)){
			data_to_send.userId = options.userid;
			if (options.userAdmin){data_to_send.userAdmin = options.userAdmin;}
			//data_to_send.userAdmin = options.userAdmin;
			config.username = options.displayname;
			$('.live_comment_container').remove();
			$('.comments_more_button').remove();
			config.more = false;
			$('.comments_user_button').hide();
			$('.comments_or_div').hide();
			$('.comments_input_user').width($('.comments_input_box').width());
			$('.comments_input_user').val(config.username);
			action({
				action: 'load',
				start: -1
			});
			action({
				action: 'refresh'
			});
		}
	}
	
	// ANIMATION QUEUE
	queue = function(element,effect){
		var r = queue.list.length;
		queue.list[r] = {};
		queue.list[r].element = element;
		queue.list[r].effect = effect;
		queue.run();
	};
	queue.list = [];
	queue.running = false;
	queue.run = function(){
		if (!queue.running&&test(queue.list[0])) {
			var item = queue.list[0].element;
			var opt = queue.list[0].effect;
			var tempfunction = (test(opt.options.complete))?opt.options.complete:function(){};
			opt.options.complete = function(){
				tempfunction.call(this);
				queue.remove();
			};
			if (item.delay && item.length > 0) 
				item.delay(opt.delay).animate(opt.actions, opt.options);
			else 
				item.animate(opt.actions, opt.options);
			queue.running = true;
		}
	};
	queue.remove = function(){
		queue.list.splice(0,1);
		queue.running = false;
		if(queue.list.length>0) queue.run();
	};
	
	// TEST
	var test = function(variable){
		return (typeof variable != 'undefined' && variable != null && variable != false && variable != '');
	};
	var cl = function(variable){
		if(window.console) return console.log(variable);
	};
	
	// PUBLIC
	Comments = function(){
		if (!test(arguments[0]) || !('action' in arguments[0])) 
			return initialize(arguments[0]);
		else 
			return action(arguments[0]);
	};
	
})();

