var isIE6 = /msie|MSIE 6/.test(navigator.userAgent);
var topicalUsers;
var message;
var presentation;
var searchtopics;
var counter;

var active = true;
var unseen = false;
var unvisited = false;
var blink = false;
var blinker="";

var online = false;

var connected = false;
var xmls = new XMLSocket();

var contacts = new Array();
var topics = new Array();
var currentTopic;
var nrOfMessages;
var addedMessages=1;

var messagesPerPage = 25;
var page = 1;

var ip;
var port;
var sockets = false;

var getter;
var topicsGetter;
var contactsGetter;
var pinger;
var caller;
var visitor;
var page = 1;

var dm=false;
var id;
var user;
var timeZoneOffset=0;
var sId;
var sKey;

var basetitle = document.title;


var nrOfUpdatedTopics = 0;
var nrOfUpdatedContacts = 0;
var currentUpdated = false;

var soundsOn=false;
var sndNewMessage;
//var sndNewContact;
//var sndUpdatedTopic;

var settings = new Array();

var lang = new Array();

var simpleMode = true;

var extras = [];

var editor;

var mentioning;

var encryption = false;

soundManager.url = '/';


function getSelText(win,doc){
	return (doc.all) ? doc.selection.createRange().text : doc.getSelection();
}

function catchTab(o, e) {
	var kC = e.keyCode ? e.keyCode : e.charCode ? e.charCode : e.which;
	if (kC == 9 && !e.shiftKey && !e.ctrlKey && !e.altKey)
	{
		var oS = o.scrollTop;
		if (o.setSelectionRange)
		{
			var sS = o.selectionStart;
			var sE = o.selectionEnd;
			o.value = o.value.substring(0, sS) + "\t" + o.value.substr(sE);
			o.setSelectionRange(sS + 1, sS + 1);
			o.focus();
		}
		else if (o.createTextRange)
		{
			document.selection.createRange().text = "\t";
			e.returnValue = false;
		}
		o.scrollTop = oS;
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		return false;
	}
	return true;
}


function setCaretTo(iframename, pos) {
	obj=document.getElementById(iframename).contentWindow;
	var range= obj.getSelection().getRangeAt(0);
	//alert('Current position: '+range.startOffset+' inside
	//'+range.startContainer);
	range.setStart(range.startContainer, pos);
	range.setEnd(range.startContainer, pos);
}

function var_dump(obj) {
   if(typeof obj == "object") {
      return "Type: "+typeof(obj)+((obj.constructor) ? "\nConstructor: "+obj.constructor : "")+"\nValue: " + obj;
   } else {
      return "Type: "+typeof(obj)+"\nValue: "+obj;
   }
}//end function var_dump

function closeExtras(){
	for(var i=0; i<extras.length; i++){
		extras[i].style.display = "none";
	}
}


function sortTopicList(listId){
	var oUl = document.getElementById(listId);
	var lis = oUl.getElementsByTagName('LI');
	var swapped = true;
	while(swapped){
		swapped=false;
		for(var i=0; i<lis.length-1; i++){
			var x = lis[i];
			var y = lis[i+1];
			if(typeof x == "object" && typeof y == "object"){
				var xa = x.getElementsByTagName('A')[0];
				var ya = y.getElementsByTagName('A')[0];
				//alert("x("+xa.innerHTML+"): "+xa.className.indexOf("updated")+"   y("+ya.innerHTML+"): "+ya.className.indexOf("updated"));
				if( (xa.innerHTML != 'undefined' || ya.innerHTML != 'undefined') && 
					( 
					  (xa.className.indexOf("updated")<0&&xa.className.indexOf("mentioned")<0&&ya.className.indexOf("updated")>=0) ||
					  (xa.className.indexOf("updated")>=0&&ya.className.indexOf("updated")>=0&&xa.innerHTML>ya.innerHTML) || 
					  (xa.className.indexOf("mentioned")<0&&ya.className.indexOf("mentioned")>=0) || 
					  (xa.className.indexOf("updated")>0&&ya.className.indexOf("mentioned")>=0) || 
					  (xa.className.indexOf("mentioned")>=0&&ya.className.indexOf("mentioned")>=0&&xa.innerHTML>ya.innerHTML)
					) 
				){
					if(oUl.firstChild!=x){
						oUl.insertBefore(y,x);
						swapped=true;
					}
				}
			}
		}
	}
}



function updateBlink(){
	if(blink){
		document.title = "_ "+basetitle;
	}else{
		document.title = "* "+basetitle;
	}
	blink=!blink;
}

function getTimeStr(date,timeOffset){
	var dateNow = new Date();
	var dateObj = new Date();
	dateObj.setTime(Date.parse(date));
	dateObj.setSeconds(dateObj.getSeconds()+timeOffset);
	var hours = dateObj.getHours();
	if(hours<10) hours = "0"+hours;
	var mins = dateObj.getMinutes();
	if(mins<10) mins = "0"+mins;
	var day="";
	if(dateNow.getDate()!=dateObj.getDate()||dateNow.getMonth()!=dateObj.getMonth()||dateNow.getFullYear()!=dateObj.getFullYear()){
			day = dateObj.getFullYear()+"-";
			day += (dateObj.getMonth()<10)? "0"+dateObj.getMonth() : dateObj.getMonth(); 
			day += "-";
			day += (dateObj.getDate()<10)? "0"+dateObj.getDate() : dateObj.getDate(); 
			day += " ";
	}
	return day+hours+":"+mins;
}

function updateTitle(){
	//alert("active: "+active+" currentUpdated: "+currentUpdated+" updatedTopics: "+nrOfUpdatedTopics+" updatedContacts: "+nrOfUpdatedContacts);
	if(active){
		clearInterval(blinker);
		blinker="";
		if(unvisited){
			document.title = "* "+basetitle;
		}else{
			document.title = basetitle;
		}
	}else{
		if(unseen){
			if(blinker=="") blinker = window.setInterval(updateBlink,1000);
		}else if(unvisited){
			document.title = "* "+basetitle;		
		}else{
			document.title = basetitle;
		}
	}
}



function Message(id,topic,user,text,avatar,time,nr,timeOffset){
	if(typeof timeOffset=="undefined") timeOffset=0;
	this.id=id;
	this.topic=topic;
	this.user=user;
	this.text=text;
	this.avatar=avatar;
	this.time=getTimeStr(time,timeOffset);
	this.nr=nr;
	this.createObj = function(){
		alreadyRendered = document.getElementById("message"+this.id);
		if(alreadyRendered){
			return alreadyRendered;
		}else{
			var myLi=document.createElement('li');
			myLi.id="message"+this.id;
			if(online&&this.text.match(mentioning)!=null) myLi.className="mentioned";
			var myAvatarLink=document.createElement('a');
			myAvatarLink.setAttribute("href","/users/"+this.user);
			var myAvatar = document.createElement('img');
			myAvatar.setAttribute('src',this.avatar);
			myAvatar.setAttribute('class','avatar');
			myAvatar.setAttribute('width','24');
			myAvatar.setAttribute('height','24');
			myAvatar.setAttribute('alt',this.user);
			myAvatarLink.appendChild(myAvatar);
			
			var myCite=document.createElement('cite');
			var myUserLink=document.createElement('a');
			myUserLink.setAttribute("href","/users/"+this.user);
			myUserLink.innerHTML = this.user;
			myCite.appendChild(myUserLink);
			
			var myEm=document.createElement('em');
			//myEm.innerHTML = "@ ";
			
			var myPerma=document.createElement('a');
			myPerma.setAttribute("href","/"+this.topic+"/"+this.id);
			myPerma.innerHTML = this.time;
			
			myEm.appendChild(myPerma);
			
			//var myP=document.createElement('p');
			//myP.innerHTML = this.text;
			
			var mySpace=document.createTextNode(" ");
			
			myLi.appendChild(myAvatarLink);
			myLi.appendChild(mySpace);
			myLi.appendChild(myCite);
			myLi.appendChild(mySpace);
			myLi.appendChild(myEm);
			//myLi.appendChild(myP);
			myLi.innerHTML += "<p>"+this.text+"<p>";
			return myLi;
		}
	}
	
	this.obj = this.createObj();
}

function msgCmp(msg1,msg2){
	return msg2.id-msg1.id;
}

function Contact(name){
	this.name = name;
	this.updated = function(){
		
		var contactlink = document.getElementById("cl_"+this.name);
		if(contactlink){
			if(contactlink.className.indexOf("updated")<0 && contactlink.className.indexOf("sel")<0){
				contactlink.className += " updated";
				contactlink.innerHTML += " *";
				unvisited=true;
				sortTopicList("contacts");
			}else if(contactlink.className.indexOf("sel")<0){
				unvisited=true;
			}
		}else{
			var contacts = document.getElementById("contacts");
			if (!contacts){
				var contactspl = document.getElementById('contacts_placeholder');
				if (contactspl){
					contactspl.innerHTML='<h3>'+__("Your Contacts")+'</h3><ul class="nav" id="contacts"></ul>';
					contacts = document.getElementById("contacts");
				}
			}
			
			if (contacts){
				contacts.innerHTML +='<li><a href="/users/'+this.name.toLowerCase()+'" id="cl_'+this.name+'" class=" updated">'+this.name+' *</a></li>';
				unvisited=true;
				sortTopicList("contacts");
				if(soundsOn&&settings["sndNewMessage"]==true&&!active&&sndNewMessage!=null) sndNewMessage.play();
			}
		}
		
		
		
	}
}

function Topic(name,urlstring){
	this.name=name;
	this.urlstring=urlstring;
	this.messages = new Array();
	this.nr = 0;
	this.dupeblock = new Array();
	this.addOldMessage = function(msg,render){
		if(typeof(this.dupeblock[msg.id])=='undefined'){
			this.dupeblock[msg.id]=true;
			render = typeof(render) != 'undefined' ? render : false;
			this.messages.push(msg);
			//this.messages.sort(msgCmp);
		
			if(render){
				//alert("before: "+this.messages[1].obj);
				//document.getElementById("messagelist").insertAfter(msg.obj,this.messages[this.messages.length-2].obj);
				document.getElementById("messagelist").appendChild(msg.obj);
			}
		}
	}
	this.addNewMessage = function(msg,render){
		if(typeof(this.dupeblock[msg.id])=='undefined'){
			this.dupeblock[msg.id]=true;
			nrOfMessages++;
			addedMessages++;
			render = typeof(render) != 'undefined' ? render : false;
			this.messages.unshift(msg);
			if(render){
				if(this.messages.length>1){
					if(msg.user!=user){ 
						//currentUpdated = true;
						unseen = true;
						updateTitle();
						if(soundsOn&&settings["sndNewMessage"]==true&&!active&&sndNewMessage!=null) sndNewMessage.play();
					}
					document.getElementById("messagelist").insertBefore(msg.obj,this.messages[1].obj);
				}else{
					document.getElementById("messagelist").appendChild(msg.obj);
				}
				if(this.messages.length>messagesPerPage*page){
					var old = this.messages.pop();
					document.getElementById("messagelist").removeChild(old.obj);
					delete(this.dupeblock[old.id]);
				}
			}
		}
	}
	this.updated = function(mentioned){
		var topiclink = document.getElementById("tl_"+this.urlstring);
		if(topiclink){
			if(topiclink.className.indexOf("updated")<0 && topiclink.className.indexOf("mentioned")<0 && topiclink.className.indexOf("sel")<0){
				topiclink.className += mentioned? " mentioned" : " updated";
				var parts = topiclink.innerHTML.split("<");
				topiclink.innerHTML = parts[0]+" * ";
				if(parts.length>1) topiclink.innerHTML += "<"+parts[1];
				unvisited = true;
				if(soundsOn&&settings["sndNewMessage"]==true&&!active&&sndNewMessage!=null) sndNewMessage.play();
				sortTopicList("mytopics");
			}else if(topiclink.className.indexOf("sel")<0){
				if(topiclink.className.indexOf("updated")>=0 && mentioned){
					topiclink.className = topiclink.className.replace("updated","mentioned");
					sortTopicList("mytopics");
				}
				unvisited = true;
			}
		}
		
	}
}


// private method for UTF-8 encoding
utf8_encode = function (string) {
	string = string.replace(/\r\n/g,"\n");
	var utftext = "";

	for (var n = 0; n < string.length; n++) {

		var c = string.charCodeAt(n);

		if (c < 128) {
			utftext += String.fromCharCode(c);
		}
		else if((c > 127) && (c < 2048)) {
			utftext += String.fromCharCode((c >> 6) | 192);
			utftext += String.fromCharCode((c & 63) | 128);
		}
		else {
			utftext += String.fromCharCode((c >> 12) | 224);
			utftext += String.fromCharCode(((c >> 6) & 63) | 128);
			utftext += String.fromCharCode((c & 63) | 128);
		}

	}

	return utftext;
},

// private method for UTF-8 decoding
utf8_decode = function (utftext) {
	var string = "";
	var i = 0;
	var c = c1 = c2 = 0;

	while ( i < utftext.length ) {

		c = utftext.charCodeAt(i);

		if (c < 128) {
			string += String.fromCharCode(c);
			i++;
		}
		else if((c > 191) && (c < 224)) {
			c2 = utftext.charCodeAt(i+1);
			string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
		}
		else {
			c2 = utftext.charCodeAt(i+1);
			c3 = utftext.charCodeAt(i+2);
			string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}

	}

	return string;
}

function socketSend(msg){
	if(encryption){
		msg = encryptMe(msg);
	}
	xmls.send(msg);
}

function decryptMe(text){
	text = text.replace(/\[nullbyte\]/g,"\0");
	text = utf8_decode(byteArrayToString(rijndaelDecrypt(stringToByteArray(text), stringToByteArray(sKey.substring(0,16)), 'ECB')));
	text = text.replace(/\0/g,"");
	return text;
}

function encryptMe(text){
	text = byteArrayToString(rijndaelEncrypt(utf8_encode(text),stringToByteArray(sKey.substring(0,16)), 'ECB'));
	text = text.replace(/\0/g,"[nullbyte]");
	return text;
}

function turnOnEncryption(){
	encryption=true;
}

initsockets = function() {
	messages = document.getElementById('messages');
	xmls.init("xmlsocket-div");
	
	function connect() {
		xmls.onConnect = function(success) {
			if(success){
				connected = true;
				window.clearInterval(getter);
				window.clearInterval(topicsGetter);
				window.clearInterval(contactsGetter);
				if(sId){
					//xmls.send("key "+sId);
					setTimeout('socketSend("key '+sId+'")',1);
					setTimeout('turnOnEncryption()',1);
				}
				if(online){
					//xmls.send("iam "+user+" "+id);
					setTimeout('socketSend("iam '+user+' '+id+'")',2);
				}

				pinger = window.setInterval(ping,30000);

				//xmls.send("subscribe "+topics[currentTopic].name); //subscribe to current topic
				if(dm || currentTopic!=null){
					setTimeout('socketSend("subscribe '+topics[currentTopic].name+'")',3);
					//alert("sent");
					//setTimeout('xmls.send(\'[nullbyte]òwál¢Ñ¥<[backslash]n#«ß« c«º"ä[nullbyte]:TÞ|;æ@í$eÀO<+eÓ@\')',3);
				}
			}else{
				//alert("could not connect");
				setTimeout(connect, 3000);
			}
		};
		xmls.onData = function(text) {
			if(sId){
				text = decryptMe(text);
			}
			try{
				var command = eval('(' + text + ')');
			}catch(e){
				alert("error: #"+text+"#");
				//document.write(text);
			}
			if(command){
				if(command.type=="newMessage"){
					var newMessage = command.message;
					topics[currentTopic].addNewMessage(new Message(newMessage.id,newMessage.group,newMessage.user,newMessage.content,newMessage.avatar,newMessage.createDate,addedMessages,timeZoneOffset),true);
					visitor = ajaxCall("/visit_topic.php","topicname="+currentTopic,function(http_request){},"text/html; charset=UTF-8");
				}else if(command.type=="updatedTopic"){
					topics[command.topic].updated(command.mentioned);
					updateTitle();
				}else if(command.type=="updatedContact"){
					if(!contacts[command.contact]) contacts[command.contact] = new Contact(command.contact);
					contacts[command.contact].updated();
					updateTitle();
				}else{
					alert("unknown command: "+text);
				}
			}
			/*
			if(text.indexOf("message")==0){
				text = text.replace("message ","");
				var newMessage = eval('(' + text + ')');
				topics[currentTopic].addNewMessage(new Message(newMessage.id,newMessage.group,newMessage.user,newMessage.content,newMessage.avatar,newMessage.createDate,addedMessages,timeZoneOffset),true);

				visitor = ajaxCall("/visit_topic.php","topicname="+currentTopic,function(http_request){},"text/html; charset=UTF-8");
			}else{
				alert("text (decrypted): "+text);
			}*/

		};
		xmls.onClose = function(){
			//alert("server has gone away");
			encryption=false;
			getter = window.setInterval(getNewMessages,3000);
			topicsGetter = window.setInterval(getUpdatedTopics,5000);
			contactsGetter = window.setInterval(getUpdatedContacts,5000);
			window.clearInterval(pinger);
			connect();
		}
		xmls.connect(ip,port);
	};
	setTimeout(connect, 1500);
};

/*function send(msg){
	if(connected){
		xmls.send(msg);	
	}
}*/

function getLastId(){
	var permas = getElementsByClass("perma",document.getElementById("messagelist"),"a");
	if(permas) return permas[0].getAttribute("rel");
}


soundManager.onload = function() {
	sndNewMessage = soundManager.createSound({
		id: 'newMessage',
		url: '/snd/zippo.mp3',
		volume: 50
	});	

	/*sndNewContact = soundManager.createSound({
		id: 'newContact',
		url: '/snd/newmsg.mp3',
		volume: 50
	});
	sndUpdatedTopic = soundManager.createSound({
		id: 'updatedTopic',
		url: '/snd/crack.mp3',
		volume: 50
	});
	*/
	soundsOn = true;
}

soundManager.onerror = function(e) {
	soundsOn = false;
}


Array.prototype.indexOf=function(o,i){for(var j=this.length,i=i<0?i+j<0?0:i+j:i||0;i<j&&this[i]!==o;i++);return j<=i?-1:i};

String.prototype.getBytes = function() {return encodeURIComponent(this).replace(/%../g, 'x').length;};
String.prototype.nlength = function() {return this.replace(/\r?\n/g, 'xx').length;};
String.prototype.count = function(s1) {return this.length - this.replace(new RegExp(s1,"g"), '').length;};

function initAjax(mimetype){
	var http_request;
	if (mimetype===null) mimetype = 'text/xml';
	if (window.XMLHttpRequest) { // Mozilla, Safari,...
		http_request = new XMLHttpRequest();
		if (http_request.overrideMimeType) {
			http_request.overrideMimeType(mimetype);
		}
	}else if(window.ActiveXObject){ // IE
		try {
			http_request = new ActiveXObject("Msxml2.XMLHTTP");
		}catch(e){
			try {
				http_request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e2) {}
		}
	}
	if (!http_request) {
		alert('Could not create an XMLHTTP instance');
		return false;
	}
   return http_request;
}

function ajaxCall(url,question,fun,doctype){
	if (doctype==null) doctype = 'text/xml';
	var http_request = initAjax(doctype);
	if(http_request){
		http_request.onreadystatechange = function(){
			if (http_request.readyState == 4){
				if (http_request.status == 200){
					fun(http_request);
				}
			}
		};
		http_request.open('POST', url, true);
		http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		http_request.send(question);
	}
}

function arr_uniq(arr){
     var a=[],i;
     arr.sort();
     for(i=0;i<arr.length;i++)
     {
         if(arr[i]!==arr[i+1])
         {
             a[a.length]=arr[i];
         }
     }
     return a;
 
}

function getCaretPos(obj){
	if(obj.selectionStart){
		return obj.selectionStart;
	}else if(document.selection && document.selection.createRange){
		obj.focus();
		var sel = document.selection.createRange();
		var dup = sel.duplicate();
		var c = "\001";
		sel.text=c;
		dup.moveToElementText(obj);
		var pos = dup.text.indexOf(c);
		sel.moveStart('character',-1);
		sel.text="";
		return pos;
	}else{
		return -1;
	}
}

setCaretPos = function (obj, position) {
	if (obj.setSelectionRange) {  
		obj.focus();  
		obj.setSelectionRange(position, position);
	} else if (obj.createTextRange) {  
		var range = obj.createTextRange();
		range.move("character", position);  
		range.select(); 
	} else if(window.getSelection){
		
		s = window.getSelection();
		var r1 = document.createRange();
		
		
		var walker=document.createTreeWalker(obj, NodeFilter.SHOW_ELEMENT, null, false);
		var p = position;
		var n = obj;
		
		while(walker.nextNode()) {
			n = walker.currentNode;
			if(p > n.value.length) {
				p -= n.value.length;
			}
			else break;
		}
		n = n.firstChild;
		r1.setStart(n, p);
		r1.setEnd(n, p);
		
		s.removeAllRanges();
		s.addRange(r1);
		
	} else if (document.selection) {
		var r1 = document.body.createTextRange();
		r1.moveToElementText(obj);
		r1.setEndPoint("EndToEnd", r1);
		r1.moveStart('character', position);
		r1.moveEnd('character', position-obj.innerText.length);
		r1.select();
	} 
}


function setSelRange(inputEl, selStart, selEnd){ 
	if (inputEl.setSelectionRange){ 
		inputEl.focus(); 
		inputEl.setSelectionRange(selStart, selEnd); 
	}else if(inputEl.createTextRange){
 		var range = inputEl.createTextRange(); 
		range.collapse(true); 
		range.moveEnd('character', selEnd); 
		range.moveStart('character', selStart); 
		range.select(); 
	}
}

function getKey(str,keys){
	keys=arr_uniq(keys);//keys.unique();
	var matches=[]; //new Array();
	for(var i=0; i<keys.length; i++){
		if (keys[i].substring(0,str.length)==str){
			matches.push(keys[i].substring(str.length));	
		}

	}
	if(matches.length==1){
		return matches[0];
	}else if(matches.length>1){
		var common = 0;
		var tryAnother=true;
		while(tryAnother){
			var chr = matches[0].charAt(common);  
			for(var i=1; i<matches.length; i++){
				if(matches[i].charAt(common)!=chr){
					tryAnother=false;
					break;
				}
			}
			common++;
		}
		return matches[0].substring(0,common-1);
	}else{
		return null;
	}
}

function messageKeyCheck(evt){
	var isSafari = navigator.userAgent.toLowerCase().indexOf("safari") != -1;
	var code;
	if (typeof evt === 'undefined') evt = window.event;
	if (evt && evt.keyCode) code = evt.keyCode;
	else if (evt.which) code = evt.which;
	
	switch(code){
		case 25:
			if(!isSafari) break;
		case 9:
			var end = getCaretPos(message);
			var startStr = message.value.substr(0,end);
			var arr = startStr.split(/\s/);
			var str = arr[arr.length-1];
			if(str.charAt(0)=="@"){
				str = str.substring(1);
				var key = getKey(str,topicalUsers);
				if(key!=null){
					message.value = startStr + key + message.value.substring(end);
					var pos = startStr.length + key.length;
					setSelRange(message,pos,pos);
				}
				return false;
			}
			break;
		default:
			break;
	}

	return true;
}

function toggleDisplay(layer){
	if(document.getElementById(layer).style.display!="block"){
		document.getElementById(layer).style.display="block";
	}else{
		document.getElementById(layer).style.display="none";
	}
}

function getUpdatedContacts(){
	ajaxCall("/get_updated_contacts.php","id=1",function(http_request){
		if(http_request.responseText!=""){
			ucontacts = http_request.responseText.split(",");
			//nrOfUpdatedContacts=ucontacts.length;
			/*if(ucontacts.length>1 || (ucontacts.length==1 && document.getElementById("cl_"+ucontacts[0]) && document.getElementById("cl_"+ucontacts[0]).className.indexOf("current")<0)){
				unvisited=true;
			}*/
			for(var i=0; i<ucontacts.length; i++){
				contacts[ucontacts[i]].updated();
			}
			updateTitle();	
		}
	},"text/html; charset=UTF-8");
}

function getUpdatedTopics(){
	ajaxCall("/get_updated_topics.php","id=1",function(http_request){
		if(http_request.responseText!=""){
			utopics = http_request.responseText.split(",");
			nrOfUpdatedTopics=utopics.length;
			/*if(utopics.length>1 || (utopics.length==1 && document.getElementById("tl_"+utopics[0]).className.indexOf("sel")<0)){
				unvisited=true;
			}*/
			for(var i=0; i<utopics.length; i++){
				var mentioned = (utopics[i].indexOf("*")>0)? true : false;
				topics[utopics[i].replace("*","")].updated(mentioned);
				
				/*var topiclink = document.getElementById("tl_"+utopics[i].replace("*",""));
				if(topiclink){
					/*
					if(topiclink.className.indexOf("updated")<0 && topiclink.className.indexOf("mentioned")<0 && topiclink.className.indexOf("sel")<0){
						topiclink.className += mentioned? " mentioned" : " updated";
						parts = topiclink.innerHTML.split("<");
						topiclink.innerHTML = parts[0]+" * ";
						if(parts.length>1) topiclink.innerHTML += "<"+parts[1];
						unvisited = true;
						if(soundsOn&&settings["sndNewMessage"]==true&&!active&&sndNewMessage!=null) sndNewMessage.play();
						sortTopicList("mytopics");
					}else if(topiclink.className.indexOf("sel")<0){
						if(topiclink.className.indexOf("updated")>=0 && mentioned){
							topiclink.className = topiclink.className.replace("updated","mentioned");
							sortTopicList("mytopics");
						}
						unvisited = true;
					}
				}*/
			}
			updateTitle();
		}
	},"text/html; charset=UTF-8");
}

function getMessages(pagelink,topicname){
	ajaxCall("/get_messages.php","topicname="+topicname+"&start="+(page*messagesPerPage)+"limit="+messagesPerPage,function(http_request){
		if(http_request.responseText!=""){
			var oldMessages = eval('(' + http_request.responseText + ')');
			for(var i=0; i<oldMessages.length; i++){
				topics[currentTopic].addOldMessage(new Message(oldMessages[i].id,oldMessages[i].group,oldMessages[i].user,oldMessages[i].content,oldMessages[i].avatar,oldMessages[i].createDate,i+addedMessages+page-1),true);
			}
		
			if((page+1)*messagesPerPage>=nrOfMessages){
				pagelink.innerHTML="";
			}else{
				pagelink.onclick=function(){
					getMessages(pagelink,topicname);
					return false;
				};
			}
			page++;
		}
	},"text/html; charset=UTF-8");

}

function getNewMessages(){
	lastid = (typeof(topics[currentTopic].messages[0])!='undefined')? topics[currentTopic].messages[0].id : 0;
	caller = ajaxCall("/get_new_messages.php","topicname="+currentTopic+"&biggerthan="+lastid,function(http_request){
		if(http_request.responseText!=""){
			var newMessages = eval('(' + http_request.responseText + ')');
			for(var i=0; i<newMessages.length; i++){
				topics[currentTopic].addNewMessage(new Message(newMessages[i].id,newMessages[i].group,newMessages[i].user,newMessages[i].content,newMessages[i].avatar,newMessages[i].createDate,addedMessages),true);
			}
			/*if(newMessages.length>0 && !active){
				unseen = true;
				updateTitle();
			}*/
		}
	},"text/html; charset=UTF-8");
}





function search(input){
	var q = input.value.toLowerCase();
	matches = new Array();
	for(var i=0; i<searchtopics.length; i++){
		if(searchtopics[i].toLowerCase().indexOf(q)>=0){
			matches.push(searchtopics[i]);
		}
	}
	reslist = document.getElementById("res");
	reslist.innerHTML="";
	if(q.length>0){
		for(var i=0; i<matches.length && i<20; i++){
			reslist.innerHTML += '<li><a href="/'+matches[i].toLowerCase().replace(/ /g,"+")+'">'+matches[i].toLowerCase().replace(q,'<strong>'+q+'</strong>')+'</a></li>';
		}
		if(matches.length==0 && q.length>=3){
			reslist.innerHTML=__("No <strong>%s</strong> group exists. <a href=\"%s\">Create it</a>?").replace("%s",q).replace("%s",'/create+public?topicname='+q); //  "No group called <strong>"+q+'</strong> exists, <a href="/create+public?topicname='+q+'">create it</a>?'
		}
	}
}

function send(){
	var msgToSend = "";
	message = document.getElementById("message");
	if(message!=null && message.value!="" || !simpleMode){
		if(simpleMode){
			if(currentTopic.indexOf("directmessage_")==0){
				var talkingTo = currentTopic.split("_viewing_")[1];
				var contactlink = document.getElementById("cl_"+talkingTo);
				if(!contactlink){
					var contacts = document.getElementById("contacts");
					if (!contacts){
						var contactspl = document.getElementById('contacts_placeholder');
						if (contactspl){
							contactspl.innerHTML='<h3>'+__("Your Contacts")+'</h3><ul class="nav" id="contacts"></ul>';
							contacts = document.getElementById("contacts");
						}
					}
					
					if (contacts){
						contacts.innerHTML += '<li><a href="/users/'+talkingTo.toLowerCase()+'" id="cl_'+talkingTo+'" class="sel updated">'+talkingTo+'</a></li>';
						//document.getElementById("remove_contact").innerHTML = '<p><input type="submit" name="leave" value="(-) Remove from Your Contacts" class="leave" /></p>';
					}
				}						
			}
			message.readOnly=true;
			message.disabled=true;
			if(document.messageform.post!=null){ 
				document.messageform.post.disabled=true;
				var oldval = document.messageform.post.value;
				document.messageform.post.value="Sending...";
			}
			msgToSend = message.value;
			var msgType="simple";
		}else{
			msgToSend = getAdvancedMessage();
			var msgType="html";
			if(document.messageform.post!=null){ 
				document.messageform.post.disabled=true;
				var oldval = document.messageform.post.value;
				document.messageform.post.value="Sending...";
			}

		}
		ajaxCall("/newmessage.php","topic="+currentTopic+"&type="+msgType+"&message="+encodeURIComponent(msgToSend),function(http_request){
			if(http_request.responseText!=""&&http_request.responseText!="done"){
				alert("Error: "+http_request.responseText);
			}else{
				if(!connected) getNewMessages();
				if(simpleMode){
					message.value="";
					message.readOnly=false;
					message.disabled=false;
					if(document.messageform.post!=null) document.messageform.post.disabled=false;
					if(document.messageform.post!=null) document.messageform.post.value=oldval;
					document.messageform.message.focus();
					//count_chars(document.getElementById("message"));
				}else{
					if(document.messageform.post!=null) document.messageform.post.disabled=false;
					if(document.messageform.post!=null) document.messageform.post.value=oldval;
					resetAdvancedMessage();
					//toggleMode();
				}
			}
		},"text/html; charset=UTF-8");
	}
	return false;
}

function ping(){
	socketSend("ping");
}

function count_chars(txtarea){
	if(counter!=null){
		var chars = 250;//420;
		if(txtarea.value.nlength()>=chars) txtarea.value=txtarea.value.substring(0,chars-txtarea.value.count("\n"));
		counter.innerHTML = __("%d characters left").replace("%d",(chars-txtarea.value.nlength())); // + " characters left";
	}
}

/*function urlencode(str) {
	return escape(str).replace('+', '%2B').replace('%20', '+').replace('*', '%2A').replace('/', '%2F').replace('@', '%40');
}*/

function urlencode( s ){
   return encodeURIComponent( s ).replace( /\%20/g, '+' ).replace( /!/g, '%21' ).replace( /'/g, '%27' ).replace( /\(/g, '%28' ).replace( /\)/g, '%29' ).replace( /\*/g, '%2A' ).replace( /\~/g, '%7E' );
}

function init(){
	message = document.getElementById("message"); //document.messageform.message;
	presentation = document.getElementById("presentation");
	counter = document.getElementById("counter");
		
	if(message != null){
		message.onkeydown=function(evt){
			count_chars(message);
			return messageKeyCheck(evt);
		}
		message.onkeyup=function(){
			count_chars(message);
		};
		document.messageform.onsubmit=send;
	}
	if(presentation != null){
		presentation.onkeydown=function(){
			count_chars(presentation);
		}
		presentation.onkeyup=function(){
			count_chars(presentation);
		};
	}
	
	var status = document.getElementById("status");
	if(status){
		changestatus = function(){
			var os = status.innerHTML;
			status.innerHTML = '<form id="statusform"><input id="editstatus" type="text" value="'+os+'" maxlength="20" /></form>';
			var editstatus = document.getElementById("editstatus");
			editstatus.focus();
			var statusform = document.getElementById("statusform");
			
			closeedit = function(){
				ajaxCall("/newstatus.php","status="+urlencode(editstatus.value),function(http_request){},"text/html; charset=UTF-8");
				status.innerHTML = (editstatus.value.replace(/ /g,"")!="")? editstatus.value.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") : __("Click to set status");
				status.onclick = changestatus;				
			}
			statusform.onsubmit=function(){
				closeedit();
				return false;
			}
			document.onclick = function(e){
				var target = (e && e.target) || (event && event.srcElement);
				if(target!=status && target!=editstatus && target!=statusform){
					closeedit();
				}
			}
			status.onclick = function(){}
			
		}
		status.onclick = changestatus; 
	}
	
	var contactspl = document.getElementById('contacts_placeholder');
	if (contactspl){
		contactsGetter = setInterval(getUpdatedContacts,5000);
	}
	
	var mytopics = document.getElementById('mytopics');
	if (mytopics){
		topicsGetter = setInterval(getUpdatedTopics,5000);
	}
	
	var hasmessagelist = document.getElementById('messagelist');
	if (hasmessagelist&&page==1){
		getter = window.setInterval(getNewMessages,3000);
	}
	
	if(sockets){
		initsockets();
	}
	
	//sndNewMessage = document.getElementById("sndNewMessage");
	
	if(online){
		mentioning = new RegExp("@<a href=\"/users/"+user+"\">"+user+"</a>","i");
	}
}

function getElementsByClass(className,node,tag) {
	var classElements = new Array();
	if (node == null)	node = document;
	if (tag == null) tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	for(var i=0, j=0; i<elsLen; i++){
		if (els[i].className.split(" ").indexOf(className)>-1){
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

winblur = function(){
	active=false;
}
winfocus = function(){
	active=true;
	unseen=false;
	updateTitle();
}

if (/*@cc_on!@*/false) { //IE
	document.onfocusin = winfocus;
	document.onfocusout = winblur;
} else {
	window.onfocus = winfocus;
	window.onblur = winblur;
}

window.onload=init;


function __(phrase){
	return phrase;
}

function toggleMode(){
	var modeSimple = document.getElementById("modeSimple");
	var modeAdvanced = document.getElementById("modeAdvanced");

	if(simpleMode){
		var val = document.getElementById("message").value;
		modeSimple.style.display="none";
		if(modeAdvanced==null){
			document.messageform.innerHTML = '<p id="modeAdvanced"><label for="message">'+__("Write your message and hit Send to post:")+'<a href="" onclick="toggleMode(); return false;" id="mode">'+__("simple post")+' &#9650;</a></label><span class="toolbar"><a href="#" id="boldButton" title="'+__("bold")+'" onclick="return false;">'+__("bold")+'</a><a href="#" id="italicButton" title="'+__("italic")+'" onclick="return false;">'+__("italic")+'</a><a href="#" id="linkButton" title="'+__("link")+'" onclick="return false;">'+__("link")+'</a><a href="#" id="codeButton" title="code" onclick="return false;">code</a><a href="#" id="imageButton" title="'+__("image")+'" onclick="return false;">'+__("image")+'</a><a href="#" id="videoButton" title="'+__("video")+'" onclick="return false;">'+__("video")+'</a></span><iframe id="editFrame" src="/page.html?v=1"></iframe><input type="submit" value="'+__("Send")+'" name="post" onclick="send(); return false;" /> </p>' + document.messageform.innerHTML;
			var newStuffLoaded = function(){
				if(val!=null && val!=""){
					document.getElementById('editFrame').contentWindow.document.getElementsByTagName('body')[0].innerHTML="<p>"+val+"<br></p>";
				}
				createEditor();
			}
			setTimeout(newStuffLoaded,300);
		}else{
			modeAdvanced.style.display="block";
		}
		var focusIframe = function(){
			//document.getElementById('editFrame').focus();
			document.getElementById('editFrame').contentWindow.document.body.focus();
		};
		setTimeout(focusIframe,300);
	}else{
		modeAdvanced.style.display="none";
		modeSimple.style.display="block";
		document.messageform.message.focus();
	}
	simpleMode = !simpleMode;
}

function getAdvancedMessage(){
	return document.getElementById('editFrame').contentWindow.document.getElementsByTagName('body')[0].innerHTML;
}
function resetAdvancedMessage(){
	document.getElementById('editFrame').contentWindow.document.getElementsByTagName('body')[0].innerHTML="<p><br></p>";
	document.getElementById('editFrame').contentWindow.document.body.focus();
}


function switchImageForm(selectedForm,selectedLi){
	document.getElementById("fromDisc").style.display="none";
	document.getElementById("fromUrl").style.display="none";
	document.getElementById("fromGallery").style.display="none";
	document.getElementById("liDisc").className="";
	document.getElementById("liUrl").className="";
	document.getElementById("liGallery").className="";
	document.getElementById(selectedLi).className="active";
	document.getElementById(selectedForm).style.display="block";
	return false;
}

function GUI(){}
GUI.showLightbox = function(){
	if(this.lightbox==null){
		this.lightbox = document.createElement("DIV");
		this.lightbox.id="lightbox";
		this.lightbox.onclick = closeExtras;
		extras.push(this.lightbox);
		document.getElementsByTagName("BODY")[0].appendChild(this.lightbox);
	}else{
		this.lightbox.style.display="block";
	}
}
GUI.showError = function(error){
	GUI.showLightbox();
	if(this.error==null){
		this.error = document.createElement("DIV");
		this.error.className = "floatingWin";
		this.error.id = "guiError";
		this.error.onclick=closeExtras;
		extras.push(this.error);
		document.getElementsByTagName("BODY")[0].appendChild(this.error);
	}else{
		this.error.style.display="block";
	}
	this.error.innerHTML=error;
}

function CodeEditor(){}
CodeEditor.showForm = function(callback,code){
	this.callback = callback;
	GUI.showLightbox();
	this.codeEditor = document.getElementById("codeEditor");
	if(this.codeEditor == null){
		this.codeEditor = document.createElement("DIV");
		this.codeEditor.id="codeEditor";
		this.codeEditor.className="floatingWin";
		
		this.codeEditor.innerHTML = '<ul><li id="liCode" class="active"><a href="#" onclick="return switchImageForm(\'fromCode\',\'liCode\');">'+__("Code")+'</a></li></ul><div><form id="fromCode" name="fromCode" onsubmit="return CodeEditor.submit();"><label for="code">'+__("Paste or write code:")+'</label><textarea name="code" onkeydown="return catchTab(this,event)"></textarea><input type="submit" value="'+__("Insert")+'" class="button" /></form></div>';
		
	}else{
		this.codeEditor.style.display="block";
	}
	document.getElementsByTagName("BODY")[0].appendChild(this.codeEditor);
	document.fromCode.code.focus();
	extras.push(this.codeEditor);
	
	if(code){
		document.fromCode.code.value = code.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&'); //.replace(/\&gt;/g,">").replace(/\&lt;/g,"<").replace(/\&amp;/g,"&");
	}
}
CodeEditor.submit = function(callback){
	var code = document.fromCode.code.value.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
	this.callback(code);
	document.fromCode.code.value="";
	closeExtras();
	return false;
}

function VideoUploader(){}
VideoUploader.showForm = function(callback){
	this.callback = callback;
	GUI.showLightbox();
	//	ImageUploader.showLightbox();
	this.videoUpload = document.getElementById("videoUpload");
	if(this.videoUpload == null){
		this.videoUpload = document.createElement("DIV");
		this.videoUpload.id="videoUpload";
		this.videoUpload.className="floatingWin";
		
		this.videoUpload.innerHTML = '<ul><li id="liVideoUrl" class="active"><a href="#" onclick="return switchImageForm(\'fromVideoUrl\',\'liVideoUrl\');">'+__("Video from URL")+'</a></li></ul><div><form id="fromVideoUrl" name="fromVideoUrl" onsubmit="return VideoUploader.uploadFromUrl();"><label for="file">'+__("URL to video:")+'</label><input type="text" name="url" onfocus="if(this.value==\'http://\') this.value=\'\';" id="videoUrl" value="http://" /><input type="submit" value="'+__("Insert")+'" class="button" /></form></div>';
		
	}else{
		this.videoUpload.style.display="block";
	}
	document.getElementsByTagName("BODY")[0].appendChild(this.videoUpload);
	
	extras.push(this.videoUpload);
	
}
VideoUploader.uploadFromUrl = function(){
	var videoUrl = document.fromVideoUrl.url.value;
	var callback = this.callback;
	this.videoUpload.style.display="none";
	document.fromVideoUrl.url.value = "http://";
	closeExtras();
	callback(videoUrl);
	return false;
}



function ImageUploader(){}
ImageUploader.showLightbox = function(){
	
	GUI.showLightbox();
}

ImageUploader.showLoading = function(){
	if(this.loading==null){
		this.loading = document.createElement("DIV");
		this.loading.id="loading";
		extras.push(this.loading);
		document.getElementsByTagName("BODY")[0].appendChild(this.loading);
	}else{
		this.loading.style.display="block";
	}
}



ImageUploader.showForm = function(callback){
	this.callback = callback;
	GUI.showLightbox();
	//	ImageUploader.showLightbox();
	var imageUpload = document.getElementById("imageUpload");
	if(this.imageUpload == null){
		this.imageUpload = document.createElement("DIV");
		this.imageUpload.id="imageUpload";
		this.imageUpload.className="floatingWin";
		
		this.imageUpload.innerHTML = '<ul><li id="liDisc" class="active"><a href="#" onclick="return switchImageForm(\'fromDisc\',\'liDisc\');">'+__("Image from Disc")+'</a></li><li id="liUrl"><a href="#" onclick="return switchImageForm(\'fromUrl\',\'liUrl\');">'+__("from URL")+'</a></li><li id="liGallery"><a href="#" onclick="return switchImageForm(\'fromGallery\',\'liGallery\');">'+__("from Gallery")+'</a></li></ul><div><form id="fromDisc" action="/newImageFromDisc.php" method="post" name="fromDisc" enctype="multipart/form-data" onsubmit="return ImageUploader.uploadFromDisc(this);"><input type="hidden" name="MAX_FILE_SIZE" value="2000000" /><label for="image">'+__("File:")+'</label><input type="file" name="image" id="imageFile" /><input type="submit" name="uploadImageNow" value="'+__("Upload")+'" class="button" /></form><form id="fromUrl" name="fromUrl" onsubmit="return ImageUploader.uploadFromUrl();"><label for="file">'+__("Url:")+'</label><input type="text" name="url" onfocus="if(this.value==\'http://\') this.value=\'\';" id="imageUrl" value="http://" /><input type="submit" value="'+__("Upload")+'" class="button" /></form><form id="fromGallery"><p>'+__("Click one of your previously uploaded images to insert:")+'</p><div id="gallery"></div></form></div>';
		ajaxCall("/get_images.php","",function(http_request){
			if(http_request.responseText!=""&&http_request.responseText!="error"){
				//got images...

				var images = eval('(' + http_request.responseText + ')');
				var code="";
				for(var i=0; i<images.length; i++){
					code += '<img src="'+images[i].thumb+'" width="50" height="50" onclick="ImageUploader.insertFromGallery(\''+images[i].url+'\')" />';
				}
				ImageUploader.gallery.innerHTML = code;
			}
		},"text/html; charset=UTF-8");
			
	}else{
		this.imageUpload.style.display="block";
	}
	document.getElementsByTagName("BODY")[0].appendChild(this.imageUpload);
	this.gallery = document.getElementById("gallery");
	
	extras.push(this.imageUpload);
	
}
ImageUploader.addImageToGallery = function(url){
	var thumbUrl = url.replace("_430_600","_50");
	ImageUploader.gallery.innerHTML = '<img src="'+thumbUrl+'" width="50" height="50" onclick="ImageUploader.insertFromGallery(\''+url+'\')" />' + ImageUploader.gallery.innerHTML;	
}
ImageUploader.uploadFromUrl = function(){
	var imageUrl = document.fromUrl.url.value;
	var callback = this.callback;
	this.imageUpload.style.display="none";
	ImageUploader.showLoading();
	ajaxCall("/newImageFromUrl.php","url="+imageUrl,function(http_request){
		if(http_request.responseText!=""&&http_request.responseText=="error"){
			alert("Error: "+http_request.responseText);
		}else{
			url = http_request.responseText;
			if(url.substring(0,7)=="http://"){
				callback(url);
				document.fromUrl.url.value = "http://";
				ImageUploader.addImageToGallery(url);
				closeExtras();
			}else{
				GUI.showError(url);
				this.loading.style.display="none";
			}
		}
	},"text/html; charset=UTF-8");
	
	return false;
}

ImageUploader.uploadFromDisc = function(form){
	
	this.imageUpload.style.display="none";
	ImageUploader.showLoading();

	if(this.iframe == null){
		var d = document.createElement('DIV');
		d.innerHTML = '<iframe style="display:none" src="about:blank" id="uploadFrame" name="uploadFrame"></iframe>';
		document.body.appendChild(d);
		form.setAttribute('target', "uploadFrame");
		var i = document.getElementById("uploadFrame");
		this.iframe = i;
		this.iframe.onload=ImageUploader.uploadedFromDisc;
		i.onComplete = function(){
			alert("completed");
		}
	}

	return true;
}
	
ImageUploader.uploadedFromDisc = function(){
	var f = window.frames["uploadFrame"].document;
	var url = f.body.innerHTML;
	if(url.substring(0,7)=="http://"){
		ImageUploader.callback(url);
		document.fromDisc.image.value="";
		ImageUploader.addImageToGallery(url);
		closeExtras();
	}else{
		GUI.showError(url);
		this.loading.style.display="none";
	}
}

ImageUploader.insertFromGallery = function(url){
	ImageUploader.callback(url);
	closeExtras();
}



function createEditor() {

	/*
		Commands
		--------
	*/

	function Command(command, editDoc) {
		this.execute = function() {
			editDoc.execCommand(command, false, null); 
		};
		this.queryState = function() {
			return editDoc.queryCommandState(command);
		};
	}

	function ValueCommand(command, editDoc) {
		this.execute = function(value) {
			editDoc.execCommand(command, false, value); 
		};
		this.queryValue = function() {
			return editDoc.queryCommandValue(command);
		};
	}

	function LinkCommand(editDoc) {
		var tagFilter = createElementFilter("A");
		this.execute = function() {
			var a = getContaining(editWindow, tagFilter);
			var initialUrl = a ? a.href : "http://";
			var url = window.prompt("Enter an URL:", initialUrl);
			if (url===null) return;
			if (url==="") {
				editDoc.execCommand("unlink", false, null); 
			} else {
				editDoc.execCommand("createLink", false, url); 
			}
		};
		this.queryState = function() {
			return !!getContaining(editWindow, tagFilter);
		};		
	}

	function CodeCommand(editDoc) {
		var tagFilter = createElementFilter("PRE");
		var tagFilter2 = createElementFilter("CODE");
		this.execute = function() {
			if(!getContaining(editWindow, tagFilter)&&!getContaining(editWindow, tagFilter2)){
				//alert("in if");
				selText = getSelText(editWindow,editWindow.document);
				if(selText!=null && selText!='') {
					insertAround(editWindow,"code");
				}else{
					editWindow.focus();
					if (editDoc.selection && editDoc.selection.createRange) {
					    this.range = editDoc.selection.createRange();
					}
					var self = this;
					
					InsertCode = function(code){
						editWindow.focus();
						var codeCode = "<div contentEditable=\"false\" unselectable=\"on\"><pre>"+code+"</pre></div>";
						
						if(self.range && self.range.pasteHTML){
							self.range.pasteHTML(codeCode);
						}else{
							editDoc.execCommand("insertHtml", false, "<br />"+codeCode+"<br />"); 				
						}
					}
					CodeEditor.showForm(InsertCode);					
				}
			}else if(getContaining(editWindow, tagFilter)){
				//alert("let user edit his code, code is:\n"+getContaining(editWindow, tagFilter).innerHTML);
				this.containing = getContaining(editWindow, tagFilter);
				var self = this;
				EditCode = function(code){
					//alert("d: "+code);
					editWindow.focus();
					//self.containing.innerText = code;
					//self.containing.innerText = self.containing.innerText.replace("[t]","\t");
					
					self.containing.innerHTML= '';
					self.containing.appendChild(document.createTextNode(code.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&')));
					
				}
				CodeEditor.showForm(EditCode,getContaining(editWindow, tagFilter).innerHTML);
				
			}else if(getContaining(editWindow, tagFilter2)){
				var containing = getContaining(editWindow, tagFilter2);
				//alert("already in codeblock "+containing.innerHTML);
				var selText = getSelText(editWindow,editWindow.document);
				if(selText==null||selText==''){
					/*
					var pos = getCaretPos(editWindow.document.body); //doGetCaretPosition2(editWindow.document,editWindow.document);
					alert("pos: "+pos);
					
					var range= editWindow.getSelection().getRangeAt(0);
					alert('Current position: '+range.startOffset+' inside '+range.startContainer+' with content "'+range.startContainer.htmlText+'"');
					//range.setStart(getContaining(editWindow, tagFilter2), 1);
					//range.setEnd(getContaining(editWindow, tagFilter2), 1);
					
					setCaretTo("editFrame",1);
					*/
					containing.insertAdjacentHTML("afterEnd", " ");
				}else{
					containing.parentNode.replaceChild(document.createTextNode(containing.innerHTML),containing);
				}
			}
		};
		this.queryState = function() {
			return getContaining(editWindow, tagFilter)||getContaining(editWindow, tagFilter2);
		};		
	}
	


	function ImageCommand(editDoc) {
		var tagFilter = createElementFilter("IMG");
		this.execute = function() {
			var InsertImage = function(url){
				editWindow.focus();
				editDoc.execCommand("insertImage", false, url); 			
			}
			
			ImageUploader.showForm(InsertImage); //uploadImage();

		};
		this.queryState = function() {
			return !!getContaining(editWindow, tagFilter);
		};		
	}

	function VideoCommand(editDoc) {
		var tagFilter = createElementFilter("IFRAME");
		this.execute = function() {
			var InsertVideo = function(url){
				editWindow.focus();
				//http://www.youtube.com/watch?v=n6rjQ9VVLDI
				var regYoutube = new RegExp("http:\/\/(www\.)?youtube.(com|se)\/watch\\?v=([A-Za-z0-9_-]+)(.*)?","i");
				var regVimeo = new RegExp("http:\/\/(www\.)?vimeo.com\/([0-9]+)(.*)?","i");
				
				var embedCode = "";
				if(url.match(regYoutube)!=null){
					embedCode = '<iframe class="youtube-player" type="text/html" width="430" height="259" src="http://www.youtube.com/embed/'+url.match(regYoutube)[3]+'" frameborder="0"></iframe>';
				}else if(url.match(regVimeo)!=null){
					embedCode = '<iframe src="http://player.vimeo.com/video/'+url.match(regVimeo)[2]+'?portrait=0" width="438" height="246" frameborder="0"></iframe>';
					//embedCode = '<div style="background: #000; width: 430px; height: 242px"><object width="430" height="242"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed src="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="430" height="242"></embed></object></div>';
					
					//embedCode = '<object width="430" height="242"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /></object>';
					//embedCode = '<embed src="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="430" height="242"></embed>';
					//embedCode = '<object width="430" height="242"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" /><embed src="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1&amp;autoplay=0&amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="430" height="242"></embed></object>';
					//embedCode = '<object width="468" height="263"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id='+url.match(regVimeo)[2]+'&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="468" height="263"></embed></object>';
					//embedCode = '<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/E2_kAsqYFvQ&amp;hl=sv_SE&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/E2_kAsqYFvQ&amp;hl=sv_SE&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>';
				}else{
					GUI.showError(__("Only supports videos from Youtube and Vimeo so far..."));
					//alert("not matching any known video site");
				}
				if (editDoc.selection && editDoc.selection.createRange) {
				    var range = editDoc.selection.createRange();
				    if (range.pasteHTML) {
				        range.pasteHTML(embedCode);
				    }
				}else{
					editDoc.execCommand("insertHtml", false, embedCode); 			
				}
			}
			
			VideoUploader.showForm(InsertVideo); //uploadImage();
			
		};
		this.queryState = function() {
			return !!getContaining(editWindow, tagFilter);
		};		
	}
	
	function InsertHelloWorldCommand() {
		this.execute = function() {		
			var elem = editWindow.document.createElement("SPAN");
			elem.style.backgroundColor = "red";
			elem.innerHTML = "Hello world!";
			overwriteWithNode(editWindow, elem);
		}	
		this.queryState = function() {
			return false;
		 }
	}

	/*

		Controllers
		-----------
		Connects Command-obejcts to DOM nodes which works as UI

	*/

	function TogglCommandController(command, elem) {	
		this.updateUI = function() {
			var state = command.queryState();
			elem.className = state?"active":"";
		}
		var self = this;
		//elem.unselectable = "on"; // IE, prevent focus
		bindEvent(elem, "mousedown", function(evt) { 
			// we cancel the mousedown default to prevent the button from getting focus
			// (doesn't work in IE)
			if (evt.preventDefault) evt.preventDefault();
			return false;
		});		
		bindEvent(elem, "click", function(evt) { 
			command.execute(); 	
			updateToolbar();
			return false;
		});
	}
	function ValueSelectorController(command, elem) {
		this.updateUI = function() {
			var value = command.queryValue();
			elem.value = value;
		}
		var self = this;
		elem.unselectable = "on"; // IE, prevent focus		
		bindEvent(elem, "change", function(evt) { 
			editWindow.focus();
			command.execute(elem.value);	
			updateToolbar();
		});	
	}
		
	var editFrame = document.getElementById("editFrame");
	//editFrame.contentWindow.document.designMode="on";
	editFrame.contentWindow.document.body.contentEditable=true;
	var editWindow = editFrame.contentWindow;
	var editDoc = editWindow.document;
	//this.editDoc = editDoc;
	var updateListeners = [];
	var toolbarCommands = [
	                       ["boldButton", TogglCommandController, new Command("Bold", editDoc)],
	                       ["italicButton", TogglCommandController, new Command("Italic", editDoc)],
	                       ["linkButton", TogglCommandController, new LinkCommand(editDoc)],
	                       ["codeButton", TogglCommandController, new CodeCommand(editDoc)],
	                       ["imageButton", TogglCommandController, new ImageCommand(editDoc)],
		                   ["videoButton", TogglCommandController, new VideoCommand(editDoc)]
	];
	/*
	 * ["boldButton", TogglCommandController, new Command("Bold", editDoc)], 
		["italicButton", TogglCommandController, new Command("Italic", editDoc)],
		["leftButton", TogglCommandController, new Command("JustifyLeft", editDoc)],
		["rightButton", TogglCommandController, new Command("JustifyRight", editDoc)],
		["centerButton", TogglCommandController, new Command("JustifyCenter", editDoc)],
		["linkButton", TogglCommandController, new LinkCommand(editDoc)],
		["helloButton", TogglCommandController, new InsertHelloWorldCommand(editDoc)],
		["fontSelector", ValueSelectorController, new ValueCommand("FontName", editDoc)],
		["sizeSelector", ValueSelectorController, new ValueCommand("FontSize", editDoc)]
	 */
		
	//for (var ix=0; ix<toolbarCommands.length;ix++) {
	//	var binding = toolbarCommands[ix];
	toolbarCommands.map(function(binding) {
		var elemId = binding[0], ControllerConstructor = binding[1], command=binding[2];
		var elem = document.getElementById(elemId);	
		var controller = new ControllerConstructor(command, elem);		
		updateListeners.push(controller);
	});
	
	function updateToolbar() { 
		updateListeners.map(function(controller){
			controller.updateUI();
		});
		
		/*
		var content = editDoc.getElementsByTagName('body')[0].innerHTML;
		//alert("content: "+content);
		var newcontent = content.replace("</pre><pre>","\n");
		if(content!=newcontent){
			//alert(newcontent);
			editDoc.getElementsByTagName('body')[0].innerHTML=newcontent;
		}
		//editDoc.getElementsByTagName('body')[0].innerHTML = content.replace("</pre><pre>","\n");
		*/
	};	
	
	bindEvent(editDoc, "keyup", updateToolbar);
	bindEvent(editDoc, "mouseup", updateToolbar); 
}




if (!Array.prototype.map) {
	Array.prototype.map = function(fun) {
		var collect = [];
		for (var ix = 0; ix < this.length; ix++) { collect[ix] = fun(this[ix]); }
		return collect;
	}
}

function bindEvent(target, eventName, fun) {
	if (target.addEventListener) {
		target.addEventListener(eventName, fun, false);
	} else {
		target.attachEvent("on" + eventName, function(){ fun(event); });
	} 
}







/*
Editlib.js
----------
Various functions for manipulating selections, used by editing commands
*/

var getContaining = (window.getSelection)?w3_getContaining:ie_getContaining;
var overwriteWithNode = (window.getSelection)?w3_overwriteWithNode:ie_overwriteWithNode;
var insertAround = (window.getSelection)?w3_insertAround:ie_insertAround;

function createElementFilter(tagName) {
	return function(elem){ return elem.tagName==tagName; }
}

/* walks up the hierachy until an element with the tagName if found.
Returns null if no element is found before BODY */
function getAncestor(elem, filter) {
	while (elem.tagName!="BODY") {
		if (filter(elem)) return elem;
		elem = elem.parentNode;
	}
	return null;
}

function includes(elem1, elem2) {
	if (elem2==elem1) return true;
	while (elem2.parentNode && elem2.parentNode) {
		if (elem2==elem1) return true;	
		elem2 = elem2.parentNode;
	}
	return false;
}

function ie_getContaining(editWindow, filter) {
	var selection = editWindow.document.selection;
	if (selection.type=="Control") {
		// control selection
		var range = selection.createRange();
		if (range.length==1) { 
			var elem = range.item(0); 
		}
		else { 
			// multiple control selection 
			return null; 
		}
	} else {
		var range = selection.createRange();
		var elem = range.parentElement();
	}
	return getAncestor(elem, filter);		
} 

function ie_overwriteWithNode(editWindow, node) {
	var rng = editWindow.document.selection.createRange();
	var marker = writeMarkerNode(editWindow, rng);
	marker.appendChild(node);
	marker.removeNode(); // removes node but not children
}

function ie_insertAround(editWindow,tagname){
	var rng = editWindow.document.selection.createRange();
	//rng.pasteHTML("<"+tagname+">"+before+rng.text+after+"</"+tagname+">"); //eh what is before and after?
	rng.pasteHTML("<"+tagname+">"+rng.text+"</"+tagname+">");
}

// writes a marker node on a range and returns the node.
function writeMarkerNode(editWindow, rng) {
	var id = editWindow.document.uniqueID;
	var html = "<span id='" + id + "'></span>";
	rng.pasteHTML(html);
	var node = editWindow.document.getElementById(id);
	return node;
}

// overwrites the current selection with a node
function w3_overwriteWithNode(editWindow, node) {
	var rng = editWindow.getSelection().getRangeAt(0);
	rng.deleteContents();
	if (isTextNode(rng.startContainer)) {
		var refNode = rightPart(rng.startContainer, rng.startOffset)		
		refNode.parentNode.insertBefore(node, refNode);
	} else {
		if (rng.startOffset==rng.startContainer.childNodes.length) {
			refNode.parentNode.appendChild(node);
		} else {
			var refNode = rng.startContainer.childNodes[rng.startOffset];
			refNode.parentNode.insertBefore(node, refNode);
		}
	}	
}

function w3_insertAround(editWindow,tagname){
	var rng = editWindow.getSelection().getRangeAt(0);
	var newNode = editWindow.document.createElement(tagname);
	newNode.innerHTML = rng.toString();
	rng.deleteContents();
	rng.insertNode(newNode);
	
}

function w3_getContaining(editWindow, filter) {
	var range = editWindow.getSelection().getRangeAt(0);
	var container = range.commonAncestorContainer;		
	return getAncestor(container, filter);	
}

function isTextNode(node) {
	return node.nodeType==3;
}

function rightPart(node, ix) {
	return node.splitText(ix);
}
function leftPart(node, ix) {
	node.splitText(ix);
	return node;
}











function doGetCaretPosition (ctrl) {
	var CaretPos = 0;	// IE Support
	if (document.selection) {
	ctrl.focus ();
		var Sel = document.selection.createRange ();
		Sel.moveStart ('character', -ctrl.value.length);
		CaretPos = Sel.text.length;
	}
	// Firefox support
	else if (ctrl.selectionStart || ctrl.selectionStart == '0')
		CaretPos = ctrl.selectionStart;
	return (CaretPos);
}

/*function doGetCaretPosition2 (doc,ctrl) {
	var CaretPos = 0;	// IE Support
	if (doc.selection) {
	ctrl.focus ();
		var Sel = doc.selection.createRange ();
		Sel.moveStart ('character', -ctrl.value.length);
		CaretPos = Sel.text.length;
	}
	// Firefox support
	else if (ctrl.selectionStart || ctrl.selectionStart == '0')
		CaretPos = ctrl.selectionStart;
	return (CaretPos);
}*/

getElementWidth = function(el) {
	if (typeof el.clip !== "undefined") {
		return el.clip.width;
	} else {
		if (el.style.pixelWidth) {
			return el.style.pixelWidth;
		} else {
			return el.offsetWidth;
		}
	}
}

getElementHeight = function(el) {
	if (typeof el.clip !== "undefined") {
		return el.clip.height;
	} else {
		if (el.style.pixelHeight) {
			return el.style.pixelHeight;
		} else {
			return el.offsetHeight;
		}
	}
}

function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft;// - el.scrollLeft;
        _y += el.offsetTop;// - el.scrollTop;
        el = el.offsetParent; //el = el.parentNode;
    }
    return { top: _y, left: _x };
}


function Suggest(){
	this.str="";
	this.inited=false;
	this.hasFocus = false;
	this.hasObjects = false;
	this.cache = [];
	this.selectedIndex = -1;
	
	this.init = function(input){
		if(!this.inited){

			this.input = input;
			this.suggest = document.createElement("ul");
			this.suggest.className="usercomplete";
			this.suggest.style.width = (getElementWidth(this.input)-2)+"px";
			this.suggest.innerHTML = "<li>empty</li>";
			var offset = getOffset(this.input);
			this.suggest.style.top = (offset.top+getElementHeight(this.input)+12)+"px";
			this.suggest.style.left = offset.left+"px";
			document.getElementsByTagName("body")[0].appendChild(this.suggest);
			
			this.focus();
			
			
			var self = this;
			this.input.onkeyup = function(){
				self.change();
			}
			this.input.onfocus = function(){
				self.focus();
			}
			this.input.onblur = function(){
				self.blur();
			}
			
			
			document.onkeyup = function(e){
				self.keyCheck(e);
			}
			
			document.onkeypress = function(e){
				var keyID = (window.event) ? event.keyCode : e.keyCode;
				return keyID!=13&&keyID!=38;
			};
			document.onkeydown = function(e){
				var keyID = (window.event) ? event.keyCode : e.keyCode;
				return keyID!=38&&!(keyID==39&&this.hasObjects)&&keyID!=40;
			
			};

			
			
			this.inited=true;
		}
	}
	
	
	this.keyCheck = function(e){
		if(this.hasFocus){
			var keyID = (window.event) ? event.keyCode : e.keyCode;
			switch(keyID){
				case 8:
					//backspace?
					break;
				
				case 13:
				case 39:
				case 9:
					//add
					if(this.hasObjects){
						document.getElementById("comp"+this.selectedIndex).onclick();
					}
					return false;
					break;
				
				case 38:
					if(this.hasObjects){
						if(this.selectedIndex>0){
							this.selectedIndex--;
							this.update();
						}
					}
					break;
			
				case 40: // down
					if(this.objects){
						if(this.selectedIndex<this.objects.length-1){
							this.selectedIndex++;
							this.update();
						}
					}
					return false;
					break;
				
				default:
		
			}
		
			return false;
		}
	}
	
	this.focus = function(){
		if(this.input.value==__("Type username to invite")) this.input.value="";
		this.hasFocus = true;
	}
	this.blur = function(){
		//alert("blur");
		this.hasFocus = false;
		var self = this;
		var delay = function(){
			self.hide();
		}
		if(this.input.value=="") this.input.value=__("Type username to invite");
		//this.hide();
		//hideFunc = this.hide;
		setTimeout(delay,150);
	}
	
	this.show = function(){
		var offset = getOffset(this.input);
		this.suggest.style.top = (offset.top+getElementHeight(this.input)+12)+"px";
		this.suggest.style.display = "block";
		this.hasObjects=true;
	}
	this.hide = function(){
		this.suggest.style.display = "none";
		this.objects = null;
		this.hasObjects=false;
	}
	
	
	this.update = function(){
		if(this.objects && this.objects.length>0){
			this.suggest.innerHTML = "";
			for(var i=0; i<this.objects.length; i++){
				
				var start = this.objects[i].username.toLowerCase().indexOf(this.str.toLowerCase());
				var end = start+this.str.length;
				var online = this.objects[i].isOnline? ' class="online"' : '';
				
				var myLi = document.createElement("LI");
				if(this.selectedIndex == i) myLi.className="selected";
				var myA = document.createElement("A");
				myA.href="#"+i;
				myA.id="comp"+i;
				myA.rel = i;
				var self = this;
				myA.onclick = function(){
					//alert("hej "+self+" "+this.rel);
					self.action(self.objects[this.rel]);
					
				};
				myA.innerHTML='<img src="'+this.objects[i].avatar+'" width="20" height="20" '+online+'/><span>'+this.objects[i].username.substring(0,start) + "<strong>" + this.objects[i].username.substring(start,end) + "</strong>" + this.objects[i].username.substring(end,this.objects[i].username.length)+'</span>';
				myLi.appendChild(myA);
				this.suggest.appendChild(myLi);

			}
			this.show();
		}else{
			this.hide();
		}
	}
	this.toString = function(){
		return "Suggest Object";
	}
	this.change = function(){
		this.init();
		this.caretPos = doGetCaretPosition(this.input);
		var str = this.input.value.substring(0,this.caretPos);
		var nxt = "";
		if(this.caretPos<this.input.value.trim().length){
			nxt = this.input.value.trim().charAt(this.caretPos);
		}
		if(str!=""&&str.substring(str.length-2)!=", "&&str.substring(str.length-1)!=","&&(nxt==","||nxt=="")){
			if(str!=this.lastStr){
				this.lastStr=str;
					
				var topicArr = str.split(",");
				var complete = topicArr[topicArr.length-1];
				if(complete!=""){
					this.str = complete;
					if(typeof this.cache[complete]!="undefined"){
						this.objects = this.cache[complete];
						this.selectedIndex=0;
						this.update();
					}else{
						var self = this;
						this.caller = ajaxCall("/get_users.php","str="+complete,function(http_request){
							if (http_request.readyState == 4) {
								if (http_request.status == 200) {
									if (http_request.responseText!=""){
										var res = http_request.responseText;
										self.objects = eval("("+res+")");
										self.selectedIndex=0;
										self.update();
										self.cache[complete] = self.objects;
									}
								}	
							}	
						},"application/json");
					}
				}
			}
		}else{
			this.hide();
		}
	}

	this.action = function(user){
		var key = getKey(user.username,topicalUsers);
		if(key==null){
			
			ajaxCall("/invite_user.php","invite="+user.username+"&topic="+currentTopic,function(http_request){
				if (http_request.readyState == 4) {
					if (http_request.status == 200) {
						if (http_request.responseText!="done"){
							//alert(http_request.responseText);
							var el = document.getElementById("invite_"+user.username);
							el.parentNode.removeChild(el);
						}
					}	
				}	
			},"application/json");
			
			var status = (user.status!="")? user.status : __("No status set");
			var online = (user.isOnline)? ' class="online"' : '';
			document.getElementById("invited").innerHTML += "<dl class=\"invitedUser\" id=\"invite_"+user.username+"\"><dt><a href=\"/users/"+user.username+"\"><img src=\""+user.avatar+"\" width=\"25\" height=\"25\" alt=\"Bild\""+online+" /></a></dt><dd><a href=\"/users/"+user.username+"\">"+user.username+"</a></dd><dd><em>"+status+"</em></dd></dl>";
			document.getElementById("invited_heading").innerHTML = __("Invited (%d)").replace("%d",getElementsByClass("invitedUser",document.getElementById("second"),"dl").length);

		}else{
			alert("User "+user.username+" is already a member of this group");
		}			
		this.input.value="";
		this.hide();
		this.input.focus();
		this.lastStr="";
		return false;
	}
}



var userSuggest = new Suggest();




