var avego = avego || {};

$(document).ready(function() {
	
	var microBlogging = new avego.Microblogging("mbcontainer", "microblog/microblog.php", {
		requestThreshold: 10,
		show: 5
	});
	
	microBlogging.start();
});

avego.Microblogging = (function(elementID, url, options) {
	
	var _elementID = elementID;
	var _element = $("#" + elementID);
	var _itemClass = elementID + "-micro-blogging-item";
	
	var _options = {max: 30, delay: 5000, show: 5, requestThreshold: 3};
	_options = $.extend({}, _options, options);

	var _queue = new Array();
	var _animeTimer;
	
	var _self = {
			
		start : function() {
			if ($(_element).length == 0) {
				return;
			}
			
			if (_queue.length == 0) {
				_loadMicroBlogging();
				return;
			}
			
			_startAnimation();
		},
		
		stop : function() {
			if (_animeTimer != null) {
				_animeTimer.clearInterval();
			}
		},
		
		push : function(messages) {
			for (var i = 0; i < messages.length; i++) {
				_queue.push(messages[i]);
			}
			_startAnimation();
		}
	};
	
	var _blogLoader = new avego.MicroBloggingLoader(_self, url);
	
	var _loadMicroBlogging = function() {
		_blogLoader.loadBlogs(_options.max);
	};
	
	var _startAnimation = function() {
		if (_animeTimer != null || _queue.length == 0) {
			return;
		}

		$(_element).empty();
		_fillBox();
		
		if (_queue.length > 0) {
			_animeTimer = setInterval(function() {
				_run();
			}, _options.delay);			
		}
	};
	
	var _fillBox = function() {
		if ($("." + _itemClass).length > 0) {
			return;
		}
		
		for (var i = 0; i < _options.show; i++) {
			_addNextToHTML();
		}
		
		$("." + _itemClass).show();
		_loadMore();
	};
	
	var _run = function() {
		_addNextToHTML();
		_showFirst();
		_removeLast();
	};
	
	var _showFirst = function() {
		$("." + _itemClass + ":first").slideDown(500);
		_loadMore();
	};
	
	var _removeLast = function() {
		var count = _element.find("." + _itemClass).length;
		if (count > _options.show) {
			$("." + _itemClass + ":last").slideUp(500, function() {
				$(this).remove();
				_checkRemove();
			});
		}
	};

	var _checkRemove = function() {
		while (_element.find("." + _itemClass).length > _options.show) {
			$("." + _itemClass + ":last").remove();
		}
	};
	
	var _loadMore = function() {
		if (_queue.length < _options.requestThreshold) {
			_loadMicroBlogging(_options.max);
		}
	};
	
	var _addNextToHTML = function() {
		var message = _queue.shift();
		if (message == null || typeof(message) == "undefined") {
			return;
		}
		
		_addMessageToHtml(message);
	};
	
	var _addMessageToHtml = function(message) {
		_element.prepend(avego.MicroBloggingRender.renderMessage(message, _itemClass));
	};
	
	return _self;
});

avego.MicroBloggingRender = (function() {
	
	var ICON_PATH = "wp-content/themes/envision/images/microblog/";
	var _userNameCellCompact, _userNameCellFull, _targetNameCell, _fromToCell, _routeCell, _atCell;
	
	var _self = {
		renderMessage : function(message, itemClass) {
			return _render(message, itemClass);
		}
	};
	
	var _init = function() {
		$("body").append("<div id=\"mb_userNameCellCompact\" style=\"width:55px;font-size:13px;font-weight:bold;\"></div>");
		$("body").append("<div id=\"mb_userNameCellFull\" style=\"width:100px;font-size:13px;font-weight:bold;\"></div>");
		$("body").append("<div id=\"mb_targetNameCell\" style=\"width:60px;font-size:11px;font-weight:bold;\"></div>");
		$("body").append("<div id=\"mb_fromToCell\" style=\"width:164px;font-size:11px;font-weight:bold;\"></div>");
		$("body").append("<div id=\"mb_routeCell\" style=\"width:400px;font-size:11px;font-weight:bold;\"></div>");
		$("body").append("<div id=\"mb_atCell\" style=\"width:380px;font-size:11px;font-weight:bold;\"></div>");
		_userNameCellCompact = $("#mb_userNameCellCompact");
		_userNameCellFull = $("#mb_userNameCellFull");
		_targetNameCell = $("#mb_targetNameCell");
		_fromToCell = $("#mb_fromToCell");
		_routeCell = $("#mb_routeCell");
		_atCell = $("#mb_atCell");
	};
	
	var _render = function(message, itemClass) {
		var actionTarget = _getActionTarget(message);
		
		var html = [];
		html.push(
			"<div class='post ", itemClass ,"' style='display:none;'>",
				"<div class='photo'>",
					"<img src='", _getUserPhoto(message), "' />",
				"</div>",
				"<div class='mbcontent'>",
					"<div class='leftcontent'>",
						"<span class='username'>", _normalizeName(_getUserName(message, actionTarget), message.name), "</span> | ",
						"<span class='action'>", _getAction(message.type), "</span> ",
						actionTarget,
						"<span class='actionicon'><img src='", _getIcon(message.type), "' /></span>",
					"</div>",
					_getRatingHtml(message),
					"<div class='fromtocontent'>",
						_getFromToContent(message),
					"</div>",
				"</div>",
			"</div>"
		);
		
		return html.join("");
	};
	
	var _getUserName = function(message, actionTarget) {
                var myName = message.name;;

		// Added by Martin - Jan 20. Only want first name to display (so Martin, instead of Martin G)
                if (myName.indexOf(" ") != -1) {
                        myName = myName.substring(0, myName.indexOf(" "));
                }

		if (actionTarget.replace(" ", "").length > 0) {
			return _ellipsedText(_userNameCellCompact, myName);
		}
		
		return _ellipsedText(_userNameCellFull, myName);
	};

	var _normalizeName = function(ellipsedName, originalName) {
		
		// Commented out by Martin - Jan 20. Need to use ellipsed name always as some
		// longer names were causing the text on line 1 to overlap.
		//if (ellipsedName.indexOf("...") != -1 && ellipsedName.indexOf(" ") == -1) {
		//	return originalName.substring(0, originalName.indexOf(" "));
		//}
	
		return ellipsedName;
	};
	
	var _getUserPhoto = function(message) {
		var link = [];
		link.push(
			"http://st-core.avego.com/api/object/users/",
			message.id,
			"/photo?useDefault=true"
		);
		return link.join("");
	};
	
	var _getRatingHtml = function(message) {
		var rating = Math.round(message.rating);
		var html = [];		
		html.push(
			"<div class='rightcontent rate'>",
				"<span class='tripcount'>", message.tripCount < 1000 ? message.tripCount : "999+", message.tripCount > 1 ? " Trips" : " Trip", " Shared</span>",
				"<ul>",
					"<li", rating > 0 ? " class='selected'" : "", "><a href='#####'></a></li>",
					"<li", rating > 1 ? " class='selected'" : "", "><a href='#####'></a></li>",
					"<li", rating > 2 ? " class='selected'" : "", "><a href='#####'></a></li>",
					"<li", rating > 3 ? " class='selected'" : "", "><a href='#####'></a></li>",
					"<li", rating > 4 ? " class='selected'" : "", "><a href='#####'></a></li>",
				"</ul>",
			"</div>"
		);
		
		return html.join("");
	};
	
	var _getAction = function(type) {
		if (type.indexOf("RIDER_BOOK") > -1) {
			return "Booked a Ride";
		}
		else if (type.indexOf("RIDER_DEMAND_MATCH") > -1) {
			return "Offered Ride to";
		}
		else if (type.indexOf("RIDER_IN_CAR") > -1) {
			return "Picked Up";
		}
		else if (type.indexOf("RIDER_DROP_OFF") > -1) {
			return "Dropped off";
		}
		else if (type.indexOf("DRIVER_START_FROMTO") > -1) {
			return "Started a Trip";
		}
		else if (type.indexOf("DRIVER_END_FROMTO") > -1) {
			return "Finished a Trip";
		}
		
		return "Shared";
	};
	
	var _getActionTarget = function(message) {
		var type = message.type;
		var msg = message.message;
		if (type.indexOf("RIDER_DEMAND_MATCH") > -1) {
			var name = _getStrBetween(msg, "offered", " a ride from");
                        if (name.indexOf(" ") != -1) {
                             name = name.substring(0, name.indexOf(" "));    // Added by Martin Jan 20 - display first names only
                        }
			return "<span class='targetuser'>" + _normalizeName(_ellipsedText(_targetNameCell, name), name) + "</span> ";
		}
		else if (type.indexOf("RIDER_IN_CAR") > -1) {
			var name = _getStrBetween(msg, "picked up", " at");
                        if (name.indexOf(" ") != -1) {
                             name = name.substring(0, name.indexOf(" "));    // Added by Martin Jan 20 - display first names only
                        }
			return "<span class='targetuser'>" + _normalizeName(_ellipsedText(_targetNameCell, name), name) + "</span> ";
		}
		else if (type.indexOf("RIDER_DROP_OFF") > -1) {
			var name = _getStrBetween(msg, "dropped off", " at");
                        if (name.indexOf(" ") != -1) {
                             name = name.substring(0, name.indexOf(" "));    // Added by Martin Jan 20 - display first names only
                        }
			return "<span class='targetuser'>" + _normalizeName(_ellipsedText(_targetNameCell, name), name) + "</span> ";
		}

		return " ";
	};
	
	var _getStrBetween = function(message, start, end) {
		var startIndex = Math.max(0, message.indexOf(start));
		var endIndex = message.length;
		if (!avego.Validator.isEmptyStr(end) && message.indexOf(end) > -1) {
			endIndex = message.indexOf(end);
		}
		message = message.substring(startIndex, endIndex);
		message = message.replace(start, "");
		return jQuery.trim(message);
	};
	
	var _getIcon = function(type) {
		var icon = "Started.png";
		if (type.indexOf("RIDER_BOOK") > -1) {
			icon = "Booked.png";
		}
		else if (type.indexOf("RIDER_DEMAND_MATCH") > -1) {
			icon = "Offered.png";
		}
		else if (type.indexOf("RIDER_IN_CAR") > -1) {
			icon = "Started.png";
		}
		else if (type.indexOf("RIDER_DROP_OFF") > -1) {
			icon = "DroppedOff.png";
		}
		else if (type.indexOf("DRIVER_START_FROMTO") > -1) {
			icon = "Started.png";
		}
		else if (type.indexOf("DRIVER_END_FROMTO") > -1) {
			icon = "Finished.png";
		}
		
		return ICON_PATH + icon;
	};
	
	var _getFromToContent = function(message) {
		var fromTo = _getFromTo(message);
		var html = [];
		
		if (!avego.Validator.isEmptyStr(fromTo.at)) {
			html.push(
				"<span class='fromtotitle'>At:&nbsp;</span>",
				"<span class='fromto'>", _ellipsedText(_atCell, fromTo.at), "</span>"
			);
		}
		else if (!avego.Validator.isEmptyStr(fromTo.route)) {
			html.push(
				"<span class='fromto'>", _ellipsedText(_routeCell, fromTo.route), "</span>"
			);
		}
		else {
			html.push(
				"<span class='fromtotitle'>From:&nbsp;</span>",
				"<span class='fromto'>", _ellipsedText(_fromToCell, fromTo.from), "</span>",
				"<span class='fromtotitle'>&nbsp;&nbsp;&nbsp;&nbsp;To:&nbsp;</span>",
				"<span class='fromto'>", _ellipsedText(_fromToCell, fromTo.to), "</span>"
			);
		}
		
		return html.join("");
	};
	
	var _getFromTo = function(message) {
		var type = message.type;
		var msg = message.message;
		if (type.indexOf("RIDER_BOOK") > -1) {
			return {
				from : _getStrBetween(msg, "booked a ride from", " to"),
				to : _getStrBetween(msg, " to")
			};
		}
		else if (type.indexOf("RIDER_DEMAND_MATCH") > -1) {
			return {
				from : _getStrBetween(msg, "a ride from", " to"),
				to : _getStrBetween(msg, " to")
			};
		}
		else if (type.indexOf("RIDER_IN_CAR") > -1) {
			return {
				at : _getStrBetween(msg, " at")
			};
		}
		else if (type.indexOf("RIDER_DROP_OFF") > -1) {
			return {
				at : _getStrBetween(msg, " at")
			};
		}
		else if (type.indexOf("DRIVER_START_FROMTO") > -1) {
			return {
				route : _getStrBetween(msg, "started trip")
			};
		}
		else if (type.indexOf("DRIVER_END_FROMTO") > -1) {
			return {
				route : _getStrBetween(msg, "finished trip")
			};
		}
		
		return {from : "N/A", to : "N/A", at : "N/A", route : "N/A"};
	};
	
	var _ellipsedText = function(element, text) {
		var clone = element.clone().hide()
								   .css("position", "absolute")
								   .css("overflow", "visible")
								   .width("auto")
								   .appendTo("body");
		
		clone.html(text);

		while (text.length > 0 && clone.width() > element.width()) {
			text = text.substr(0, text.length - 1);
			clone.html(text + "...");
		}
		
		var result = clone.html();
		clone.remove();
		return result;
	}
	
	$(document).ready(function() {
		_init();
	});
	
	return _self;
	
})();

avego.MicroBloggingLoader = (function(controller, url) {
	
	var _controller = controller;
	var _url = url;
	
	var _self = {
		loadBlogs : function(count) {
			_nextBlogs(count);
		}
	};
	
	var _nextBlogs = function(count) {
		var ajaxRequest = new avego.Ajax({
			url: url,
			data: {nret: count, ghost: "true"}
		});
    	ajaxRequest.subscribe("onsuccess", function (e) {
    		var result = new Array();
    		if (e.data.rs == "success") {
    			$.each(e.data.blogs, function(i, blog) {
    				var message = {id: blog.id, name: blog.u, rating: blog.r, tripCount: blog.tc, message: blog.m, type: blog.t};
    				result.push(message);
    			});
    		}
    		
    		_controller.push(result);
    	});
	};
	
	return _self;
});

avego.Ajax = (function (options) {
	
	var _options = options;
	// default options
	var _dataType = _options.dataType || "json";
	var _type = _options.method || "POST";
	var _cache = _options.cache || false;
	var _async = _options.async && true;
	// custom events exposed by this widget
	var _customEventHandler = avego.customEventHandler (["onsuccess", "onfail"]);
	
	// extend pubsub to cater for event handling
    var _self = $.extend({}, _customEventHandler, {});
    
    var _init = function () {
    	if (_options.url == null || avego.Validator.isEmptyStr(_options.url)) {
    		return;
    	}
    	
    	$.ajax({ 
    		url: _options.url,
    		data: _options.data,
    		dataType: _dataType,
    		type: _type,
    		cache: _cache,
    		async: _async,
    		success: _handleSuccess,
    		error: _handleError
    	});
    }

	var _handleSuccess = function(data, status) {
		if (_dataType.toLowerCase() == "json" && typeof(data) == "string") {
			data = eval("(" + data + ")");			
		}
		
		_self.fire ("onsuccess", {data: data, status: status});
	}
	
	var _handleError = function(xhr, status, e) {
		_self.fire ("onfail", {xhrRequest: xhr, status: status, error: e});
	}
	
	var _filter = function(data, type) {
		if (type == "json") {
			return data.replace("<", "&lt;").replace(">", "&gt;");
		}
	};

	$(document).ready(function () {		
		_init ();	
	});
	
	return _self;
});

avego.customEventHandler = function(events, nonCustomEventHandler) {

    var _self = {};
    _self.__events = {};

    _self.addSupportedEvents = function(events) {	
        for (var i = 0; i < events.length; i++) {
    		_self.__events[events[i]] = [];
    	}
    }
    
    _self.subscribe = function(eventType, eventCallback) {
    
        if (typeof _self.__events[eventType] === "undefined") {
        	
        	if (typeof nonCustomEventHandler  !== "undefined") {
        		nonCustomEventHandler (eventType, eventCallback);
        	}
        	else {
            	throw "Unsupported Event Type";
            }
        }
        else {
        	_self.__events[eventType][_self.__events[eventType].length] = eventCallback;
        }
    };

    _self.fire = function(eventType, data) {
    
        if (typeof _self.__events[eventType] === "undefined") {
            throw "Unsupported Event Type";
        }

        for(var i = 0; i < _self.__events[eventType].length; i++) {
            _self.__events[eventType][i](data);
        }
    };
    
    _self.addSupportedEvents (events);

    return _self;
};

avego.Validator = (function() {
	
	var _self = {
		isEmptyStr : function(value) {
			if (value == null || typeof(value) == "undefined" || value.length == 0) {
				return true;
			}
			
			return jQuery.trim(value).length == 0;
		}
	};
	
	return _self;
})();

