Index: viewHistory.php
===================================================================
--- viewHistory.php	(revision 0)
+++ viewHistory.php	(revision 0)
@@ -0,0 +1,51 @@
+<?
+/*
+ * licqweb. Copyright 2005, Philip Nelson
+ *
+ * This file is part of licqweb.
+ *
+ * licqweb is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * licqweb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with licqweb; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+require_once('config.php');
+require_once('rms.php');
+
+session_start();
+$uin = $_SESSION['uin'];
+$password = $_SESSION['password'];
+session_write_close();
+
+if (!rmsLogin("$uin\r\n", "$password\r\n")) {
+	header('Content-Type: text/xml');
+	echo "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
+	echo "<response><method>loginFailed</method><result>Couldn't log in to rms plugin!</result></response>";
+	exit;
+}
+
+$messagesXML="";
+
+$messages = rmsViewHistory($_GET['id'], $_GET['pp'], $_GET["lenght"], $_GET["offset"]);
+foreach ($messages as $message)
+	$messagesXML .= "<message>" . xmlentities($message['msg']) . "</message><from>".$message['from']."</from><time>" . $message['time'] . "</time>";
+
+
+header('Content-Type: text/xml');
+echo "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
+echo "
+<response>
+  <method>viewHistory</method>
+  <result><id>" . $_GET['id'] . "</id><pp>" . $_GET['pp'] . "</pp><messages>$messagesXML</messages></result>
+</response>
+";
+?>

Property changes on: viewHistory.php
___________________________________________________________________
Name: svn:executable
   + *

Index: rms.php
===================================================================
--- rms.php	(revision 6178)
+++ rms.php	(working copy)
@@ -259,4 +259,51 @@
 function xmlentities ($string) {
    return str_replace (array('&', '"', "'", '<', '>'), array ('&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;'), $string);
 }
+
+function rmsViewHistory($id, $pp, $lenght = 10, $offset = 0) {
+	global $sock;
+	$result = array();
+	
+	$cmd = "HISTORY " . $id . "." . $pp . " " . $lenght . " " . $offset . "\r\n";
+	sendData($cmd);
+
+	$packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+	if (substr($packet, 0, 3) >= 400) {
+		return false;
+	}
+	
+   // kses input filtering
+	$allowed = array('b' => array(),
+					 'i' => array(),
+					 'a' => array('href' => 1, 'title' => 1),
+					 'p' => array('align' => 1),
+					 'br' => array(),
+					 'font' => array('size' => 1, 'color' => 1, 'face' => 1)
+					);
+	
+	while(!preg_match("/^232 /", $packet)) {
+	
+	   $msg = "";
+	   $from = substr($packet, 16);
+	   $packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+   	$snttime = substr($packet, 12);
+   
+   	$packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+   	$packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+   	
+   	while(!preg_match("/^223 /", $packet)){
+   	  $msg .= (($msg!="")?"<br/>":"").$packet;
+   	  $packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+   	}
+   	
+   	if (get_magic_quotes_gpc()) {
+   		$msg = stripslashes($msg);
+   	}
+   	$result[] = array('msg' => kses($msg, $allowed), 'time' => trim($snttime), 'from' => trim($from));
+   	
+   	$packet = socket_read($sock, 1024, PHP_NORMAL_READ);
+	}
+	return $result;
+}
+
 ?>
Index: index.php
===================================================================
--- index.php	(revision 6178)
+++ index.php	(working copy)
@@ -4,10 +4,11 @@
         <title>licq</title>
 		<link rel="StyleSheet" type="text/css" href="licqweb.css" />
 		<link rel="shortcut icon" href="images/favicon.ico">
+		<script type="text/javascript" src="licqweb.js" />
     </head>
-    <body onload="checkSession()">
+    <body onload="init()">
 	<div id="tooltip"></div>
-	<script type="text/javascript" src="licqweb.js" />
+
     <h1>licq<i><font color="#5555ff">web</font></i></h1>
 	<div id="login" class="loginwin">
 		<div class="bar">licqweb login</div>
@@ -20,7 +21,12 @@
 	<div id="contactList" class="box" style="left:10px;top:150px;display:none;">
 		<div class="bar" onmousedown="init_drag(event, 'contactList')" id="nick">licqweb</div>
 		<div id="contacts"></div>
-		<div id="ownerStatus"></div>
+		<div style="display:box;height:18px">
+		 <div id="ownerStatus"></div>
+		 <div class="resizer" onmousedown="init_resize(event, 'contacts', 100, 100)">
+		    <img class="resizerImage" src="images/resizer.png" />
+		 </div>
+		</div>
 	</div>
 	<div id="statusMenu"></div>
 	<div id="windows"></div>
Index: licqweb.js
===================================================================
--- licqweb.js	(revision 6178)
+++ licqweb.js	(working copy)
@@ -19,8 +19,9 @@
  */
 
 //option vars
-var showOffline = false;
+var showOffline = true;
 var maxLogLines = 20;
+var showHistory = true;
 
 var xmlhttp = new XMLHttpRequest(); //for serverpush connection
 xmlhttp.multipart = true;
@@ -116,7 +117,7 @@
 	var messages = response.getElementsByTagName('message');
 	var times = response.getElementsByTagName('time');
 	for (var i = 0; i < messages.length; ++i) {
-		txtdiv.innerHTML += '(' + times[i].firstChild.data + ') ' + contacts[pp][id].nick + ': ' + messages[i].firstChild.data + "<br/>";
+		txtdiv.innerHTML += '(<span class="msgDate">' + times[i].firstChild.data + '</span>) <span class="msgNick">' + contacts[pp][id].nick + '</span>: <span class="msgText">' + messages[i].firstChild.data + "</span><br/>";
 	}
 	txtdiv.scrollTop = txtdiv.scrollHeight;
 }
@@ -168,7 +169,7 @@
 			} else {
 				pp = contact.pp.toLowerCase();
 			}
-			var imgsrc = "images/" + pp + "." + contact.status.toLowerCase() + ".png";
+			var imgsrc = "images/" + pp + "." + contact.status.toLowerCase().replace(" ","") + ".png";
 			if (parseInt(contact.nummsgs) > 0) {
 				uclass = "newmessage";
 				imgsrc = "images/msg.png";
@@ -192,6 +193,7 @@
 		contacts[pp][id].status = status;
 		contacts[pp][id].nummsgs = messages;
 		contacts[pp][id].nick = nick;
+		contacts[pp][id].historyShowed = false;
 	} else {
 		contacts[pp][id] = new Contact(id, pp, nick, status, messages);
 		var newcontact = document.createElement('div');
@@ -205,14 +207,15 @@
 
 function getWindowHtml(id, pp, nick) {
 	var key = id + '-' + pp;
-	return "<div class=\"window\" style=\"left:300px;top:150px\" id=\"" + key + "-w\">" +
+	return "<div onClick=\"set_focus(event, '" + key + "')\" class=\"window\" style=\"left:300px;top:150px\" id=\"" + key + "-w\">" +
 				"<div onmousedown=\"init_drag(event, '" + key + "-w')\" class=\"bar\">" +
 					"<div class=\"wintitle\">" + nick + " (" + pp + ")</div>" +
 					"<div onclick=\"showContactWindow('" + id + "', '" + pp + "')\" class=\"close\">[close]</div>" +
 				"</div>" +
 				"<div class=\"convo\" id=\"" + key + "-txt\"></div>" + 
-				"<div class=\"msginput\"><textarea id=\"" + key + "-input\" onKeyPress=\"textarea_keypress(event, '" + id + "', '" + pp + "')\"></textarea><br>" +
+				"<div class=\"msginput\"><textarea id=\"" + key + "-input\" onKeyPress=\"textarea_keypress(event, '" + id + "', '" + pp + "')\" ></textarea><br>" +
 					"<input type=\"submit\" class=\"button\" value=\"Send\" onclick=\"sendMessage('" + id + "', '" + pp + "'); return false\" />" +
+					"<div class=\"resizer\" onmousedown=\"init_resize(event, '" + key + "-txt', 150, 50)\"><img class=\"resizerImage\" src=\"images/resizerMsg.png\" /></div>" +
 				"</div>" +
 			"</div>";
 }
@@ -250,7 +253,7 @@
 	var message = ackMessages[uid];
 	var txt = document.getElementById(message.id + '-' + message.pp + '-txt');
 	if (res == "done.") {
-		txt.innerHTML += "(" + ts + ") " + nick + ": " + message.message.replace(/[\r\n]+/g, "<br/>") + "<br/>";
+		txt.innerHTML += "(<span class=\"msgDate\">" + ts + "</span>) <span class=\"msgNick\">" + nick + "</span>: <span class=\"msgText\">" + message.message.replace(/[\r\n]+/g, "<br/>") + "</span><br/>";
 	} else {
 		txt.innerHTML += "--- Message failed!<br/>";
 	}
@@ -264,6 +267,11 @@
 	if (contacts[pp][id].nummsgs > 0) {
 		requestViewEvent(id, pp);
 	}
+	if(showHistory==true && contacts[pp][id].historyShowed != true){
+	   requestViewHistory(id, pp);
+	   contacts[pp][id].historyShowed = true;
+	}
+	   
 	win = document.getElementById(id + '-' + pp + '-w');
 	if (win.style.display == 'block') {
 		win.style.display = 'none';
@@ -272,7 +280,7 @@
 	}
 	var txtdiv = document.getElementById(id + '-' + pp + '-txt');
 	txtdiv.scrollTop = txtdiv.scrollHeight;
-	//win.style.zIndex = ++dragwin.win.style.zIndex;
+	win.style.zIndex = ++dragwin.zIndex;
 	//dragwin.win = win;
 }
 
@@ -315,7 +323,7 @@
 			document.getElementById(key + '-i').src = "images/msg.png";
 		} else {
 			document.getElementById(key + '-s').className = contacts[pp][id].status;
-			document.getElementById(key + '-i').src = "images/" + pp.toLowerCase() + "." + contacts[pp][id].status.toLowerCase() + '.png';
+			document.getElementById(key + '-i').src = "images/" + pp.toLowerCase() + "." + contacts[pp][id].status.toLowerCase().replace(" ","") + '.png';
 		}
 	} else {
 	}
@@ -340,7 +348,7 @@
 function _updateOwners() {
 	var statushtml = "";
 	for (var pp in owners) {
-		statushtml += "<img onclick=\"showSelectStatus(event, '" + owners[pp].id + "', '" + pp + "'); return false\" src=\"images/" + pp.toLowerCase() + "." + owners[pp].status.toLowerCase() + ".png\"/> ";
+		statushtml += "<img onclick=\"showSelectStatus(event, '" + owners[pp].id + "', '" + pp + "'); return false\" src=\"images/" + pp.toLowerCase() + "." + owners[pp].status.toLowerCase().replace(" ","") + ".png\"/> ";
 	}
 	document.getElementById('ownerStatus').innerHTML = statushtml;
 }
@@ -352,7 +360,7 @@
 	statuss["MSN"] = new Array('Online', 'Away', 'Occupied');
 	var statushtml = "";
 	for (var i = 0; i < statuss[pp].length; ++i) {
-		statushtml += "<div onclick=\"changeStatus('" + pp + "', '" + statuss[pp][i] + "')\"><img src=\"images/" + pp.toLowerCase() + "." + statuss[pp][i].toLowerCase() + ".png\">" + statuss[pp][i] + "</div>";
+		statushtml += "<div onclick=\"changeStatus('" + pp + "', '" + statuss[pp][i] + "')\"><img src=\"images/" + pp.toLowerCase() + "." + statuss[pp][i].toLowerCase().replace(" ","") + ".png\">" + statuss[pp][i] + "</div>";
 	}
 	statusMenu.innerHTML = statushtml;
 	statusMenu.style.left = e.pageX;
@@ -428,7 +436,7 @@
 
 /* Tool tip stuff */
 var enabletip = false;
-var tooltip = document.getElementById('tooltip');
+var tooltip = null;
 
 function showToolTip(pp, id){
 	tooltip.innerHTML = contacts[pp][id].id + ' (' + contacts[pp][id].pp + ')<br>' + contacts[pp][id].status + '<br>Messages: ' + contacts[pp][id].nummsgs;
@@ -460,10 +468,8 @@
 dragwin.zIndex = 0;
 
 function init_drag(event, id) {
-	var el;
-	var x, y;
 
-	dragwin.win = document.getElementById(id);
+   dragwin.win = document.getElementById(id);
 
 	dragwin.startX = event.clientX + window.scrollX;
 	dragwin.startY = event.clientY + window.scrollY;
@@ -494,3 +500,93 @@
 	document.removeEventListener("mousemove", start_drag, true);
 	document.removeEventListener("mouseup", stop_drag, true);
 }
+
+function set_focus(event, key){
+   win = document.getElementById(key + "-w");
+   win.style.zIndex = ++dragwin.zIndex;
+   event.preventDefault();
+   
+   /*input = document.getElementById(key + "-input");
+   input.focus();*/
+   
+   //stop_propagate(event);
+}
+
+function stop_propagate(event){
+   if (!event) var event = window.event;
+	event.cancelBubble = true;
+	if (event.stopPropagation) event.stopPropagation();
+}
+
+/* Window resizing stuff */
+var resizewin = new Object();
+
+function init_resize(event, id, minW, minH) {
+	resizewin.win = document.getElementById(id);
+	resizewin.minW = minW;
+	resizewin.minH = minH;
+
+	resizewin.startX = event.clientX + window.scrollX;
+	resizewin.startY = event.clientY + window.scrollY;
+	resizewin.startWidth = parseInt(resizewin.win.style.width, 10);
+	resizewin.startHeight = parseInt(resizewin.win.style.height,  10);
+
+	if (isNaN(resizewin.startWidth)) resizewin.startWidth = resizewin.win.offsetWidth;
+	if (isNaN(resizewin.startHeight)) resizewin.startHeight = resizewin.win.offsetHeight;
+
+	//resizewin.win.style.zIndex = ++resizewin.zIndex;
+
+	document.addEventListener("mousemove", do_resize, true);
+	document.addEventListener("mouseup", stop_resize, true);
+	event.preventDefault();
+}
+
+function do_resize(event) {
+	var x, y;
+	x = event.clientX + window.scrollX;
+	y = event.clientY + window.scrollY;
+
+	
+	if(resizewin.minW < (resizewin.startWidth + x - resizewin.startX)){
+	  resizewin.win.style.width = (resizewin.startWidth + x - resizewin.startX) + "px";
+	  
+	  /*Sorry for this hack. Mozilla does not shrink parent DIV according to the content (until redraw).*/
+	  resizewin.win.parentNode.style.width = (resizewin.startWidth + x - resizewin.startX) + "px";
+	}
+   if(resizewin.minH < (resizewin.startHeight + y - resizewin.startY)){
+	  resizewin.win.style.height = (resizewin.startHeight + y - resizewin.startY) + "px";
+   }
+	
+	event.preventDefault();
+}
+
+function stop_resize(event) {
+	document.removeEventListener("mousemove", do_resize, true);
+	document.removeEventListener("mouseup", stop_resize, true);
+}
+
+function init(){
+   checkSession();
+   
+   tooltip = document.getElementById('tooltip'); //Sometimes tooltip variable was null
+}
+
+function requestViewHistory(id, pp) {
+	xmlhttp2 = new XMLHttpRequest();
+	xmlhttp2.onreadystatechange = acceptResponse2;
+	xmlhttp2.open("GET", baseurl + "/viewHistory.php?id=" + id + "&pp=" + pp + "&lenght=10&offset=0", true);
+	xmlhttp2.send(null);
+}
+
+function viewHistory(response) {
+	var id = response.getElementsByTagName('id')[0].firstChild.data;
+	var pp = response.getElementsByTagName('pp')[0].firstChild.data;
+	var txtdiv = document.getElementById(id + '-' + pp + '-txt');
+	var messages = response.getElementsByTagName('message');
+	var times = response.getElementsByTagName('time');
+	var froms = response.getElementsByTagName('from');
+	for (var i = messages.length-1; i >=0 ; --i) {
+		txtdiv.innerHTML += '(<span class="msgDate">' + times[i].firstChild.data + '</span>) <span class="msgNick">' + froms[i].firstChild.data + '</span>: <span class="msgText">' + messages[i].firstChild.data + "</span><br/>";
+	}
+	txtdiv.scrollTop = txtdiv.scrollHeight;
+}
\ No newline at end of file
Index: images/resizer.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: images/resizer.png
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Index: images/resizerMsg.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: images/resizerMsg.png
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Index: licqweb.css
===================================================================
--- licqweb.css	(revision 6178)
+++ licqweb.css	(working copy)
@@ -108,6 +108,26 @@
 	left: 300px;
 }
 
+#ownerStatus {
+   left:0px;
+   width:20px;
+   position:absolute;
+}
+
+.resizer {
+   right:0px;
+   bottom:0px;
+   width:18px;
+   height:18px;
+   position:absolute;
+}
+
+.resizerImage {
+   bottom:0px;
+   position:absolute;
+   right:0px;
+}
+
 .box {
 	background-color: #eee;
 	border: 1px solid #000000;
@@ -128,12 +148,13 @@
 	max-width: 350px;
 	overflow: hidden;
 	float: left;
+	cursor: Default;
 }
 
 .close {
 	background-color: #333355;
 	float: right;	
-    cursor: pointer;
+   cursor: pointer;
 }
 
 .content {
@@ -218,3 +239,16 @@
 	border: 1px solid #8ca8cf;
 	width: 100px;
 }
+
+.msgText {
+   color: #000000;
+}
+
+.msgDate {
+   color: #FF0000;
+}
+
+.msgNick {
+   color: #0000FF;
+   font-weight: bold;
+}
\ No newline at end of file
