/**
 * Chat room components
 */

String.prototype.repeat = function(n) {
	var s = '';
	for (var i = 0; i < n; i++) {
		s += this;
	}
	return s;
}

Number.prototype.expand = function(ch, n) {
	var nn = this.toString();
	var h = nn.length;
	if (h < n) {
		nn = '0'.repeat(n - h) + nn;
	}
	return nn;
}

Array.prototype.remove = function(from, to) {
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

/**
 * Chat room class
 * 
 * @param div_prefix
 * @param channel_bareJid
 */
AbcChatRoom = function(div_prefix, channel_bareJid) {
		
	this.div_prefix = div_prefix;
	this.bareJid = channel_bareJid;
	this.connection = null;
	this.userJid = '';
	this.userList = new AbcUserList(this);
};

AbcChatRoom.prototype = {
		
		bareJid: 'common@conference.server.com',
		div_prefix: 'common',
		connection: null,
		userJid: '',
		userList: null,
		
		bind: function (conn, userJid) {
			this.connection = conn;
			this.userJid = userJid;
			
			// Attach to strophejs's events
			conn.addHandler((function(obj){return function(elem){return obj.onPresence(elem);};})(this), null, 'presence', null, null,  null);
			conn.addHandler((function(obj){return function(elem){return obj.onMessage(elem);};})(this), null, 'message', null, null,  null);
			$('#croom_' + this.div_prefix + ' .input').keypress((function(obj){return function(event){return obj.onKeyPressed(event)};})(this));
		},
		
		initData: function (room) {
			for (var j = room.history.length - 1; j >= 0; j --) {
				this.addMessage(room.history[j].ts, room.history[j].nick, room.history[j].message, false);
			}
			
			this.scrollToBottom(false);
		},
		
		sendMessage: function (msg) {
    		var reply = $msg({to: Strophe.getBareJidFromJid(this.bareJid), from: this.userJid, type: 'groupchat'}).c('body', msg);
    		this.connection.send(reply.tree());
		},
		
		addMessage: function (ts, nick, message, isslidebottom) {
			
			var dd = new Date(parseInt(ts));
			
			var vm = '#croom_' + this.div_prefix + ' .text';
			// Check if it is required to slide down
			var needslide = ($(vm).attr('scrollTop') + $(vm).height() + 10 > $(vm).attr('scrollHeight'));
			
			$(vm).append('<p><span class="d">[' + dd.getHours().expand('0', 2) + ':' + dd.getMinutes().expand('0', 2) + ':' + dd.getSeconds().expand('0', 2) + ']</span><span class="f">&nbsp;' + nick + ':&nbsp;</span><span class="m">' + message + '</span></p>');
			
			if ((needslide) && (isslidebottom)) {
				// Scroll down
				this.scrollToBottom(true);
			}
		},
		
		scrollToBottom: function (is_animate) {
			var vm = '#croom_' + this.div_prefix + ' .text';
			if (is_animate) {
				$(vm).animate({ scrollTop: ($(vm).attr("scrollHeight") - $(vm).height()) }, 300);
			} else {
				$(vm).attr('scrollTop', ($(vm).attr("scrollHeight") - $(vm).height()));
			}
		},
		
		charListDiv: function() {
			return '#croom_' + this.div_prefix + ' .charlist';			
		},
		
		onPresence: function(pres) {
			this.userList.updateByStanza(pres);
			return true;
		}, 
		
		onMessage: function(msg) {
		    var to = msg.getAttribute('to');
		    var from = msg.getAttribute('from');
		    var type = msg.getAttribute('type');
		    var elems = msg.getElementsByTagName('body');

		    if (type == "groupchat" && elems.length > 0) {
		    	var body = elems[0];
		    	this.addMessage(new Date().getTime(), Strophe.getResourceFromJid(from), Strophe.getText(body), true);
		    }

		    // we must return true to keep the handler alive.  
		    // returning false would remove it after it finishes.
		    return true;
		},
		
		onKeyPressed: function(event) {
			
			var value = $('#croom_' + this.div_prefix + ' .input').val();
			
			if ((event.keyCode == 10) || (event.keyCode == 13)) {	// (event.ctrlKey) && 
	        	this.sendMessage(value);
	        	$('#croom_' + this.div_prefix + ' .input').val('');
	        	return false;
	        } else {
	        	return true;
	        }
		}
		
};

/**
 * Chat user list class
 * 
 * @param chatJid
 * @param htmlContainer
 */
AbcUserList = function(chatRoom) {
	this.chatRoom = chatRoom;
	this.users = [];
};

AbcUserList.prototype = {
		
		chatRoom: null,
		users: [],
		
		updateByStanza: function (st) {
		    var to = st.getAttribute('to');
		    var from = st.getAttribute('from');
		    var type = st.getAttribute('type');
		    var x = st.getElementsByTagName('x');
		    if ((x) && (x[0])) {
		    	item = x[0].getElementsByTagName('item');
		    }
		    if ((item) && (item[0])) {
		    	var affiliation = item[0].getAttribute('affiliation');
		    	var role = item[0].getAttribute('role');
		    } else {
		    	var affiliation = '';
		    	var role = '';
		    }

			XMPPlog('PRESENCE (from: ' + from + ', to: ' + to + ', type: ' + type);
			
		    if (Strophe.getBareJidFromJid(from) == Strophe.getBareJidFromJid(this.chatRoom.bareJid)) {
		    	if (type == 'unavailable') {
		    		this.removeUser(from);
		    		this.refresh();
		    	} else {
		    		this.updateUser(from, affiliation, role, type);
		    		this.refresh();
		    	}
		    }
		},
		
		removeUser: function (ujid) {
			remd = false;
			for (var i = 0; i < this.users.length; i ++) {
				if (this.users[i].jid == ujid) {
					this.users.remove(i);
					remd = true;
					break;
				}
			}
			
			return remd;
		},
		
		updateUser: function (ujid, uaffiliation, urole) {
			var id = -1;
			for (var i = 0; i < this.users.length; i ++) {
				if (this.users[i].jid == ujid) {
					with (this.users[i]) {
						affiliation = uaffiliation;
						role = urole;
					}
					id = i;
					break;
				}
			}
			if (id < 0) {
				// Append user
				this.users.push({
						'jid': ujid,
						'nick': Strophe.getResourceFromJid(ujid),
						'type': '',
						'affiliation': uaffiliation,
						'role': urole
				});
			}
		},
		
		refresh: function () {
			var s = '';
			for (var i = 0; i < this.users.length; i ++) {
				status_img = '<img src="/images/spchat/user.png" alt="" title="Онлайн">&nbsp;';
				s += '<li>' + status_img + this.users[i].nick + '</li>';
			}
			
			$(this.chatRoom.charListDiv()).empty();
			$(this.chatRoom.charListDiv()).append('<ul>' + s + '</ul>');
		}
};



