/**
*	(c) www.fijiwebdesign.com
*/

// Global Object
function mod_liveusers() {
	this.ver = '0.1';
}

// prototypes
mod_liveusers.prototype = {
	
	// url of joomla index2.php page
	site_url : null,
	
	// id of element to write debug info to
	debug_id : 'ajcthis.debug', 

	// simple debug
	debug : function(txt) {
		var el = document.getElementById(this.debug_id);
		if (!el) return false;
		
		el.value += txt+"\r\n";
	},
	
	// open private chat window
	privateChat : function(recipient, roomid) {
	
		// we have to replace non-alphanumeric chars due to IE bug.
		var win_name = "pm_" + recipient.replace(/[^a-zA-Z0-9]/g, '_'); 
		var settings=
		"toolbar=no,location=no,directories=no,"+
		"status=no,menubar=no,scrollbars=no,"+
		"resizable=yes,width=" + lvu_pm_width + ",height=" + lvu_pm_height;
		var url = lvu_serverUrl + "index2.php?option=com_ajaxchat&task=pm&recipient=" + recipient;
		
		// unset flag for open note
		this.unsetOpenNoteFlag(recipient, roomid);
		
		try {
			if (this.pm_window[win_name].location && !this.pm_window[win_name].closed) {
				this.pm_window[win_name].focus();
			} else {
				throw('');	
			}
		} catch(e) {
			// window doesn't exist
			this.pm_window[win_name] = window.open(url, win_name, settings);
			//this.pmwinTimer[win_name] = this.focusWin(win_name);
			return;
		}
	},
	
	pm_window : new Array(), // holds all the PM window references
	pmwin_interval : 500, // wait before focusing window
	pmwinTimer : new Array(), // saves timeout refs
	
	// focus the pm window
	focusWin : function(name, no_retry) {
		try {
			this.pm_window[name].focus();
		} catch (e) {
			// retry after a short wait
			if (!no_retry) {
				return setTimeout(function() { focusWin(name, true); }, this.pmwin_interval);
			} else {
				alert('You may have a popup blocker that is not allowing you to view chat windows.');	
			}
		}
	},
	
	// onload handlers
	addLoadEvent : function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			}
		}
	},
	
	// check the conneciton to the chat room
	checkConnection : function() {
		this.debug('checking connection...');
		var data = "option=" + encode('com_ajaxchat') + "&no_html=" + encode(1) + "&task=" + encode('status');
		return new AJAXRequest("post", this.site_url, data, this.validateNewConnection);
	},
	
	no_polling : false, // polling flag
	no_connect : false, // global connection toggle
	connectCount : 0, // total number of connect tries
	// create a new connection to chatroom
	newConnection : function() {
	
		this.connectCount++;
	
		this.debug('new connection req');
		if (this.no_connect) return false; // currently negotiating connection
		else this.no_connect = true; // set flag for currently connecting
	
		// stop msgs polling
		this.no_polling = true;
		
		var data = "option=" + encode('com_ajaxchat') + "&no_html=" + encode(1) + "&task=" + encode('connect');
		return new AJAXRequest("post", this.site_url, data , this.validateNewConnection);
	},
	
	newConnectionTimer : null, // setTimeout var
	validateNewConnection : function(xhr) {
		try {
			if (xhr.readyState == 4) {
				lvu.connectCount++;
				lvu.no_connect = false; // allow new connections
			
				if (xhr.status == 200) {
					var xml = xhr.responseXML;
					var text = xhr.responseText;
					lvu.debug('Connection Response:'+text);
			
					// parse the xml
					if (xml) {
						if (xml.documentElement) {
			
							var conn = xml.documentElement.getElementsByTagName('connection');
							var status = conn[0].getAttributeNode("status").nodeValue;
							
							if (status == 1) { // we have a connection, start checking for notifications
								lvu.no_polling = false;   // restart polling
								lvu.no_connect = false; // restart new connections
								lvu.showNotifications();
								return true;
							} else if (status == -9) { // User has been banned
								return false; // for now
							} else {
								lvu.negotiateConnection();
							}
						}
					}
				}
			}
		} catch(e) { /* lvu.debug('validateNewConnection exception: '+e); */ }
	},
	
	negotiateConnection : function() {
		this.debug('Negotiating new connection...');
		if (this.connectCount > 3) { 
			this.debug('Connection refused...');
			return false; // todo: we tried twice, so die.
		} else {
			this.debug('Connection retry...');
			this.newConnection(); // retry connection
		}
	},
	
	// new notifications
	period_notify : 10000,
	showNotifications : function() { // get new notifications
		this.debug('new notes req');
		if (this.no_polling) {
			return false;
		}
		var data = "option="+encode('com_ajaxchat')+"&no_html="+encode(1)+"&task="+encode('notify')+'&r='+encode((new Date()).getTime());
		return new AJAXRequest("post", this.site_url, data, this.displayNotifications);
	
	},
	
	_setTimeout_notes : true,
	notesTimer : null, // setTimeout for notes
	
	// display notifications
	displayNotifications : function(xhr) {
		try {
			if (xhr.readyState == 4) {
				if (xhr.status == 200) {
					var xml = xhr.responseXML;
					var text = xhr.responseText;
					lvu.debug('Notes Response:'+text);
		
					// parse the xml
					if (xml) {
					  if (xml.documentElement) {
						var notifications = xml.documentElement.getElementsByTagName("note");
		
		
						if (notifications.length > 0) {
		
							for (var i = 0; i < notifications.length; i++) {
		
								var roomid = notifications[i].getAttributeNode("roomid").nodeValue;
								var creator = notifications[i].getAttributeNode("creator").nodeValue;
								lvu.alertNotification(creator, roomid);
		
							}
		
						} else {
						  //lvu.validateResponse(xml); // validate connection
						}
					  }
					}
				} else {
					lvu.negotiateConnection();
					return false;
				}
				requestMode = false;
				if (lvu._setTimeout_notes) {
					lvu.notesTimer = setTimeout(function() { lvu.showNotifications(); }, lvu.period_notify);
				} else lvu._setTimeout_notes = true;
			}
		} catch(e) { /* lvu.debug('displayNotifications exception: '+e); */ }
	
	}, // display notifications
	
	ajc_note_open : 1,
	alertNotification : function(creator, roomid, no_set_flag) {
	
		if (this.is_userIgnored(creator)) {
			// alert('user is ignored:'+creator);
			return false;
		}
		
		// check to see if win exists
		var win_name = "pm_" + creator;
		try {
			if (pm_window[win_name].location && !pm_window[win_name].closed) {
				focusWin(win_name); // focus window
				return true;
			}
		} catch(e) { this.debug('alertNotification exception:'+e); }
		
		var fn = function(creator, roomid) {
			var html = '<div class="lvu_note moduletable">';
			html += '<h3>'+lvu_note_header+'</h3>';
			html += '<div class="lvu_note_msg">'+lvu_note_msg.replace(/\{username\}/, creator)+'</div>';
			
			html += '<div class="lvu_note_links">';
			html += '<input type="button" onclick="lvu.privateChat(\''+creator+'\', '+roomid+');lvu.closeAlert(\''+creator+'\');return false;" class="button" value="'+lvu_note_chat+'" />';
			html += '<input type="button" onclick="lvu.closeAlert(\''+creator+'\', true);return false;" class="button" value="'+lvu_note_ignore+'" />';
			html += '</div>';
			
			html += '</div>';
	
			ajcTip.showTip(document.body, 'alertNotification', html, 0, document.body.clientWidth-256, 250, false, 'pointer');
			
			var note = document.getElementById('alertNotification');
	
			// sets fixed position or set an onscroll listener for M$ IE.
			if (lvu.supportsFixedPositioning()) {
				note.style.position = 'fixed';
			} else {
				note.style.top = lvu.winScrollTop()+'px'; // move to top
				lvu.setWindowOnscrollListerner(); // set onscroll listener
			}
		}
		
		if (this.ajc_note_open == 1) {
			if (!ajcTip.tip_status) {
				ajcTip.tip_status = true;
				fn(creator, roomid);
				if (window.focus) { window.focus(); }
				ajcTip.tip_status = false;
			} else {
				fn(creator, roomid);
			}
			// set a cookie for this notification to span new pages
			if (!no_set_flag) {
				this.setOpenNoteFlag(creator, roomid);
			}
			
		} else {
			this.privateChat(creator, roomid);
		}
	},
	
	/**
	* Sets the window onscroll listener to move note 
	*/
	setWindowOnscrollListerner : function() {
		// todo: do not overwite listerners
		window.onscroll = function() {
			try {
				var note = document.getElementById('alertNotification');
				if (note) {
					note.style.top = lvu.winScrollTop()+'px';
				}
			} catch(e) { lvu.debug('Liveusers, win onscroll execption: '+e); }
		}	
	},
	
	/**
	* Checks if the browser supports fixed positioning
	*/
	supportsFixedPositioning : function() {
		
		// check if this is firefox. todo: fix
		if (navigator.userAgent && navigator.userAgent.indexOf("MSIE") == -1) {
			return true; // not IE
		}
		return false;
	},
	
	ajc_ignored : new Array(),
	// close alert: add a cookie to track ignored users/save to db
	closeAlert : function(user, ignore) {
		var note = document.getElementById('alertNotification');
		if (note) {
			if (ignore) {
				// confirm
				if (confirm('Stop viewing messages from '+user+'?')) {
					// ignore the user for this session
					note.style.display = 'none';
					this.ignoreUser(user);
					// alert(this.ajc_unread_notes);
					this.unsetOpenNoteFlag(user);
				}
			} else {
				note.style.display = 'none';
			}
		}
	},
	
	ajc_unread_notes : new String(), // unread notifications
	
	// set flag for an open notification
	setOpenNoteFlag : function(user) {
		var c = new commonLib();
		this.ajc_unread_notes = this.ajc_unread_notes+user+';';
		c.setCookie('ajc_unread_notes', this.ajc_unread_notes, false, '/');
	},
	
	// remove open note flag
	unsetOpenNoteFlag : function(user, roomid) {
		var regex = new RegExp(user+';', "g");
		this.ajc_unread_notes = this.ajc_unread_notes.replace(regex, '');
		var c = new commonLib();
		c.setCookie('ajc_unread_notes', this.ajc_unread_notes, false, '/');
	},
	
	// ban the user for this session
	ignoreUser : function(user) {
		this.ajc_ignored[this.ajc_ignored.length] = user;
		this.ajc_ignored_str = '';	
		for (var i = 0; i < this.ajc_ignored.length; i++ ) {
			this.ajc_ignored_str += this.ajc_ignored[i]+';';	
		}
		var c = new commonLib();
		c.setCookie('ajc_ignored', this.ajc_ignored_str, false, '/'); // todo: escape ;'s
	},
	
	// check if banned
	is_userIgnored : function(user) {	
		for (var i = 0; i < this.ajc_ignored.length; i++ ) {
			if (this.ajc_ignored[i] == user) {
				return true;	
			}
		}
		return false;
	},
	
	// get client win scroll
	winScrollTop : function() {
		var pos = 0;
		if (document.documentElement && document.documentElement.scrollTop) {
			pos = document.documentElement.scrollTop; 
		} else if (document.body) {
			  pos = document.body.scrollTop; 
		} else if (window.innerHeight) {
			  pos = window.pageYOffset; 
		}
		return pos;
	},
	
	// get the server url
	getServerUrl : function(serverUrl) {
	
		// make sure we have the same domain (www.example.com || example.com)
		browserUrl = window.location.href;
		var wserver = serverUrl.match(/^http:\/\/www\./) ? true : false;
		var wbrowser = browserUrl.match(/^http:\/\/www\./) ? true : false;
		if (wserver != wbrowser) {
			if (wbrowser) {
				serverUrl = serverUrl.replace(/^http:\/\//, 'http://www.');
			} else {
				serverUrl = serverUrl.replace(/^http:\/\/www\./, 'http://');
			}
		}
		return serverUrl;
	}

};

// start up our application
var lvu = new mod_liveusers();
lvu.addLoadEvent(function() { 
						  
	this.period_notify = 30000;
	
	// match www. and non-www domains
	lvu.site_url = lvu.getServerUrl(lvu_serverUrl)+'index2.php';
	
	// alert('Live site: '+lvu.site_url);
	
	// get list of ignored users
	var c = new commonLib();
	lvu.ajc_ignored_str = c.getCookie('ajc_ignored');
	// alert('Ignored Users Cookie: '+lvu.ajc_ignored_str);
	// get list of unread notes
	var unread_notes = c.getCookie('ajc_unread_notes');
	if (unread_notes && unread_notes != '') {
		lvu.ajc_unread_notes = unread_notes;
	}
	// alert('Unread Notes Cookie: '+lvu.ajc_unread_notes);
	
	if (lvu.ajc_ignored_str && lvu.ajc_ignored_str != '') {
		lvu.ajc_ignored_arr = lvu.ajc_ignored_str.split(';');
		for (var i = 0; i < lvu.ajc_ignored_arr.length; i++ ) {
			var user = lvu.ajc_ignored_arr[i];
			if (user && user != '') {
				lvu.ajc_ignored[lvu.ajc_ignored.length] = user;
			}
		}
	}
	
	// check to see if we have an existing connection
	lvu.checkConnection(); 

	// handle unread notes
	if (lvu.ajc_unread_notes && lvu.ajc_unread_notes != '') {
		
		lvu.ajc_unread_notes_arr = lvu.ajc_unread_notes.split(/;/);
		for (var i = 0; i < lvu.ajc_unread_notes_arr.length; i++) {
			try {
				var user = lvu.ajc_unread_notes_arr[i];
				if (user && user != '') {
					//alert('Open note from Cookie: '+user);
					lvu.alertNotification(user, -1, true);
				}
			} catch(e) {
				// alert('Reopen Notifications Exception: '+e);
			}
		}
	}
	
	// test
	//lvu.alertNotification('admin', -1);
	//lvu.alertNotification('joe', -1);
	//lvu.alertNotification('peter', -1);
	
	//c.setCookie('ajc_unread_notes', '');
	//c.setCookie('ajc_ignored', '');
	
	//alert(c.getCookie('ajc_unread_notes'));
	//alert(c.getCookie('ajc_ignored', ''));
	
});
