/*
 * (c) 2006-2009 Robert (nospor) Nodzewski
 * email: (nospor at gmail dot com)
 * license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
 * Dodatkowo, począwszy od wersji 1.0, wymagane jest umieszczenie na stronie wykorzystującej ShoutBox 
 * informacji o autorze wraz z linkiem do jego strony.
 * version: 1.3
 *
 */

/**
 * Klasa ShoutBox
 * 
 * @param {String} id  unikalny identyfikator. Ważne, by tworzony obiekt nazywal sie tak samo jak to id, np:
 * var sb = new ShoutBox('sb');
 * @param {Integer} refreshTime  czas odświerzania w milisekundachsekundach
 * @param {String} baseLink  link bazowy do skryptu odbierającego żądania.
 * @param {String} type typ wyświetlania (down lub up). Można wyświetlać nowe wiadomości na dole lub na górze. (domyślnie: down)
 */
function ShoutBox(id, refreshTime, baseLink, type, win){
	this.id = id;
	this.idMsg = null;
	this.idFirstMsg = null; //id wiadomości, która jest aktualnie pierwsza
	this.refreshTime = refreshTime || 10000;// domyślny czas to 10 sekund
	this.baseLink = baseLink || 'ShoutBox.php';
	this.events = {};
	this.down = (!type || type == 'down') ? true : false;
	this.body = jQuery('#'+this.id+'_body');
	this.win = win;
	ShoutBox.objNick = document.getElementById('sb_nick');
	ShoutBox.objMessage = document.getElementById('sb_message');
	if (ShoutBox.objMessage){
		ShoutBox.objMessage.onblur = function() {ShoutBox.setFocus();};
		ShoutBox.objMessage.onkeydown = function(event) {if (ShoutBox.isTab(event)) return ShoutBox.searchUser(this); else ShoutBox.usersIndex = -1;};
	}
};
//teksty
ShoutBox.txtScrollLock = 'Zablokuj scroll';
ShoutBox.txtScrollUnlock = 'Odblokuj scroll';
ShoutBox.txtFloodingLock = 'Blokada pisania jeszcze przez sekund: ';
ShoutBox.txtRemoveConfirm = 'Czy na pewno chcesz usunąć tę wiadomość?';
ShoutBox.txtRemoveError = 'Nie udało się usunąć wiadomości';
ShoutBox.txtGettingError = 'Nie udało się pobrać danych';
ShoutBox.txtEditError = 'Nie udało się zmienić wiadomości';
ShoutBox.txtEditClick = 'Kliknij by edytować';

ShoutBox.objWait = null;

ShoutBox.scrollLocked = false;
ShoutBox.switchScroll = function(obj) {
	if (ShoutBox.scrollLocked){
		obj.className = 'sb_unlocked';
		obj.title = ShoutBox.txtScrollLock;
		ShoutBox.scrollLocked = false;
	} else {
		obj.className = 'sb_locked';
		obj.title = ShoutBox.txtScrollUnlock;
		ShoutBox.scrollLocked = true;
	};
	return true;		
};

ShoutBox.objUsersOnline = null;
ShoutBox.setUsersOnline = function(json) {
	var idSb = json.id;
	var online = json.o;
	if (!idSb || !online)
		return ;
	var obj = jQuery('#'+idSb+'_online_users');
	obj.empty();
	ShoutBox.users = null;	
	ShoutBox.users = new Array();	
	for (var nick in online){
		obj.append(online[nick]);
		ShoutBox.users.push(nick);
	}
	return true;		
};

ShoutBox.floodingTime = 0;
ShoutBox.floodingLock = function() {
	var objSubmit = document.getElementById('sb_submit');
	if (ShoutBox.objMessage && objSubmit){
		if (ShoutBox.floodingTime){
			ShoutBox.objMessage.disabled = true;
			objSubmit.disabled = true;
			ShoutBox.objMessage.value = ShoutBox.txtFloodingLock+ ShoutBox.floodingTime;
			ShoutBox.floodingTime--;
			setTimeout('ShoutBox.floodingLock()',1000);
		} else {
			ShoutBox.objMessage.disabled = false;
			objSubmit.disabled = false;
			ShoutBox.objMessage.value = '';
		}
	}
};

ShoutBox.users = null;
ShoutBox.usersIndex = -1;
ShoutBox.usersSearch = '';
ShoutBox.searchUser = function(objMsg) {
	if (!ShoutBox.users)
		return ;
	//pobranie ostatniego wyrazu
	var objReg = /(^|\s)(\w*)$/;
	if (ShoutBox.usersIndex == -1){
		var str = objMsg.value.match(objReg);
		if (str && str.length==3)
			ShoutBox.usersSearch = str[2];
		else
			ShoutBox.usersSearch = '';
	};
	
	//wyszukanie w tablicy userów
	var uLength = ShoutBox.users.length, sUser,sActualUser, objPattern;
	if (ShoutBox.users && uLength > 0){
		if (ShoutBox.usersIndex==-2)
			ShoutBox.usersIndex=0
		else	
			ShoutBox.usersIndex++;
		if (ShoutBox.usersIndex<uLength){
			for (;ShoutBox.usersIndex<uLength;ShoutBox.usersIndex++){
				sActualUser = ShoutBox.users[ShoutBox.usersIndex];
				objPattern = new RegExp("^"+ShoutBox.usersSearch,"i"); 
				if (!ShoutBox.usersSearch || sActualUser.match(objPattern)){
					sUser = sActualUser;
					break;
				};
				sUser = ShoutBox.usersSearch;
			};
			if (ShoutBox.usersIndex>=uLength)
				ShoutBox.usersIndex=-2;
		} else {
			sUser = ShoutBox.usersSearch;
			ShoutBox.usersIndex=-2;
		}	
	} else
		sUser = ShoutBox.usersSearch;
	
	//wyswietlenie znalezionego slowa
	objMsg.value = objMsg.value.replace(objReg,'$1'+sUser);
	ShoutBox.wasTab = true;
	return false;
};

ShoutBox.wasTab = false;
ShoutBox.objMessage = null;
ShoutBox.objNick = null;
ShoutBox.setFocus = function(){
	if (ShoutBox.wasTab){
		ShoutBox.wasTab = false;
		ShoutBox.objMessage.focus();
	}
};

ShoutBox.showHideWait = function(type) {
	if (!ShoutBox.objWait && ShoutBox.objWait != null)
		return false;
	if (!ShoutBox.objWait && !(ShoutBox.objWait = document.getElementById('sb_wait'))){
		ShoutBox.objWait = false;
		return false;
	};
	ShoutBox.objWait.style.display = (type=='show' ? 'block' : 'none');
	return true;		
};

ShoutBox.isEnter = function(evt){
	evt = evt ? evt : window.event;
	return (evt.keyCode == 13 || evt.keyCode == 3);
};
ShoutBox.isTab = function(evt){
	evt = evt ? evt : window.event;
	if (evt.keyCode == 9){
		if (evt.preventDefault) {
			evt.preventDefault();
			evt.stopPropagation();
		} else {
			evt.returnValue = false;
			evt.cancelBubble = true;
		};
		return true;
	};
	return false;
};

ShoutBox.prototype.sendMessage = function(){
	var objMessage = ShoutBox.objMessage;
	var message = objMessage.value;
	objMessage.value = '';
	ShoutBox.showHideWait('show');
	var postdata = {
		message : message,
		sb_a  : 'add',
		sb_id : this.id
	};
	if (ShoutBox.objNick)
		postdata['nick'] = ShoutBox.objNick.value;
	if (this.idMsg)
		postdata['sb_idMsg'] = this.idMsg;
	
	jQuery.ajax({
		type: "POST",
		url: this.baseLink,
		data : postdata,
		dataType: "json",
		success: function(obj) {
			var idSb = obj.id;
			if (!idSb) return false;
			eval(idSb+'.write(obj, "write");');ShoutBox.showHideWait('hide');},
		error : function(obj) {ShoutBox.showHideWait('hide');}
	});
	
	objMessage.focus();
};
ShoutBox.prototype.getMessages = function(){
	//var gettime = $.cookie('shoutbox-get');
	//var timenow = new Date();
	//timenow.setTime(timenow.getTime() - (10 * 1000));
	//if(!gettime || gettime <= timenow.getTime()) {
		if (this.idMsg==null)
			ShoutBox.showHideWait('show');
		var postdata = {
			sb_a  : 'read',
			sb_id : this.id,
			sb_window : this.win
		};
		if (this.idMsg)
			postdata['sb_idMsg'] = this.idMsg;
		jQuery.ajax({
			type: "POST",
			url: this.baseLink,
			data : postdata,
			dataType: "json",
			success: function(obj) {
				var date1 = new Date();
				date1.setTime(date1.getTime());
				//$.cookie('shoutbox-get', date1.getTime(), { expires: 30, path: '/' });	
				var idSb = obj.id;
				if (!idSb) return false;
				eval('if ('+idSb+'.idMsg==null) ShoutBox.showHideWait("hide");'+idSb+'.write(obj, "read");');
			},
			error : function(obj) {ShoutBox.showHideWait("hide");}
		});
	//}
	
	setTimeout(this.id+'.getMessages()', this.refreshTime);
};

ShoutBox.prototype.getHistory = function(){
	ShoutBox.showHideWait('show');
	var postdata = {
		sb_a  : 'history',
		sb_id : this.id,
		sb_idFirstMsg : this.idFirstMsg
	};
	if (this.idMsg)
		postdata['sb_idMsg'] = this.idMsg;
	
	jQuery.ajax({
		type: "POST",
		url: this.baseLink,
		data:postdata,
		dataType: "json",
		success: function(obj) {
			var idSb = obj.id;
			if (!idSb) return false; 
			ShoutBox.showHideWait("hide");
			eval(idSb+'.write(obj, "history");');
		},
		error : function(obj) {ShoutBox.showHideWait('hide');}
	});
	
};

ShoutBox.prototype.dm = function(idActMsg){
	if (!confirm(ShoutBox.txtRemoveConfirm))
		return ;
	ShoutBox.showHideWait('show');
	var postdata = {
		sb_a  : 'delete',
		sb_id : this.id,
		sb_idActMsg:idActMsg
	};
	
	jQuery.ajax({
		type: "POST",
		url: this.baseLink,
		data:postdata,
		dataType: "json",
		success: function(obj) {ShoutBox.dma(obj);},
		error : function(obj) {alert(ShoutBox.txtRemoveError);ShoutBox.showHideWait('hide');}
	});
	
};

ShoutBox.dma = function(json){
	var result = json.r;
	var idSb = json.id;
	if (!idSb) return false;
	if (!result || result=='0')
		alert(ShoutBox.txtRemoveError);
	else {
		jQuery('#'+idSb+'_m'+result).remove();
	};
	eval(idSb+'.write(json, "delete");');		
	ShoutBox.showHideWait('hide');	
}

ShoutBox.prototype.tti = function(idActMsg){
	ShoutBox.showHideWait('show');
	var postdata = {
		sb_a  : 'getrfm',
		sb_id : this.id,
		sb_idActMsg:idActMsg
	};
	
	jQuery.ajax({
		type: "POST",
		url: this.baseLink,
		data:postdata,
		dataType: "json",
		success: function(obj) {
			ShoutBox.ttia(obj);
		},
		error : function(obj) {alert(ShoutBox.txtGettingError);ShoutBox.showHideWait('hide');}
	});
	
};

ShoutBox.ttia = function(json){
	var result = json.r;
	var resultText = json.rt;
	var idSb = json.id;
	if (!idSb) return false;
	if (!result || result=='0'){
		if (!json.m)
			alert(ShoutBox.txtGettingError);
	}	
	else {		
		jQuery('#'+idSb+'_m'+result).replaceWith(resultText);
	};
	eval(idSb+'.write(json, "edit");');
	ShoutBox.showHideWait('hide');	
}

ShoutBox.prototype.inputToText = function(idActMsg, inputObj){
	ShoutBox.showHideWait('show');
	var postdata = {
		sb_a  : 'edit',
		sb_id : this.id,
		sb_idActMsg:idActMsg,
		message:inputObj.value
	};
	
	jQuery.ajax({
		type: "POST",
		url: this.baseLink,
		dataType: "json",
		data: postdata,
		success: function(obj) {
			ShoutBox.itta(obj);
		},
		error : function(obj) {alert(ShoutBox.txtEditError);ShoutBox.showHideWait('hide');}
	});
	
};

ShoutBox.itta = function(json){
	var result = json.r;
	var resultText = json.rt;
	var idSb = json.id;
	if (!idSb) return false;
	if (!result || result=='0' || !resultText)
		if (!json.m)
			alert(ShoutBox.txtEditError);
	if (result && result != '0'){	
		jQuery('#'+idSb+'_m'+result).replaceWith(resultText);
	};
	eval(idSb+'.write(json, "edit");');		
	ShoutBox.showHideWait('hide');	
}

/**
 * 
 * @param {Object} xml - xml
 * @param {Object} actionName - nazwa akcji w jakiej zostało wykonane. Mogą byc:
 *  - write
 *  - read
 *  - history
 *  - delete
 *  - edit
 */
ShoutBox.prototype.write = function(json, actionName){
	var lastMessage = (this.idMsg == null) ? 0 : this.idMsg;
	var _idMsg = json.lmi;
	var idSb = json.id;
	var his = (actionName == 'history');
	var poshis = his;
	if (!this.down)
		poshis = !his;
	var noMoreHistory = json.nmh;
	var flooding = json.f;
	if (flooding && !ShoutBox.floodingTime){
		ShoutBox.floodingTime = flooding;
		ShoutBox.floodingLock();
	};	
	this.idMsg = (_idMsg && _idMsg>this.idMsg) ? _idMsg : this.idMsg;
	this.idFirstMsg = json.fmi || this.idFirstMsg;
	var messages = json.m, message,adminMessage,idActualMessage,classmessage, classtime;
	var classnick, classtext, stylemessage, styletime, stylenick, styletext, idDivMsg;
	var startH = this.body.get(0).scrollHeight, idDivText, sbmessage,_el;
	if (messages){
		for (var i in messages){
			message = messages[i].m;
			adminMessage = messages[i].a == 1 ? true : false;
			idActualMessage =  i;
			if (!his && !adminMessage && idActualMessage <= lastMessage)
				continue;
			if (poshis)
				this.body.prepend(message);
			else
				this.body.append(message);
		};
		if (actionName == 'read' && !lastMessage)
			actionName = "readall";
		this.runEvent('message', {actionName: actionName});
		if (!ShoutBox.scrollLocked){ 
			if (!his)
				this.body.get(0).scrollTop = this.down ? this.body.get(0).scrollHeight : 0;
			else	
				this.body.get(0).scrollTop = this.down ? this.body.get(0).scrollHeight - startH - this.body.get(0).offsetHeight : startH;
		} else {
			if (his)
				this.body.get(0).scrollTop = this.down ? this.body.get(0).scrollTop + (this.body.get(0).scrollHeight - startH) : this.body.get(0).scrollTop;
			else	
				this.body.get(0).scrollTop = this.down ? this.body.get(0).scrollTop : this.body.get(0).scrollTop + (this.body.get(0).scrollHeight - startH);
		}		
	};
	if (noMoreHistory){ // nie ma juz historii, wiec wyłączmy przycisk
		var objHistory = document.getElementById(idSb+'_history');
		if (objHistory){
			objHistory.className = 'sb_nohistory';
			objHistory.onclick=function(){};
		}
	};
	ShoutBox.setUsersOnline(json);
};

ShoutBox.prototype.bind = function(eventName, data, func){
	this.events[eventName] = {data : data, func : func};
}
ShoutBox.prototype.runEvent = function(eventName, params){
	if (typeof this.events[eventName] != "undefined"){
		var data = this.events[eventName].data;
		if (!data) data = {};
		data.params = params;
		this.events[eventName].func(data);
	}
}
