/*
	pitptoctrl.js
	
	This file is part of the Pixeltamer Internet Toolkit. Copyright (C) 2007 pixeltamer.net	
	
	Controls specific to PTO services like chat, news, forum	
*/

function PitPTOCtrlWhoList(p_iX,p_iY,p_iW,p_iH,p_sTitle)
{
	PitPTOCtrlWhoList.BaseCtor.call(this,p_iX,p_iY,p_iW,p_iH,p_sTitle);
	this.m_sTagName="div";
	this.m_sTagClass="wholist";
};
Inherit(PitPTOCtrlWhoList,PitCtrlTopLevel,"PitPTOCtrlWhoList");

PitPTOCtrlWhoList.prototype.RefreshAttributes=function()
{
	if(!this.m_xOutputBox)
	{
		this.m_xOutputBox=new PitCtrlStatic(2,2,this.m_iW-18,this.m_iH-5,"");
		this.m_xOutputBox.m_sTagClass="list";
		this.AddChild(this.m_xOutputBox);
	};
	PitPTOCtrlWhoList.Super.RefreshAttributes.call(this);
};

PitPTOCtrlWhoList.prototype.UpdateTick=function()
{
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_sRPCRoom);
	xRPC.SetParams("cmd","/whoimm");
	xRPC.SetParams("time","0");
	xRPC.m_sCmd="/whoimm";
	xRPC.m_bQuiet=true;
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	var xWnd=this;
	
	xRPC.OnSucceed=function(){
		var xD=xRPC.m_xResults;
		if(xD)
		{
			var axUsers=xD.Users;
			var sR="";
			var i,iC=axUsers.length;
			for(i=0;i<iC;i++)
			{
				var xUser=axUsers[i];
				if(xUser.F)
				{
					sR+='<span style="white-space:nowrap;">';
					if((xUser.F&(1<<2))!=0) {sR+='<img src="images/hourglass.gif" style="position: relative; top: 2px;" title="AFK">';};
					if((xUser.F&(1<<0))!=0) {sR+='<img src="images/star_gold.gif" style="position: relative; top: 2px;" title="Administrator">';};
					if((xUser.F&(1<<1))!=0) {sR+='<img src="images/star_silver.gif" style="position: relative; top: 2px;" title="Moderator">';};
					sR+=xUser.N;
					sR+='</span> ';
				}
				else
				{
					sR+=xUser.N+" ";
				};
			};
			xWnd.m_xOutputBox.SetText(sR);
		}
		else
		{
			xWnd.m_xOutputBox.SetText("ERROR:"+xRPC.m_sResultText);
		};
	};
	xRPC.Send();
	var hThis=this.m_hHnd;
	window.setTimeout(function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.UpdateTick();};
		},10000);
};


PitPTOCtrlWhoList.prototype.Open=function(p_sURL,p_sRoom)
{
	this.m_sRPCURL=p_sURL;
	this.m_sRPCRoom=p_sRoom;
	this.UpdateTick();
//	this.SendChatCommand("/list",true,"roomlist");
//	this.SwitchTab("Rooms");
};

function PitPTOCtrlChat(p_iX,p_iY,p_iW,p_iH,p_sTitle)
{
	PitPTOCtrlChat.BaseCtor.call(this,p_iX,p_iY,p_iW,p_iH,p_sTitle);
	this.m_sTagName="div";
	this.m_sTagClass="chat";
	if(!p_iX){p_iX=0;};
	if(!p_iY){p_iY=0;};
	if(!p_iW){p_iW=100;};
	if(!p_iH){p_iH=100;};
	this.m_iX=p_iX;
	this.m_iY=p_iY;
	this.m_iW=p_iW;
	this.m_iH=p_iH;

//	this.AddTopLevelBehaviour(true,true);
	
	this.m_xSubsTab=null;
	this.m_xOutput=null;
	this.m_xInput=null;
	
	this.m_axRooms=new Array();
	this.m_asRoomList=new Array();
	this.m_asIgnoreList=-1;
	
	this.m_sRPCURL="";

	this.m_iUpdateTimeoutRL=100;
	this.m_iUpdateTimeoutML=100;
	this.m_iTimer=-1;
	
	this.m_iChatUpdateTime=2000;
	this.m_xLastSecondary=new Date();
	
	this.m_bEditAtTop=false;
	this.m_bReverseMessages=true;
	this.m_bTabsVisible=true;
	
	this.m_bUserInfo=true;
	this.m_sRoomListTextColor="#000";
	
	this.m_xScrollBox=null;
	this.m_xSoundPlayer=null;
	this.m_bSoundNotify=false;
	
	if(pit_GetCookie("pitChatSndNot","0")=="1") {this.m_bSoundNotify=true;};
	
	this.AddStyles(g_xPitStyleDef.PitPTOCtrlChat);
};

// function PitCtrlScrollPanel(p_sBarStyle,p_iX,p_iY,p_iW,p_iH,p_sFrameStyle,p_iFrameOffset,p_sFrameBGColor,p_fFrameTransparency)
Inherit(PitPTOCtrlChat,PitCtrlTopLevel,"PitPTOCtrlChat");

PitPTOCtrlChat.prototype.Destruct=function()
{
	pit_ClearFnc(this.m_xOutput);
	this.m_xOutput=null;
	this.m_xSubsTab=null;
	this.m_xInput=null;
	this.m_xScrollBox=null;
	if(this.m_iTimer!=-1)
	{
		window.clearTimeout(this.m_iTimer);
	};
	pit_Purge(this.m_axRooms);
	pit_Purge(this.m_axRoomList);
	PitPTOCtrlChat.Super.Destruct.call(this);
};

PitPTOCtrlChat.prototype.OnResize=function()
{
	this.GetCurRect();
	this.UpdateLayout();
	PitPTOCtrlChat.Super.OnResize.call(this);
	this.RefreshFrame();
};

PitPTOCtrlChat.prototype.UpdateLayout=function()
{
	var xR=this.GetContentRect();
	xR.m_iX+=2;xR.m_iY+=2;xR.m_iW-=4;xR.m_iH-=4;
	this.m_xScrollBox.UpdateRect();
	this.m_xScrollBox.SetSize(xR.m_iW-22,this.m_xScrollBox.m_iH);
	var iTH=0;
	var iIH=this.m_xInput.m_iH;
	var iTY=0;
	if(this.m_bTabsVisible)
	{
		iTH=this.m_xSubsTab.m_iH;
		this.m_xSubsTab.SetRect(xR.m_iX,xR.m_iY,xR.m_iW,iTH);
	}
	else
	{
		iTH=0;
		this.m_xSubsTab.SetRect(xR.m_iX,-this.m_xSubsTab.m_iH*2,xR.m_iW,this.m_xSubsTab.m_iH);
	};
	if(this.m_bEditAtTop)
	{
		
		this.m_xOutput.SetRect(xR.m_iX,xR.m_iY+iTH+4+iIH,xR.m_iW,xR.m_iH-iTH-iIH-4);
		this.m_xInput.SetRect(xR.m_iX,xR.m_iY+iTH+2,xR.m_iW,iIH);
	}
	else
	{
		this.m_xOutput.SetRect(xR.m_iX,xR.m_iY+iTH+2,xR.m_iW,xR.m_iH-iTH-iIH-4);
		this.m_xInput.SetRect(xR.m_iX,xR.m_iY+xR.m_iH-iIH,xR.m_iW,iIH);
	};
};

PitPTOCtrlChat.prototype.RefreshAttributes=function()
{
	if(!this.m_xSubsTab)
	{
		var hThis=this.m_hHnd;
		this.m_xSubsTab=new PitCtrlTab(10,30,300,this.m_xStyleDef.TabStyle);
		this.m_xOutput=new PitCtrlScrollPanel(this.m_xStyleDef.ScrollStyle,10,60,200,200,"",0,"",1);
		this.m_xInput=new PitCtrlEdit(10,10,200,20);
		this.m_xSubsTab.m_iCloseTabs=1;

		this.m_xSubsTab.m_xOnTabActivate=function(p_sTab)
		{
			var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.SwitchTab(p_sTab);};
		};
		this.m_xSubsTab.m_xOnTabClose=function(p_sTab)
		{
			var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.CloseRoom(p_sTab);};
		};
		
		this.m_xOutput.m_bAutoArrange=true;
		this.m_xOutput.m_bOverlapPages=false;
		this.m_xOutput.m_iVSpacing=0;
		
		this.m_xScrollBox=new PitCtrlPanel(0,0,this.m_iW-32-0,2);
		this.m_xOutput.AddChild(this.m_xScrollBox);
		var xScrD=this.m_xScrollBox.MakeEl();
		xScrD.style.fontSize=this.m_xStyleDef.ScrollFontSize+"px";
		
		this.m_xOutput.OnSetScrollPos=function(p_iPos,p_iRange)
		{
		};
		
		this.AddChild(this.m_xSubsTab);
		this.AddChild(this.m_xOutput);
		this.AddChild(this.m_xInput);
		
		this.m_xInput.GetEl().maxLength=256;
		this.m_xInput.SetKeyCmdID(1);
		this.m_xInput.OnCmd=function(p_iCmd,p_xE)
		{
			if(p_xE.m_iKeyCode!=13) {return true;};
			var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
				var sVal=xThis.m_xInput.GetEl().value;
				xThis.m_xInput.GetEl().value="";
				xThis.SendChatCommand(sVal);
			};
			return false;
		};
	};

	this.UpdateLayout();
	
	this.m_xSubsTab.RefreshAttributes();
	this.m_xOutput.RefreshAttributes();
	this.m_xInput.RefreshAttributes();
	PitPTOCtrlChat.Super.RefreshAttributes.call(this);
	this.UpdateLayout();
};

PitPTOCtrlChat.prototype.EscapeText=function(p_sText)
{
	var sOrg=p_sText;
	p_sText=p_sText.replace(/&/g,"&amp;");
	p_sText=p_sText.replace(/</g,"&lt;");
	p_sText=p_sText.replace(/>/g,"&gt;");
	if(p_sText.match(/\uA025;\uA025/))
	{
		p_sText=p_sText.replace(/\uA025;\uA025/, '<span style="white-space:nowrap;">');
		p_sText=p_sText.replace(/\uA025;\uA025/g, '</span> <span style="white-space:nowrap;">');
		p_sText=p_sText+"</span>";
	};
	p_sText=p_sText.replace(/\uA025afk\uA025/g, '<img src="images/hourglass.gif" style="position: relative; top: 2px;" title="AFK">');
	p_sText=p_sText.replace(/\uA025adm\uA025/g, '<img src="images/star_gold.gif" style="position: relative; top: 2px;" title="Administrator">');
	p_sText=p_sText.replace(/\uA025op\uA025/g, '<img src="images/star_silver.gif" style="position: relative; top: 2px;" title="Moderator">');
	p_sText=p_sText.replace(/(http:\/\/\S*)/g, '<a href="$1" target="_blank">$1<\/a>');
	return p_sText;
};

PitPTOCtrlChat.prototype.SwitchTab=function(p_sTab)
{
	var xThis=this;
	if(this.m_iTimer!=-1)
	{
		window.clearTimeout(this.m_iTimer);
	};
	this.m_iChatUpdateTime=2000;
	this.UpdateTick();	
	if(p_sTab=="@")
	{
		pit_SetIH(this.m_xScrollBox.MakeEl(),"");
		this.UpdateRoomListDisplay();
	}
	else if(p_sTab=="@i")
	{
		pit_SetIH(this.m_xScrollBox.MakeEl(),"");
		this.UpdateIgnoreListDisplay();
	}
	else
	{
		var iIdx=this.FindRoom(p_sTab);
		if(iIdx!=-1)
		{
			pit_SetIH(this.m_xScrollBox.MakeEl(),"");
			this.UpdateRoomMsgDisplay(this.m_axRooms[iIdx]);
		};
		if(this.m_bReverseMessages)
		{
			this.m_xOutput.SetScrollPos(0);
		}
		else
		{
			this.m_xOutput.SetScrollPos(this.m_xOutput.GetScrollRange());
		};
	};
};

PitPTOCtrlChat.prototype.QueryIgnoreList=function()
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_xSubsTab.GetActiveTab());
	xRPC.SetParams("cmd","/ignored");
	xRPC.SetParams("time","0");
	xRPC.m_sCmd="/ignored";
	xRPC.m_bQuiet=true;
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	
	xRPC.OnSucceed=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);
		if(xThis&&xRPC.m_xResults.ign){
			xThis.m_asIgnoreList=xRPC.m_xResults.ign;
		};
	};
	
	xRPC.Send();
};

PitPTOCtrlChat.prototype.QueryRoomList=function()
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_xSubsTab.GetActiveTab());
	xRPC.SetParams("cmd","/list");
	xRPC.SetParams("time","0");
	xRPC.m_sCmd="/list";
	xRPC.m_bQuiet=true;
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	xRPC.OnSucceed=function(){
		var xD=xRPC.m_xResults;
		if(xD.status && xD.status=="ok")
		{
			var asNewList=new Array();
			var i,iC=xD.count;
			for(i=0;i<iC;i++)
			{
				asNewList.push(xD["E_"+i]);
			};
			asNewList.sort();
			var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
				if(xThis.m_sAutoRoom)
				{
					xThis.m_asRoomList=asNewList;
					var sR=xThis.m_sAutoRoom;
					xThis.m_sAutoRoom=null;
					xThis.GotoRoom(sR);
				}
				else
				{
					if(!asNewList.equal(xThis.m_asRoomList))
					{
						xThis.m_asRoomList=asNewList;
						if(xThis.m_xSubsTab.GetActiveTab()=="@")
						{
							xThis.UpdateRoomListDisplay();
						};
					};
				};
			};
		};
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
			xThis.ScheduleUpdate(10000);
		};
	};
	xRPC.OnFail=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
			xThis.ScheduleUpdate(10000);
		};
	};
	xRPC.Send();
};

PitPTOCtrlChat.prototype.SecondaryUpdate=function()
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	var i,iC=this.m_axRooms.length;
	if(iC==0){return;};
	var xRPC=new PitRPC();
	var sCmd="/#";
	for(i=0;i<iC;i++)
	{
		sCmd+=" \"#"+this.m_axRooms[i].m_sName+"\"";
	};
//	pit_LogT("QCM ",p_sRoom);
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("cmd",sCmd);
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	xRPC.OnSucceed=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.UpdateRoomMessages(xRPC);};
	};
	xRPC.OnFail=function(){
	};
	xRPC.Send();
};

PitPTOCtrlChat.prototype.QueryCurrentMessages=function(p_sRoom)
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	var xRPC=new PitRPC();
	var iIdx=this.FindRoom(p_sRoom);
	if(iIdx==-1){return;};
	var iTime=this.m_axRooms[iIdx].m_iLastTime;
//	pit_LogT("QCM ",p_sRoom);
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",p_sRoom);
	xRPC.SetParams("cmd","/?");
	xRPC.SetParams("time",iTime);
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	xRPC.OnSucceed=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
			xThis.UpdateRoomMessages(xRPC);
			xThis.ScheduleUpdate(xThis.m_iChatUpdateTime);
		};
	};
	xRPC.OnFail=function(){
		pit_Log("Fail:",xRPC.m_iStatus);
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){
			xThis.ScheduleUpdate(5000);
		};
	};
	xRPC.Send();
};

PitPTOCtrlChat.prototype.ScheduleUpdate=function(p_iTime)
{
	var hThis=this.m_hHnd;
	if(this.m_iTimer!=-1)
	{
		window.clearTimeout(this.m_iTimer);
	};
	this.m_iTimer=window.setTimeout(function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.UpdateTick();};
		},p_iTime);
};

PitPTOCtrlChat.prototype.UpdateTick=function()
{
	this.m_iTimer=-1;
	if(!this.m_xSubsTab){return;};
	var xNow=new Date();
	if(xNow-this.m_xLastSecondary>50000)
	{
		this.m_xLastSecondary=xNow;
		this.SecondaryUpdate();
		if(this.m_asIgnoreList!=-1) {this.QueryIgnoreList();};
	};
	if(this.m_asIgnoreList==-1) {this.QueryIgnoreList();};
	var sCurrentRoom=this.m_xSubsTab.GetActiveTab();
	if(sCurrentRoom=="@")
	{
		this.QueryRoomList();
	}
	else if(sCurrentRoom.length>0)
	{
		this.QueryCurrentMessages(sCurrentRoom);
	};
};

PitPTOCtrlChat.prototype.CreateUserElement=function(p_sUser)
{
	if(this.m_bUserInfo) {
		return "<a href='/community_viewprofile.html?"+p_sUser+"'>"+p_sUser+"</a>";
	} else {
		return p_sUser;
	};
};

PitPTOCtrlChat.prototype.CreateMessageDiv=function(p_xM,p_iLastTime)
{
	var xD=document.createElement("div");
	p_xM.m_xDiv=xD;
	var iType=p_xM.X;
	var bAdm=(iType&(1<<30))!=0;
	var bMod=(iType&(1<<31))!=0;
	iType&=~((1<<31)|(1<<30));
		
	if(this.m_asIgnoreList!=-1&&this.m_asIgnoreList.length>0)
	{
		if((!bAdm)&&(!bMod)&&(this.m_asIgnoreList.indexOf(p_xM.N)!=-1)) {return;};
	};
	
	if(iType==0)
	{
		xD.className=(bAdm&&this.m_xStyleDef.ChatLineClassAdm)?this.m_xStyleDef.ChatLineClassAdm:(bMod&&this.m_xStyleDef.ChatLineClassOp)?this.m_xStyleDef.ChatLineClassOp:this.m_xStyleDef.ChatLineClass;
		if((p_iLastTime)&&(p_xM.T-p_iLastTime>32*60*5))
		{
			var iT=Number(p_xM.T);
			var xDS=new Date();
			xDS.setTime((iT/32)*1000);
			if(!this.m_bReverseMessages)
			{
				pit_SetIH(xD,this.CreateUserElement(p_xM.N)+":&nbsp;"+this.EscapeText(p_xM.M)+"<br><span class='"+this.m_xStyleDef.ChatLineTimeSepClass+"'>["+pit_LeadZero2(""+xDS.getHours())+":"+pit_LeadZero2(""+xDS.getMinutes())+"]</span>");
			}
			else
			{
				pit_SetIH(xD,this.CreateUserElement(p_xM.N)+":&nbsp;"+this.EscapeText(p_xM.M)+"<br><span class='"+this.m_xStyleDef.ChatLineTimeSepClass+"'>["+pit_LeadZero2(""+xDS.getHours())+":"+pit_LeadZero2(""+xDS.getMinutes())+"]</span>");
			};
		}
		else
		{
			pit_SetIH(xD,this.CreateUserElement(p_xM.N)+":&nbsp;"+this.EscapeText(p_xM.M));
		};
	}
	else if(iType==1)
	{
		var iT=Number(p_xM.T);
		var xDS=new Date();
		xDS.setTime((iT/32)*1000);

		
		xD.className=this.m_xStyleDef.ChatLineSysClass;
		pit_SetIH(xD,"["+pit_LeadZero2(""+xDS.getHours())+":"+pit_LeadZero2(""+xDS.getMinutes())+"] "+p_xM.N+"&nbsp;"+this.EscapeText(p_xM.M));
	}
	else if(iType==2)
	{
		xD.className=this.m_xStyleDef.ChatLineUsrClass;
		pit_SetIH(xD,"* "+p_xM.N+"&nbsp;"+this.EscapeText(p_xM.M));
	}
	else if(iType==3)
	{
		xD.className=this.m_xStyleDef.ChatLineUsrClassMsg?this.m_xStyleDef.ChatLineUsrClassMsg:this.m_xStyleDef.ChatLineUsrClass;
		pit_SetIH(xD," "+p_xM.N+":&nbsp;"+this.EscapeText(p_xM.M));
	}
};

PitPTOCtrlChat.prototype.UpdateRoomMessages=function(p_xRPC)
{
	var xD=p_xRPC.m_xResults;
	if(!xD){pit_Log("JSON-Error:",p_xRPC.m_sResultText);return;};
	if(xD.cmd!="/?"){return;};
	var iR,iRC=xD.count;
	var bActivity=false;
	for(iR=0;iR<iRC;iR++)
	{
		var xRm=xD["E_"+iR];
		if(xRm)
		{
			if(xRm.status=="ok")
			{
				var iRIdx=this.FindRoom(xRm.room);
				if(iRIdx!=-1)
				{
					var xRoom=this.m_axRooms[iRIdx];
					if(xRoom.m_iLastTime==0)
					{
						var xB=this.m_xScrollBox;
						var xD=xB.MakeEl();

						for(var iM=0;iM<xRoom.m_axLines.length;iM++)
						{
							if(!xRoom.m_axLines[iM].m_xDiv) {continue;};
							xD.removeChild(xRoom.m_axLines[iM].m_xDiv);
							xRoom.m_axLines[iM].m_xDiv=null;
						};
					};
					
					var iM,iMC=xRm.count;
					if(iMC>0)
					{
						if(this.m_bSoundNotify) {this.SoundNotifyPlay();};
					
						for(iM=0;iM<iMC;iM++)
						{
							var xMSrc=xRm["M_"+iM];
							xMSrc.m_xDiv=null;
							if(xMSrc.T<=xRoom.m_iLastTime) {continue;}; //dup
							xRoom.m_axLines.push(xMSrc);
							xRoom.m_iLastTime=xMSrc.T;
						};
						if(xRm.room==this.m_xSubsTab.GetActiveTab())
						{
							this.UpdateRoomMsgDisplay(xRoom);
							bActivity=true;
						};
					};
					if(xRm.version!=xRoom.m_iVersion)
					{
						if(xRoom.m_iVersion!=-1) {xRoom.m_iLastTime=0;};
						xRoom.m_iVersion=xRm.version;
					};
				};
			}
			else if(xRm.status=="no_auth")
			{
				this.CloseRoom(xRm.room);
			};
		};
	};
	if(bActivity)
	{
		this.m_iChatUpdateTime=2000;
	}
	else
	{
		if(this.m_iChatUpdateTime<=10000)
		{
			this.m_iChatUpdateTime=this.m_iChatUpdateTime+200;
		};
	};
};

PitPTOCtrlChat.prototype.UpdateRoomMsgDisplay=function(p_xRoom)
{
	var xB=this.m_xScrollBox;
	var xD=xB.MakeEl();
	var bFullRefresh=false;
	if(!xD.firstChild){
		bFullRefresh=true;
	};
	var iOldScroll=this.m_xOutput.GetScrollPos();
	var iScrollRange=this.m_xOutput.GetScrollRange();
	var hThis=this.m_hHnd;
	var iM,iMC;
	if(this.m_bReverseMessages)
	{
		iMC=p_xRoom.m_axLines.length;
		while(iMC>128)
		{
			if(!bFullRefresh)
			{
				var xLast=xD.lastChild;
				xD.removeChild(xLast);
				pit_Purge(xLast);
				xLast=null;
			};
			p_xRoom.m_axLines.splice(0,1);
			iMC=p_xRoom.m_axLines.length;
		};
		if(bFullRefresh)
		{
			for(iM=0;iM<iMC;iM++)
			{
				p_xRoom.m_axLines[iM].m_xDiv=null;
			};
		};
		var iLastT=0;
		for(iM=0;iM<iMC;iM++)
		{
			var xL=p_xRoom.m_axLines[iM];
			if(!xL.m_xDiv)
			{
				this.CreateMessageDiv(xL,iLastT);
				xD.insertBefore(xL.m_xDiv,xD.firstChild);
			}
			else if(bFullRefresh)
			{
				xD.insertBefore(xL.m_xDiv,xD.firstChild);
			};
			iLastT=xL.T;
		};
		xB.SetAutoHeight();
		xB.UpdateRect();
		this.m_xOutput.RefreshAttributes();
		var iNewScroll=iOldScroll;
		if((iOldScroll>iScrollRange/2)&&(iScrollRange>1))
		{
			iOldScroll=iScrollRange-iOldScroll;
			iScrollRange=this.m_xOutput.GetScrollRange();
			iOldScroll=iScrollRange-iOldScroll;
			if(iOldScroll>iScrollRange){iOldScroll=iScrollRange;};
			this.m_xOutput.SetScrollPos(iOldScroll-1,false);
			this.m_xOutput.SetScrollPos(iOldScroll,true);
		}
		else
		{
			iScrollRange=this.m_xOutput.GetScrollRange();
			if(iOldScroll>iScrollRange){iOldScroll=iScrollRange;};
			this.m_xOutput.SetScrollPos(iOldScroll+1,false);
			this.m_xOutput.SetScrollPos(iOldScroll,true);
		};
	}
	else
	{
		iMC=p_xRoom.m_axLines.length;
		while(iMC>128)
		{
			if(!bFullRefresh)
			{
				var xLast=xD.firstChild;
				xD.removeChild(xLast);
				pit_Purge(xLast);
				xLast=null;
			};
			p_xRoom.m_axLines.splice(0,1);
			iMC=p_xRoom.m_axLines.length;
		};
		if(bFullRefresh)
		{
			for(iM=0;iM<iMC;iM++)
			{
				p_xRoom.m_axLines[iM].m_xDiv=null;
			};
		};
		var iLastT=0;
		for(iM=0;iM<iMC;iM++)
		{
			var xL=p_xRoom.m_axLines[iM];
			if(!xL.m_xDiv)
			{
				this.CreateMessageDiv(xL,iLastT);
				xD.appendChild(xL.m_xDiv);
			}
			else if(bFullRefresh)
			{
				xD.appendChild(xL.m_xDiv);
			};
			iLastT=xL.T;
		};
		xB.SetAutoHeight();
		xB.UpdateRect();
		this.m_xOutput.RefreshAttributes();
		var iNewScroll=iOldScroll;
		if(iOldScroll>iScrollRange/2)
		{
			iOldScroll=iScrollRange-iOldScroll;
			iScrollRange=this.m_xOutput.GetScrollRange();
			iOldScroll=iScrollRange-iOldScroll;
			if(iOldScroll>iScrollRange){iOldScroll=iScrollRange;};
			this.m_xOutput.SetScrollPos(iOldScroll-1,false);
			this.m_xOutput.SetScrollPos(iOldScroll,true);
		}
		else
		{
			iScrollRange=this.m_xOutput.GetScrollRange();
			if(iOldScroll>iScrollRange){iOldScroll=iScrollRange;};
			this.m_xOutput.SetScrollPos(iOldScroll+1,false);
			this.m_xOutput.SetScrollPos(iOldScroll,true);
		};
	};
};

PitPTOCtrlChat.prototype.UpdateRoomListDisplay=function()
{
	var xNewBox=this.m_xScrollBox;
	var xD=xNewBox.MakeEl();
	xD.className="chatpnl";
	pit_SetIH(xD,"");
	var i,iC=this.m_asRoomList.length;
	var hThis=this.m_hHnd;
	for(i=0;i<iC;i++)
	{
		var sRoom=this.m_asRoomList[i];
		var xS=document.createElement("a");
		xS.className="chatbtn";
		xS.style.color=this.m_sRoomListTextColor;
		xS.href="javascript:/**/";
		xS.onmouseup=function(sR){
			return function(){
				var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.GotoRoom(sR);};
			}}(sRoom);
		pit_SetIH(xS,this.EscapeText(sRoom));
		xD.appendChild(xS);
		xD.appendChild(document.createElement("br"));
	};
	xNewBox.SetAutoHeight();
	this.m_xOutput.SetScrollPos(0,true);
	this.m_xOutput.RefreshAttributes();
};

PitPTOCtrlChat.prototype.UpdateIgnoreListDisplay=function()
{
	var xNewBox=this.m_xScrollBox;
	var xD=xNewBox.MakeEl();
	xD.className="chatpnl";
	pit_SetIH(xD,"");
	var i,iC=this.m_asIgnoreList.length;
	var hThis=this.m_hHnd;
	for(i=0;i<iC;i++)
	{
		var sIgnore=this.m_asIgnoreList[i];
		var xS=document.createElement("a");
		xS.className="chatbtn";
		xS.style.color=this.m_sRoomListTextColor;
		xS.href="javascript:/**/";
		xS.onmouseup=function(sR){
			return function(){
				var xThis=g_xPitBoxes.GetBox(hThis);
				if(xThis){xThis.SendChatCommand("/unignore "+sR);};
			}}(sIgnore);
		pit_SetIH(xS,this.EscapeText(sIgnore));
		xD.appendChild(xS);
		xD.appendChild(document.createElement("br"));
	};
	xNewBox.SetAutoHeight();
	this.m_xOutput.SetScrollPos(0,true);
	this.m_xOutput.RefreshAttributes();
};

PitPTOCtrlChat.prototype.FindRoom=function(p_sRoom)
{
	var i,iC=this.m_axRooms.length;
	for(i=0;i<iC;i++)
	{
		if(this.m_axRooms[i].m_sName==p_sRoom){return i;};
	};
	return -1;
};

PitPTOCtrlChat.prototype.CreateRoomTab=function(p_sRoom)
{
	var iIdx=this.FindRoom(p_sRoom);
	if(iIdx!=-1){return;};
	var xR=new Object();
	xR.m_sName=p_sRoom;
	xR.m_axLines=new Array();
	xR.m_iLastTime=0;
	xR.m_iVersion=-1;
	this.m_axRooms.push(xR);
	this.m_xSubsTab.AddSingleTab(p_sRoom);
	this.m_xSubsTab.MoveTab("@");
	this.m_xSubsTab.SetActiveTab(p_sRoom);
	this.ScheduleUpdate(100);
};

PitPTOCtrlChat.prototype.CloseRoom=function(p_sRoom)
{
	var iIdx=this.FindRoom(p_sRoom);
	if(iIdx==-1){return;};
	this.m_xSubsTab.CloseTab(p_sRoom);
	this.m_axRooms.splice(iIdx,1);
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_xSubsTab.GetActiveTab());
	xRPC.SetParams("cmd","/leave \"#"+p_sRoom+"\"");
	xRPC.SetParams("time","0");
	xRPC.SetComplex(false);
	xRPC.Send();
};

PitPTOCtrlChat.prototype.GotoRoom=function(p_sRoom)
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	if(this.FindRoom(p_sRoom)==-1)
	{
		this.JoinRoom(p_sRoom);
		return;
	};
};

PitPTOCtrlChat.prototype.JoinRoom=function(p_sRoom)
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_xSubsTab.GetActiveTab());
	xRPC.SetParams("cmd","/join \"#"+p_sRoom+"\"");
	xRPC.SetParams("time","0");
	xRPC.SetComplex(true);
	xRPC.m_bQuiet=true;
	var hThis=this.m_hHnd;
	xRPC.OnSucceed=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.DoneChatCommand(xRPC);};
	};
	xRPC.OnFail=function(){
	};
	xRPC.Send();
};

PitPTOCtrlChat.prototype.DoneChatCommand=function(p_xRPC)
{
	var xD=p_xRPC.m_xResults;
	if(!xD)
	{
		pit_Log("JSON-Error:",p_xRPC.m_sResultText);
		return;
	};
//	pit_Log("Done: ",p_xRPC.m_sResultText);
	if(xD.cmd=="/join")
	{
		var i,iC=xD.count;
		for(i=0;i<iC;i++)
		{
			if(xD["E_"+i].status=="ok")
			{
				this.CreateRoomTab(xD["E_"+i].room);
			};
		};
	};
	if(xD.cmd=="/ignore"||xD.cmd=="/unignore"||xD.cmd=="/ignored")
	{
		if(xD.ign)
		{
			this.m_asIgnoreList=xD.ign;
			if(this.m_xSubsTab.GetActiveTab()=="@i")
			{
				this.UpdateIgnoreListDisplay();
			};
		};
	};
	if(xD.cmd=="/ignored")
	{
		if(this.m_xSubsTab.FindTab("@i")==-1)
		{
			this.m_xSubsTab.AddSingleTab("@i",0,false,"Ignore");
		};
	};
};

PitPTOCtrlChat.prototype.ShowClientSytemMsg=function(p_sName,p_sMsg)
{
	var iIdx=this.FindRoom(this.m_xSubsTab.GetActiveTab());
	if(iIdx==-1) {return;};
	var xRoom=this.m_axRooms[iIdx];
	var iT=(new Date()).getTime()/1000*32;
	xRoom.m_axLines.push({"X":1,"N":p_sName,"T":iT,"M":p_sMsg});
	this.UpdateRoomMsgDisplay(xRoom);
}

PitPTOCtrlChat.prototype.SendChatCommand=function(p_sCmd)
{
	if((!this.m_sRPCURL)||(this.m_sRPCURL.length==0)){return;};
	
	if(this.m_xSubsTab.GetActiveTab()=="@i")
	{
		if(p_sCmd.slice(0,1)!="/") {p_sCmd="/ignore "+p_sCmd;};
	};
	
	var asCmd=p_sCmd.replace(/^\s+/, '').toLowerCase().split(" ");
	
	if(asCmd.length>0)
	{
		if(asCmd[0]=="/sound")
		{
			if(this.m_xSoundPlayer==1) {this.ShowClientSytemMsg("Sound:","No Audio supported by browser!");return;};
			

			var bShowStatus=false;
			var bSaveStatus=false;
			if(asCmd.length>1)
			{
				var sOpt=asCmd[1];
				if(sOpt=="test") {this.SoundNotifyPlay();}
				else if(sOpt=="set") {this.m_xStyleDef.SoundNotify=asCmd[2];this.SoundNotifyLoad();}
				else if(sOpt=="on") {this.m_bSoundNotify=true;bShowStatus=true;bSaveStatus=true;}
				else if(sOpt=="off") {this.m_bSoundNotify=false;bShowStatus=true;bSaveStatus=true;}
				else {this.ShowClientSytemMsg("Sound Notification:","Invalid Command:"+sOpt);}
			}
			else
			{
				bShowStatus=true;
			};
			if(bSaveStatus)
			{
				pit_SetCookie("pitChatSndNot",this.m_bSoundNotify?"1":"0");
			};
			if(bShowStatus)
			{
				this.ShowClientSytemMsg("Sound Notification:",this.m_bSoundNotify?"On":"Off");
			};
			return;
		};
	};
	
	var xRPC=new PitRPC();
	xRPC.SetURL(this.m_sRPCURL);
	xRPC.SetFunction("chat");
	xRPC.SetParams("room",this.m_xSubsTab.GetActiveTab());
	xRPC.SetParams("cmd",p_sCmd);
	xRPC.SetParams("time","0");
	xRPC.m_sCmd="/?";
	xRPC.m_bQuiet=true;
	xRPC.SetComplex(true);
	var hThis=this.m_hHnd;
	xRPC.OnSucceed=function(){
		var xThis=g_xPitBoxes.GetBox(hThis);if(xThis){xThis.DoneChatCommand(xRPC);};
	};
	xRPC.OnFail=function(){
	};
	xRPC.Send();
	this.m_iChatUpdateTime=2000;
	this.ScheduleUpdate(100);
};

PitPTOCtrlChat.prototype.SoundNotifyLoad=function()
{
	try {
		this.m_xSoundPlayer=new Audio();
		var sMP3=this.m_xSoundPlayer.canPlayType("audio/mpeg");
		if(sMP3==""||sMP3=="no") {this.m_xStyleDef.SoundNotify=this.m_xStyleDef.SoundNotify.replace(".mp3",".ogg");};
		this.m_xSoundPlayer=new Audio(this.m_xStyleDef.SoundNotify);
		
	} catch(e) {this.m_xSoundPlayer=1;return;};
};

PitPTOCtrlChat.prototype.SoundNotifyPlay=function()
{
	if(this.m_xSoundPlayer==null) {this.SoundNotifyLoad();};
	if(this.m_xSoundPlayer==1||this.m_xSoundPlayer==null) {return;};
	this.m_xSoundPlayer.play();
}

PitPTOCtrlChat.prototype.OpenChat=function(p_sURL,p_sAutoRoom)
{
	this.m_sAutoRoom=p_sAutoRoom;
	this.m_axRooms=new Array();
	this.m_xSubsTab.CloseAllTabs();
	this.m_xSubsTab.AddSingleTab("@",0,true,"Rooms");
	this.m_xSubsTab.SetActiveTab("@");
	this.m_sRPCURL=p_sURL;
	this.ScheduleUpdate(100);
//	this.SendChatCommand("/list",true,"roomlist");
//	this.SwitchTab("Rooms");
};

