function DOMChat(chat_container , clone_obj) {
    this.me = {};
    this.objects = {};
    this.infos = {};
    this.design = clone_obj;
    this.container = chat_container;
}

DOMChat.prototype.__getName = function(jid) {if(jid.indexOf('@') >= 0)return jid.split("@")[0]; else return jid;} //for internal use only
DOMChat.prototype.__hasObj  = function(jid) {return (typeof this.objects[this.__getName(jid)] !== 'undefined');} //for internal use only

DOMChat.prototype.countOpenWindows = function() {
    var wins = this.getJids();
    var cnt = wins.length;

    for(var i=0; i < wins.length; i++)
        if(this.isHidden(wins[i])) cnt--;
	
    return (cnt < 0)?0:cnt;
}

DOMChat.prototype.getJids  = function(){ 
    var keys = new Array();
	
    for(var k in this.objects)
        keys.push(k);
	
    return keys;
}

DOMChat.prototype.getChat = function(jid) {
    if(!this.__hasObj(jid))return false;

    return this.objects[this.__getName(jid)];
}

DOMChat.prototype.removeChat = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    var jid = this.__getName(jid);
    delete this.infos[jid];
	
    delete this.objects[jid];
    $('#chat_'+jid.css_esc()).remove();
    return true;
}

DOMChat.prototype.addMessage = function(jid, me, msg, mid) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);
    var chatbox = this.objects[jid].find(".chatMessages");
    var name = cls = id = '';
    var myinfo = this.getMyInfo(jid);
    var tl = RosterManager.getLanguage(jid);

    if(me)
    {
        name = Me.name;
        cls = 'myself';
        id = this.getMessageCount(jid) + 1;
        this.setMessageCount(jid,id);
        mid = 'msg_'+Me.getNode()+'_'+getTime().replace(':',1)+id; //getTime() always returns 4 digits
    }
    else
    {
        var info = this.getInfo(jid);
        name = info.name.split(' ')[0]; //Only first name should be shown
        cls = 'other';
    }

    chatbox.append( "<li class='"+cls+"' id='"+mid+"' slang='"+myinfo.lang+"' tlang='"+tl+"' rel='"+id+"' style='display:none'>" +
        "<h5>"+name+":</h5>" +
        "<p class='org' >"+msg+"</p>" +
        "<span class='time'>"+getTime()+"</span>"+
        "</li>");

    chatbox.find('li#'+mid.css_esc()).fadeIn(500);
    chatbox.scrollTo('100%',150);
    return mid;
}

DOMChat.prototype.addMessageTranslation = function(jid, mid, msg, status, trans_id) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);

    var message= this.objects[jid].find('#'+mid.css_esc());
    if(!message) return false;

    var msg_tr = message.find('.translated');
    trans_id = (!trans_id || trans_id < 1)?0:trans_id;

    if(msg_tr.length > 0){
        msg_tr.attr('status',status);
        msg_tr.attr('trans_id',trans_id);
        msg_tr.html(msg);
    }
    else{
        message.append("<p class='translated' status='"+status+"' trans_id='"+trans_id+"' >"+msg+"</p>");
        msg_tr = message.find('.translated');
    }

    if(msg_tr && status == ChatMessageStatus.MACHINE_TRANSLATED) msg_tr.addClass('mt');
    else msg_tr.removeClass('mt');

    message.parent().scrollTo('100%',mid);
    return true;
}

DOMChat.prototype.addReport = function(jid, mid, abbreviation, text) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);
    var message= this.objects[jid].find("#"+mid.css_esc());

    if(message.find('.report').length > 0)
        message.find('.report').html(abbreviation+'<span class="explanation">'+text+'</span>');
    else
        message.append('<span class="report">'+abbreviation+'<span class="explanation">'+text+'</span></span>')

    var info = this.getInfo(jid);

    message.find('.report > a.report_link').click(function(){
        var par      = $(this).parents('li');

        var trans_id = par.find('p.translated').attr('trans_id');
        var type     = trans_id.substr(0,2);
        trans_id     = trans_id.substr(2);

        var data = {
            reporterid : Me.id,
            trans_id : trans_id,
            type : type,
            lang : par.attr('slang'),
            tlang: par.attr('tlang'),
            text : par.find('p.org').text(),
            translation: par.find('p.translated').text()
            };

        $.post(ChatConfig.REPORT_URL, data, function(data){
            if(data.RESULT && data.RESULT == 'SUCCESS')
                message.find('.report').html('<a href="javascript:void(0)">I</a><span class="explanation">'+ChatMessages.translation_reported+'</span>');
        },'json');

        return false;
    })

    return true;
}

DOMChat.prototype.addSystemMessage = function(jid, msg) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);
    var chatbox = this.objects[jid].find(".chatMessages");
	
    chatbox.append( "<li class='system'>" +
        "<p>"+msg+"</p>" +
        "<span class='time'>"+getTime()+"</span>"+
        "</li>");
    chatbox.scrollTo('100%',150);
    return true;
}

DOMChat.prototype.hideChat = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    this.objects[this.__getName(jid)].hide();
}

DOMChat.prototype.showChat = function(jid, show_translations_only, show_minimized) {
    if(!this.__hasObj(jid))return false;
	
    var myinfo = this.getMyInfo(jid);
    var pinfo = this.getInfo(jid);
	
    this.setMode(jid, (myinfo.lang == pinfo.lang), show_translations_only);

    var chat = this.getChat(jid);

    if(show_minimized == true)
        this.minimizeChat(jid);
	
    chat.show();
	
    if(!show_minimized) chat.find('.newmsg').focus();//Focus on the text area when showChat is called
//this.objects[this.__getName(jid)].show();
}	

DOMChat.prototype.maximizeChat = function(jid, minimizeAll) {
    if(!this.__hasObj(jid))return false;

    if(minimizeAll == true) this.minimizeAll(); // Minimize all windows
	
    var obj = this.getChat(jid);
    this.setMinimizedCount(jid,'');
    obj.removeClass("minimizeMode");
		
    if(!this.getInfo(jid).video_chat_minimized)
        this.maximizeVideoChat(jid);

    try{
        var vobj = this.getVideoObject(jid)
        if(vobj) vobj.attr('width',obj.width()); //Adjust the videochat width. This code is also in _setMode
	}catch(e){if(window.console) console.log(e)}
	
    if(obj.find('h4.name').hasClass('newmessage'))
        obj.find('h4.name').removeClass('newmessage');

    var name_obj = obj.find('h4.name .name');

    if(name_obj.attr('full')){
        name_obj.text(name_obj.attr('full'));
        name_obj.attr('full','');
    }

    var chatbox = obj.find(".chatMessages");
    chatbox.scrollTo('100%');
	
    obj.find('textarea.newmsg').focus();
}

DOMChat.prototype.minimizeChat = function(jid) {
    //try{console.log('DOMChat.prototype.minimizeChat ',jid)}catch(e){}
    if(!this.__hasObj(jid))return false;

    var obj = this.objects[this.__getName(jid)];
    obj.addClass("minimizeMode");
	
    if(!this.isVideoChatMinimized(jid)){//if not minimized, minimize it
        this.minimizeVideoChat(jid);
        this.getInfo(jid).video_chat_minimized = false; //set this to false, so on maximize we can restore it
    }
	
    var nobj = obj.find('h4.name .name');
    if(!nobj.attr('full') || nobj.attr('full').length < 1){
        nobj.attr('full',nobj.text());
        var tle = obj.find('h4.name').text().trim();

        if(tle.length > ChatConfig.TITLE_MINIMIZED_WORD_LENGTH){
            obj.find('h4.name .name').text(tle.substr(0,ChatConfig.TITLE_MINIMIZED_WORD_LENGTH) + '...');
        }
    }
}

DOMChat.prototype.minimizeAll = function(except_jid){
    var jids = this.getJids();
    except_jid = (except_jid && except_jid.length > 0 && except_jid.indexOf && except_jid.indexOf('@') >=0 )? Strophe.getNodeFromJid(except_jid):except_jid;

    for(var i=0; i < jids.length; i++){
        if(except_jid && jids[i] != except_jid) continue;
        this.minimizeChat(jids[i]);
	try{this.closeVideoChat(jids[i]);}catch(e){}
    }
}

DOMChat.prototype.setStyle = function( jid, style_name ){

    var chatbox = this.getChat(jid);
    if(chatbox == undefined || !chatbox) return false;

    switch(style_name){
        case 'offline' :
            this.disable(jid);
            chatbox.addClass('offline');
            break;
        case 'new_message' :
            chatbox.removeClass('offline');
            chatbox.find('h4.name').addClass('newmessage');
            break;
        case 'normal' : //reset everything to normal
            this.enable(jid);
            chatbox.removeClass('offline');
            chatbox.find('h4.name').attr('class','name');
            break;
    }
}

DOMChat.prototype.isMinimized = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    return this.objects[this.__getName(jid)].hasClass("minimizeMode");
}

DOMChat.prototype.isHidden = function(jid) {
    if(!this.__hasObj(jid))return false;

    return (this.objects[this.__getName(jid)].is(":visible") != true);
}

DOMChat.prototype.setMinimizedCount = function(jid, count) {
    if(!this.__hasObj(jid))return false;
	
    var obj = this.getChat(jid);
    var title = obj.find('.messageCount');
    title.text((count == '')?'':'('+count+')');
}

DOMChat.prototype.setTitleBar = function( jid, name, mood, count)
{
    if(!this.__hasObj(jid))return false;
	
    var obj = this.getChat(jid);
    var holder = obj.find('h4.name');
    holder.find('.name').text(name);
    holder.find('.minimizeMood').attr('class','minimizeMood '+mood);
    holder.find('.messageCount').text(count);
}

DOMChat.prototype.disable = function(jid){
    var chat = this.getChat(jid);

    if(chat){
        chat.find('textarea').addClass('disable').attr('disabled','disabled');
        chat.find('.language a, .mood a').css('visibility','hidden');
    }
}

DOMChat.prototype.enable = function(jid){
    var chat = this.getChat(jid);
    if(chat){
        chat.find('.newmsg').removeAttr('disabled').removeClass('disable');
        chat.find('.language a, .mood a').css('visibility','visible');
    }
}

DOMChat.prototype.getMode = function(jid){
    if(!this.__hasObj(jid))	return false;
    return this.getInfo(jid).mode;
}

DOMChat.prototype._setMode = function(jid, mode){
    if(!this.__hasObj(jid))	return false;

    var modes = {
        'simple':'',
        'translated':'',
        'sameLang':''
    };

    if(!(mode in modes) || !this.__hasObj(jid))
        return false;

    var obj = this.getChat(jid);
    var box  = obj.find('.newmsg');
    var minimizeCls = (obj.hasClass('minimizeMode'))?' minimizeMode':'';

    switch(mode)
    {
        /*case 'simple':
                obj.attr('class','chat'+minimizeCls);
                box.attr('maxlength',ChatConfig.CHAT_BOX_MIN_LENGTH);
                this.getInfo(jid).mode = 'simple';
                break;
        case 'translated' :
                obj.attr('class','chat translatedMode'+minimizeCls);
                box.attr('maxlength',ChatConfig.CHAT_BOX_MIN_LENGTH);
                this.getInfo(jid).mode = 'translated';
                break;
        case 'sameLang' :
                obj.attr('class','chat sameLang'+minimizeCls);
                box.attr('maxlength',ChatConfig.CHAT_BOX_MAX_LENGTH);
                this.getInfo(jid).mode = 'sameLang';
                break;*/
        default :
            obj.attr('class','chat translatedMode'+minimizeCls);
            box.attr('maxlength',ChatConfig.CHAT_BOX_MIN_LENGTH);
            this.getInfo(jid).mode = 'translated';
            break;
    }

    try{
        var vobj = this.getVideoObject(jid); //Adjust the videochat width
        if(vobj.attr) vobj.attr('width',obj.width());
	}catch(e){if(window.console) console.log(e)}

    var msgbox = obj.find(".chatMessages");
    if(msgbox)	msgbox.scrollTo('100%');

    return true;
}

DOMChat.prototype.setMode = function(jid, is_samelang, is_simple){
    if(!this.__hasObj(jid))	return false;
	
    if(is_samelang)
        this._setMode(jid,'sameLang');
    else if(is_simple)
        this._setMode(jid,'simple');
    else
        this._setMode(jid,'translated');
	
    return true;
}

DOMChat.prototype.setMessageCount = function(jid, count) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);
    this.infos[jid].me.message_count = count;
    return true;
}

DOMChat.prototype.getMessageCount = function(jid) {
    if(!this.__hasObj(jid))return false;
    jid = this.__getName(jid);
	
    if(!this.infos[jid].me.message_count)
        this.infos[jid].me.message_count = 0;
	
    return this.infos[jid].me.message_count;
}

DOMChat.prototype.setSessionId = function(jid, id) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
	
    this.infos[jid].partner.sid = id;
    return true;
}

DOMChat.prototype.getSessionId = function(jid) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
	
    return this.infos[jid].partner.sid;
}

DOMChat.prototype.getJidFromSessionId = function(session_id) {
	
    for(var jid in this.infos){
        if(this.__hasObj(jid) && this.infos[jid].partner.sid == session_id)
            return jid;
    }

    return null;
}

DOMChat.prototype.addPartnerInfo = function(jid, id, name, image) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
    this.infos[jid].partner = {id : id, name: name, image : image};
	
    this.setTitleBar(jid,name);
    var new_obj = this.getChat(jid);
    var avt = new_obj.find('img.avatar').attr('alt',name);
    avt.attr('src',(isImage(image))?urlProfilePic+image:ChatConfig.DEFAULT_IMAGE);

    var avtl = new_obj.find('a.avatar_link').attr('href','#'+ChatConfig.PROFILE_URL+id);
    avtl.click(function(evt){
        loadPage($(this).attr('href').substr(1));
        return false;
    });
    return true;
}

DOMChat.prototype.getInfo = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    return this.infos[this.__getName(jid)].partner;
}
DOMChat.prototype.setInfo = function(jid, lang, mood) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
    this.infos[jid].partner.lang = lang;
    this.infos[jid].partner.mood = mood;

    /*Settings for video chat*/
    this.infos[jid].partner.video_chat_minimized = true;

    /*Settings for my partner*/
    var new_obj = this.getChat(jid);
    new_obj.find('ul.info li.lang').text( ChatLanguages.getLanguageName(lang) );
    new_obj.find('ul.info li.mood').attr('class','mood '+mood);
    this.setTitleBar(jid,this.infos[jid].partner.name,mood);
    return true;
}

DOMChat.prototype.getMyInfo = function(jid) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;

    return this.infos[jid].me;
}

DOMChat.prototype.setMyInfo = function(jid, name, lang, mood, id ) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
    this.infos[jid].me = {id : id, lang : lang, mood : mood, name: name};
	
    this.setMyLanguage(jid, lang);
    this.setMyMood(jid, mood);
    return true;
}

DOMChat.prototype.setMyLanguage = function(jid, lang) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
		
    var new_obj = this.getChat(jid);
    new_obj.find('li.language > a').text( ChatLanguages.getLanguageName(lang) );
    new_obj.find('li.language > a').attr('lang',lang);
	
    this.infos[jid].me.lang = lang;
    return true;
}

DOMChat.prototype.setMyMood = function(jid, mood) {
    jid = this.__getName(jid);
    if(!this.__hasObj(jid))return false;
		
    var new_obj = this.getChat(jid);
    new_obj.find('li.mood > a').text(new_obj.find('.selectMood li.'+mood+' a').attr('title'));
    this.infos[jid].me.mood = mood;
    return true;
}

DOMChat.prototype.clearStoredSuggestion = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    var new_obj = this.getChat(this.__getName(jid));
    new_obj.find(".newmsg").attr("suggestion", "");
    new_obj.find(".newmsg").attr("suid", "0");
    return true;
}

DOMChat.prototype.awaitingTranslations = function(jid) {
    if(!this.__hasObj(jid))return false;
	
    var new_obj = this.getChat(this.__getName(jid));
    var waiting_transalation = new_obj.find(".chatMessages .translated").filter( function (index){
        return ($(this).attr('status') > 1);
    });
	
    return waiting_transalation.length;
}

DOMChat.prototype.getTopics = function(jid) {
	
    var obj = null;
    if( !(obj= this.getChat(jid)) ) return false;
	
    var str = '';
    var spans = obj.find('.chatTopic span').each( function(index, dom){str += $(dom).text()+'|';});
	
    return str.substring(0,str.length-1);
}

DOMChat.prototype.toggleVideoChat = function(jid, close){
    if(!this.__hasObj(jid))return false;

    var fobj = this.getVideoObject(jid);
    if(!fobj || (fobj.length && fobj.length < 1)) return false;

    if(close)
        this.minimizeVideoChat(jid);
    else
        this.maximizeVideoChat(jid);
}

DOMChat.prototype.minimizeVideoChat = function(jid){
    if(!this.__hasObj(jid))return false;
    var fobj = this.getVideoObject(jid);
    if(!fobj) return false;

    try{
        fobj.attr('height',(!$.support.objectAll)?1:0); //Can't set height to 0, or IE breaks
	}catch(e){if(window.console) console.log(e)}

    fobj.parents('.videoChat').css('height',0);
    this.getInfo(jid).video_chat_minimized = true;
}

DOMChat.prototype.maximizeVideoChat = function(jid){
    if(!this.__hasObj(jid))return false;
    var fobj = this.getVideoObject(jid);
    if(!fobj) return false;
	
    var h = fobj.attr('old_height') || ChatConfig.DEFAULT_VIDEO_HEIGHT;

    try{
        fobj.attr('height',h);
        fobj.parents('.videoChat').css('height',h+'px');
	}catch(e){if(window.console) console.log(e)}
	
    this.getInfo(jid).video_chat_minimized = false;
}

DOMChat.prototype.isVideoChatMinimized = function(jid){
    if(!this.__hasObj(jid))return false;

    var fobj = this.getVideoObject(jid);
    if(!fobj) return false;

    return (fobj.attr('height') <= 1)?true:false; //<= 1 because IE gives 1, but FF gives 0
}

DOMChat.prototype.getVideoObject = function(jid){
    if(!this.__hasObj(jid))return false;
    var obj	 = this.objects[this.__getName(jid)];
	
    if(obj.find('.videoChat > object').length < 1) return false;
    return obj.find('.videoChat > object');
}

DOMChat.prototype.closeVideoChat = function(jid){
    if(!this.__hasObj(jid))return false;
	
    try{
        var obj = this.getVideoObject(jid);
        if(obj && obj.length > 0 && obj.get(0)){
            closeVideoChat(obj.get(0))
            closeVideoChatWSound(obj.get(0))
        }
    }catch(e){
        if(window.console) console.log(e);
        return false;
    }
	
    //Minimize video chat before closing
    if(!this.isVideoChatMinimized(jid)){
        this.minimizeVideoChat(jid)
        this.showVideoChatPanel(jid);
    }
	
    return true;
}

DOMChat.prototype.showVideoChatPanel = function(jid){
    if(!this.__hasObj(jid))return false;

    try{
        this.getChat(jid).find('a.videoReqSound,a.videoReq').addClass('active');
	}catch(e){if(window.console) console.log(e);return false;}

    return true;
}

DOMChat.prototype.hideVideoChatPanel = function(jid){
    if(!this.__hasObj(jid))return false;

    try{
        this.getChat(jid).find('a.videoReqSound,a.videoReq').removeClass('active');
    }catch(e){
        if(window.console) console.log(e);
        return false;
    }

    return true;
}

DOMChat.prototype.displayTypingMessage = function(jid, show){
    if(!this.__hasObj(jid))return false;

    try{
        var obj = this.getChat(jid).find('h4.name');
        if(show) obj.addClass('typing'); else obj.removeClass('typing');
    }catch(e){
        if(window.console) console.log(e);
        return false;
    }

    return true;
}

DOMChat.prototype.vcToggleButtonVisible = function(jid, bool , sound){
    if(!this.__hasObj(jid))return false;
    if(sound == undefined || sound == false || sound != 'sound') bool = !bool;
    var new_obj = this.getChat(jid);

    if(bool){
        new_obj.find('a.videoReqSound').addClass('active');
        new_obj.find('a.videoReq').removeClass('active');
    }else{
        new_obj.find('a.videoReqSound').removeClass('active');
        new_obj.find('a.videoReq').addClass('active');
    }
}

//DOMChat.prototype.newChat = function(jid, name, lang, mood) {
DOMChat.prototype.newChat = function(jid, id) {
	
    if(this.__hasObj(jid)) // After clicking 'remove' this call still returns true
        return this.objects[this.__getName(jid)];
	
    var new_obj = this.design.clone().attr("id","chat_" + this.__getName(jid));
	
    //Clear internal suggestions.
    new_obj.find(".newmsg").attr("suggestion", "");
    new_obj.find(".newmsg").attr("suid", "0");
	
    var name_tag = this.__getName(jid);
    this.container.append( new_obj );
	
    var DMCClone = this;
	
    /*
	 * ADDING HANDLERS
	 */

    // Minimize/Maximize the window
    new_obj.find('li.minimize').click( function(){
        if(DMCClone.isMinimized(jid)){
            DMCClone.maximizeChat(jid, true);//DMCClone.maximizeChat(jid, true);
        }
        else{
            DMCClone.closeVideoChat(jid);
            DMCClone.minimizeChat(jid);
			
            new_obj.find('.myLangs').attr('class','myLangs inactive'); //Close the language menu
            new_obj.find('.selectMood').attr('class','selectMood inactive');//Close the mood menu
        }
			
        return false;
    });

    new_obj.find('h4.name').click( function(){
        if(DMCClone.isMinimized(jid)){
            DMCClone.maximizeChat(jid, true);//DMCClone.maximizeChat(jid, true);
        }

        return false;
    });

    // Minimize/Maximize the video chat
    new_obj.find('a.videoReq').click( function(){
        if(DMCClone.isMinimized(jid)) return false;
        var fobj = DMCClone.getVideoObject(jid);

        if(DMCClone.isVideoChatMinimized(jid)){
            DMCClone.toggleVideoChat(jid);
            DMCClone.vcToggleButtonVisible(jid,true,'video')
            try{
                openVideoChat(fobj.get(0));
                if(DMCClone.getSessionId(jid)) VideoChat.sendRequest(jid,'video');//sendMessage(jid,"", "");
            }catch(e){if(window.console) console.log(e)}
        }else{
            DMCClone.toggleVideoChat(jid, true);
            DMCClone.showVideoChatPanel(jid);
            try {closeVideoChat(fobj.get(0))}catch(e){if(window.console) console.log(e)}
        }
        return false;
    });

    // Minimize/Maximize the video chat with sound
    new_obj.find('a.videoReqSound').click( function(){
        if(DMCClone.isMinimized(jid)) return false;

        var fobj = DMCClone.getVideoObject(jid);
		
        if(DMCClone.isVideoChatMinimized(jid)){
            DMCClone.toggleVideoChat(jid);
            DMCClone.vcToggleButtonVisible(jid,true,'sound')
            try{
                openVideoChatWSound(fobj.get(0));
                if(DMCClone.getSessionId(jid)) VideoChat.sendRequest(jid,'sound');
            }catch(e){
                if(window.console) console.log(e)
                    }
        }else{
            DMCClone.toggleVideoChat(jid, true);
            try{
                closeVideoChatWSound(fobj.get(0));
            }catch(e){
                if(window.console) console.log(e)
                    }
            DMCClone.showVideoChatPanel(jid);
        }

        return false;
    });

    // Close the window
    new_obj.find('li.close').click( function(){
        $(document).trigger('chat_ended',jid);
        return false;
    });

    new_obj.find('textarea.newmsg').focus( function(e){
        new_obj.find('.allTopics').attr('class','allTopics inactive');
    })
	
    //Set the MAXLENGTH of the textarea
    new_obj.find('textarea.newmsg').keypress( function(e){
        var exclude_list = {
            32:'',
            9:''
        };
        //If delete or backspace, return true
        if(e.keyCode > 0 && e.keyCode <= 46 && !(e.keyCode in exclude_list))
            return true;
		
        return ($(this).val().length <= $(this).attr('maxlength'));
    });
	
    // Send a new message
    new_obj.find('textarea.newmsg').keyup( function(e){
        var the_sed_obj = $('#chat_'+name_tag.css_esc()+ " .suggestSentences");
        var myinfo = DMCClone.getMyInfo(jid);
        var painfo = DMCClone.getInfo(jid);
		
        //if the UP key is pressed and box is not in sameLang mode, select the suggestion
        if(e.keyCode == 38 && DMCClone.getMode(jid) != 'sameLang'){
            var lis = new_obj.find('.suggestSentences li');
            if(lis.length > 0 )	$(lis[0]).addClass('sugg').find('a').focus();
            return false;
        }
		
        if(e.keyCode == 13){ // if ENTER is pressed
			
            if($.trim($(this).val()) == 0 || $.trim($(this).val()).length > $(this).attr('maxlength')){ //Dont send a message if empty or too large
                $(this).val($.trim($(this).val()))
                return false;
            }
			
            // Replace all newline chars and trim the string
            var val = $(this).val().replace(/\n/g,'').trim().htmlentities();
            $(this).val(val);
			
            var t = {
                msg : val
            };
			
            if(myinfo.lang == painfo.lang) { //language is same
                $(document).trigger('message_send', [jid, t] );
                $(this).val('');
                the_sed_obj.hide();
                return true;
            }
			
            /*
             * Check if the message entered is actually in the suggestions listed.
             * If yes, put the suggestion in the .newmsg box, so it can be picked later
             */
            var as = the_sed_obj.find('a');
						
            for(var i=0; i < as.length ; i++)
            {
                if($(as[i]).text().trim() == val)
                {
                    $(this).attr('suggestion',val);
                    break;
                }
            }
						
            /**
             * IF THE SUGGESTION HAS A #1# THEN CHECK IF THE VARIABLE
             * HAS BEEN FILLED
             * IF YES, THE SUGGESTION IS VALID
             * IF MORE DATA IS ADDED THE SUGGESTION SHOULD BE CLEARED
             * IF NO, DONT SEND THE DATA
             * IF THE VARIABLE IS DELETED, THE SUGGESTION SHOULD BE CLEARED
             */
			
            if($(this).attr('suggestion') !== '')
            { // suggestion is selected
								
                t.suggestion = $(this).attr('suggestion').trim();
                t.rootid = $(this).attr('rootid').trim();
                t.relatedid = $(this).attr('relatedid').trim();
                		
                //Now check if the suggestion had parameters
                var temp = t.suggestion.split(ChatConfig.SUGGEST_PLACEHOLDER_PATTERN);
				
                if(temp.length > 1)
                {
                    var replacement_words = new Array();
                    var wc = 0;
                    var no_of_words = Math.ceil(temp.length/2);
					
                    if(temp[temp.length - 1] == "")
                        temp.length--;
					
                    for(var k=0; k < no_of_words; k++)
                    {
                        wc += temp[k].wordCount();
                        replacement_words[k] = val.getWordAt(wc);
                    }
					
                    for(var k in replacement_words)
                    {
                        var regex = ChatConfig.SUGGEST_PLACEHOLDER_PATTERN;
                        if(regex.test(replacement_words[k]))
                            return false;
                    }

                    $(this).val('');
                    the_sed_obj.hide();
                    DMCClone.clearStoredSuggestion(jid);
                    $(document).trigger('message_send', [jid,t]);
                    return true;
                }
				
                if(val === t.suggestion) { //suggestion was selected but not modified
                    $(document).trigger('message_send', [jid, t] );
                    $(this).val('');
                    the_sed_obj.hide();
                    DMCClone.clearStoredSuggestion(jid);
                    return true;
                }
            }
			
            $(document).trigger('message_send', [jid, t] );
            $(this).val('');
            the_sed_obj.hide();
            return;
        }
		
        //$(this).attr('suggestion','');
		
        if(e.keyCode == 8) return false; //back button hit
        if($.trim(this.value) == 0) return false;

        if(!ChatDetect.isTimerSet(jid))
            ChatDetect.sendTypingMessage(jid, true);

        ChatDetect.setTimer(jid);

        if(myinfo.lang != painfo.lang)
        {
            if(this.value.length <= 5 || e.keyCode == 32){ //First 5 chars send a request
                var st_obj = new SE(this.value, myinfo.lang, painfo.lang, 4, new_obj, the_sed_obj, $(this));
                return;
            }
        }
    });

    //On focus, close the mood and language popup
    new_obj.find('textarea.newmsg').focus(function(){
        new_obj.find('.myLangs, .selectMood, .allTopics').removeClass('active').addClass('inactive');
    })

    //Popup the language selection box
    new_obj.find('.language > a').click( function(e){
		
        var obj = new_obj.find('.myLangs');
        if(obj.hasClass('active'))
            obj.attr('class','myLangs inactive');
        else{
            obj.attr('class','myLangs active');
            new_obj.find('.selectMood').attr('class','selectMood inactive');//Close the mood menu
        }

        return false;
    });
	
    //Select a language from the selection
    new_obj.find('.myLangs a').click( function(e){
        new_obj.find('.myLangs').attr('class','myLangs inactive');

        var lang = $(this).attr('lang');
        var lang_full = $(this).text();
        new_obj.find('.language > a').attr('lang',lang).text(lang_full);

        DMCClone.setMyLanguage(jid,lang);
        var info = DMCClone.getMyInfo(jid);

        $(document).trigger('status_changed',[jid, info]);
        return false;
    });
	
    //Popup the mood selection box
    new_obj.find('.mood > a').click( function(e){
        var obj = new_obj.find('.selectMood');
        if(obj.hasClass('active'))
            obj.attr('class','selectMood inactive');
        else{
            new_obj.find('.myLangs').attr('class','myLangs inactive');//Close the language menu
            obj.attr('class','selectMood active');
        }

        return false;
    });
	
    //Select a mood and update the UI
    new_obj.find('.selectMood a').click( function(e){
        new_obj.find('.selectMood').attr('class','selectMood inactive');
		
        var mood = $(this).attr('title').toLowerCase();
        new_obj.find('.mood > a').text(mood);
		
        DMCClone.setMyMood(jid,mood);
        var info = DMCClone.getMyInfo(jid);
		
        $(document).trigger('status_changed',[jid, info]);
        return false;
    });
	
    /*
	 * ----------
	 * TOPICS
	 * ----------
	 */
    //On initialize, assign close events to the chat topics. Also assign them as they are being added.
    /*new_obj.find('.chatTopic li a.close').click( function(e){
		$(this).parent().remove();
	});*/
	
    // Show/hide the topics box
    new_obj.find('.showAllTopic').click( function(e){
        var obj = new_obj.find('.allTopics');
		
        if(obj.hasClass('active'))
            obj.attr('class','allTopics inactive');
        else
            obj.attr('class','allTopics active');

        return false;
    });
	
    // Select a topic
    new_obj.find('.allTopics li a').click( function(e){
        //better to clone a hidden li. This makes making HTML changes easier.
        var obj = new_obj.find('.chatTopic');
        var count = obj.children().length;
		
        if( count < 5) //MAX 5 items
        {
            obj.append('<li><span>'+$(this).text()+'</span><a title="'+ChatMessages.close_topic_title+'" href="#" class="close">Close</a></li>');
			
            $(obj.children()[count]).find('a.close').click(function(e){
				
                var val = $(this).parent().children('span').text();
                $(this).parent().remove();
				
		var objs = new_obj.find('.allTopics li a').filter(function(index){return ($(this).text() == val)});
                objs.parent().show();
            });
			
            $(this).parent().hide();
        }

        return false;
    });
	
    /*
	 * ----------
	 * BOTTOM BAR
	 * ----------
	 */
    //Show/Hide the bottom bar
    new_obj.find('a.expand').click(function(){
        var obj = new_obj.find('.myInfo');
        obj.attr('class','myInfo '+((obj.hasClass('active'))?'inactive':'active'));
        return false;
    });
	
    name = this.__getName(jid);
    this.objects[name] = new_obj;
    this.infos[name] = new Object();
	
    return new_obj;
}