//
/**
 * xChat Application
 *
 * @author    
 * @copyright (c) 
 * @date      
 * @version   $Id$
 * @last changes
 *
 * 
 * @license xchat.js is licensed under the terms of the Open Source
 * LGPL 3.0 license. Commercial use is permitted to the extent that the 
 * code/component(s) do NOT become part of another Open Source or Commercially
 * licensed development library or toolkit without explicit permission.
 * 
 * License details: http://www.gnu.org/licenses/lgpl.html
 */
 
// Window and Panels

function xChat () {
	
	this.xchatwinobj = false;
	this.last_sid = false;//319663;
	this.ctrChat = {};
	this.pollHomeInterval = (1000*55); //45?
	this.pollBGChatInterval = (1000*10);
	this.isVisible = false;
	this.windowHeight = 600;
	this.windowWidth = 800;
	
	// ------------------------------------------------------------------------------------------
	// init the chat window
	// ------------------------------------------------------------------------------------------
	
	this.init = function(bt) {
		if(!this.xchatwinobj) {
		
			var d = {
				title:$L('Chat'),
				animEl: bt ? bt.id : false,
				modal: true,
				minWidth:300,
				width:this.windowWidth,
				height:this.windowHeight,
				layout: 'border',
				stateful:false,
				shadow:true,
				shadowOffset:8,
				shim:false,	
				closable:true,
				closeAction:'hide',
				maximizable:true,
				id:'xchatwin',
				listeners: {
					hide: {scope:this, fn: function(tp,t) {
						for(k in this.ctrChat) {
							Chat.UpdateUserInFo(running_user_sid,'offline',k);
						}
						this.isVisible = false;
					}},
					maximize: {scope:this, fn: function(tp,t) {
						// scrollTo 0,0 cause window is going to be restored beforehide (otherwise we can´t scroll on the page) 
						// and the window should be on same place of closing / restoring 
						window.scrollTo(0,0);
					}},
					beforeshow: {scope:this, fn: function(tp,t) {
						window.scrollTo(0,0);				
					}},
					beforehide: {scope:this, fn: function(tp,t) {
						tp.restore();
					}}
				},
				items:[{
					xtype:'xchatwintabpanel',
					id:'xchatwintabpanel',
					listeners: {
						beforeremove: {scope:this, fn: function(tp,t) {
							if(t && t.xtype && t.xtype == 'xchattab') {
								Chat.Livechat.operate(t.sid,'offline');
								this.ctrChat[t.sid] = null;
							}
						}},
						tabchange:{scope:this, fn: function(tp,t) { // save active tab in state
							// load home
							if(t.id == 'xchatwinmaintabpanel') {
								if(this.isVisible == true) Chat.loadHome(false,true);
							} else if(!Chat.ctrChat[t.chatroom_sid]) return false;
							// reset tab title
							if(t
							&& t.xtype
							&& t.xtype == 'xchattab'
							&& t.title != Chat.ctrChat[t.chatroom_sid].title) {
								if(Chat.ctrChat[t.chatroom_sid]
								&& Chat.ctrChat[t.chatroom_sid].unseenMsg) Chat.ctrChat[t.chatroom_sid].unseenMsg=0;
								t.setTitle(Chat.ctrChat[t.chatroom_sid].title);
							}
						}}		
					}
				}],
				cls:'x-local'
			};
			
			this.xchatwinobj = new Ext.Window(d);
			this.xchatwinobj.on("show", function(w) {
					
					// update size and position
					var WHeight = PAGEdom.getWindowHeight();	
					var WWidth = PAGEdom.getWindowWidth();	
					var update_size = false;
					if(this.windowHeight >= (WHeight-50)) {
						this.windowHeight = (WHeight-100);
						var update_size = true;
					}
					if(this.windowWidth >= (WWidth-50)) {
						this.windowWidth = (WWidth-50);
						var update_size = true;
					}					
					if(update_size) {
						w.setSize(this.windowWidth,this.windowHeight);
					}
					
					PHPOS.checkAndSetPosition(w);
					
					// ------------------------------------------------------------------------------------------
					// startup function - load a chatroom
					// ------------------------------------------------------------------------------------------					
					if(typeof this.afterwinshown == 'function') {
						this.afterwinshown.defer(100,this,this.afterwinshownArgs);
						this.afterwinshownArgs = [];
						this.afterwinshown = false;
					}
					this.loadHome.defer(this.pollHomeInterval,this,[true,true]);
					this.isVisible = true;
				},this,{delay:50}
			); 
		}
		if(bt && 1==2) this.xchatwinobj.show.defer(50, this.xchatwinobj,[bt]); // && bt.id
		else this.xchatwinobj.show.defer(50, this.xchatwinobj);			
		
		
		
		/*Ext.EventManager.on(window, 'unload', function() {
			var win = Ext.getCmp('xchatwin');
			win.close();
			alert('unload');
			
		});  */
	}
	
	// ------------------------------------------------------------------------------------------
	// reload user home, maybe this shoud be done every x-min?
	// ------------------------------------------------------------------------------------------
	
	this.loadHome = function(poll,bg) {
		if(!Ext.get('xchatwinmaintabpanel')) return false;
		if(poll) {
			this.loadHome.defer(Chat.pollHomeInterval,Chat,[true,true]); 
		} 
		if((typeof bg == 'undefined') || (!bg)) Ext.get('xchatwinmaintabpanel').mask($L('Loading...'), 'x-mask-loading');
		var xchatwinmaintabpanel = Ext.getCmp('xchatwinmaintabpanelview');
		var store = xchatwinmaintabpanel.getStore();
		if(store) {
			store.reload();
		}
		var xchatwinmaintabpanelusergrid = Ext.getCmp('xchatwinmaintabpanelusergrid');
		if(xchatwinmaintabpanelusergrid && typeof xchatwinmaintabpanelusergrid.reload == 'function') {
			xchatwinmaintabpanelusergrid.reload();
		}		
	}	

	this.getTimer = function(time) {
		  secondsPerMinute = 60;
		  secondsPerHour = secondsPerMinute * 60;
		  var hours = Math.floor(time / secondsPerHour);
		  var remainingTime = time - hours * secondsPerHour;
		  var minutes = Math.floor(remainingTime / secondsPerMinute);
		  var seconds = remainingTime - minutes * secondsPerMinute;
		  var formattedTime = '';
		  formattedTime += hours + ':';
		  formattedTime += minutes < 10 ? '0' + minutes + ':' : minutes + ':';
		  formattedTime += seconds < 10 ? '0' + seconds : seconds;
		  return formattedTime;
	}

	// ------------------------------------------------------------------------------------------
	// get the chat conf - needs to run for every chat
	// handles opening of chattab
	// ------------------------------------------------------------------------------------------	
	this.getConf = function(title,sid,iconCls,bParams,addConf) {

		if(Ext.get('xchatwin') && Ext.get('xchatwin').isMasked()) {
			Ext.get('xchatwin').mask($L('Loading...'), 'x-mask-loading');
		} else Ext.get('xchatwinmaintabpanel').mask($L('Loading...'), 'x-mask-loading');
		
		var xchatwinmaintabpanel = Ext.getCmp('xchatwinmaintabpanelview');
		var params = {chatroom:sid,chat_operation:'getconf'};
		Ext.Ajax.request({
				waitMsgTarget:false,//this.id,
				url: '/local/tools/xchat/xform.php',
				method: 'POST', 
				scope:this,
				params: params,
				opt:{
					title:title,
					sid:sid,
					iconCls:iconCls,
					bParams:bParams
				},
				failure:function(response,options){

				},
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);
					if(!Chat.ctrChat[options.opt.sid]) Chat.ctrChat[options.opt.sid] = {};
					if(responseData && responseData.conf) {
						Chat.ctrChat[options.opt.sid].conf = responseData.conf;
						if((!Chat.ctrChat[options.opt.sid].conf.flag_open)) {
							// chat is gone...
							Ext.Msg.show({
								 title:'Chat'
								,msg: 'Dieser Chat wurde geschlossen und steht nicht mehr zur Verfügung.'
								,icon:Ext.Msg.INFO
								,buttons:Ext.Msg.OK
								,minWidth:350
								,maxWidth:400			
								,scope:this
							});	
							Chat.loadHome();
						} else if(Chat.ctrChat[options.opt.sid].conf.flag_open == 'n'
						&& Chat.ctrChat[options.opt.sid].conf.can_open == true) {
							Chat.operate(options.opt.sid,'open',{
								mask:'xchatwinmaintabpanel',
								question:'Der Chat ist noch geschlossen, soll er jetzt geöffnet werden?',
								callback:function(title,sid,iconCls,bParams,addConf) {
									Chat.ctrChat[sid].conf.flag_open = 'y';
									Chat.openChatTab(title,sid,iconCls,bParams,addConf);
								},
								callback_args:[options.opt.title,options.opt.sid,options.opt.iconCls,options.opt.bParams,options.opt.addConf]
							});
						} else if(Chat.ctrChat[options.opt.sid].conf.flag_open == 'n') {
							Ext.get('xchatwinmaintabpanel').unmask();
							Chat.ctrChat[options.opt.sid] = {};
							Ext.Msg.show({
								 title:'Chat'
								,msg: 'Der Chat ist noch geschlossen... Erst wenn er vom Team geöffnet wurde, ist es möglich hineinzugehen.'
								,icon:Ext.Msg.INFO
								,buttons:Ext.Msg.OK
								,minWidth:350
								,maxWidth:400			
								,scope:this
							});								
						} else {
							Ext.get('xchatwinmaintabpanel').unmask();
							Chat.openChatTab(options.opt.title,options.opt.sid,options.opt.iconCls,options.opt.bParams,options.opt.addConf);	
						}
						
					} else {
						// no conf found!
					}
				}                       
			 }
		);	
	}	

	// ------------------------------------------------------------------------------------------
	// open the chat tab if a conf exists or (re)load conf first 
	// ------------------------------------------------------------------------------------------			
	this.openChatTab = function(title,sid,iconCls,bParams,addConf) {
		
		// init chat, if not initialized
		if((!this.xchatwinobj)
		|| (this.xchatwinobj.hidden == true)) {
			this.afterwinshown = this.openChatTab;
			this.afterwinshownArgs = [title,sid,iconCls,bParams,addConf];
			this.init();
			return false;
		}
		
		// get conf
		if((!this.ctrChat[sid]) || (typeof this.ctrChat[sid].conf != 'object')) {
			this.getConf(title,sid,iconCls,bParams,addConf);
			return false;
		}

		if(typeof bParams != 'object') bParams = {};
		var dParams = {iv:'n'}; 
		bParams = Ext.apply(dParams,bParams);
		
		if(!this.ctrChat[sid]) this.ctrChat[sid] = {};
		// check invisibility		
		if(typeof bParams == 'object' 
		&& bParams.iv 
		&& bParams.iv == 'y') {
			if(typeof this.ctrChat[sid].conf != 'object') this.ctrChat[sid].conf = {};
			this.ctrChat[sid].conf.chatter_flag_status = 'invisible';
			this.ctrChat[sid].conf.can_pm = 0;
			this.ctrChat[sid].conf.can_open = 0;
			this.ctrChat[sid].conf.can_edit = 0;
		}
		
		var title = this.ctrChat[sid].conf.title;
		
		if(!iconCls) iconCls='x-chat-icon';    
		var clock = new Ext.Toolbar.TextItem('');
		var version = new Ext.Toolbar.TextItem(title);
		var timer = new Ext.Toolbar.TextItem('');
		this.ctrChat[sid].opentimer = 0;
		var endtime = new Date();
		var endtime = Date.parseDate(this.ctrChat[sid].conf.end_timestamp, "Y-m-d H:i:s" );
		if(endtime) var end = new Ext.Toolbar.TextItem({id:'endtime'+sid,text:$L('End')+' ' + endtime.format("H:i")});	
		else var end = new Ext.Toolbar.TextItem({id:'endtime'+sid,text:$L('End')+': offen'});	
		this.ctrChat[sid]['tbar_endtimestamp_item'] = end;
		this.ctrChat[sid]['unseenMsg'] = 0;	
		this.ctrChat[sid]['title'] = title;		
		
		var conf = {
        	xtype: 'xchattab',
        	bParams: bParams ? bParams : null,
        	id: 'chat'+sid,
        	sid:sid,
        	chatroom_sid:sid,
            title: title,
            iconCls: iconCls,
            closable:true,
            autoScroll:true,
            layout:'fit',
			bbar: new Ext.StatusBar({
				id: 'chat'+sid+'_chat_status',
				defaultText: '',
				defaultIconCls: 'default-icon',
				iconCls: 'ready-icon',
				items: [
					version,' ',clock, ' ',timer,' ',end,' '
				]
			}),		            
			listeners: {
				afterlayout: {single:true, fn: function(c,l){
						// Add a class to the parent TD of each text item so we can give them
						// some custom inset box styling:
						Ext.fly(clock.getEl().parentNode).addClass('x-status-text-panel');
						Ext.fly(version.getEl().parentNode).addClass('x-status-text-panel');
						Ext.fly(timer.getEl().parentNode).addClass('x-status-text-panel');
						Ext.fly(end.getEl().parentNode).addClass('x-status-text-panel');
						
						// Kick off the clock timer that updates the clock el every second:
						Ext.TaskMgr.start({
							run: function(){
								if(clock.getEl()) Ext.fly(clock.getEl()).update(new Date().format('d.m H:i'));
								else Ext.TaskMgr.stop(this);
							},
							interval: 1000
						});	
						
						// Kick off the timer that updates el every second:
						Ext.TaskMgr.start({
							args:[c],
							run: function(c){
								var taskRunCount = 0;
								if((!c)
								|| (!Chat.ctrChat[c.sid])
								) {
									Ext.TaskMgr.stop(this);
									return;
								}
								if(Chat.ctrChat[c.sid] && Chat.ctrChat[c.sid].opentimer) var taskRunCount = Chat.ctrChat[c.sid].opentimer;
								var time = Chat.getTimer(taskRunCount);
								Ext.fly(timer.getEl()).update(time);
								Chat.ctrChat[c.sid].opentimer++;
							},
							interval: 1000
						});							
					}
				}					
			}					            
        };

		if(addConf) {
			Ext.apply(conf,addConf); 
		}	
		
		var tab = Ext.getCmp('chat'+sid);
        if(!tab) var tab =  Ext.getCmp('xchatwintabpanel').add(conf); //.show()
        
		tab.doLayout();	
		tab.show();
        
        return tab;		
	}

	// ------------------------------------------------------------------------------------------
	// the main chat loading function, reload the chat every sec if its the active chat item
	// in background only every 15sec
	// maybe, it is important to control this function, so it never fails or to restart it, if it
	// fails
	// ------------------------------------------------------------------------------------------		
	this.testIdx=0; 
	this.loadChat = function(v,chatroom_sid,last_sid) {
		
		// check if tab exists
		var chattab = Ext.getCmp('chat'+chatroom_sid);
		if(!chattab) return false;
		if((!v) || (!v.getStore())) return false;
		var params = {chatroom:chatroom_sid,last_sid:last_sid};
		//if(this.testIdx == 15) return;
		
		// no sleep process on chats in background, just load your stuff
		var tabpanel = Ext.getCmp('xchatwintabpanel');
		var activeTab = tabpanel.getActiveTab();
		params.nosleep = 'on'; // load chatitems without sleeping process
		if(activeTab) {
			switch(activeTab.xtype) {
				case'xchattab':
					if(activeTab.id == v.baseId) {	
						params.nosleep = 'of'; // load chatitems without sleeping process
					}
					break;
			}
		}

		Ext.Ajax.request({   //Specify options (note success/failure below that
				//waitMsg: 'loading...',
				waitMsgTarget:false,//this.id,
				url: '/local/tools/xchat/xlivechat.php',
				method: 'POST', 
				v:v,
				scope:this,
				params: params,
				failure:function(response,options){
					var v = options.v;
					var chatroom_sid = options.params.chatroom;
					// slow down chats in background
					var tabpanel = Ext.getCmp('xchatwintabpanel');
					var activeTab = tabpanel.getActiveTab();
					var interval = 15000; // chat tab in background
					if(activeTab) {
						switch(activeTab.xtype) {
							case'xchattab':
								if(activeTab.id == v.baseId) {	
									var interval = 1000; // active chat tab
								}
								break;
						}
					}
					Chat.loadChat.defer(interval,Chat,[v,chatroom_sid,v.last_sid]); // Chat.last_sid for testing
					Chat.testIdx++;	
				},
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
					if(responseData && responseData.success === false) {
						var chatroom_sid = options.params.chatroom;
						var chattab = Ext.getCmp('chat'+chatroom_sid+'');
						if(chattab) {
							var xchatwintabpanel= Ext.getCmp('xchatwintabpanel');
							xchatwintabpanel.remove('chat'+chatroom_sid);
							var endMsg = 'Der Chat wurde beendet.';
							if(responseData.errorMsg && responseData.errorMsg.length>0) var endMsg = responseData.errorMsg;
							Ext.Msg.show({
								 title:'Chatende'
								,msg: endMsg
								,icon:Ext.Msg.INFO
								,buttons:Ext.Msg.OK
								,minWidth:350
								,maxWidth:400			
								,scope:this
							});								
						}						
						return;
					}
					var v = options.v;
					if(!v) return false;
					var chatroom_sid = options.params.chatroom;
					v.last_sid = responseData.saved_chat_sid;
					var store = v.getStore();
					if(!store) return false;
					var jump_id = false;
					// add data to store
					// doing my own request, cause order of automatic insert was wrong
					if(responseData.records && responseData.records.length > 0) {
						for(ri=0;ri<responseData.records.length;ri++) {
							if(responseData.records[ri]['html']
							&& responseData.records[ri]['html'].indexOf('var msid') > 0) {
								// sometimes js is stored directly - so we need to eval this content. hope, this will work in all browsers...
								try {
									eval(responseData.records[ri]['html']);
								} catch(e) {
									// evaluating failed
									// if(typeof console == 'object') console.log('x loadChat success found JS-HTML EVAL FAILED!: %o',responseData.records[ri]['html']);
								}
							} else {
								var rec = new store.recordType({
									newRecord:true
								});
								rec.fields.each(function(f) {
									rec.data[f.name] = responseData.records[ri][f.name] || null;
								});	
								rec.id=responseData.records[ri]['id'];
								rec.commit();
								store.add(rec);	
								var jump_id = rec.id;
							}
						}
					}
					
					if(jump_id) Chat.Livechat.jump(jump_id,chatroom_sid);
					
					// slow down chats in background
					var tabpanel = Ext.getCmp('xchatwintabpanel');
					var activeTab = tabpanel.getActiveTab();
					var interval = Chat.pollBGChatInterval; // chat tab in background
					if(activeTab) {
						switch(activeTab.xtype) {
							case'xchattab':
								if(activeTab.id == v.baseId) {	
									var interval = 100; // active chat tab
								}
								break;
						}
					}
		
					Chat.loadChat.defer(interval,Chat,[v,chatroom_sid,v.last_sid]); // Chat.last_sid for testing
					Chat.testIdx++;					
					
				}                       
			 }
		);	
	}
	
	// ------------------------------------------------------------------------------------------
	// pollChatter every 15secs, this is a check, every user, which chatter record is out of time
	// (1 min) will be kicked
	// ------------------------------------------------------------------------------------------	
	this.pollChatter = function(v,chatroom_sid) {

		// check if tab exists
		var chattab = Ext.getCmp('chat'+chatroom_sid);
		if(!chattab) return false;
		if((!v) || (!v.getStore())) return false;
		var params = {chatroom:chatroom_sid,poll:'user',chat_operation:'checkuser'};

		Ext.Ajax.request({
				waitMsgTarget:false,
				url: '/local/tools/xchat/xform.php',
				method: 'POST', 
				v:v,
				scope:this,
				params: params,
				failure:function(response,options){
					var v = options.v;
					var chatroom_sid = options.params.chatroom;
					var interval = 15000; // chat tab in background
					Chat.pollChatter.defer(interval,Chat,[v,chatroom_sid]);
					Chat.testIdx++;	
				},
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);
					var v = options.v;
					if(!v) return false;
					var chatroom_sid = options.params.chatroom;
					v.last_sid = responseData.saved_chat_sid;
					var store = v.getStore();
					if(!store) return false;
					
					// add data to store
					// doing my own request, cause order of automatic insert was wrong
					if(responseData.records && responseData.records.length > 0) {
						for(ri=0;ri<responseData.records.length;ri++) {

						}
					}
					
					// get all users in the store, if it is a writing user everything is fine, else flag him as maybe gone
					// hm, this is bullshit... funzt, muss aber auch in den load der chatter rein...
					/*var g = Ext.getCmp('chat'+chatroom_sid+'_chatter');
					var num_records = g.store.getTotalCount();
					for(gidx=0;gidx<num_records;gidx++) {
						var record = g.store.getAt(gidx);
						if(!record.data['user_sid']) continue;
						if(record.data['user_sid'].length == 0 || record.data['user_sid'] == 'alladvisors') continue;
						var writer = false;
						for(widx=0;widx<responseData.writing_users.length;widx++) {
							if(responseData.writing_users[widx]['chatter_user_sid'] == record.data['user_sid']) {
								var writer = true;
							} 
						}
						if(!writer) {
							//record.set('profillink','<span class="disabled">'+record.data.profillink+'</span>');
							//record.commit();
							this.markChatterCell(chatroom_sid,g,gidx,true);
						} 	
					}*/
					
					var interval = 15000; // chat tab in background		
					Chat.pollChatter.defer(interval,Chat,[v,chatroom_sid]); // Chat.last_sid for testing
					Chat.testIdx++;					
					
				}                       
			 }
		);	
	}
	
	// mark these chatters as dis- or enabled
	this.markChatterCell = function(chatroom_sid,g,row,mark) {
		var col = 1;
		if(g.use_csm) var col = 2;
		var col = g.colModel.findColumnIndex('profillink');
		var view = g.getView();
		if(view) {
			var  cell = view.getCell(row,col);
			var xcell = Ext.get(cell);
			if(mark) {
				xcell.addClass('disabled');
				xcell.setOpacity(.5);
			} else {
				xcell.removeClass('disabled');
				xcell.setOpacity(1);
			}
		}
	}

	// ------------------------------------------------------------------------------------------
	// UpdateUserInFo, mostly called via livechat
	// ------------------------------------------------------------------------------------------		
	this.UpdateUserInFo = function(user_sid,status,sid) {
		
		if(!user_sid) var user_sid = running_user_sid;
		
		switch(status) {
			//default:
			case"reload":
				var chattergrid = Ext.getCmp('chat'+sid+'_chatter');
				chattergrid.reload();
				break;
			case"online":
				var chattergrid = Ext.getCmp('chat'+sid+'_chatter');
				chattergrid.reload();				
				break;
			case"invisible":
			
				break;
			case"kicked":
			case"banned":
			case"offline":
				if(user_sid == running_user_sid) {
					// stop any request?
					// close chatwindow
					var chattab = Ext.getCmp('chat'+sid+'');
					
					if(chattab) {
						var xchatwintabpanel= Ext.getCmp('xchatwintabpanel');
						xchatwintabpanel.remove('chat'+sid);
					}
					var msg=false;
					switch(status) {
						case'kicked':
							var title = 'Kick';
							var msg = 'Du wurdest aus dem Chat geworfen...'; 
							break;
						case'banned':
							var title = 'Ban';	
							var msg = 'Du wurdest aus dem Chat verbannt...'; 
					}
					if(msg) {
						Ext.Msg.show({
							 title:title
							,msg: msg
							,icon:Ext.Msg.INFO
							,buttons:Ext.Msg.OK
							,minWidth:350
							,maxWidth:400			
							,scope:this
						});	
					}
				} else {
					var chattergrid = Ext.getCmp('chat'+sid+'_chatter');
					chattergrid.reload();	
				}
				break;		
		}
	}
	

	// ------------------------------------------------------------------------------------------
	// It would be nice to control any Ajax Request...
	// ------------------------------------------------------------------------------------------			
	this.controlAjaxRequests = function() {
		//Ext.lib.Ajax._queue
		//DebugDump(Ext.lib.Ajax._queue,'Ext.lib.Ajax._queue');
	}
	this.checkAjaxRequest = function() { // donno
		DebugDump(Ext.Ajax,'Ext.Ajax');
		DebugDump(Ext.Ajax.getQueue(),'Ext.Ajax.getQueue');
		DebugDump(Ext.lib.Ajax,'Ext.lib.Ajax');
		DebugDump(Ext.lib.Ajax._queue,'Ext.lib.Ajax._queue');
		DebugDump(Ext.lib.Ajax._activeRequests,'Ext.lib.Ajax._activeRequests');	
	}

	// ------------------------------------------------------------------------------------------
	// Kick and Ban - should be renamed to "Chatuserfunctions"
	// ------------------------------------------------------------------------------------------		
	this.kick = function(tid,context,ask){
		var g = Ext.getCmp(tid);
		var selModel = g.getSelectionModel();
		var m = selModel.getSelections();
		
		var sid = false;
		for(var i = 0, len = m.length; i < len; i++){ 
			var user_sid = m[i].json['user_sid'];	
			var nickname = m[i].json['nickname'];	
		}	
		
		// show if there are items selected
		if(!selModel.hasSelection()) {
			Ext.MessageBox.show({
				animEl:this.id,
				buttons:Ext.Msg.OK,
				skope:this,
				icon:Ext.MessageBox.ERROR,
				modal:false,
				msg:'Es ist niemnd ausgewählt...',
				title:'Warning',
				minWidth:250,
				maxWidth:300
			});					
			return false;
		}
		
		switch(context) {
			case'kicked':
				var title = 'Kick';
			case'banned':
				var title = 'Ban';				
		}
		
		var c = selModel.getCount();
		// aks user, if he is really shure
		Ext.Msg.show({
			 title:title
			,msg: ('Wirklich '+nickname+ask)
			,icon:Ext.Msg.QUESTION
			,buttons:Ext.Msg.YESNO
			,minWidth:350
			,maxWidth:400			
			,scope:this
			,fn:function(response) {
				if('yes' !== response) {
					return;
				}
				this.doKick(tid,context,{user_sid:user_sid,nickname:nickname,g:g,selModel:selModel,m:m});
			}
		});	
	}


	this.doKick = function(tid,context,p) {

		for(var i = 0, len = p.m.length; i < len; i++){ 			
			var sid = p.m[i].json['sid'];
			if(sid) { 
				p.g.store.remove(p.m[i]);
				p.selModel.selectRow(0);
			}
		}
		
		var params = {chatroom:p.g.bParams.chatroom,noxml:1,user_operation_sid:p.user_sid,chat_operation:context};

		Ext.Ajax.request({
				waitMsg: 'kick...',
				waitMsgTarget:'chat'+p.g.bParams.chatroom+'_chatter',
				url: '/local/tools/xchat/xform.php',
				method: 'POST', 
				scope:this,
				params: params,//end params
				failure:function(response,options){
					// Ext.MessageBox.alert('Warning','Cound not able to go offline, please contact the administrator.');
				},    
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
				}                                     
			 }
		); 
		
	}

	// ------------------------------------------------------------------------------------------
	// Main Operation Function, use only this functions for any operation
	// ------------------------------------------------------------------------------------------		
	this.operate = function(chatroom_sid,context,p){
		
		if(p.question) {
			var title = $L('Hinweis')
			// aks user, if he is really shure
			Ext.Msg.show({
				 title:title
				,msg: p.question
				,icon:Ext.Msg.QUESTION
				,buttons:Ext.Msg.YESNO
				,minWidth:350
				,maxWidth:400			
				,scope:this
				,fn:function(response) {
					if('yes' !== response) {
						return;
					}
					this.doOperate(chatroom_sid,context,p);
				}
			});	
		} else this.doOperate(chatroom_sid,context,p);
	}


	this.doOperate = function(chatroom_sid,context,p) {

		if(p.mask) {
			var chattab = Ext.get(p.mask);
			if(!p.waitMsg) p.waitMsg = $L('Loading...');
			if(chattab) chattab.mask(p.waitMsg, 'x-mask-loading');
		}
		
		var params = {chatroom:chatroom_sid,chat_operation:context};
		if(typeof p.params == 'object') var params = Ext.apply(params,p.params);
		
		Ext.Ajax.request({
				url: '/local/tools/xchat/xform.php',
				method: 'POST', 
				p:p,
				chatroom_sid:chatroom_sid,
				scope:this,
				params: params,
				failure:function(response,options){
					// Ext.MessageBox.alert('Warning','Cound not able to go offline, please contact the administrator.');
					var chattab = Ext.get(options.p.mask);
					if(chattab) chattab.unmask();
				},    
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
					if(options.p.mask) {
						var chattab = Ext.get(options.p.mask);
						if(chattab) chattab.unmask();
					}
					if(typeof options.p.callback == 'function') {
						if(typeof options.p.callback_args != 'object') options.p.callback_args = [this,response,options];
						p.callback.defer(100,this,options.p.callback_args);
					}
				}                                     
			 }
		); 
	}	

	// ------------------------------------------------------------------------------------------
	// UpdateChatroom
	// ------------------------------------------------------------------------------------------	
	this.UpdateChatroom = function(chatroom_sid,context) {
		
		switch(context) {
			case'close': // chatroom was closed
				Chat.ctrChat[chatroom_sid] = false;
				Chat.UpdateUserInFo(running_user_sid,'offline',chatroom_sid);
				Ext.Msg.show({
					 title:$L('Chat')
					,msg: 'Der Chat wurde geschlossen'
					,icon:Ext.Msg.INFO
					,buttons:Ext.Msg.OK
					,minWidth:350
					,maxWidth:400			
					,scope:this
					,fn:function(response) {}
				});
				
				this.loadHome();
				break;
		}
	}	

	// ------------------------------------------------------------------------------------------
	// Editor - open ChatEditor
	// ------------------------------------------------------------------------------------------
	this.editor_win_counter=0;
	this.editRecordWindow=function(btn,sid,content_key,baseParams,xtype,conf,wconf) { // title?
		
		var grid;
		if(typeof wconf != 'object') var wconf = {};
		if(typeof conf != 'object') var conf = {};
		if(!content_key || content_key.length == 0) {
			Ext.Msg.alert('Error', 'No content key found');
			return false;
		}
		if(!sid) {
			Ext.Msg.alert('Error', 'No id found');
			return false;
		}
		
		if(!wconf.title || wconf.title.length == 0) {
			if(this.ownerCt && this.ownerCt.title && this.ownerCt.title.length >0) wconf.title = this.ownerCt.title;
			else wconf.title = $L('editor');		
		}

		var h = wconf.edit_window_height ? wconf.edit_window_height : 400;
		var w = wconf.edit_window_width ? wconf.edit_window_width : 700;
		var b = Ext.getBody().getSize();
		var x = (b.width/2) - (w/2);
		var y = (b.height/2) - (h/2);
		
		if(typeof baseParams != 'object') var baseParams = {noxml:'1'};
		else if(baseParams.send_rows && baseParams.grid_id) {
			var grid = Ext.getCmp(baseParams.grid_id);
			if(typeof grid.lastSelectedRows == 'object') { // chatter online panel
				var rows = [];
				for(var lr=0;lr<grid.lastSelectedRows.length;lr++) {
					rows[lr] = grid.lastSelectedRows[lr]['user_sid'];
				}
			}
			baseParams['lastSelectedRows'] = rows.join(',');
		}		
		
		var xtype = 'xphposform';
		if(wconf.editor_win_xtype) xtype = wconf.editor_win_xtype;
		
		var win_id = wconf.id + '_editorwin';
		var state_id = win_id+'_'+content_key;
		win_id += this.editor_win_counter;
		var form_id = wconf.id+'_editorwin_form'+this.editor_win_counter;
		
		var default_conf = {
			xtype:xtype
			,cls:'x-gray-btn'
			,bParams:baseParams
			,id: form_id
			,p_id: form_id
			,editor_win_counter:this.editor_win_counter
			,p_height: h
			,p_width: w					
			,win_id: win_id
			,grid_id: (typeof grid == 'object') ? grid.id : false
			,sid:sid
			,content_key:content_key
			,waitMsgTarget:win_id
		};
		
		if(typeof conf != 'object') var conf = {};
		if(typeof this.editor_conf == 'object') {
			Ext.apply(conf,this.editor_conf);
		}
		Ext.apply(conf,default_conf); 

		var win_conf = {
			 id: win_id
			,form_id: form_id
			,editor_win_counter:this.editor_win_counter
			,modal: true
			,title:wconf.title
			,iconCls: wconf.iconCls ? wconf.iconCls : 'none'
			,width: w
			,height: h
			,stateful:true
			,stateEvents:["resize"]
			,stateId:state_id		
			,plain:true
			,layout:'fit'
			,closable:true
			,border:false
			,maximizable:true	
			,items:conf
			,listeners: {
				maximize: function(w){
					w.center();
				},
				beforestatesave:function(p,state) {
					if(p && p.maximized) return false;
				}
			}					
		};

		var win = new Ext.Window(win_conf);
		win.doLayout();	
		
		win.on("close", this.onCloseEditorWin, this);    
		win.on("show", function(w) {
				// nothing to do right now
			},win,{delay:100}
		); 
		win.show();			
		this.editor_win_counter++;
		
	}

	this.onCloseEditorWin=function(w) {
		var f = Ext.getCmp(w.form_id);
		var values = f.getForm().getValues();
		if(values) {
			if(values['fields[root.ajaxbody.editor][end_timestamp]']) { // update end timestamp
				var sid = values['fields[root.ajaxbody.editor][sid]'];
				var end_timestamp = values['fields[root.ajaxbody.editor][end_timestamp]'];
				if(Chat.ctrChat && Chat.ctrChat[sid]) {
					var tbar_endtimestamp_item = Chat.ctrChat[sid]['tbar_endtimestamp_item'];
					var endEl = tbar_endtimestamp_item.getEl();
					var endtime = new Date();
					var endtime = Date.parseDate(end_timestamp, "Y-m-d H:i:s" );
					endEl.update($L('End')+' ' + endtime.format("d.m H:i"));
				}
			}
		}
		// reload chats
		if(f && f.has_been_submitted) {
			this.loadHome();
		}
		
	}	
}

var Chat = new xChat();

// ------------------------------------------------------------------------------------------
// handle all Livechat functions called via xlivechat
// ------------------------------------------------------------------------------------------
function LiveChat() {
	
	this.init = function() {
		
	}
	
	this.end = function(chatroom_sid) {}
	
	this.jump = function(el_id,chatroom_sid) {
		var el = Ext.get('text_'+el_id);
		if(!el) return false;
		var parent = el.parent('.x-panel-body');
		if(!parent) return false;
		var maxtop = parent.getTop() + parent.getHeight();
		
		// both is working...
		/*if(maxtop && 
		maxtop > 0
		&& el.getTop()
		&& maxtop > (el.getTop()-el.getHeight()-50)) el.scrollIntoView(parent);
		*/
		
		if(maxtop && 
		maxtop > 0
		&& el.getTop()
		&& maxtop > (el.getTop()-el.getHeight()-50)) parent.scroll('down',600000000);		
		
	
		// show unseen messages in tab title
		if(Ext.getCmp('xchatwintabpanel')) var activeTab = Ext.getCmp('xchatwintabpanel').getActiveTab();
		if(activeTab && activeTab.id != 'chat'+chatroom_sid) {
			if(!Chat.ctrChat[chatroom_sid]) return false;
			Chat.ctrChat[chatroom_sid].unseenMsg++;
			if(Ext.getCmp('chat'+chatroom_sid)) {
				Ext.getCmp('chat'+chatroom_sid).setTitle('('+Chat.ctrChat[chatroom_sid].unseenMsg+') ' + Chat.ctrChat[chatroom_sid].title);
			}
		}
		
	}
	
	// ------------------------------------------------------------------------------------------
	// delete a chat message
	// ------------------------------------------------------------------------------------------	
	this.del = function(chatroom_sid,chat_sid,user_sid,flag_type) {
		if(flag_type == 'system-message') return;
		var xchatpanelview = Ext.getCmp('chat'+chatroom_sid+'_chat');
		if(!xchatpanelview) return false;
		var store = xchatpanelview.getStore();
		if(!store) return false;
		var record = store.getById(chat_sid);
		
		if(Chat.ctrChat[chatroom_sid] 
		&& Chat.ctrChat[chatroom_sid].conf 
		&& Chat.ctrChat[chatroom_sid].conf.can_edit) {
			var chatitem = Ext.get('text_'+chat_sid);
			if(chatitem) chatitem.setStyle('text-decoration','line-through');
		} else if(record){
			store.remove(record);		
		}
		
		if(flag_type == 'context') return;
		Chat.operate(chatroom_sid,'delete',{params:{chat_sid:chat_sid}});		
	}
	
	// ------------------------------------------------------------------------------------------
	// donno, if this is in use, hopefully not!
	// ------------------------------------------------------------------------------------------	
	this.UpdateUserInFo = function(chatter_sid,status,chatroom_sid) {
		// possible to check, if a request is allready running?
		// check _queue? and running requests?
		Chat.checkAjaxRequest();
	}

	// ------------------------------------------------------------------------------------------
	// donno, if this is in use, hopefully not!
	// ------------------------------------------------------------------------------------------	
	this.operate=function(sid,op,q) {
		if(q) {
			this.do_operate(sid,op);
		} else this.do_operate(sid,op);
		
	}

	this.do_operate = function(sid,op) {
		var params = {chatroom:sid,chat_operation:op,noxml:1};
		Ext.Ajax.request({   //Specify options (note success/failure below that
				waitMsg: 'going offline...',
				waitMsgTarget:'chat'+sid,
				url: '/local/tools/xchat/xform.php',
				method: 'POST', 
				scope:this,
				params: params,//end params
				failure:function(response,options){
					// Ext.MessageBox.alert('Warning','Cound not able to go offline, please contact the administrator.');
				},//end failure block      
				success:function(response,options){
					var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
				}//end success block                                      
			 }//end request config
		); //end request  				
	}
}

Chat.Livechat = new LiveChat();
Chat.Livechat.init();

//--------------------------------------------------------------------------------------- //
if(typeof Ext == 'object') {

	/*****************************************************
	*/ function __xChatTabPanel() {}
	/******************************************************/
	
	// ------------------------------------------------------------------------------------------
	// load and configure the chat tabpanel
	// ------------------------------------------------------------------------------------------		
	Chat.xChatTabPanel = Ext.extend(Ext.TabPanel, {
		initComponent:function() {

			var clock = new Ext.Toolbar.TextItem('');
			var today = new Ext.Toolbar.TextItem(new Date().format('d.m.Y'));	
			var version = new Ext.Toolbar.TextItem('v0.8b');	
			
			Ext.apply(this, {
				stateful:true,
				region: 'center',
				activeTab: 0,
				defaults:{layout:'fit'},
				resizeTabs:true, // turn on tab resizing
				enableTabScroll:true,
				plugins: new Ext.ux.TabCloseMenu(),
				layoutOnTabChange:true,
				cls:'x-local',				
				items: [{
						id:'xchatwinmaintabpanel',
						xtype:'xchatwinmaintabpanel',
						title: $L('Übersicht'),
						closable:false,
						iconCls: 'x-house-tab',
						bbar: new Ext.Toolbar({
							id: 'xchatwinmaintab_status',
							// These are just the standard toolbar TextItems we created above.  They get
							// custom classes below in the render handler which is what gives them their
							// customized inset appearance.
							// defaults to use when the status is cleared:
							defaultText: '',
							defaultIconCls: 'default-icon',
							text: '',
							iconCls: 'ready-icon',
							items: [{xtype:'tbspacer'},{
									 text: $L('Reload')
									,id: 'xchatwinmaintab_status_reload'
									,icon:'/javascripts/ext/resources/images/slate/grid/refresh.gif'
									,ctCls:'x-local-bt'
									,iconCls:'x-btn-text-icon'
									,handler:function(button) {
										Ext.get('xchatwinmaintabpanel').mask($L('Loading...'), 'x-mask-loading');
										// reload view
										var xchatwinmaintabpanel = Ext.getCmp('xchatwinmaintabpanelview');
										var store = xchatwinmaintabpanel.getStore();
										if(store) {
											store.reload();
										}
										// reload user online
										var xchatwinmaintabpanelusergrid = Ext.getCmp('xchatwinmaintabpanelusergrid');
										if(xchatwinmaintabpanelusergrid && typeof xchatwinmaintabpanelusergrid.reload == 'function') {
											xchatwinmaintabpanelusergrid.reload();
										}										
									}
								},
								{xtype:'tbspacer'},{xtype:'tbspacer'},{xtype:'tbfill'},
								version,' ',today,' ',clock, ' '
							]
						}),							
						listeners: {
							render: {single:true,fn: function(v,e){
									// Add a class to the parent TD of each text item so we can give them
									// some custom inset box styling:
									Ext.fly(clock.getEl().parentNode).addClass('x-status-text-panel');
									Ext.fly(today.getEl().parentNode).addClass('x-status-text-panel');
									Ext.fly(version.getEl().parentNode).addClass('x-status-text-panel');
									// Kick off the clock timer that updates the clock el every second:
									Ext.TaskMgr.start({
										run: function(){
											Ext.fly(clock.getEl()).update(new Date().format('H:i:s'));
										},
										interval: 1000
									});									
								}
							}							
						}					
					}
				]
			}); 
		
			// call parent
			Chat.xChatTabPanel.superclass.initComponent.apply(this, arguments);
		} 
		
	});
	
	// register xtype
	Ext.reg('xchatwintabpanel', Chat.xChatTabPanel);



	/*****************************************************
	*/ function __xChatMainTabPanel() {}
	/******************************************************/	
	// ------------------------------------------------------------------------------------------
	// The Main Tabitem, it contains the view of all available chatrooms
	// ------------------------------------------------------------------------------------------		
	Chat.xChatMainTabPanel = Ext.extend(Ext.Panel, {
		initComponent:function() {
			
			var items = [];
			items[0] = {xtype:'xchatwinmaintabpanelview', // DataView
				region:'center',
				autoScroll:true,
				id:'xchatwinmaintabpanelview',
				emptyText: '<div class="chatAnnouncement">Es wurden keine Chats gefunden</div>',
				listeners: {
					render: {fn:function(v,e){ 
						// donno, Safari ignores autoScroll
						var xchatwinmaintabpanelview = Ext.get('xchatwinmaintabpanelview');
						if(xchatwinmaintabpanelview) {
							var of = xchatwinmaintabpanelview.getStyle('overflow');
							if(of && of != 'auto') xchatwinmaintabpanelview.setStyle('overflow','auto');
						}
						Ext.get('xchatwin').mask($L('Loading...'), 'x-mask-loading');
						var params = {start:0, limit:browserLimit,noxml:'1'};
						v.getStore().load({params:params,callback:function(r,o,s) {
							// no callback for now...
						}});
					}, single:true}      						
				}
			};
			if(typeof running_user_level != 'undefined' && running_user_level >= 125) {

				var userpanel_sm = new Ext.grid.CheckboxSelectionModel({ // Ext.grid.SmartCheckboxSelectionModel
					//singleSelect:true,
					//email:true,
					//saveOnClick:false,
					//header:'<div class="xgrid3hdchecker">'+$L('PM')+'</div>',
					handleMouseDown: function(g, rowIndex, e) {
						if(e.getTarget('a')){
							return false;
						}
						this.constructor.prototype.handleMouseDown.call(this, g, rowIndex, e);
					},
					listeners: {
						rowdeselect: {scope:this,fn: function(sm,rowIndex,r) {
							var xchatwinmaintabpanelusergrid = Ext.getCmp('xchatwinmaintabpanelusergrid');
							xchatwinmaintabpanelusergrid.saveSelection(xchatwinmaintabpanelusergrid.store);
						}},
						rowselect: {scope:this,fn: function(sm,rowIndex,r) {
							var xchatwinmaintabpanelusergrid = Ext.getCmp('xchatwinmaintabpanelusergrid');
							xchatwinmaintabpanelusergrid.saveSelection(xchatwinmaintabpanelusergrid.store);
						}}					
					}
				});

				items[1] = {
					title:$L('User online') +' (nur für Berater)',
					region:'east',
					initialLoadMask:true,
					//frame:true,
					id:'xchatwinmaintabpanelusergrid',
					width: 250,
					minSize: 100,
					minWidth:100,
					split:true,
					xtype:'xphposgrid',
					content_key:'xchatonlineview',
					iconCls:'x-user-ico',
					iconCls:'x-users-tab',
					cls:'x-local x-user-online-grid x-gray-btn',
					//bParams:bParams,
					view: new Ext.grid.GridView({
						autoFill:true,
						forceFit:true,
						deferEmptyText:true,
						emptyText:$L('Niemand da...')
					}),
					use_csm:true,
					sm:userpanel_sm,
					enableHdMenu:false,
					show_page_toolbar:false,
					show_limit:false,
					show_row_expander:false,
					show_filters:false,
					show_search:false,
					lastSelectedRows:[],
					aftermetaloaded:function(g,m) {
						if(g.use_csm) {
							var num_records = g.store.getTotalCount();
							if(num_records > 0) {
								// selection
								if(typeof g.lastSelectedRows == 'object') {
									g.aftermeta_restore_sel = true;
									for(var i=0;i<g.lastSelectedRows.length;i++) {
										var sel_idx = g.store.find('user_sid',g.lastSelectedRows[i].user_sid);
										if(sel_idx >=0) {
											g.getSelectionModel().selectRow(sel_idx,true);
										} 									
									}
									g.aftermeta_restore_sel = false;
								} 
							} 
						}
					},
					saveSelection:function(s,o) {
						var g = Ext.getCmp(s.baseParams.tid);
						if(g.aftermeta_restore_sel) return;
						if(g && g.use_csm) {
							var selModel = g.getSelectionModel();
							var m = selModel.getSelections();
							var sid = false;
							g.lastSelectedRows = [];
							for(var i = 0, len = m.length; i < len; i++){ 
								var user_sid = m[i].json['user_sid'];	
								g.lastSelectedRows[i] = {idx:i,user_sid:user_sid};
							}
						}	
					},
					listeners: {
						afterlayout: {scope:this,single:true,fn: function(grid,layout) {
							grid.loadMask.disable();
							// add listener to store grid selection
							grid.store.addListener('beforeload',grid.saveSelection); 
						}}	
					}					
				};
			}
			
			Ext.apply(this, {
				layout:'border',
				items:items
			}); 
			
			// call parent
			Chat.xChatMainTabPanel.superclass.initComponent.apply(this, arguments);
		}		
	});
	
	// register xtype
	Ext.reg('xchatwinmaintabpanel', Chat.xChatMainTabPanel);

	/*****************************************************
	*/ function __xChatMainTabPanelView() {}
	/******************************************************/	
	// ------------------------------------------------------------------------------------------
	// The view of our main tabitem
	// ------------------------------------------------------------------------------------------	
	Chat.xChatMainTabPanelView = Ext.extend(Ext.DataView, {
		initComponent:function() {

			var chatDataType = [
				{name: 'id'},
				{name: 'html'},
				{name: 'cls'},
				{name: 'start_timestamp_i'},
				{name: 'end_timestamp_i'},
				{name: 'comp_start_timestamp',type:'int'}
			];
		   
            var storeChatAnnouncements = new Ext.data.JsonStore({
                url: '/local/tools/xchat/ajax_get_announcements.php',
                root: 'records',
                fields: chatDataType,
                remoteSort:false,
                sortInfo:{field: "comp_start_timestamp", direction: "ASC"},
                listeners: {
                    'load': {fn:function(s,r,o){ 
                    	//this.view.select(0); 
						if(Ext.get('xchatwin')) Ext.get('xchatwin').unmask();
						if(Ext.get('xchatwinmaintabpanel')) Ext.get('xchatwinmaintabpanel').unmask();
                    }}                  
                },
                baseParams:{noxml:1}
            });
		   
			var resultTpl = new Ext.XTemplate(
				'<tpl for=".">',
				'<div class="chatAnnouncement {cls}">',
					'{html}',
				'</div></tpl>'
			);
		
			Ext.apply(this, {
				tpl: resultTpl,
				itemSelector: 'div.chatAnnouncement',
				store: storeChatAnnouncements,
				//autoScroll:true,
				cls:'x-local chathomeview',
				style:'padding:10px;',
				emptyText:$L('no records found'),
				region:'center'			
			}); 
			
			// call parent
			Chat.xChatMainTabPanelView.superclass.initComponent.apply(this, arguments);
		} 
	});
	
	// register xtype
	Ext.reg('xchatwinmaintabpanelview', Chat.xChatMainTabPanelView);


	
	/*****************************************************
	*/ function _____xChatTab() {}
	/******************************************************/

	// ------------------------------------------------------------------------------------------
	// The chat tabitem
	// ------------------------------------------------------------------------------------------		

	Chat.xChatTab = Ext.extend(Ext.Panel, {
		initComponent:function() {

			if(typeof this.bParams != 'object') this.bParams = {};
			var bParams = {chatroom:this.sid,chatroom_sid:this.sid}; 
			bParams = Ext.apply(this.bParams,bParams);
			
			if(Chat.ctrChat[this.sid].conf.can_pm == 1) {
				var chatterpanel_sm = new Ext.grid.CheckboxSelectionModel({ // Ext.grid.SmartCheckboxSelectionModel
					singleSelect:true,
					//email:true,
					//saveOnClick:false,
					header:'<div class="xgrid3hdchecker">'+$L('PM')+'</div>',
					handleMouseDown: function(g, rowIndex, e) {
						if(e.getTarget('a')){
							return false;
						}
						this.constructor.prototype.handleMouseDown.call(this, g, rowIndex, e);
					},
					listeners: {
						rowselect: {scope:this,fn: function(sm,rowIndex,r) {
							var bbar = sm.grid.getBottomToolbar();
							if(bbar
							&& bbar.items
							&& bbar.items.items) {
								var items = bbar.items.items;
								for(i=0;i<items.length;i++) {
									if(items[i].icon
									&& items[i].icon == "/images/icons/ico_kick.gif") {
										if(r.data.user_sid
										&& r.data.user_sid.length > 0
										&& r.data.user_sid != 'alladvisors'
										&& r.data.user_sid != running_user_sid) items[i].enable();
										else items[i].disable();
									}
									
									if(items[i].icon
									&& items[i].icon == "/images/icons/ico_ban.gif") {
										if(r.data.user_sid
										&& r.data.user_sid.length > 0
										&& r.data.user_sid != 'alladvisors'
										&& r.data.user_sid != running_user_sid) items[i].enable();
										else items[i].disable();
									}									
								}
							}
							if(Ext.getCmp('field_to_nickname'+this.sid)) {
								Ext.getCmp('field_to_nickname'+this.sid).setValue(r.data.nickname);
								Ext.getCmp('field_to_user_sid'+this.sid).setValue(r.data.user_sid);
							}
						}}						
					}
				});
				

				
				var chatterpanel_use_csm = true;
			} else {
				var chatterpanel_sm = new Ext.grid.RowSelectionModel({singleSelect:true});
				var chatterpanel_use_csm = false;
			}
			
			var center_items = [];
			var xchatpanelview = {
				region:'center',
				autoScroll:true,
				items:[{
					xtype:'xchatpanelview',
					last_sid:0,
					bParams:bParams,
					baseId:this.id,
					id:this.id+'_chat',
					cls:'x-chatpanel',
					chatroom_sid:this.chatroom_sid,
					sid:this.sid,
					frame:false,
					border:false				
				}]
			};
			center_items.push(xchatpanelview);
			
			if(Chat.ctrChat[this.sid].conf.chatter_flag_status != 'invisible') {
				var xchatformpanel = {
					initialLoadMask:false,
					height: 100,
					region:'south',
					baseId:this.id,
					id:this.id+'_form',
					chatroom_sid:this.chatroom_sid,
					sid:this.sid,
					bParams:bParams,
					xtype:'xchatformpanel',
					listeners: {
						afterlayout:{single:true,fn:function(){
							// initial set Values of form
							this.getForm().setValues([
								{id:'field_chatroom'+this.sid,value:this.sid,key:'chatroom'},
								{id:'field_chat_operation'+this.sid,value:'insert',key:'chat_operation'}
							]);
						}},
					},
					split:true
				};
				center_items.push(xchatformpanel);
			}
			
	
			
			Ext.apply(this, {
				stateful:true,
				labelAlign: 'left',
				layout:'border',		
				items: [{
					region:'center',
					minSize: 100,
					minWidth:100,
					split:true,
					layout:'border',
					stateful:true,
					id:this.id+'_center',
					items:center_items
				},{
					region:'east',					
					width: 250,
					minSize: 100,
					minWidth:100,
					split:true,	
					collapsible:true,
					header:false,
					collapsed:true,
					collapseMode:'mini',
					cmargins:{left:2,right:2},
					listeners:{
						beforecollapse: {scope:this,  fn: function(tp,t) {
							if(tp.initital_load == true) return true;
							tp.initital_load = true;
							state = Ext.state.Manager.getProvider().get('maintabmainpaneleast');
							if(state && state['collapsed']) { // && 
								// stay collapsed
							} else return false;
						}}				
					},
					stateful:true,
					layout:'border',
					id:this.id+'_east',					
					items:[{
						//title:$L('Chatter'),
						xtype:'xphposgrid',
						content_key:'chatterpanel',
						iconCls:'x-user-ico',
						cls:'x-local x-chattergrid x-gray-btn',
						bParams:bParams,
						view: new Ext.grid.GridView({
							autoFill:true,
							forceFit:true,
							deferEmptyText:true,
							emptyText:$L('Niemand da...')
						}),
						sm:chatterpanel_sm,
						use_csm:chatterpanel_use_csm,
						//csm_conf:{singleSelect:true},
						//initialLoadMask:true,
						enableHdMenu:false,
						show_page_toolbar:false,
						show_limit:false,
						show_row_expander:false,
						show_filters:false,
						show_search:false,
						tbar:new Ext.xChatterPanelTBar({
							chatroom_sid:this.sid,
							items:[{
								xtype: 'tbtext', 
								text: '<img style="" src="/images/spacer.gif" width="1" height="16" />'				
							}]
						}),	
						aftermetaloaded:function(g,m) {
							if(g.use_csm) {
								var num_records = g.store.getTotalCount();
								if(num_records > 1) {
									// selection
									if(typeof g.lastSelectedRow == 'object') {
										var sel_idx = g.store.find('user_sid',g.lastSelectedRow.user_sid);
										if(sel_idx >=0) {
											g.getSelectionModel().selectRow(sel_idx);
										} else g.getSelectionModel().selectRow(0);
									} else {
										var selModel = g.getSelectionModel();
										var m = selModel.getSelections();
										selModel.selectRow(0); // default: select first row		
									}
								} else {
									g.lastSelectedRow = {};
								}
							}
						},	
						iconCls:'x-users-tab',
						region:'center',
						sid:this.sid,
						chatroom_sid:this.sid,
						baseId:this.id,
						id:this.id+'_chatter',
						frame:false,
						border:false,
						saveSelection:function(s,o) {
							var g = Ext.getCmp(s.baseParams.tid);
							if(g && g.use_csm) {
								var selModel = g.getSelectionModel();
								var m = selModel.getSelections();
								var sid = false;
								for(var i = 0, len = m.length; i < len; i++){ 
									var user_sid = m[i].json['user_sid'];	
								}
								g.lastSelectedRow = {idx:i,user_sid:user_sid};
							}
							
						},
						listeners: {
							afterlayout: {scope:this,single:true,fn: function(grid,layout) {
								grid.loadMask.disable();
								var params = {start:0, limit:browserLimit,noxml:'1'};
								var chatpanel = Ext.getCmp(grid.baseId+'_chat');
								
								if((!chatpanel.last_sid) && (Chat.last_sid) && (Chat.last_sid >0)) chatpanel.last_sid = Chat.last_sid; // test case!
								
								// ------------------------------------------------------------------------------------------
								// This is where we the livechat is loaded!
								// ------------------------------------------------------------------------------------------	
								Chat.loadChat.defer(1000,Chat,[chatpanel,grid.sid,chatpanel.last_sid]);
								// ------------------------------------------------------------------------------------------
								// This is the first load for polling the chatter 
								// ------------------------------------------------------------------------------------------									
								Chat.pollChatter.defer(3000,Chat,[chatpanel,grid.sid,chatpanel.last_sid]);
								
								// add listener to store grid selection
								grid.store.addListener('beforeload',grid.saveSelection); 
							}}	
						}
					}]
				}]
			}); 
			
			Chat.xChatTab.superclass.initComponent.apply(this, arguments);
		} 
	});

	// Register New Event Form
	Ext.reg('xchattab', Chat.xChatTab);



	/*****************************************************
	*/ function __xChatFormPanel() {}
	/******************************************************/	
	// ------------------------------------------------------------------------------------------
	// The chat form, type here to chat
	// ------------------------------------------------------------------------------------------	
	
	Chat.xChatFormPanel = Ext.extend(Ext.FormPanel, {
		initComponent:function() {

			Ext.apply(this, {
				url:'/local/tools/xchat/xform.php',
				baseParams:{chatroom_sid:this.sid,noxml:true},
				xtype:'form',
				trackResetOnLoad:false,
				split:true,
				sid:this.sid,
				chatroom_sid:this.chatroom_sid,
				tbar:new Ext.xChatFormPanelTBar({
					chatroom_sid:this.chatroom_sid,
					items:[{
						xtype: 'tbtext', 
						text: '<img style="" src="/images/spacer.gif" width="1" height="16" />'				
					}]
				}),					
				items:[{
					xtype:'textarea',
					enableKeyEvents:true,
					hideLabel:true,
					name: 'chattext_org',
					id: 'field_chattext'+this.sid,
					value:'huhu',
					emptyText:$L('Type here'),
					anchor:'100% 0', //100% 0
					allowBlank:true,
					lastMessages:[],
					listeners: {
						invalid: function(){},
						valid: function(){},
						specialkey: function(f, e){
							/*if(e.getKey() == 13 && Ext.getCmp('login-userName').isValid() && Ext.getCmp('login-password').isValid() && Ext.getCmp('domino-submit-button').disabled == false){
								Ext.getCmp('domino-submit-button').handler.call(Ext.getCmp('domino-submit-button').scope)
							}*/
						},
						keyup:function(f,e) {

							if (e.shiftKey) return; 
							
							if(e.getKey() == 13) { // return
								var rqpform = f.findParentByType('xchatformpanel');
								var chattext = Ext.getCmp('field_chattext'+rqpform.sid).getValue('');
								var params = {
									noxml:'1',
									chattext:chattext
								};
								Ext.getCmp('field_chattext'+rqpform.sid).setValue('');
								Ext.getCmp('field_chattext'+rqpform.sid).focus();			
								
								rqpform.getForm().submit({
									url:'/local/tools/xchat/xform.php',
									params:params,
									failure:function(form,action){
										//DebugDump(action,'failure!!');
										//Ext.getCmp('field_chattext'+form.sid).setValue('');
										//Ext.getCmp('field_chattext'+form.sid).focus();
																				
									},
									success:function(form,action) {
										//DebugDump(action,'success!!');
										//Ext.getCmp('field_chattext').reset();
										//DebugDump(form,'+this.sid '+form.sid)
										//Ext.getCmp('field_chattext'+form.sid).setValue('');
										//Ext.getCmp('field_chattext'+form.sid).focus();
									}
								});
								
								// save last messages (only 10)								
								this.lastMessages[this.lastMessages.length] = chattext;
								if(this.lastMessages.length == 10) {
									t = this.lastMessages.shift();
								}								
								
							} 
							
						}
					}		
				},{
					xtype:'hidden',
					name:'chat_operation',
					id:'field_chat_operation'+this.sid,
					value:'insert'
				},{
					xtype:'hidden',
					name:'chatroom',
					id:'field_chatroom'+this.sid,
					value:this.sid
				},{
					xtype:'hidden',
					name:'to_nickname',
					id:'field_to_nickname'+this.sid,
					value:''
				},{
					xtype:'hidden',
					name:'to_user_sid',
					id:'field_to_user_sid'+this.sid,
					value:''
				}]
			});
			
			// call parent
			Chat.xChatFormPanel.superclass.initComponent.apply(this, arguments);
		} // eo function initComponent
	});
	
	// register xtype
	Ext.reg('xchatformpanel', Chat.xChatFormPanel);



	/*****************************************************
	*/ function __xChatPanelView() {}
	/******************************************************/	
	// ------------------------------------------------------------------------------------------
	// The live chat view, this is where loadChat puts its data
	// ------------------------------------------------------------------------------------------	
	Chat.xChatPanelView = Ext.extend(Ext.DataView, {
		initComponent:function() {

		   var chatDataType = [
			   {name: 'html'},{name: 'id'}
			 ];
		   
            var storeChat = new Ext.data.JsonStore({
                url: '/local/tools/xchat/xlivechat.php',
                root: 'records',
                fields: chatDataType,
                remoteSort:true,
                listeners: {
                    load: {fn:function(s,r,o){ 
                    	// store will not be loaded 
                    	// an own request will handle this store by adding items to the store
                    	// see Chat.loadChat
                    }}
                },
                baseParams:{noxml:1}
            });
		   
			var resultTpl = new Ext.XTemplate(
				'<tpl for=".">',
				'<div class="chat" id="{id}">',
					'{html}',
				'</div></tpl>'
			);

			Ext.apply(this, {
				tpl: resultTpl,
				itemSelector: 'div.chat',
                singleSelect: true,
                overClass:'x-view-over',				
				store: storeChat,
				autoScroll:true,
				emptyText:'',
			}); 
			
			// call parent
			Chat.xChatPanelView.superclass.initComponent.apply(this, arguments);
		} // eo function initComponent
	});
		
	// register xtype
	Ext.reg('xchatpanelview', Chat.xChatPanelView);


/*****************************************************
*/ function _____xChatterPanelTBar() {}
/******************************************************/	

// ------------------------------------------------------------------------------------------
// Chatter toolbar, put any functions here
// ------------------------------------------------------------------------------------------	
Ext.xChatterPanelTBar = Ext.extend(Ext.Toolbar,{
	   
	   initComponent: function() {
		  Ext.xChatterPanelTBar.superclass.initComponent.call(this);
	   },

		onRender: function(ct,position) {
			Ext.xChatterPanelTBar.superclass.onRender.call(this, ct,position);		
			this.callback();
		},
		
		callback: function(){ 

			// display a menu for teamer or just a close button for users. 
			var conf = Chat.ctrChat[this.chatroom_sid].conf;
			var chatroom_sid = this.chatroom_sid;
			
			this.addButton({
				 text: $L('Chat verlassen')
				,id: 'leavechatbutton'+chatroom_sid
				,icon:'/images/icons/ico_leave.gif'
				,iconCls:'x-btn-text-icon'
				,handler:function(button) {
					Chat.UpdateUserInFo(running_user_sid,'offline',chatroom_sid);
				}
			});			
			
			if(conf.is_teamer) {
				var menuitems = [];
				var midx=0;
				
				// close chat
				if(conf.can_open
				&& conf.can_edit
				&& conf.flag_open == 'y') {
					menuitems[midx] = {
						text: $L('Chat schließen'), 
						iconCls:'x-btn-text-icon',
						icon:'/images/icons/ico_schliessen.gif',
						id:'closechatbutton'+chatroom_sid,
						handler: function(button) {
							Chat.operate(chatroom_sid,'close',{mask:'chat'+chatroom_sid,question:'Wirklich den Chat schließen? Der Chat wird beendet und niemand kann mehr schreiben. Falls das Protokoll an ist, wird es geschrieben, das kann einige Zeit dauern.'});
						}
					};
					midx++;
				}

				if(midx>0) {
					menuitems[midx] = '-';
					midx++;				
				}
				// moderator
				var mod_checked = false;
				if(conf.chatter_flag_type && conf.chatter_flag_type == 'moderator') var mod_checked = true;
				menuitems[midx] = new Ext.menu.CheckItem({
					text: $L('Ich bin Moderator'), 
					checked:mod_checked,
					id:'moderatorchatbutton'+chatroom_sid,
					hideOnClick:false,
					handler: function(item) {
						var flag_type = 'chatter';
						var checked = ! item.checked;
						if(checked) flag_type = 'moderator';
						Chat.operate(chatroom_sid,'set_type',{params:{flag_type:flag_type,user_operation_sid:running_user_sid}});
					}
				});
				midx++;

				if(midx>0) {
					menuitems[midx] = '-';
					midx++;				
				}		
				
				if(conf.can_edit 
				&& ((conf.flag_public == 'n') || (conf.a_sid >0))) {
					menuitems[midx] = {
						text: $L('Chat bearbeiten'), 
						iconCls:'x-btn-text-icon',
						icon:'/javascripts/ext/plugins/img/edit.gif',
						id:'editchatbutton'+chatroom_sid,
						chatroom_sid:chatroom_sid,
						handler: function(button) {
							var chatter_panel = Ext.getCmp('chat'+this.chatroom_sid+'_chatter');
							var conf = Chat.ctrChat[this.chatroom_sid].conf;
							Chat.editRecordWindow(false,this.chatroom_sid,'xchatroomeditor',{type:'fast'},false,{},{
								iconCls:'x-chat-icon',
								edit_window_height:400,
								edit_window_width:300,
								title:conf.title,
								id:'editor'+this.chatroom_sid
							}); 
						}
					};
					midx++;					
				}
			}
			
			// reset menuitems
			if(conf.chatter_flag_status == 'invisible') var midx = 0;
			
			if(midx>0) {
				this.addSpacer();
				this.addSeparator();		
				this.addSpacer();	
				var menubutton = {
					xtype:'tbbutton',
					text: $L('Menü'),
					handler:function(bt) {
						// open menu
						bt.showMenu();
					},
					menu:new Ext.menu.Menu({
						listeners: {
							show: {scope:this,fn: function(mn) {
							}}	
						},
						items: menuitems
					})
				};
				this.add(menubutton);
			}
			
		},
		
		handleAjaxrequest: function(args) {}		
	}

);

/*****************************************************
*/ function _____xChatFormPanelTBar() {}
/******************************************************/	

// ------------------------------------------------------------------------------------------
// Chatter toolbar, put any functions here
// ------------------------------------------------------------------------------------------	
Ext.xChatFormPanelTBar = Ext.extend(Ext.Toolbar,{
	   
	   initComponent: function() {
		  Ext.xChatFormPanelTBar.superclass.initComponent.call(this);
	   },

		onRender: function(ct,position) {
			Ext.xChatFormPanelTBar.superclass.onRender.call(this, ct,position);		
			if(typeof Chat.smileys == 'object') {
				this.callback(Chat.smileys);
			} else {
				var params = {chatroom:this.chatroom_sid,chat_operation:'getsmilies',noxml:1};
				Ext.Ajax.request({
						url: '/local/tools/xchat/xform.php',
						method: 'POST', 
						scope:this,
						params: params,//end params
						failure:function(response,options){
							// Ext.MessageBox.alert('Warning','No Smileys found, please contact the administrator.');
						},
						success:function(response,options){
							var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
							this.callback(responseData);
							Chat.smileys = responseData;
						}
					 }
				);
			}
		},
		
		callback: function(responseData){ 

			var conf = Chat.ctrChat[this.chatroom_sid].conf;
			var chatroom_sid = this.chatroom_sid;
			if((!responseData.smiley)) return false;

			var menuitems = [];
			var midx=0; 
			for(var i=0;i<responseData.smiley.length;i++) {
				menuitems[midx] = {
					text: responseData.smiley[i].description, 
					iconCls:'x-btn-text-icon',
					icon: responseData.smiley[i].img_path,
					id:'smiley'+responseData.smiley[i].sid,
					chatroom_sid:chatroom_sid,
					emoticon:responseData.smiley[i].emoticon
				};
				midx++;	
				
			}

			if(midx>0) {
				this.addFill();	
				var menubutton = {
					text: '<img src="/images/smilies/smily_smile.gif" width="15" height="15" />',
					menuAlign:'bl-tl',
					menu:new Ext.menu.Menu({
						listeners: {
							beforeshow: {scope:this,fn: function(mn) {
								mn.el.addClass('smiley-list');
								mn.el.setHeight(300);
								mn.el.setStyle('overflow-y','auto');
							}},
							itemclick: {fn: function(bt,e) {
								var textbox = Ext.getCmp('field_chattext'+bt.chatroom_sid);
								var v = textbox.getValue();
								if(v && v.length >0) v = v+' ';
								if(textbox) textbox.setValue(v+bt.emoticon);								
								this.hide();
								textbox.focus();
							}}								
						},
						items: menuitems
					})
				};
				this.add(menubutton);
			}			
		}
	}
);


/*****************************************************
*/ function __CHATTER_RENDERER() {}
/******************************************************/
// ChatterFlagType
Ext.ux.renderer.ChatterFlagTypeRenderer = function(options) {
	var value = options.value;
	value = value === undefined || value === null ? '' : value;
	switch(options.record.data.flag_type) {
		case'moderator':
			value = '<div class="moderator" style="font-weight:bold;">'+value+'</div>';
			break;		
	}
	
	return value;
};

Ext.ux.renderer.ChatterFlagType = function(item) {
    return function(value, meta, record) {
        return Ext.ux.renderer.ChatterFlagTypeRenderer({value: value, meta: meta, record: record, item: item});
    };
}


/*****************************************************
*/ function __AJAX_REQUEST_QUEUE() {}
/******************************************************/



/** 
 * Overrides ext-adapter behavior for allowing queuing of AJAX requests. 
 * 
 */ 
/* 
 * Portions of this code are based on pieces of Yahoo User Interface Library 
 * Copyright (c) 2007, Yahoo! Inc. All rights reserved. 
 * YUI licensed under the BSD License: 
 * http://developer.yahoo.net/yui/license.txt 
 */ 
Ext.lib.Ajax = function() { 

    /** 
     * @type {Array} _queue A FIFO queue for processing pending requests 
     */ 
    var _queue = []; 

    /** 
     * @type {Number} _activeRequests The number of requests currently being processed. 
     */ 
    var _activeRequests = 0; 

    /** 
     * @type {Number} _concurrentRequests The number of max. concurrent requests requests allowed. 
     */ 
    var _concurrentRequests = 2; 

    switch (true) { 
        case Ext.isIE8: 
            _concurrentRequests = window.maxConnectionsPerServer; 
        break; 
        case Ext.isIE: 
            _concurrentRequests = 2; 
        break; 
        case Ext.isSafari: 
        case Ext.isChrome: 
        case Ext.isGecko3: 
            _concurrentRequests = 4; 
        break; 
    } 

    var activeX = [ 
        'MSXML2.XMLHTTP.3.0', 
        'MSXML2.XMLHTTP', 
        'Microsoft.XMLHTTP' 
    ], CONTENTTYPE = 'Content-Type'; 

    // private 
    function setHeader(o) 
    { 
        var conn = o.conn, prop; 

        function setTheHeaders(conn, headers) { 
            for (prop in headers) { 
                if (headers.hasOwnProperty(prop)) { 
                    conn.setRequestHeader(prop, headers[prop]); 
                } 
            } 
        } 

        if (pub.defaultHeaders) { 
            setTheHeaders(conn, pub.defaultHeaders); 
        } 

        if (pub.headers) { 
            setTheHeaders(conn, pub.headers); 
            delete pub.headers; 
        } 
    } 

    // private 
    function createExceptionObject(tId, callbackArg, isAbort, isTimeout) 
    { 
        return { 
            tId : tId, 
            status : isAbort ? -1 : 0, 
            statusText : isAbort ? 'transaction aborted' : 'communication failure', 
            isAbort: isAbort, 
            isTimeout: isTimeout, 
            argument : callbackArg 
        }; 
    } 

    // private 
    function initHeader(label, value) 
    { 
        (pub.headers = pub.headers || {})[label] = value; 
    } 

    // private 
    function createResponseObject(o, callbackArg) 
    { 
        var headerObj = {}, 
            headerStr, 
            conn = o.conn, 
            t, 
            s; 

        try { 
            headerStr = o.conn.getAllResponseHeaders(); 
            Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){ 
                t = v.indexOf(':'); 
                if(t >= 0){ 
                    s = v.substr(0, t).toLowerCase(); 
                    if(v.charAt(t + 1) == ' '){ 
                        ++t; 
                    } 
                    headerObj[s] = v.substr(t + 1); 
                } 
            }); 
        } catch(e) {} 

        return { 
            tId : o.tId, 
            status : conn.status, 
            statusText : conn.statusText, 
            getResponseHeader : function(header){return headerObj[header.toLowerCase()];}, 
            getAllResponseHeaders : function(){return headerStr}, 
            responseText : conn.responseText, 
            responseXML : conn.responseXML, 
            argument : callbackArg 
        }; 
    } 

    // private 
    function releaseObject(o) 
    { 
        //console.log(o.tId+" releasing"); 
        _activeRequests--; 

        o.conn = null; 
        o = null; 

        _processQueue(); 
    } 

    // private 
    function handleTransactionResponse(o, callback, isAbort, isTimeout) 
    { 
        if (!callback) { 
            releaseObject(o); 
            return; 
        } 

        var httpStatus, responseObject; 

        try { 
            if (o.conn.status !== undefined && o.conn.status != 0) { 
                httpStatus = o.conn.status; 
            } 
            else { 
                httpStatus = 13030; 
            } 
        } 
        catch(e) { 
            httpStatus = 13030; 
        } 

        if ((httpStatus >= 200 && httpStatus < 300) || (Ext.isIE && httpStatus == 1223)) { 
            responseObject = createResponseObject(o, callback.argument); 
            if (callback.success) { 
                if (!callback.scope) { 
                    callback.success(responseObject); 
                } 
                else { 
                    callback.success.apply(callback.scope, [responseObject]); 
                } 
            } 
        } 
        else { 
            switch (httpStatus) { 
                case 12002: 
                case 12029: 
                case 12030: 
                case 12031: 
                case 12152: 
                case 13030: 
                    responseObject = createExceptionObject(o.tId, callback.argument, (isAbort ? isAbort : false), isTimeout); 
                    if (callback.failure) { 
                        if (!callback.scope) { 
                            callback.failure(responseObject); 
                        } 
                        else { 
                            callback.failure.apply(callback.scope, [responseObject]); 
                        } 
                    } 
                break; 

                default: 
                    responseObject = createResponseObject(o, callback.argument); 
                    if (callback.failure) { 
                        if (!callback.scope) { 
                            callback.failure(responseObject); 
                        } 
                        else { 
                            callback.failure.apply(callback.scope, [responseObject]); 
                        } 
                    } 
            } 
        } 

        releaseObject(o); 
        responseObject = null; 
    } 

    // private 
    function handleReadyState(o, callback) 
    { 
        callback = callback || {}; 
        var conn = o.conn, 
            tId = o.tId, 
            poll = pub.poll, 
            cbTimeout = callback.timeout || null; 

        if (cbTimeout) { 
            pub.timeout[tId] = setTimeout(function() { 
                pub.abort(o, callback, true); 
            }, cbTimeout); 
        } 

        poll[tId] = setInterval( 
            function() { 
                if (conn && conn.readyState == 4) { 
                    clearInterval(poll[tId]); 
                    poll[tId] = null; 

                    if (cbTimeout) { 
                        clearTimeout(pub.timeout[tId]); 
                        pub.timeout[tId] = null; 
                    } 

                    handleTransactionResponse(o, callback); 
                } 
            }, 
            pub.pollInterval); 
    } 

    /** 
     * Pushes the request into the queue if a connection object can be created 
     * na dimmediately processes the queue. 
     * 
     */ 
    function asyncRequest(method, uri, callback, postData) 
    { 
        var o = getConnectionObject(); 

        if (!o) { 
            return null; 
        } else { 
            _queue.push({ 
               o        : o, 
               method   : method, 
               uri      : uri, 
               callback : callback, 
               postData : postData 
            }); 
            //console.log(o.tId+" was put into the queue"); 
           
            var head = _processQueue(); 

            if (head) { 
                //console.log(o.tId+" is being processed at the head of queue"); 
                return head; 
            } else { 
                //console.log(o.tId+" was put into the queue and will be processed later on"); 
                return o; 
            } 
        } 
    } 

    /** 
     * Initiates the async request and returns the request that was created, 
     * if, and only if the number of currently active requests is less than the number of 
     * concurrent requests. 
     */ 
    function _processQueue() 
    { 
        var to = _queue[0]; 
        //DebugDump(to,'to is ');
        if (to && _activeRequests < _concurrentRequests) { 
            to = _queue.shift(); 
            _activeRequests++; 
            return _asyncRequest(to.method, to.uri, to.callback, to.postData, to.o); 
        } 
    } 


    // private 
    function _asyncRequest(method, uri, callback, postData, o) 
    { 
        if (o) { 
            o.conn.open(method, uri, true); 

            if (pub.useDefaultXhrHeader) { 
                initHeader('X-Requested-With', pub.defaultXhrHeader); 
            } 

            if(postData && pub.useDefaultHeader && (!pub.headers || !pub.headers[CONTENTTYPE])){ 
                initHeader(CONTENTTYPE, pub.defaultPostHeader); 
            } 

            if (pub.defaultHeaders || pub.headers) { 
                setHeader(o); 
            } 

            handleReadyState(o, callback); 
            o.conn.send(postData || null); 
        } 
        return o; 
    } 

    // private 
    function getConnectionObject() 
    { 
        var o; 

        try { 
            //console.log(pub.transactionId+" is the current transaction id"); 
            if (o = createXhrObject(pub.transactionId)) { 
                pub.transactionId++; 
            } 
        } catch(e) { 
        } finally { 
            return o; 
        } 
    } 

    // private 
    function createXhrObject(transactionId) 
    { 
        var http; 

        try { 
            http = new XMLHttpRequest(); 
        } catch(e) { 
            for (var i = 0; i < activeX.length; ++i) { 
                try { 
                    http = new ActiveXObject(activeX[i]); 
                    break; 
                } catch(e) {} 
            } 
        } finally { 
            return {conn : http, tId : transactionId}; 
        } 
    } 

    var pub = { 

        request : function(method, uri, cb, data, options) { 
            if(options){ 
                var me = this, 
                    xmlData = options.xmlData, 
                    jsonData = options.jsonData, 
                    hs; 

                Ext.applyIf(me, options); 

                if(xmlData || jsonData){ 
                    hs = me.headers; 
                    if(!hs || !hs[CONTENTTYPE]){ 
                        initHeader(CONTENTTYPE, xmlData ? 'text/xml' : 'application/json'); 
                    } 
                    data = xmlData || (Ext.isObject(jsonData) ? Ext.encode(jsonData) : jsonData);
                } 
            } 
            return asyncRequest(method || options.method || "POST", uri, cb, data); 
        }, 

        serializeForm : function(form) 
        { 
            var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
                hasSubmit = false, 
                encoder = encodeURIComponent, 
                element, 
                options, 
                name, 
                val, 
                data = '', 
                type; 

            Ext.each(fElements, function(element) { 
                name = element.name; 
                type = element.type; 

                if (!element.disabled && name){ 
                    if(/select-(one|multiple)/i.test(type)){ 
                        Ext.each(element.options, function(opt) { 
                            if (opt.selected) { 
                                data += String.format("{0}={1}&", 
                                                     encoder(name), 
                                                     encoder((opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttribute('value') !== null) ? opt.value : opt.text)); 
                            } 
                        }); 
                    } else if(!/file|undefined|reset|button/i.test(type)) { 
                        if(!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)){ 

                            data += encoder(name) + '=' + encoder(element.value) + '&'; 
                            hasSubmit = /submit/i.test(type); 
                        } 
                    } 
                } 
            }); 
            return data.substr(0, data.length - 1); 
        }, 

        useDefaultHeader : true, 
        defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', 
        useDefaultXhrHeader : true, 
        defaultXhrHeader : 'XMLHttpRequest', 
        poll : {}, 
        timeout : {}, 
        pollInterval : 50, 
        transactionId : 0, 


        abort : function(o, callback, isTimeout) 
        { 
            var me = this, 
                tId = o.tId, 
                isAbort = false; 

            //console.log(o.tId+" is aborting - was "+o.tId+" in progress?: "+me.isCallInProgress(o)); 

            if (me.isCallInProgress(o)) { 
                o.conn.abort(); 
                clearInterval(me.poll[tId]); 
                me.poll[tId] = null; 

                clearTimeout(pub.timeout[tId]); 
                me.timeout[tId] = null; 

                // @ext-bug 3.0.2 why was this commented out? if the request is aborted 
                // programmatically, the timeout for the "timeout"-handler is never destroyed, 
                // thus this method would at least be called once, if the initial reason is 
                // that no timeout occured. 
                //if (isTimeout) { 
                //    me.timeout[tId] = null; 
                //} 

                  handleTransactionResponse(o, callback, (isAbort = true), isTimeout); 
            } else { 
                // check here if the current call was in progress. This might not be the case 
                // if the connection was put into the queue, waiting to get triggered 
                for (var i = 0, max_i = _queue.length; i < max_i; i++) { 
                    if (_queue[i].o.tId == o.tId) { 
                        _queue.splice(i, 1); 
                        //console.log(o.tId+" was not a call in progress, thus removed from the queue at "+i); 
                        break; 
                    } 
                } 

            } 

            return isAbort; 
        }, 

        isCallInProgress : function(o) { 
            // if there is a connection and readyState is not 0 or 4 
            return o.conn && !{0:true,4:true}[o.conn.readyState]; 
        }, 

       getQueue : function(o) { 
            // if there is a connection and readyState is not 0 or 4 
            return _queue; 
        }        
    }; 
    return pub; 
}();  


} else alert('Ext is not defined');




function Typewriter(str) {
	this.str = str;
	this.start = 0;
	this.end = this.str.length+1;
	this.interval = 100;
	this.part = '';
	this.startcounter = 1;
	this.counter = this.startcounter;
	this.node = false;
	this.loop = false;
	this.keepcontent = false;
	this.running = false;
	
	this.init = function(node) {
		this.node = node;
		if(this.keepcontent) this.savedcontent = this.node.innerHTML;
		//this.typer = setTimeout(function(){ this.type(); }.bind(this), this.interval);
		this.type();
		this.running = true;
	}
	
	this.type = function(slide) {
		if(this.counter == this.end) { 
			if(this.loop) this.counter = this.startcounter;
			else {
				/*clearTimeout(this.typer);
				if(this.keepcontent) this.node.innerHTML  = this.savedcontent;
				this.running = false;*/
				this.stop();
				return;
			}
		}
		this.part = this.str.slice(this.start, this.counter);
		this.node.innerHTML = this.part;
		this.counter++;
		this.typer = setTimeout(function(){ this.type(); }.bind(this), this.interval);
	}
	
	this.stop = function() {
		clearTimeout(this.typer);
		if(this.keepcontent) this.node.innerHTML  = this.savedcontent;
		this.running = false;
	}
}




/*******************************************************
 */ function ____ChatUser________() {} /*
 *******************************************************/

debug_mode = false;

function openAdvisors(event,chatroom_sid,context,fid) {
	SmartDialog('/chatberatung/berater/'+chatroom_sid+'/empfaenger', null, null,'yes',800,600);
	checkmodalwindow = setInterval("checkModalWindow('"+chatroom_sid+"','"+context+"','"+fid+"')", 50);
}

function openUsers(event,chatroom_sid,context,fid) {
	SmartDialog('/chatberatung/user/'+chatroom_sid+'/empfaenger', null, null,'yes',800,600);
	checkmodalwindow = setInterval("checkModalWindow('"+chatroom_sid+"','"+context+"','"+fid+"')", 50);
}

function checkModalWindow(chatroom_sid,context,fid) {
	if(SmartDialog._modal.closed) { 
		clearInterval(checkmodalwindow);
		getChatters(null,context,chatroom_sid,fid);
	}
}

function getProtocolChatters(max,context,el_sid,fid) {
	p_el = '';
	if(el_sid && el_sid.length>0) {
		document.getElementById(fid).innerHTML = 'Teilnehmer werden geladen...';
		protocol_sid = el_sid;
		p_el = '&p_el='+fid;
	} else {
		document.getElementById('recipients').innerHTML = 'Teilnehmer werden geladen...';
		protocol_sid = document.getElementById('fields_root_editor_sid').value;
	}
	if(!protocol_sid) return false;
	if(!context) context = '';
	max_recipients = '';
	if(max) max_recipients = '&max='+max;
	url = '/php-os/app_chatmanager/scripts/chat_protocolusers.php?context='+context+'&protocol_sid='+protocol_sid+max_recipients+p_el;
	url = checkUrl(url);
	url = addColorset(url);	
	if(debug_mode == true) FensterOeffnen(url,'Chatters',400,400,'auto');
	else loadIntoIframe(url,'menuFrame');
}

function getChatters(max,context,el_sid,fid) {

	p_el = '';
	if(el_sid && el_sid.length>0) {
		document.getElementById(fid).innerHTML = 'Teilnehmer werden geladen...';
		chatroom_sid = el_sid;
		p_el = '&p_el='+fid;
	} else {
		chatroom_sid = document.getElementById('fields_root_editor_sid').value;
		if((chatroom_sid) && chatroom_sid.length>0) document.getElementById('recipients').innerHTML = 'Teilnehmer werden geladen...';
		else {
			document.getElementById('recipients').innerHTML = 'Bitte erst speichern, um weitere Teilnehmer hinzuzuziehen.';
			chatroom_sid=false;
		}
		p_el = '&p_el='+fid;
	}
	//if(typeof console == 'object') console.log('x chatroom_sid: %o',chatroom_sid);
	if(!chatroom_sid) return false;
	if(!context) context = '';
	max_recipients = '';
	if(max) max_recipients = '&max='+max;
	url = '/php-os/app_chatmanager/scripts/chat_users.php?context='+context+'&chatroom_sid='+chatroom_sid+max_recipients+p_el;
	url = checkUrl(url);
	url = addColorset(url);	
	
	if(debug_mode == true) FensterOeffnen(url,'Chatters',400,400,'auto');
	else loadIntoIframe(url,'menuFrame');
}

function updateChatterList() {
	group = document.getElementById('group').value;
	if(!group || group.length == 0) return false;
	chatroom_sid = document.getElementById('fields_root_editor_sid').value;
	if(!chatroom_sid || chatroom_sid.length == 0) return false;
	groupaction = document.getElementById('groupaction').value;
	document.getElementById('recipients').innerHTML = 'Teilnehmer werden geladen...';
	url = '/php-os/app_chatmanager/scripts/chat_chattergroup.php?chatroom_sid='+chatroom_sid+'&group='+group+'&groupaction='+groupaction;
	url = checkUrl(url);
	url = addColorset(url);	
	if(debug_mode == true) FensterOeffnen(url,'Chatters',400,400,'auto');
	else loadIntoIframe(url,'menuFrame');	
}

function deleteChatterList() {
	chatroom_sid = document.getElementById('fields_root_editor_sid').value;
	if(!chatroom_sid || chatroom_sid.length == 0) return false;
	document.getElementById('recipients').innerHTML = 'Keine Teilnehmer ausgew&auml;hlt';
	url = '/php-os/app_chatmanager/scripts/chat_chattergroup.php?chatroom_sid='+chatroom_sid+'&groupaction=deleteall';
	url = checkUrl(url);
	url = addColorset(url);	
	if(debug_mode == true) FensterOeffnen(url,'Chatters',400,400,'auto');
	else loadIntoIframe(url,'menuFrame');		
}


function viewChatters(recipients,p_el) {
	
	// enable editing buttons, if possible
	if($('cbh1')) {
		$('cbh1').disabled=false;
		$('cbh1').removeClassName('disabled');
	}
	if($('cbh2')) {
		$('cbh2').disabled=false;
		$('cbh2').removeClassName('disabled');
	}
	
	if(p_el && p_el.length > 0) {
		document.getElementById(p_el).innerHTML = recipients;
	} else {
		document.getElementById('recipients').innerHTML = recipients;
	}
	loadIntoIframe('/none','menuFrame');
}

