/*** Utility functions ***/
var debug = 0;
var oneCom = null;

var is_ie = /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent);


function newin(id, aid, revert, opacity) {
	var e = Elem(id);
	if (!opacity) {
		opacity = 200;
		Elem(aid).style.background  = 'black';
		Elem(aid).style.color  = 'white';
	}
	if (!revert) revert = 0;
	opacity -= 5;
	if (opacity < 0) opacity = 0;
	e.parentNode.style.backgroundColor = "rgb(200,255," + (200 - opacity) + ")";
	if (opacity > 50) {
		setTimeout("newin('" + id + "', '" + aid + "', " + (revert || 0) + ", " + opacity + ")", 35);
	} else {
		if (revert) e.value = com.content[id];
		e.parentNode.style.backgroundColor = "rgb(245, 245, 245)";
		Elem(aid).style.background  = 'white';
		Elem(aid).style.color  = 'black';
	}
}


function errorin(id, opacity) {
	if (!opacity) opacity = 238;
	opacity -= 3;
	if (opacity < 0) opacity = 0;
	var e = Elem(id);
	e.parentNode.style.backgroundColor = "rgb(238," + (238 - opacity) + "," + (255 - opacity) + ")";
	if (opacity > 0) {
		setTimeout("errorin('" + id + "', " + opacity + ")", 3);
	}
}


/** SOCIALNODE ( Adds content to on-screen chat windows, like the social timeline) **/

SocialNode = function(e, o, ms) {
	var box = newElem('div', { 'class': 'socialnode' });
	if (o.from) {
		box.appendChild( newElem('div', { 'class' : 'author' }, o.from.screenname + ' says:' ) );
		box.appendChild( newElem('div', { 'class' : 'content' }, o.content ) );
	} else {
		box.appendChild( newElem('div', { 'class' : 'content' }, o.content ) );
	}
	children = e.getElementsByTagName("DIV");
	// e.insertBefore(box, children[0]);
	e.appendChild(box);
	e.scrollTop = e.scrollHeight;

	this.box = box;
	this.id = box.id;

	this.socialin();
}

SocialNode.prototype = {
	socialin : function() {
		if (!this.opacity) this.opacity = 100;
		this.opacity -= 1;
		this.box.style.backgroundColor = "rgb(255,255," + (255 - this.opacity) + ")";
		var _this = this;
		if (this.opacity > 0)
			setTimeout(function() { _this.socialin(); }, 4);
			//setTimeout(function (thisobj) { thisobj.socialin(); }, 4, this);
	}
};

/** ALERTBOX (Alerts that drop down from the top of the screen) **/

AlertBox = function(o, ms) { 
	var e = Elem('notifications');
	if (!e) return;
	var box = newElem('div', { 'class': 'chatbox' });
	box.style.display = 'none';

	this.box = box; 
	this.id = box.id;

	if (o.type == 'info') {
		box.appendChild( newElem( 'div', { 'class' : 'chatboxin' }, o.content) );
	} else {
		var div = box.appendChild( newElem( 'div', { 'class' : 'chatboxin' }) );
		div.appendChild( newElem( 'div', { 'class' : 'author' }, o.from.screenname + " says:") );
		div.appendChild( newText( o.content ) );
	}
	box.onclick = function(e) { 
		var msg = "Chat ";
		var pre = "with ";
		if (o.members) {
			for (var m=0, ml = o.members.length; m<ml; m++) {
				if (o.members[m].id == com.user) continue;
				msg = msg + pre + o.members[m].screenname;
				pre = ", ";
			}
		} else if (o.topic == com.page_topic) {
			msg = 'Story chat';
			if (com.title) {
				msg = msg + ": " + com.title;
			}
		}
		com.init_chat( o.topic, msg) ;
		Elem('topicmsg' + o.topic).value = '__open';
		com.send('topicmsg' + o.topic, o.topic);
		Elem('topicmsg' + o.topic).value = '';
	};
	children = e.getElementsByTagName("DIV");
	if (children.length) {
		e.insertBefore(box, children[0]);
	} else {
		e.appendChild(box);
	}
	var _this = this;
	setTimeout(function () { _this.fadein(); }, ms);
	setTimeout(function () { _this.opacity = null; _this.fadeaway(); }, 5000 + ms);
};

AlertBox.prototype = {
	fadein : function () {
		if (!this.opacity) this.opacity = -55;
		this.box.style.display = 'block';
		this.box.style.marginTop = this.opacity + 'px';
		this.opacity += 4;
		var _this = this;
		if (this.opacity < 0)
			setTimeout(function () { _this.fadein(); }, 2);
	},
	fadeaway : function () {
		if (!this.opacity) this.opacity = 100;
		if (this.opacity > 10) {
			this.box.style.opacity = this.opacity / 100;
			this.opacity *= 0.9;
			var _this = this;
			setTimeout(function () { _this.fadeaway(); }, 20);
		} else {
			this.box.style.display = 'none';
		}
	}
};

/** COMMUNICATOR **/

WallLayout = function() {}
WallLayout.prototype = {
	add_columns : 0,
	del_columns : 0,
	show_columns : 0,
	show_footer : 0,
	scenes : 0,
	style : 'wall',
	cell_movable : 1,
	cell_header : 1,
	cell_attach : 1,
	timeline: 0,
	btn_add_scene : 0
};
NewPlanLayout = function() {}
NewPlanLayout.prototype = {
	add_columns : 1,
	del_columns : 1,
	show_columns : 1,
	show_footer : 1,
	scenes : 1,
	style : 'tabular',
	cell_movable : 0,
	cell_header : 0,
	cell_attach : 0,
	btn_add_scene : 1,
	timeline: 1
};
PlanLayout = function() {}
PlanLayout.prototype = {
	add_columns : 1,
	del_columns : 1,
	show_columns : 1,
	show_footer : 1,
	scenes : 1,
	style : 'tabular',
	cell_movable : 0,
	cell_header : 0,
	cell_attach : 0,
	btn_add_scene : 1
};

Communicator = function () { 
}

Communicator.prototype = {
	failed : 0,
	story : 0,
	user : 0,
	locks : {},
	lockupdate : 0,
	session: 0,
	in_playback: 0,
	is_member: 0,
	online : [],
	mode: 'updates',
	currelem : null,
	wantedelem : null,
	oldelem : null,
	activerequest : null,
	updatefrequence : 2500,
	lastactivity : 0,
	activitylimit : 25000, /* milliseconds */
	isactive: 1,
	lastrequest : null,
	columns:  [{ name: 'Col1', type: 'text', heading: 'Col1'}],
	content : {},
	current : {}, /* For cell content during playback */
	/* Activities */
	lasttopic : null,
	lastupdate : null,
	topicclass : null,
	layout : new PlanLayout(),

	/* Moving rows */
	dragObject : null,
	mouseOffset : null,
	currow : null,
	rows : [],
	rowpos : [],

	/* messages */
	titleClick : "Title - click to edit", /* This is for titles in the notes page, kept here so that it can be changed easily */

	/* z-index value, this is incremented whenever you need to put something on top, 
	   e.g. me.style.zIndex = this.top_of_it_all++; */
	top_of_it_all : 5000000,

	init : function() {
		var _this = this;
		if (oneCom) _this = oneCom;
		oneCom = _this;

		_this.in_playback = 1;
		_this.cookies = new Cookies();
		_this.set_mode('playback');
		var chats = _this.cookies.get('openchats');
		if (chats) {
			chats = chats.split(',');
			for (var i=0, ic=chats.length; i < ic; i++) {
				var vars = chats[i].split('|');
				_this.display_chat(vars[0], vars[3].split('±').join(','));
				if (vars[1]) {
					var chat = Elem('chat' + vars[0]);
					chat.style.left = vars[1] + 'px';
					chat.style.top = vars[2] + 'px';
				}
			}
		}
		return _this;
	},

	get_mode : function() {
		var node_elem = Elem('mode');
		return node_elem.value;
	},

	set_mode : function( mode ) {
		var node_elem = Elem('mode');
		if (node_elem) {
			node_elem.value = mode;
		}
		if (mode == 'static') {
			var pb = Elem('playback');
			if (pb) {
				pb.innerHTML = '';
				pb.style.display = 'none';
			}
			var soc = Elem('social');
			if (soc) {
				soc.style.display = 'block';
			}
			this.display_timeline();
		}
	},

	get_request : function() {
		var req = null;
		if (window.XMLHttpRequest) {
			req = new XMLHttpRequest();
		} else {
			req = new ActiveXObject("Msxml2.XMLHTTP");
			if (!req) 
				req = new ActiveXObject("Microsoft.XMLHTTP");
		}
		this.req = req;
		return req;
	},
	get_updates : function() {
		var req = this.get_request();
		if (!req) return;
		if (this.activerequest) return;
		this.activerequest = 1;

		try { 
			var _this = this;
			req.onreadystatechange = function() { _this.process_updates(req); };
			var url = '/connect/';
			if (document.getElementById('plan')) this.mode = 'plan';
			if (this.mode == 'plan') url = url + 'plan/';
			if (this.page_topic) url = url + this.page_topic;
			req.open("GET", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	submit_message : function(topic, message, name, row) {
		var req = this.get_request();
		if (!req) return;

		try { 
			var url = "/connect/submit/";
			if (this.mode == 'plan') url = url + "plan/";
			url = url + "?topic=" + encodeURIComponent(topic) + '&message=' + encodeURIComponent(message);
			if (name) url = url + "&name=" + encodeURIComponent(name);
			if (row) url = url + "&row=" + encodeURIComponent(row);
			if (name && this.story) url = url + "&story=" + encodeURIComponent(this.story);
			var _this = this;
			req.onreadystatechange = function() { _this.process_updates(req); };
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	send : function( id, topic, name, row ) {
		var value = Elem(id).value;
		this.submit_message(topic, value, name, row);
	},

	open_chat : function(id) {
		var req = this.get_request();
		if (!req) return;

		try { 
			var url = "/connect/create_topic/" + id;
			req.onreadystatechange = function() {};
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	discard_chat : function(id) {
		var elem = Elem(id);
		var topic = id.substring(4);
		Elem('topicmsg' + topic).value = '__close';
		this.send('topicmsg' + topic, topic);
		if (elem) elem.parentNode.removeChild(elem);

		// Remove from open chats cookie
		var chats = this.cookies.get('openchats');
		if (chats) {
			chats = chats.split(',');
		} else {
			chats = [];
		}
		var newchats = [];
		for (var i=0, ic=chats.length; i < ic; i++) {
			if (chats[i].indexOf(topic + '|') < 0) {
				newchats.push( chats[i] );
			}
		}
		this.cookies.set('openchats', newchats.join(","), null, '/');
	},

	chat_onkeyup : function(e) {
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;

		if (e.keyCode == 13 && elem.value != '') { // Return
			var topic = elem.parentNode.parentNode.id.substring(4);
			this.send('topicmsg' + topic, topic);
			elem.value = '';
		}
	},

	init_chat : function(topicid, headline, welcome) {
		this.display_chat(topicid, headline, welcome);
		//this.load_history( topicid, 0, 10 ); => moved to display_chat
	},
	load_history : function (topicid, oldid, count) {
		var req = this.get_request();
		if (!req) return;
		var _this = this;
		try { 
			var url = "/connect/fetch_history/" + topicid + "/" + oldid + "/" + count;
			req.onreadystatechange = function(e) { _this.update_history( req ) };
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},

	update_history : function (req) {
		if (req.readyState != 4) return;
		this.activerequest = null;
		if (req.status != 200 && req.status != 0 && req.status != 304) return;

		this.obj = JSON.parse(req.responseText);
		var json = this.obj;

		this.update_members(json.topic, json.members);

		if (!json.updates || !json.updates.length) return;
		var chat = Elem('chat' + json.topic);
		if (!chat) return;
		var win = Elem('chatArea' + json.topic);
		if (win.childNodes.length && win.childNodes[0].childNodes.length) {
			if (win.childNodes[0].childNodes[0].tagName == 'A') {
				win.childNodes[0].removeChild(win.childNodes[0].childNodes[0]);
			}
		}

		var topic = json.topic;
		var updates = json.updates;
		var more = json.more;

		var _this = this;
		var oldid = 0;
		var lasttime = null;
		var before = null;
		if (win.childNodes.length) before = win.childNodes[0];

		for (var i=updates.length - 1; i >= 0; i--) {
			var msg = updates[i];
			if (this.lastupdate < msg.id) this.lastupdate = msg.id;
			var comment = chat.appendChild( newElem("div", { 'class' : 'chatCommentOld' } ) );
			var chattime = msg.time;
			if (msg.content == '__close') {
				//comment.appendChild( newElem( 'i', {}, msg.screenname + ' closed the conversation window') );
			} else if (msg.content == '__open') {
				//comment.appendChild( newElem( 'i', {}, msg.screenname + ' reopened the conversation window') );
			} else {
				if (chattime && !lasttime || lasttime != chattime) {
					comment.appendChild( newElem( 'span', { 'class' : 'chattime' }, chattime ) );
					lasttime = chattime;
				}
				comment.appendChild( newElem( 'b', {}, msg.screenname + ': ') );
				comment.appendChild( newText( msg.content ) );
			}
			if (before) {
				win.insertBefore(comment, before);
			} else {
				win.appendChild(comment);
			}
			oldid = msg.id;
		}
		if (more) {
			var comment = chat.appendChild( newElem("div", { 'class' : 'chatCommentOld' } ) );
			var a = comment.appendChild( newElem( 'a', { 'href' : '#' }, ' Load older comments ' ) );
			a.onclick = function(e) {
				_this.load_history( topic, oldid, 10);
			};
			win.insertBefore(comment, win.childNodes[0]);
		}
		win.scrollTop = win.scrollHeight;
	},
	update_members : function (topicid, members) {
		if (!members) return;
		var chat = Elem('chatPeople' + topicid);
		var in_chat = Elem('inChat' + topicid);
		var others_chat = Elem('othersChat' + topicid);
		in_chat.innerHTML = '';
		others_chat.innerHTML = '';

		var taken = {};
		var title = "Chat ";
		var sep = " with ";
		var _this = this;
		for (var i=0, ic=members.length; i<ic; i++) {
			taken[members[i].id] = 1;
			if (members[i].id != this.user) {
				title = title + sep + members[i].screenname;
				sep = ", ";
			}
			var person = in_chat.appendChild( newElem('div', { 'class' : 'person user'+members[i].id, 'id' : 'chat' + topicid + 'p' + members[i].id }, members[i].screenname) );
			/* person.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var split = elem.id.indexOf('p');
				var topicid = elem.id.substring(4,split);
				var id = elem.id.substring( split + 1 );
				_this.remove_from_topic( topicid, id);
			}; */
			var is_on = 0;
			for (var j=0,jc=this.online.length; j < jc; j++) {
				if (this.online[j].id == members[i].id) is_on = 1;
			}
			if (!is_on) {
				person.style.color = 'gray';
			}
		}
		for (var i=0, ic=this.online.length; i < ic; i++) {
			if (taken[ this.online[i].id ]) continue;
			var person = others_chat.appendChild( newElem('div', { 'class' : 'person user'+this.online[i].id, 'id' : 'chat' + topicid + 'p' + this.online[i].id }, this.online[i].screenname) );
			var id = this.online[i].id;
			person.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var split = elem.id.indexOf('p');
				var topicid = elem.id.substring(4,split);
				var id = elem.id.substring( split + 1 );
				_this.add_to_topic( topicid, id);
			};
		}
		if (others_chat.childNodes.length == 0) {
			others_chat.appendChild( newElem('div', { 'class' : 'person', 'style' : 'font-size: 8pt', 'id' : 'noone' + topicid } , 'None of your other friends are online at the moment') );
		}
		var ct = Elem('headline' + topicid);
		ct.innerHTML = '';
		ct.appendChild( newText( title ) );
	},

	add_to_topic : function( topicid, userid ) {
		var req = this.get_request();
		if (!req) return;
		var _this = this;
		try { 
			var url = "/connect/add_to_topic/" + topicid + "/" + userid;
			req.onreadystatechange = function(e) { _this.update_history( req ) };
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},

	remove_from_topic : function( topicid, userid ) {
		var req = this.get_request();
		if (!req) return;
		var _this = this;
		try { 
			var url = "/connect/remove_from_topic/" + topicid + "/" + userid;
			req.onreadystatechange = function(e) { _this.update_history( req ) };
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},

	get_highest_zIndex : function() {
		var all = document.getElementsByTagName("*");
		var z = 1;
		for (var i=0, ic=all.length; i<ic; i++) {
			if (z < all[i].style.zIndex) z = all[i].style.zIndex;
		}
		return z;
	},

	display_chat : function(topicid, headline, welcome) {
		if (!headline) headline = "Chat " + topicid;
		if (Elem('chat' + topicid)) return;
		var chat = newElem('div', { 'class' : 'cChat', 'id' : 'chat' + topicid });
		var h2 = chat.appendChild( newElem('h2', {} ));
		var imgdiv = h2.appendChild( newElem( 'div', { 'class' : 'chatcloseimg' } ) );
		//var ppl_img = imgdiv.appendChild( newElem( 'img', { 'src' : '/images/icons/people_icon.gif', 'alt' : 'People list', 'width' : '25', 'style' : 'position: relative; top: 3px' } ) );
		var ppl_img = imgdiv.appendChild( newElem( 'a', { 'href' : '#' }, 'Add people' ) );
		var img = imgdiv.appendChild( newElem( 'img', { 'src' : '/images/icons/delete.png' } ) );
		var _this = this;
		h2.onmousedown = function(e) {
			if (!e) e = window.event;
			var elem = e.srcElement || e.currentTarget;

			this.top_of_it_all = _this.get_highest_zIndex() + 1;
			elem.zIndex = this.top_of_it_all++;

			// Prevent text selection in various browsers:
			document.body.focus();
			document.onselectstart = function () { return false; }; // IE
			elem.ondragstart = function() { return false; }; 

			_this.dragchat = elem.parentNode;
			if (_this.dragchat.parentNode.tagName == 'H2') // IE8 -- IMG
				_this.dragchat = _this.dragchat.parentNode.parentNode;
			if (_this.dragchat.tagName == 'H2') // IE8 -- H2
				_this.dragchat = _this.dragchat.parentNode;

			var mouse = _this.mouse_xy(e);
			var elempos = _this.elem_xy(_this.dragchat);
			_this.dragoffset = { 'x' : mouse.x - elempos.x, 'y' : mouse.y - elempos.y };
			_this.lastmouse = { 'x' : mouse.x, 'y' : mouse.y };
			_this.fire = 0;
			document.onmousemove = function(e) {
				e = e || window.event;
				_this.fire = _this.fire + 1;
				//Elem('sq').value = _this.fire;
				if (!_this.dragchat) return false;
				var mouse = _this.mouse_xy(e);
				mouse.x = mouse.x - (_this.dragoffset.x);
				mouse.y = mouse.y - (_this.dragoffset.y);
				_this.dragchat.style.left = mouse.x + 'px';
				_this.dragchat.style.top = mouse.y + 'px';
				return false;
			};
			elem.onmouseup = document.onmouseup = function(e) {
				document.onmousemove = function() {};
				elem.onmouseup = document.onmouseup = function() {};
				var topic = _this.dragchat.id.substring(4);
				Elem('topicmsg' + topic).focus();
				_this.dragchat = null;

				/* Update cookies */
				var chats = _this.cookies.get('openchats');
				if (chats) {
					chats = chats.split(',');
				} else {
					chats = [];
				}

				var mouse = _this.mouse_xy(e);
				mouse.x = mouse.x - (_this.dragoffset.x);
				mouse.y = mouse.y - (_this.dragoffset.y);

				var newchats = [];
				for (var i=0, ic=chats.length; i < ic; i++) {
					if (chats[i].indexOf(topicid + '|') == 0) {  // This one
						var vars = chats[i].split('|');
						newchats.push(topicid + '|'+ mouse.x + '|' + mouse.y + '|' + vars[3]);
					} else {
						newchats.push(chats[i]);
					}
				}
				_this.cookies.set('openchats', newchats.join(","), null, '/');
			};

			// Prevent text selection in various browsers:
			return false;
		};
		var ppl = chat.appendChild( newElem('div', { 'class' : 'chatPeople', 'id' : 'chatPeople' + topicid } ));
		//ppl.appendChild( newElem('h2', {}, 'Remove') );
		ppl.appendChild( newElem('div', { 'id' : 'inChat' + topicid, 'class' : 'inChat' }));

		ppl.appendChild( newElem('h2', {}, 'Add more') );
		ppl.appendChild( newElem('div', { 'id' : 'othersChat' + topicid }));
		var main = chat.appendChild( newElem('div', {'class' : 'chatArea', 'id' : 'chatArea' + topicid } ));
		var div = main.appendChild( newElem('div') );
		if (welcome) 
			div.appendChild( newElem('i', {}, welcome ) );
		var _this = this;
		ppl_img.onclick = function(e) {
			if (!e) e = window.event;
			var elem = e.srcElement || e.currentTarget;
			var chat = elem.parentNode.parentNode.parentNode;
			var topicid = chat.id.substring(4);
			var p = Elem('chatPeople' + topicid);
			var a = Elem('chatArea' + topicid);
			if (p.style.display == 'block') {
				p.style.display = 'none';
				chat.style.width = '400px';
				a.style.width = '380px';
			} else {
				p.style.display = 'block';
				//chat.style.width = '500px';
				a.style.width = '280px';
			}
		}
		img.onclick = function(e) {
			if (!e) e = window.event;
			var elem = e.srcElement || e.currentTarget;
			_this.discard_chat( elem.parentNode.parentNode.parentNode.id );
		};
		h2.appendChild( newElem('div', { 'id' : 'headline' + topicid, 'style' : 'height: 1.4em' }, headline ) );
		var entry = chat.appendChild( newElem('div', { 'class' : 'entry' }) );
		var textarea = entry.appendChild( newElem('textarea', { 'id' : 'topicmsg' + topicid }));
		textarea.onkeyup = function(e) { 
			_this.chat_onkeyup(e) 
		};
		Elem('chatanchor').appendChild(chat);
		textarea.focus();
		this.load_history( topicid, 0, 20 );

		// Make sure it's not on top of anything else
		var pos_top = 200;
		var pos_left = 200;
		var chat_windows = getElementsByClass("cChat");
		for (var i=0, ic=chat_windows.length; i < ic; i++) {
			if (chat_windows[i].id == chat.id) continue;
			if (chat_windows[i].offsetLeft == pos_left &&
				chat_windows[i].offsetTop == pos_top) {
				pos_left += 50;
				pos_top += 50;
				i = 0;
				continue;
			}
		}
		chat.style.left = pos_left + 'px';
		chat.style.top = pos_top + 'px';


		// Store open chats in a cookie
		var chats = this.cookies.get('openchats');
		if (chats) {
			chats = chats.split(',');
		} else {
			chats = [];
		}
		for (var i=0, ic=chats.length; i < ic; i++) {
			if (chats[i].indexOf( topicid + '|' ) == 0) { // Already in there
				return;
			}
		}
		chats.push( topicid + '|||' + headline.split(',').join('±') );
		this.cookies.set('openchats', chats.join(","), null, '/');
	},

	presence_display : function( online ) {
		var _this = this;
		var presence = Elem('presence');
		if (presence) { /* Unfortunately, cross browser support requires us to embed styling here */
			var off_list = []
			var on_list = [];
			var list = newElem("ul", { 'style' : 'float: right', 'id' : 'presencelist' });
			var new_offline = [];
			var new_online = [];
			for (var i=0, j=this.online.length; i<j; i++) {
				var id = this.online[i].id;
				var found = 0;
				for (var i2=0, j2=online.length; i2 < j2; i2++) {
					if (online[i2].id == this.online[i].id) found = 1;
				}
				if (!found) {
					new_offline.push(this.online[i]);
				}
			}
			for (var i=0, j=online.length; i < j; i++) {
				var person = online[i];
				var found = 0;
				for (var i2=0, j2=this.online.length; i2<j2; i2++) {
					if (this.online[i2].id == person.id) found = 1;
				}
				if (!found) {
					new_online.push(person);
				}
				if (person.id != this.user) {
					var li_class = "off_page";
					if (person.on_page) li_class="on_page";
					var li = newElem('li', {'class' : 'presenceItem' });
					li.onclick = function(e) { 
						if (!e) e = window.event;
						var elem = e.srcElement || e.currentTarget;
						if (elem.tagName != 'LI') elem = elem.parentNode;
						var id = elem.childNodes[0].id.substring(6);
						var name = elem.childNodes[1].innerHTML;
						//_this.display_chat(id, name);
						_this.open_chat(id);
					};
					li.appendChild( newElem('img', { 'id' : 'avatar' + person.id, 'class' : li_class, 'src' : person.avatar || '/images/default/profile_40.gif', 'width' : '25', 'height' : '25', 'alt' : person.screenname, 'title' : person.screenname }) );
					li.appendChild( newElem('span', null, person.screenname) );
					if (person.on_page) {
						on_list.push( li );
					} else {
						off_list.push( li );
					}
				}
			}
			/* Update chat boxes off/online */
			for (var i=0, ic=new_offline.length; i < ic; i++) {
				if (Elem('pres'  +new_offline[i].id)) {
					Elem('pres'  +new_offline[i].id).style.display = 'none';
				}
				var g = getElementsByClass("user" + new_offline[i].id);
				for (var gi=0, gc=g.length; gi < gc; gi++) {
					if (g[gi].parentNode.id.indexOf("othersChat") == 0) {
						var others_chat = g[gi].parentNode;
						g[gi].parentNode.removeChild(g[gi]);
						if (others_chat.childNodes.length == 0) {
							var topicid = others_chat.id.substring(10);
							others_chat.appendChild( newElem('div', { 'class' : 'person', 'style' : 'font-size: 8pt', 'id' : 'noone' + topicid } , 'None of your other friends are online at the moment') );
						}
					} else {
						var topicid = g[gi].parentNode.id.substring(6);
						var area = Elem('chatArea' + topicid);
						if (area) {
							if (0) {
								var comment = area.appendChild( newElem("div", { 'class' : 'chatComment' } ) );
								comment.appendChild( newElem( 'i', {}, new_offline[i].screenname + ' went offline') );
								area.scrollTop = area.scrollHeight;
							}
						}
						g[gi].style.color = 'gray';
						
					}
				}
			}
			for (var i=0, ic=new_online.length; i < ic; i++) {
				if (Elem('pres'  +new_online[i].id)) {
					Elem('pres'  +new_online[i].id).style.display = 'inline';
				}
				var g = getElementsByClass("user" + new_online[i].id);
				for (var gi=0, gc=g.length; gi < gc; gi++) {
					g[gi].style.color = 'black';
					if (g[gi].parentNode.id.indexOf("inChat") == 0) {
						var topicid = g[gi].parentNode.id.substring(6);
						var area = Elem('chatArea' + topicid);
						if (area) {
							if (0) {
								var comment = area.appendChild( newElem("div", { 'class' : 'chatComment' } ) );
								comment.appendChild( newElem( 'i', {}, new_online[i].screenname + ' came back online') );
								area.scrollTop = area.scrollHeight;
							}
						}
					}
				}
				var chats = getElementsByClass('cChat');
				for (var ci=0, cc=chats.length; ci<cc; ci++) {
					var g = getElementsByClass("user" + new_online[i].id, chats[ci]);
					if (!g || g.length == 0) {
						var topicid = chats[ci].id.substring(4);
						var others_chat = Elem('othersChat' + topicid );
						if (others_chat) {
							var person = others_chat.appendChild( newElem('div', { 'class' : 'person user'+new_online[i].id, 'id' : 'chat' + topicid + 'p' + new_online[i].id }, new_online[i].screenname) );
							var noone = Elem('noone' + topicid);
							if (noone) noone.parentNode.removeChild(noone);
							var _this = this;
							person.onclick = function(e) {
								if (!e) e = window.event;
								var elem = e.srcElement || e.currentTarget;
								var split = elem.id.indexOf('p');
								var topicid = elem.id.substring(4,split);
								var id = elem.id.substring( split + 1 );
								_this.add_to_topic( topicid, id);
							};
						}
					}
				}
			}
			/* Update presence */
			this.online = online;
			for (var i=0, j=on_list.length; i < j; i++) {
				if (i == 0) {
					var hl;
					if (this.story) {
						hl = list.appendChild( newElem( 'li', {}, 'Viewing story' ) );
					} else {
						hl = list.appendChild( newElem( 'li', {}, 'Viewing group' ) );
					}
					hl.style.background = 'black';
					hl.style.color = 'white';
					hl.style.padding = '1px 10px';
				}
				list.appendChild(on_list[i]);
			}
			for (var i=0, j=off_list.length; i < j; i++) {
				if (i == 0) {
					var hl = list.appendChild( newElem( 'li', { }, 'Friends' ) );
					hl.style.background = 'black';
					hl.style.color = 'white';
					hl.style.padding = '1px 10px';
				}
				list.appendChild(off_list[i]);
			}
			var toggle_state = 'none';
			var toggle = null;
			if (Elem("presencelist"))  {
				toggle_state = Elem("presencelist").style.display;
				toggle = newElem("div", { 'id' : 'presencetoggle' }, "Chat: " + (off_list.length + on_list.length) + " (" + on_list.length + ")");
				toggle.onclick = function(e) {
					if (Elem("presencelist").style.display == "block") { 
						Elem("presencelist").style.display = "none"; 
					} else { 
						Elem("presencelist").style.display="block" 
					}
				};
			} else {
				toggle = newElem("div", { 'id' : 'presencetoggle' }, "Chat: " + (off_list.length + on_list.length) + " (" + on_list.length + ")");
			}
			presence.innerHTML = '';
			presence.appendChild(toggle);
			if (list.childNodes.length) 
				presence.appendChild(list);
			if (Elem("presencelist")) {
				Elem("presencelist").style.display = toggle_state;
			}
		}
	},

	process_updates : function(req) {
		if (req.readyState == 4) {
			this.activerequest = null;
			if (req.status != 200 && req.status != 0 && req.status != 304) {
				if (req.status == 400) {
					new AlertBox( { type: 'info', content: 'Session expired' }, 0 );
					this.failed = 1;
				}
			} else {
				this.obj = JSON.parse(req.responseText);
				var debug = Elem('debug');
				if (debug) debug.innerHTML = req.responseText;
				var json = this.obj;

				/* Cell locks */
				if (json.locks && json.lockupdate > this.lockupdate) {
					this.lockupdate = json.lockupdate;
					for (key in this.locks) {
						if (!json.locks[key]) {
							var e = Elem(key);
							if (e) this.removeLockLabel(e);
							delete this.locks[key];
						} else {
							delete json.locks[key];
						}
					}
					for (key in json.locks) {
						this.locks[key] = json.locks[key];
						var e = Elem(key);
						if (e) this.addLockLabel(e, json.locks[key]);
					}
				}
				if (json.online) {
					this.presence_display( json.online );
				}
				if (json.mentors_online && json.mentors_online.length) {
					/* Here's where you show mentors */
				}

				if (!json.messages) return;
				//var e = Elem('notifications');
				//e.innerHTML = req.responseText;
				var msec = 0;
				for (var i=0, j=json.messages.length; i < j; i++) {
					// topic when from(id,screenname) content type ago 
					var msg = json.messages[i];
					if (msg.name && msg.name == '__position') continue;
					if (msg.id && this.lastupdate && this.lastupdate >= msg.id) continue;
					if (msg.id) this.lastupdate = msg.id;

					var topic = msg.topic;
					var elem = Elem('topic' + topic);
					if (!msg.name) elem = null;

					/* Display activity */
					if (elem || Elem('s' + msg.topic)) { // Scene info 
						this.display_activity( this.updates.length - 1, [ {
							screenname : msg.from.screenname,
							who : msg.from.id,
							name : msg.name,
							content : msg.content,
							topic: msg.topic,
							row : msg.row
						} ]);
					}

					if (Elem('chat' + msg.topic)) elem = null;

					if (elem) { 
						//new SocialNode(elem, msg);
					} else if (msg.type == 'notification') {
						if (msg.content == '_add_chat') {
							var members = msg.members;
							var headline = "";
							for (var m=0, ml=members.length; m < ml; m++) {
								var member = members[m];
								if (member.id == this.user) continue;
								if (headline == "") {
									headline = "Chat with " + member.screenname
								} else {
									headline = headline + ", " + member.screenname
								}
							}

							if (!Elem('chat' + msg.topic)) {
								this.display_chat(msg.topic, headline, msg.from.screenname + ' started the conversation');
							}
						}
						if (msg.content == '_add_topic') { // Add new scene
							if (this.layout.style == 'tabular') {
								var topic = Elem('s' + msg.topic);
								if (!topic) this.add_scene_block(msg.topic, this.get_plan());
							}
						}
						if (msg.content == '_del_topic') { // Hide deleted scene
							if (this.layout.style == 'tabular') {
								var topic = Elem('s' + msg.topic);
								if (topic) topic.style.display = 'none';
							}
						}
						if (msg.content.indexOf('_position') == 0) {
							if (this.layout.style == 'tabular') {
								var split = msg.content.indexOf('|');
								var value = msg.content.substring(split + 1);
								msg.content = msg.content.substring(0,split);
								var id = 's' + msg.topic + 'r0';
								var rowCont = Elem(id).parentNode;
								var footer = getElementsByClass("footer", rowCont);
								if (footer.length) footer = footer[0];

								var rows = [];
								for (var i=0, ic=msg.content.length; i<ic; i++) {
									rows[i] = Elem('s' + msg.topic + 'r' + value);
								}

								for (var i=0, ic=rows.length; i<ic; i++) {
									rowCont.removeChild(rows[i]);
								}
								for (var i=0, ic=rows.length; i<ic; i++) {
									rowCont.insertBefore(rows[i], footer);
								}
							}
						}
						if (msg.content.indexOf('_add_column') == 0) {
							if (this.layout.style == 'tabular') {
								var split = msg.content.indexOf('|');
								var name = msg.content.substring(split + 1);
								var type = 'text';
								split = name.indexOf('|');
								var heading  = name.substring(split + 1);
								name = name.substring(0, split);
								for (var i=0, ic=this.columns.length; i<ic; i++) {
									if (this.columns[i].name == name) {
										warn("Skipping column " + name + " -- already in place");
										return;
									}
								}
								split = heading.indexOf('|');
								if (split) {
									type = heading.substring(0,split);
									heading = heading.substring(split+1);
								}
								for (var i=0, ic=this.extra_columns.length; i<ic; i++) {
									if (name == this.extra_columns[i].name) {
										type = this.extra_columns[i].type;
										heading = this.extra_columns[i].heading;
									}
								}

								/* Special case for plan -- apply to all scenes */
								var scenes = getElementsByClass('scene');
								if (scenes.length) {
									for (var i=0, ic = scenes.length; i < ic; i++) {
										var topic = scenes[i].id.substring(1);
										this.add_column_html(topic, { 'name' : name, 'type' : type, 'heading' : heading });
									}
								} else {
									this.add_column_html(msg.topic, { 'name' : name, 'type' : type, 'heading' : heading });
								}
								if (window.autoresize) { window.autoresize(); }
							}
						}
						if (msg.content.indexOf('_hide_column') == 0) {
							if (this.layout.style == 'tabular') {
								var split = msg.content.indexOf('|');
								var name = msg.content.substring(split + 1);
								/* Special case for plan -- apply to all scenes */
								var scenes = getElementsByClass('scene');
								if (scenes.length) {
									for (var i=0, ic = scenes.length; i < ic; i++) {
										var topic = scenes[i].id.substring(1);
										this.hide_column_html(topic, { 'name' : name, 'type' : 'text', 'heading' : heading });
									}
								} else {
									this.hide_column_html(msg.topic, { 'name' : name, 'type' : 'text', 'heading' : heading });
								}
							}
						}
					} else if (!msg.name) {
						var elem = Elem('chat' + topic);
						if (elem) {
							var chat = Elem('chatArea' + topic);
							var comment = chat.appendChild( newElem("div", { 'class' : 'chatComment' } ) );
							if (msg.content == '__close') {
							//	comment.appendChild( newElem( 'i', {}, msg.from.screenname + ' closed the conversation window') );
							} else if (msg.content == '__open') {
							//	comment.appendChild( newElem( 'i', {}, msg.from.screenname + ' reopened the conversation window') );
							} else {
								comment.appendChild( newElem( 'span', { 'class' : 'chattime' }, msg.time ) );
								comment.appendChild( newElem( 'b', {}, msg.from.screenname + ': ') );
								comment.appendChild( newText( msg.content ) );
							}
							chat.scrollTop = chat.scrollHeight;
						} else if (msg.from.id != this.user && msg.content.indexOf('__') != 0) {
							new AlertBox( msg, msec );
							msec = msec + 500;
						}
					} else if (msg.name == 'delete') {
						if (!msg.row) { msg.row = '0'; }
						var elem = Elem('s' + msg.topic + 'r' + msg.row);
						elem.style.position = 'relative';
						elem.appendChild(newElem('div', { 'class' : 'deleteRowRed'}, br(), 'Row being deleted'));
						setTimeout("Elem('s" + msg.topic + "r" + msg.row + "').style.display = 'none';", 1500);
					} else {
						if (msg.name == '__position') {
							var id = 's' + msg.topic + 'r0';
							var rowCont = Elem(id).parentNode;
							var footer = getElementsByClass("footer", rowCont);
							if (footer.length) footer = footer[0];

							var rows = [];
							for (var i=0, ic=msg.content.length; i<ic; i++) {
								rows[i] = Elem('s' + msg.topic + 'r' + msg.content[i]);
							}

							for (var i=0, ic=rows.length; i<ic; i++) {
								rowCont.removeChild(rows[i]);
							}
							for (var i=0, ic=rows.length; i<ic; i++) {
								rowCont.insertBefore(rows[i], footer);
							}
						}
						var elem = Elem(msg.name + '_' + msg.row + '_' + msg.topic);
						if (!elem) {
							var first = Elem(msg.name + '_0_' + msg.topic);
							if (first) {
							  var scene = first.parentNode.parentNode.parentNode.parentNode.parentNode;
							  var topic = scene.id.substring(1);
							  var oldrows = getElementsByClass("row", scene);
							  var rows = msg.row - oldrows.length + 1;
							  if (rows < 100) {
								  for (ri = 0; ri < rows; ri++) {
									  this.add_row({ 'topic' : topic });
								  }
							  }
							  elem = Elem(msg.name + '_' + msg.row + '_' + msg.topic);
							}
						}
						if (elem && elem.tagName == 'TEXTAREA') {
							elem.readOnly = null;
							elem.value = msg.content;
							this.content[elem.id] = msg.content;

							var flash = Elem(elem.id + '-flash');
							if (flash) {
								flash.inputImageReplacerUrl(elem.value);
							}
							//elem.style.height = 25 + 'px';
							if (this.layout.style != 'tabular') {
								elem.style.height = elem.scrollHeight;
							} else {
								var y = (elem.originalHeight) ? elem.originalHeight : 25; //default minimum height
								var uploader = getElementsByClass("imageurl", (elem.parentNode).parentNode.parentNode);
								if (uploader.length && y < 90) y = 90;
								if (elem.scrollHeight && elem.clientHeight >= elem.scrollHeight + 5 && elem.clientHeight > y) 
									elem.style.height = y + 'px';
								
								if (elem.scrollHeight && elem.clientHeight < elem.scrollHeight) {
									if (elem.scrollHeight < y) {
										elem.style.height = y + "px";
									} else {
										elem.style.height = elem.scrollHeight + "px";					
									}
								}
								var arr = getElementsByClass("grow", (elem.parentNode).parentNode.parentNode);
								var size = elem.clientHeight;
								if (size < y) size = y;
								for (var i2=0, j2=arr.length; i2<j2; i2++) {
									if (arr[i2].clientHeight > size) size = arr[i2].clientHeight;
								}
								arr = getElementsByClass("cell", (elem.parentNode).parentNode.parentNode);
								for (var i2=0, j2=arr.length; i2<j2; i2++) {
									arr[i2].style.height = size + 'px';
								}
							}
						}
					}
				}
			}
		}
	},
	update : function () {
		if (this.failed) {
			// TODO: Replace this with nice log in form on top of grayed-out page
			document.location = '/user/login?referer=' + window.location.pathname + '&message=' + encodeURIComponent('Your session timed out. Please log back in to continue.');
		} else {
			this.get_updates();
			var _this = this;
			var ts = new Date().getTime();
			if (!this.ts || ts > this.ts + 1900 && this.updatefrequence) {
				if (!this.lastactivity) this.lastactivity = ts;
				//warn("Lastactivity = " + (Number(this.lastactivity) + this.activitylimit) + ' vs ' + ts);
				if (this.lastactivity && this.lastactivity + this.activitylimit < ts) {
					this.isactive = 0;
				} else {
					setTimeout(function() { _this.update(); }, this.updatefrequence);
				}
				this.ts = ts;
			}
			this.readjust_width();
		}
	},
	readjust_width : function(init) {
		if (this.layout && this.layout.style == 'tabular') {
			var rows = getElementsByClass("row");
			if (!rows.length) return;
			var row_no = 0;
			var mells = null;
			// Skip hidden rows where width is always 0
			while (mells == null) {
				mells = getElementsByClass("mell", rows[row_no]);
				if (mells.length && mells[0].clientWidth == 0) {
					mells = null;
					row_no++;
					if (rows.length >= row_no) return;
				}
			}
			var width = 0;
			if (init) width = init;
			for (var i=0, ic=mells.length; i<ic; i++) {
				width = width + mells[i].clientWidth;
			}
			for (var i=0, ic=rows.length; i<ic; i++) {
				rows[i].style.width = (width + 30) + 'px';
			}
			rows = getElementsByClass("labelrow");
			for (var i=0, ic=rows.length; i<ic; i++) {
				rows[i].style.width = (width + 30) + 'px';
			}
			rows = getElementsByClass("footer");
			for (var i=0, ic=rows.length; i<ic; i++) {
				rows[i].style.width = (width + 30) + 'px';
			}
		}
	},

	displayAsset : function( image ) {
		var orep = image;
		orep = orep.substring( orep.indexOf('files') + 6 );
		var licid = orep.substring( 0, orep.indexOf('/') );
		orep = orep.substring( orep.indexOf('/') + 1 );
		orep = orep.substring( 0, orep.indexOf('.') );

		var req = this.get_request();
		if (!req) return;
		var _this = this;
		try { 
			var url = "/connect/get_info_from_url/" + licid + "/" + orep + "/player";
			req.onreadystatechange = function(e) { _this.displayAssetVisual( req ) };
			req.open("GET",url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	displayAssetVisual : function( req ) {
		if (req.readyState != 4) return;
		if (req.status != 200 && req.status != 0 && req.status != 304) return;

		var json = JSON.parse(req.responseText);
		var asset = json.reps[0];

		get_top_frame().displayAsset({ id: asset.id, object_id: asset.object_id, collection: asset.collection, url: asset.url, primarytype: asset.primarytype });
	},

	resize_box : function( e ) {
		if (this.dragCell) return;
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;
		e = e || window.event;
		target = elem.parentNode; // -> mell
		target.style.border = '1px solid blue';
		target.style.zIndex = this.top_of_it_all++;
		this.dragCell = target;
		this.planXY = this.elem_xy( Elem('plan') );
		this.elemXY = this.elem_xy( target );
		var _this = this;
		document.onmousemove = function( e ) {
			e = e || window.event;
			if (!_this.dragCell) return false;
			var mouse = _this.mouse_xy(e);

			var width = mouse.x - _this.elemXY.x;
			var height = mouse.y - _this.elemXY.y;
			if (width < 50) width = 50;
			if (height < 50) height = 50;

			_this.dragCell.style.width = width + 'px';
			_this.dragCell.style.height = height + 'px';

			var ta = _this.dragCell.getElementsByTagName("TEXTAREA");
			if (ta.length) {
				//width = (mouse.x - _this.elemXY.x - 30);
				width = (mouse.x - _this.elemXY.x - 20);
				if (width < 50) width = 50;
				ta[0].style.width = width + 'px';
				var height = (mouse.y - _this.elemXY.y - 70);
				if (height < 50) height = 50;
				var imgco = Elem('imagecontainer_' + ta[0].id);
				if (imgco && imgco.scrollHeight)
					height = height - imgco.scrollHeight - 5 - 30;
				if (height < 50) height = 50;
				ta[0].style.height = height + 'px';
				ta[0].style.overflow = 'auto';
			}
			ta = _this.dragCell.getElementsByTagName("H2");
			if (ta.length) {
				width = (mouse.x - _this.elemXY.x - 10 );
				if (width < 50) width = 50;
				ta[0].style.width = width + 'px';
			}
		};
		document.onmouseup = function(e) { 
			if (!e) e = window.event;
			var elem = e.srcElement || e.currentTarget;
			if (!_this.dragCell) return;

			var mouse = _this.mouse_xy(e);
			var x = (mouse.x - _this.elemXY.x);
			var y = (mouse.y - _this.elemXY.y);

			if (x < 50) x = 50;
			if (y < 50) y = 50;

			_this.dragCell.style.width = x + 'px';
			_this.dragCell.style.height = y + 'px';

			var ta = _this.dragCell.getElementsByTagName('TEXTAREA');
			if (ta.length && _this.is_member) {
				var arr = ta[0].id.split('_');
				_this.submit_message(arr[2], x + '/' + y, 'WH_' + arr[0], arr[1]);
			}

			_this.dragCell.style.border = 'solid 1px #7ba810';
			_this.dragCell = null;
			document.onmouseup = null;
			document.onmousemove = null;
		};
		return false;
	},
	cell_move : function( e ) {
		if (this.dragCell) return;
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;
		e = e || window.event;
		target = elem.parentNode; // -> mell
		var mouse = this.mouse_xy(e);
		var elem  = this.local_elem_xy(target);
		this.mouseOffset = { x: mouse.x - elem.x, y: mouse.y - elem.y };
		this.get_rows(target);
		this.dragCell = target;
		this.dragCell.style.border = '1px solid blue';
		this.dragCell.style.zIndex = this.top_of_it_all++;
		this.planXY = this.elem_xy( Elem('plan') );
		var _this = this;
		document.onmousemove = function( e ) {
			e = e || window.event;

			if (!_this.dragCell) return false;
			var mouse = _this.mouse_xy(e);
			_this.dragCell.style.position = 'absolute';
			var x = (mouse.x - _this.planXY.x - _this.mouseOffset.x - 8);
			var y = (mouse.y - _this.planXY.y - _this.mouseOffset.y - 8);
			_this.dragCell.style.top = y + 'px';
			_this.dragCell.style.left = x + 'px';
		};
		document.onmouseup = function(e) { 
			if (!e) e = window.event;
			if (!_this.dragCell) return false;
			var elem = e.srcElement || e.currentTarget;
			if (!_this.dragCell) return;
			document.onmouseup = null;
			document.onmousemove = null;

			var mouse = _this.mouse_xy(e);
			_this.dragCell.style.position = 'absolute';

			var x = (mouse.x - _this.planXY.x - _this.mouseOffset.x - 8);
			var y = (mouse.y - _this.planXY.y - _this.mouseOffset.y - 8);

			_this.dragCell.style.left = x + 'px';
			_this.dragCell.style.top = y + 'px';
			_this.dragCell.style.border = 'solid 1px #7ba810';

			var ta = _this.dragCell.getElementsByTagName('TEXTAREA');
			_this.dragCell = null;
			if (ta.length && _this.is_member) {
				var arr = ta[0].id.split('_');
				_this.submit_message(arr[2], x + '/' + y, 'XY_' + arr[0], arr[1]);
			}
		};
	},
	butt_adjust : function ( id, phase, label ) { /* Add media button adjust after flash replace */
		var butt = Elem('BX_' + id);
		if (butt) {
			if (!phase) {
				var params = {scale:"noscale",wmode:"transparent", 'align' : 'tl', 'salign' : 'tl'};
				var flashVars = {representation_type:"660x372",collectionId:this.storyboard,uploadPath:"/lib/upload",current_image:null,callJsOnNewImage:true,session:this.session,width:100,height:18, label: label ,id:'BX_' + id,fieldname:'IM_' + id};
				swfobject.embedSWF("/flash/mini_replacer.swf", 'BX_' + id, "100", "18", "9.0.124", false, flashVars,params);
				setTimeout('com.butt_adjust("' + id + '", 2, "' + label + '")', 100);
			} else {
				butt.style.position = 'absolute';
				if (label == 'Change media') {
					butt.style.right = '10px';
					butt.style.bottom = '10px';
				} else {
					butt.style.left = '0px';
					butt.style.bottom = '7px';
				}
			}
		} else {
			if (phase) {
				setTimeout( 'com.butt_adjust("' + id + '", 2, "' + label + '")', 100 );
			} else {
				setTimeout( 'com.butt_adjust("' + id + '", 0, "' + label + '")', 100 );
			}
		}
	},
	new_cell : function( c ) { /* 
		Creates and returns a cell element object
		-----------------------
		c.id => cell id 
		c.type => cell type (image|text) 
		c.ignore_content => leave content blank */

		var id = c.id;
		var type = c.type;
		var cont = newElem("div", { 'class' : 'mell' });

		var split = id.indexOf('_');
		var cell_name = id.substring(0, split);
		var cell_row  = id.substring(split + 1);
		split = cell_row.indexOf('_');
		var cell_topic = cell_row.substring(split + 1);
		cell_row = cell_row.substring(0, split);

		if (this.layout.cell_header) {
			var h2 = newElem('h2', { 'class' : 'notehead' });

			if (this.is_member) {
				var img = newElem('img', { 'src' : '/images/icons/delete.png' } );
				img.style.position = 'absolute';
				img.style.right = '2px';
				img.style.top = '2px';

				var _this = this;
				img.onmousedown = function(e) {
					if (!e) e = window.event;
					var elem = e.srcElement || e.currentTarget;
					var mell = elem.parentNode.parentNode;
					var ta = mell.getElementsByTagName("TEXTAREA");
					if (ta.length && _this.is_member) {
						if (confirm('Are you sure you want to delete this note?')) {
							var arr = ta[0].id.split('_');
							_this.submit_message(arr[2], 'deleted', 'DEL_' + arr[0], arr[1]);
							mell.style.display = 'none';
						}
					}
					e.cancelBubble = true;
					if (e.stopPropagation) e.stopPropagation();
					return false;
				};

				h2.appendChild(img);
				img.onselectstart = function() { return false };
			}

			var mells = getElementsByClass("mell").length;
			h2.appendChild( newText( 'Note ' + ( mells + 1 ) ) );

			cont.appendChild( h2 );

			if (this.layout.cell_movable) {
				var _this = this;
				h2.onmousedown = function(e) { _this.cell_move(e); };
				h2.ondrag = function(e) { return false; };
				h2.ondragstart = function() { return false };
			}

			h2 = cont.appendChild( newElem( 'h2', {}, '') );
			var title = h2.appendChild( newElem('input', { 'class' : 'connect', 'type' : 'text', 'id' : 'HEAD' + id, 'name' : 'HEAD' + id, value : unescapeHTML(this.content['HEAD' + id ] || this.titleClick) }) );
			h2.onclick = function(e) { _this.ag_focus(e); };
			title.onfocus = function(e) { _this.ag_focus(e); };
			title.onblur = function(e) { _this.ag_blur(e); };
			cont.appendChild(h2);

			var parts = [];
			var people = {};

			for (var si=0, sic=this.updates.length; si < sic; si++) {
				var act = this.updates[si].activities;
				for (var ai=0, aic=act.length; ai < aic; ai++) {
					if (act[ai].name == cell_name && act[ai].row == cell_row && act[ai].topic == cell_topic) {
						if (!people[act[ai].screenname]) {
							parts.push( act[ai].screenname );
						}
						people[act[ai].screenname] = 1;
					}
				}
			}

			var auth = newElem('div', { 'class' : 'authbox' }, 'By ');
			if (parts.length == 0) {
				/* By you */
				auth.appendChild( newElem( 'a', { 'href' : '/profile/' + encodeURIComponent(this.screenname), target : '_top' }, this.screenname ) );
			}
			for (var i=0, ic=parts.length; i < ic; i++) {
				if (i == 0) { 
					// Do nothing
				} else if (i == 1) {
					auth.appendChild( newText(', edited by ') );
				} else if (i == ic - 1) { // before last if more than 1
					auth.appendChild( newText(' and ') );
				} else if (i < ic - 1) { // before item if more than 2
					auth.appendChild( newText(', ') );
				}
				auth.appendChild( newElem( 'a', { 'href' : '/profile/' + encodeURIComponent(parts[i]) }, parts[i] ) );
			}
			cont.appendChild(auth);

		}

		var cell = newElem("div", { 'class' : 'cell' });
		cell.appendChild( newElem("div", { 'class' : 'celloverlay', 'id' : id + '_label' }) );
		cont.appendChild(cell);

		if (this.layout.cell_movable) {
			var img = newElem('img', { 'class' : 'hoveritem', 'src' : '/images/icons/resize.png' } );
			img.style.position = 'absolute';
			img.style.right = '0px';
			img.style.bottom = '0px';
			img.ondragstart = function() { return false };
			img.onselectstart = function() { return false };
			var _this = this;
			img.onmousedown = function(e) { _this.resize_box(e); return false; };
			cont.appendChild(img);
		}

		if (c.par && c.before) {
			c.par.insertBefore(cont, c.before);
		} else if (c.par) {
			c.par.appendChild(cont);
		}

		var _this = this;
		var content = null;
		if (c.ignore_content == null)
			content = this.content[id];

		if (this.current[id]) 
			content = this.current[id];

		if (type == 'text') {
			var textarea = newElem("textarea", { 'id' : id, 'class' : 'grow' });
			textarea.value = unescapeHTML(content || "");
			cell.appendChild(textarea);
			textarea.originalHeight = textarea.clientHeight;
			var _this = this;
			cell.onclick = function(e) { _this.ag_focus(e); };
			textarea.onfocus = function(e) { _this.ag_focus(e); };
			textarea.onblur = function(e) { _this.ag_blur(e); };
			textarea.onkeyup = function(e) { _this.ag_keyup(e); };
			if (this.layout.style != 'wall') {
				textarea.style.overflow = "hidden";
			}
		} else if (type == 'rich') {
			var textarea = newElem("textarea", { 'id' : id }); // , 'class' : 'grow' });
			textarea.value = unescapeHTML(content || "");
			textarea.style.resize = 'none';
			cell.appendChild(textarea);
			textarea.originalHeight = textarea.clientHeight;
			var _this = this;
			cell.onclick = function(e) { _this.ag_focus(e); };
			textarea.onfocus = function(e) { _this.ag_focus(e); };
			textarea.onblur = function(e) { _this.ag_blur(e); };
			textarea.onkeyup = function(e) { _this.ag_keyup(e); };
			if (this.layout.style != 'wall') {
				textarea.style.overflow = "hidden";
			}

			/* Show assets */
			var hta = cont.appendChild( newElem('textarea', { 'style' : 'display: none', 'id' : 'IMG_' + id }, this.content[ 'IMG_' + id ] || ''	) )
			hta.style.display = 'none'; // IE7

			var imgco = cell.insertBefore( 
				newElem('div', { 'id' : 'imagecontainer_' + id, 'class' : 'imagecontainers' } ),
				textarea
			);


			var btnLabel = "Add media";

			if (this.content['IMG_' + id]) {
				var imgs = this.content['IMG_' + id].split("\n");
				var image = imgs[0];

				if (image.indexOf('http') == 0 || image.indexOf('object:') == 0)  {
					var url = image;
					if (url.indexOf("object:") == 0) {
						url = '/images/Processing.gif';
						setTimeout("checkImage(\"" + id + "\")", 5000);
					}
					var img = newElem('img', { 'src' : url, 'id' : 'imgel_' + id });
					//, 'width' : '160', 'height' : '90' });
					// img.style.float = 'left';
					img.onload = function(e) { 
						return;
						if (!e) e = window.event;
						var img = e.srcElement || e.currentTarget;
						var gp = img.parentNode.parentNode;
						var ta = gp.getElementsByTagName("TEXTAREA");
						var height = gp.clientHeight - img.parentNode.scrollHeight - 100;
						ta[0].style.height = height + 'px';
						//setTimeout(function() { img.onload({ srcElement : img }) }, 500);
					};
					img.style.border = '1px outset black';

					img.style.width = '100%';
					if (is_ie) img.style.height = '100%';

					// Get the objrep ID from the URL, e.g. http://create.five.ymogen.net/files/2882/22894.jpeg
					var orep = image;
					orep = orep.substring(orep.indexOf('files') + 6);
					orep = orep.substring(orep.indexOf('/') + 1);
					orep = orep.substring(0, orep.indexOf('.'));

					img.onclick = function(e) { 
						_this.displayAsset( image );
					};

					imgco.appendChild(img);
					btnLabel = "Change media";
				}
			}
			if (this.is_member) {
				/* File uploads */
				var butt = newElem('button', { 'class' : 'cellattach' }, 'Attach media');
				butt.style.position = 'absolute';
				butt.style.left = '15px';
				butt.style.top = '-50px';
				butt.id = 'BX_' + id;
				//cont.appendChild(butt);
				imgco.appendChild(butt);

				cont.appendChild( newElem('input', { 'type' : 'hidden', 'id' : 'IM_' + id } ) );
				this.butt_adjust( id, 0, btnLabel );
			}

		} else if (type == 'image') {
			if (content == null) 
				content = '/images/default/story_160.gif';
			cell.appendChild( newElem('input', { 'type' : 'hidden', 'name': id, 'id': id, 'value': content }));
			if (content.indexOf("object:") >= 0) content = '/images/Processing.gif';
			var div = cell.appendChild( newElem( 'img', { 'id' : id + '-flash', 'src' : content, 'width' : '160', 'height' : '90', 'class' : 'flashImg', 'style': 'visibility: visible', 'title' : 'Please install Flash 9.0.124 or newer to be able to upload images' }) );
			var div = cell.appendChild( newElem( 'img', { 'id' : id + '-flash', 'src' : content, 'width' : '160', 'height' : '90', 'class' : 'noflashImg', 'style': 'visibility: visible', 'title' : 'Please install Flash 9.0.124 or newer to be able to upload images' }) );
			cell.appendChild( newElem('span', { 'class' : 'imageurl' }) );
			if (this.is_member) {
				var params = {scale:"noscale",wmode:"transparent", 'align' : 'tl', 'salign' : 'tl'};
				var flashVars = {representation_type:"160x90",collectionId:this.story,uploadPath:"/lib/upload",current_image:content,callJsOnNewImage:true,session:this.session,width:160,height:90,id:id + '-flash',fieldname:id};
				swfobject.embedSWF("/flash/image_replacer.swf", id + '-flash', "160", "90", "9.0.124", false, flashVars,params);
			}
		} else {
			cell.appendChild( newElem("div", {}, 'Unrecognised cell type ' + type) );
		}

		//cont.appendChild(cell);
		return cont;
	},
	add_row : function (c) { /*
		Adds rows to a scene / topic block
		---------------------
		c.topic => topic id, 
		c.rowno => backend row number to insert
		c.ignore_content => passed on to new_cell (leave cells blank) */

		var topic = c.topic;
		var rowno = c.rowno;

		var elem = Elem("s" + topic);
		var elems = getElementsByClass("rows", elem);
		elem = elems[0];

		if (!elem) return; // IE 7

		/* Create row */
		var rows = getElementsByClass("row", elem);
		var footer = getElementsByClass("footer", elem);
		footer = footer[0];
		if (rowno == null) rowno = rows.length;
		var row = newElem("div", { 'class' : 'row', 'id' : 's' + topic + 'r' + rowno });

		/* Create rowhandle */
		var handle = newElem("div", { "id" : "handle_" + rowno + "_" + topic, "class" : "rowhandle" });
		var cont = newElem("div", { 'class' : 'mell' });
		var cell = newElem("div", { 'class' : 'cell' });
		handle.onmousedown = function(e) { _this.catch_row(this, e); };

		var handle_ta = newElem('textarea', { 'class' : 'grow' });
		handle_ta.style.display = 'none';
		handle_ta.style.overflow = "hidden";

		cell.appendChild(handle_ta);
		cont.appendChild(cell);
		handle.appendChild(cont);

		if (this.is_member) {
			var img = newElem('img', { 'src' : '/images/icons/delete.png' });
			cell.appendChild(img);

			var _this = this; 
			img.onclick = function(e) { 
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var topic = _this.get_scene(elem).id.substring(1);
				var row = _this.get_row(elem).id;
				row = row.substring( row.indexOf('r') + 1);
				if (confirm("Are you sure you want to delete this row?")) {
					_this.ag_delete_row(row, topic);
				}
			};
		}

		row.appendChild(handle);

		elem.insertBefore(row, footer);
		/* Create cells */
		var total_width = 50;
		for (var i=0, il=this.columns.length; i<il; i++) {
			var col = this.columns[i];
			var id = col.name + "_" + rowno + "_" + topic;

			if (col.type == 'image') {
				total_width += 158;
			} else {
				total_width += 303;
			}
			var cont = this.new_cell({ 'par' : row, 'id' : id, 'type' : col.type, 'ignore_content' : c.ignore_content });
			//row.appendChild(cont);
		}
		row.appendChild( newElem("br", { clear: 'all' }) );
		row.style.width = total_width + 'px';

		if (this.content['delete_' + rowno + '_' + topic] && c.ignore_content == null) {
			row.style.display = 'none';
		}
		//elem.insertBefore(row, footer);
		var target = row.getElementsByTagName("TEXTAREA");
		if (target.length) {
			for (var t=0, tc=target.length; t < tc; t++) {
				this.ag_keyup({ keycode: 32, currentTarget: target[t] });
			}
		}
	},
	get_plan : function() {
		return Elem('plan');
	},
	del_scene : function(topic) {
		/* Need to get topic from backend to create new scene */
		var req = this.get_request();
		if (!req) return;
		if (!this.story) return;

		try { 
			var url = "/connect/del_scene/" + this.story + '/' + topic;
			var _this = this;
			req.onreadystatechange = function() { };
			req.open("GET", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	add_scene : function() {
		/* Need to get topic from backend to create new scene */
		var req = this.get_request();
		if (!req) return;
		if (!this.story) return;

		try { 
			var url = "/connect/add_scene/" + this.story;
			var _this = this;
			req.onreadystatechange = function() { _this.add_scene_receive(req); };
			req.open("GET", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
	},
	add_scene_block : function(topic, elem, norow) { /* Elem = parent */
		//var elem = this.get_plan();
		var _this = this;
		var scenes = getElementsByClass("scene", elem);

		var scenenum = scenes.length + 1;

		var scene = newElem("div", { 'class' : 'scene', 'id' : 's' + topic });
		var handle = newElem("div", { 'class' : 'rowhandle toprowhandle', 'id' : 'handle_' + topic }, '' );
		if (this.is_member) {
			var img = newElem('img', { 'src' : '/images/icons/delete.png' });
			handle.appendChild( img );
			img.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var topic = _this.get_scene(elem);
				topic = topic.id.substring(1);
				if (confirm("Are you sure you want to delete this scene?")) {
					_this.ag_delete_scene( topic );
				}
			};
		}
		scene.appendChild(handle);
		var h2 = scene.appendChild( newElem("h2", { 'class' : 'scenetitle' }) );
		var value = this.content['topictitle_0_' + topic] || 'Scene ' + scenenum;
		this.content['topictitle_0_' + topic] = value;
		var title = h2.appendChild( newElem('input', { 'class' : 'connect', 'type' : 'text', 'id' : 'topictitle_0_' + topic, 'name' : 'topictitle_0_' + topic, value : unescapeHTML(value) }) );
		h2.onclick = function(e) { _this.ag_focus(e); };
		title.onfocus = function(e) { _this.ag_focus(e); };
		title.onblur = function(e) { _this.ag_blur(e); };
		var rows_elem = newElem("div", { 'class' : 'rows' });
		var footer_elem;
		if (this.is_member && this.layout.show_footer) {
			footer_elem = newElem("div", { 'class' : 'footer'}, "Add a new row");
			var _this = this;
			footer_elem.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var scene = _this.get_scene(elem);
				var topic = _this.get_scene(elem);
				topic = topic.id.substring(1);
				_this.add_row({ 'topic' : topic });
			};
		} else {
			footer_elem = newElem("div", { 'class' : 'footer', 'style' : 'display: none' });
		}

		if (this.layout.show_columns) {
			var label_row = newElem('div', { 'class' : 'labelrow' });
			var label_row_handle = newElem('div', { 'class' : 'rowhandle', 'id' : 'handle_top_' + topic, 'style' : 'background: #666666' });
			//label_row_handle.appendChild( newElem('div', { 'class' : 'cellheading', 'style' : 'width: 20px;' }) );
			label_row.appendChild(label_row_handle);

			var total_width = 50;
			for (var c=0, cl=this.columns.length; c<cl; c++) {
				var col = this.columns[c];
				var width;
				if (col.type == 'image') {
					width = 158;
				} else {
					width = 303;
				}
				var handle = newElem('div', { 'class' : 'cellheading', 'style' : 'width: '+width + 'px', 'id' : col.name + '_cellheading_' + topic });
				handle.style.width = width + 'px';
				if (this.is_member && this.layout.del_columns) {
					var handle_del = newElem('div', { 'class' : 'cellheadingimg' } );
					var img = newElem('img', { 'src' : '/images/icons/delete.png', 'alt' : 'Delete', 'height' : '11', 'width' : 11 })
					handle_del.appendChild( img );
					var _this = this;
					var _topic = topic;
					var _colname = col.name;
					handle_del.onclick = function(e) { 
						if (!e) e = window.event;
						var elem = e.srcElement || e.currentTarget;
						warn(elem);
						var scene = _this.get_scene( elem );
						var topic = scene.id.substring(1);
						var colname = elem.parentNode.id.substring(0, elem.parentNode.id.indexOf('_'));
						if (confirm('Are you sure you want to remove this column?')) {
							_this.hide_column(topic, colname);
						}
						e.cancelBubble = true;
						if (e.stopPropagation) e.stopPropagation();
						return false;
					};
					img.onclick = function(e) {
						if (!e) e = window.event;
						var elem = e.srcElement || e.currentTarget;
						elem.parentNode.onclick({ srcElement : elem.parentNode });
					};
					handle.appendChild(handle_del);
				}
				handle.appendChild( document.createTextNode( col.heading ) );
				//handle.innerHTML = handle.innerHTML + col.heading;
				label_row.appendChild( handle );
				total_width += width;
			}
			label_row.style.width = total_width + 'px';
			var _this = this;
		
			if (this.layout.add_columns) {
				var plus = newElem('div', { 'id' : 'columns_' + topic, 'class' : 'planplus'}, '+');
				plus.onclick = function(e) { _this.addcol(topic); } 
				if (this.is_member) {
					label_row.appendChild(plus);
				}
			}

			rows_elem.appendChild(label_row);
		}
		rows_elem.appendChild(footer_elem);
		scene.appendChild(rows_elem);

		elem.appendChild(scene);
		if (!norow)
			this.add_row({ 'topic' : topic });
		return scene;
	},
	add_scene_receive : function(req) {
		if (req.readyState == 4) {
			this.activerequest = null;
			if (req.status != 200 && req.status != 0 && req.status != 304) {
				if (req.status == 400) {
					new AlertBox( { type: 'info', content: 'Session expired' }, 0 );
					this.failed = 1;
				}
			} else {
				var json = JSON.parse(req.responseText);

				if (!json.topic) return;
				this.add_scene_block(json.topic, this.get_plan());
			}
		}
	},
	setup : function() {
		this.is_member = 0;
		if (!this.user) return; // For when we allow non-users to read
		if (this.members) {
			for (var i=0, j=this.members.length; i < j; i++) {
				if (this.members[i].id == this.user) 
					this.is_member = 1;
			}
		}
		this.update();
	},
	release_lock : function(elem) {
		var od = this;
		var req = this.get_request();
		if (!req) return;
		if (this.oldelem && elem.id == this.oldelem)
			this.oldelem = null;
		try {
		  req.onreadystatechange = function() { };
		  req.open("GET","/connect/lock/" + this.page_topic + "/" + elem.id + "/release", true);
		  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		  req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
		  //req.setRequestHeader("Connection", "close");
		  req.send({});
		} 
		catch(err) {
			alert(err);
		}
	},
	fetch_lock : function (elem) {
		if (!elem.id) return;
		this.wantedelem = elem;
		var req = this.get_request();
		if (!req) return;
		elem.setAttribute("readonly", "readonly");
		elem.readOnly = "readonly";
		var _this = this;
		req.onreadystatechange = function(e) { _this.receive_lock(req, elem); };
		req.open("GET","/connect/lock/" + this.page_topic + "/" + elem.id, true);
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
		//req.setRequestHeader("Connection", "close");
		req.send({});
	},
	receive_lock : function(req, elem) {
		if (req.readyState == 4) {
			if (req.status != 200 && req.status != 0) {
			} else {
				if (req.responseText) {
					this.obj = JSON.parse(req.responseText);
					var lock = this.obj.lock;
					var ok = 0;
					if (this.obj.lock && this.obj.lock.user.id == this.user) {
						this.currelem = this.wantedelem;
						this.wantedelem = null;
						if (this.currelem) { 
							if (this.currelem.value == this.titleClick) {
								this.currelem.value = '';
							}
							this.currelem.readOnly = null;
							this.currelem.removeAttribute("readonly");
							this.currelem.focus();
						}
						return;
					}
					if (this.wantedelem) {
						// warn( lock );
						// errorin(this.wantedelem.id);
					}
					//this.addLockLabel(this.wantedelem, lock);
				}
				this.wantedelem = null;
			}
		}
	},
	update_plan : function () {
		// If it's already been done, don't do it again (for delayed onblur)
		if (this.oldelem == null) return 1;
		var elem = Elem(this.oldelem);
		this.oldelem = null;
		var message = elem.value;
		var temp = new Array();
		temp = elem.id.split('_');
		var name = temp[0];
		var row = temp[1];
		var topic = temp[2];
		if (message != '-used-to-be-empty-' && message != '/images/default/story_160.gif' && 
			message != this.content[elem.id]) {
			// Submit message also releases any locks, so as to save a call to the server
			this.submit_message(topic, message, name, row);
		} else {
			this.release_lock(elem);
		}
		return 1;
	},
	addLockLabel : function(elem, lock) {
		var d = Elem(elem.id + "_label");
		if (lock && lock.user.id == this.user) return;
		if (d) {
			d.innerHTML = "";
			var s = newElem("span");
			if (lock.user.avatar && this.layout.style == 'plan') {
				s.appendChild( newElem('img', { 'src' : lock.user.avatar, 'width' : 16, 'height' : 16 }) );
			}
			s.appendChild( newElem('b', {}, lock.user.screenname) );

			var sd = newElem("div");
			sd.appendChild(s);
			if (this.layout.style == 'plan') {
				sd.style.height = elem.parentNode.offsetHeight + 'px';
			}

			d.appendChild(sd);
			d.style.display = 'block';
			d.parentNode.setAttribute("class", "cell locked");
			d.parentNode.className = 'cell locked';
		}
	},
	removeLockLabel : function(elem) {
		var d = Elem(elem.id + "_label");
		if (d) {
			d.innerHTML = '';
			d.style.display = 'none'; // We need to hide it to prevent whitespace to appear in IE 7
			d.parentNode.setAttribute("class", "cell");
			d.parentNode.className = 'cell';
		}
	},
	mouse_xy : function  (e) {
		if (!e) e = window.event;
		return {
			'x' : e.clientX,
			'y' : e.clientY
		};
		/*
		return {
			'x' : e.clientX + document.documentElement.scrollLeft,
			'y' : e.clientY + document.documentElement.scrollTop
		};
		*/
	},
	abso_elem_xy : function (elem) { /* Relative to container (abso/relative positioned) */
		var x = 0, y = 0;
		do { 
			x = x + elem.offsetLeft;
			y = y + elem.offsetTop;
			elem = elem.offsetParent;
		} while (elem && elem.style.position && elem.style.position != 'static');

		return { x: x, y: y };
	},
	local_elem_xy : function (elem) {
		var x = 0, y = 0;
		do { 
			x = x + elem.offsetLeft;
			y = y + elem.offsetTop;
			elem = elem.offsetParent;
		} while (elem && elem.getAttribute("class") != 'container');

		return { x: x, y: y };
	},
	elem_xy : function (elem) {
		var x = 0, y = 0;
		while (elem.offsetParent) {
			x = x + elem.offsetLeft;
			y = y + elem.offsetTop;
			elem = elem.offsetParent;
		}
		x = x + elem.offsetLeft;
		y = y + elem.offsetTop;

		return { x: x, y: y };
	},
	get_rows : function(target) {
		this.rows = getElementsByClass("row", target.parentNode);
		for (var i=0, ic = this.rows.length; i < ic; i++) {
			this.rowpos[i] = this.elem_xy(this.rows[i]);
			if (this.rows[i].id == target.id) this.currow = i;
		}
	},
	catch_row : function(elem, e) {
		e = e || window.event;
		target = elem.parentNode;
		var mouse = this.mouse_xy(e);
		var elem  = this.local_elem_xy(target);
		this.mouseOffset = { x: mouse.x - elem.x, y: mouse.y - elem.y };
		this.get_rows(target);
		this.dragObject = target;
		this.dragObject.setAttribute("class", "row activerow");
		this.dragObject.className = 'row activerow';
		this.dragObject.getElementsByTagName("div")[0].getElementsByTagName("div")[0].getElementsByTagName("div")[0].style.background = '#8BB12E';
		var _this = this;
		document.onmousemove = function(e) { _this.on_mouse_move(e) };
		document.documentElement.onmouseup   = function(e) { _this.release_row(e); };

		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
		return false;
	},
	release_row : function(e) {
		if (this.dragObject) {
			object = this.dragObject;
			this.dragObject = null;
			object.style.position = 'static';
			object.style.cursor = null;
			var _this = this;
			object.setAttribute("class", "row");
			object.className = 'row';
			object.getElementsByTagName("div")[0].getElementsByTagName("div")[0].getElementsByTagName("div")[0].style.background = '#999999';
			var topic = object.parentNode.parentNode.id.substring(1);
			var len = topic.length + 2;

			var params = "do=rearrange";
			for (var i=0, ic = this.rows.length; i < ic; i++) {
				var rowid = this.rows[i].id.substring(len);
				params = params + '&row' + rowid + '=' + i;
			}

			var req = this.get_request();
			req.open("POST", "/connect/rows/" + topic);
			req.onreadystatechange = function() { };
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send(params);

			document.onmousemove = function(e) {};
			document.documentElement.onmouseup   = function(e) {};
		}
	},
	on_mouse_move : function(e) {
		e = e || window.event;
		if (!this.dragObject) return false;
		var mouse = this.mouse_xy(e);
		var pos = 0;
		for (var i=0, ic = this.rows.length; i < ic; i++) {
			if (this.rows[i].clientHeight) { /* Not hidden */
				if (mouse.y > this.rowpos[i].y) {
					if (!pos || this.rowpos[pos].y < this.rowpos[i].y) {
						pos = i;
					}
				}
			}
		}
		if (pos != this.currow) {
			var rowcont = this.rows[pos].parentNode;
			var current = this.rows[this.currow];
			rowcont.removeChild(current);
			//var current = this.rows[this.currow].removeNode(true);
			if (this.rowpos[pos].y < this.rowpos[this.currow].y) {
				rowcont.insertBefore(current, this.rows[pos]);
			} else {
				var next = null;
				var next_y = 9999999;
				for (var i=0, ic = this.rows.length; i < ic; i++) {
					if (i != this.currow && i != pos && (this.rowpos[i].y < next_y && this.rowpos[i].y > this.rowpos[pos].y)) {
						next = i;
						next_y = this.rowpos[i].y;
					}
				}
				if (next) {
					rowcont.insertBefore(current, this.rows[next]);
				} else {
					var footer = getElementsByClass("footer", rowcont);
					if (footer.length) {
						footer = footer[0];
						rowcont.insertBefore(current, footer);
					} else {
						rowcont.appendChild(current);
					}
				}
			}
			this.currow = pos;
			this.get_rows(current);
		}
		this.dragObject.style.cursor = 'move';
		this.dragObject.onmouseover = null;

		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();

		return false;
	},
	get_row : function(scene) {
		while (scene.getAttribute('class') != 'row') {
			scene = scene.parentNode;
		}
		return scene;
	},
	get_scene : function(scene) {
		while (scene.getAttribute('class') != 'scene') {
			scene = scene.parentNode;
		}
		return scene;
	},
	hide_column : function(topic_id, column) {
		var req = this.get_request();
		try { 
			var url = "/connect/hide_column/" + topic_id + "/" + column;
			var _this = this;
			req.onreadystatechange = function() { };
			req.open("GET", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
			req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
			//req.setRequestHeader("Connection", "close");
			req.send({});
		} catch(err) {
			alert('Error: ' + err);
		} 
		
	},
	hide_column_html : function(topic_id, column) {
		var scene = Elem('s' + topic_id);
		var labelrow = getElementsByClass('labelrow', scene);
		if (labelrow.length) labelrow = labelrow[0];
		var header = Elem(column.name + "_cellheading_" + topic_id);
		if (header) {
			column.heading = header.childNodes[ header.childNodes.length - 1].nodeValue;
			header.parentNode.removeChild(header);
		}
		var i = 0;
		var elem = Elem(column.name + "_" + i + "_" + topic_id);
		while (elem) {
			var mell = elem.parentNode.parentNode;
			mell.parentNode.removeChild(mell);
			i = i + 1;
			elem = Elem(column.name + "_" + i + "_" + topic_id);
		}
		var ec = [];
		for (var i=0, ic=this.columns.length; i<ic; i++) {
			if (this.columns[i].name != column.name) {
				ec.push(this.columns[i]);
			} else {
				var done = 0;
				for (var j=0, jc=this.extra_columns.length; j < jc; j++) {
					if (this.extra_columns[j].name == this.columns[i].name) done = 1;
				}
				if (!done) this.extra_columns.push(this.columns[i]);
			}
		}
		this.columns = ec;
		if (window.autoresize) { window.autoresize(); }
	},
	add_column_html : function(topic_id, column, ignore_content) {
		var scene = Elem('s' + topic_id);
		var labelrow = getElementsByClass('labelrow', scene);
		if (labelrow.length) labelrow = labelrow[0];
		//debugger;

		if (labelrow) {
			var plus = Elem('columns_' + topic_id);
			var width = "303px";
			if (column.type == 'image') width = '158px';
			var div = newElem('div', { 'class' : 'cellheading', 'style' : 'width: ' + width, 'id' : column.name + "_cellheading_" + topic_id });
			if (this.is_member) {
				var divdel = newElem('div', { 'id' : 'dd' + topic_id + '_' + column.name, 'style' : 'float: right;', 'onclick' : 'com.hide_column(' + topic_id + ', "' + escapeHTML(column.name) + '")' });
				divdel.appendChild(newElem('img', { 'id' : 'im' + topic_id + '_' + column.name, 'src' : '/images/icons/delete.png', 'height' : '11', 'width' : '11' }));
				var _this = this;
				divdel.onclick = function(e) {
					if (!e) e = window.event;
					var elem = e.srcElement || e.currentTarget;
					var split = elem.id.indexOf('_');
					var topic = elem.id.substring(2, split);
					var colname = elem.id.substring(split + 1);
					if (confirm('Are you sure you want to remove this column?')) {
						_this.hide_column(topic, colname);
					}
				};
				div.appendChild(divdel);
			}
			div.appendChild( newText( column.heading ) );
			//div.innerHTML = div.innerHTML + column.heading;
			labelrow.insertBefore(div, plus);
		}

		var rows = getElementsByClass('row', scene);
		for (var i=0, ic = rows.length; i < ic; i++) {
			var row = rows[i];
			var sep = row.id.indexOf('r');
			var rowid = row.id.substring(sep + 1);
			var br = row.getElementsByTagName("br");
			if (br.length) br = br[0];
			var id = column.name + '_' + rowid + '_' + topic_id;
			var cell = this.new_cell({ 'id' : id, 'type' : column.type, 'ignore_content' : ignore_content, 'par' : row, 'before' : br });
			//row.insertBefore(cell, br);
			//debugger;
			var target = row.getElementsByTagName("TEXTAREA");
			if (target.length) {
				target = target[target.length - 1];
				this.ag_keyup({ keycode: 32, currentTarget: target });
			}
		}
		this.readjust_width(0);
		var ec = [];
		var added = 0;
		for (var i=0, ic=this.extra_columns.length; i<ic; i++) {
			if (this.extra_columns[i].name != column.name) {
				ec.push(this.extra_columns[i]);
			}
		}
		for (var j=0, jc=this.columns.length; j < jc; j++) {
			if (this.columns[j].name == column.name) added = 1;
		}
		if (!added) this.columns.push(column);
		this.extra_columns = ec;
	},

/* Adding columns */

	addcol_action : function(e) {
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;

		var mycol = null;
		var newcols = [];

		if (elem.tagName == 'A') {
			var colno = elem.id.substring(3);
			for (var i=0, ic=this.extra_columns.length; i < ic; i++) {
				var col = this.extra_columns[i];
				if (i == colno) {
					mycol = {
						'elem' : col,
						'heading' : col.heading,
						'name' : col.name
					};
				}
			}
		} else if (elem.tagName == 'BUTTON') {
			mycol = {
				'heading' : Elem('addcolname').value
			};
		}

		var cols = Elem('colselect');
		if (cols) cols.parentNode.removeChild(cols);

		var scenes = getElementsByClass("scene");
		var topic = scenes[0].id.substring(1);
		//var topic = this.get_scene( elem ).id.substring(1);
		if (mycol) {
			var req = this.get_request();
			try { 
				var params = "heading=" + encodeURIComponent(mycol.heading);
				if (mycol.name) 
					params = params + "&name=" + encodeURIComponent(mycol.name);
				if (mycol.type)
					params = params + "&type=" + encodeURIComponent(mycol.type);
				var url = "/connect/add_column/" + topic;
				var _this = this;
				req.onreadystatechange = function() { };
				req.open("POST", url, true);
				req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
				req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
				//req.setRequestHeader("Connection", "close");
				req.send(params);
			} catch(err) {
				alert('Error: ' + err);
			} 
		}
	},
	addcol : function(topic) {
		var elem = Elem('colselect');
		if (elem) {
			elem.parentNode.removeChild(elem);
			return;
		}
		dialogue("Add new column", [
			'Please specify the name of the new column',
			br(),
			newElem('input', { 'type' : 'text', 'size' : '20', 'id' : 'colname', 'class' : 'biginput' })
		], {
			'OK' : function(e) {
				var _this = com;
				var scenes = getElementsByClass("scene");
				var topic = scenes[0].id.substring(1);
				var mycol = null;
				var heading = Elem('colname').value;

				for (var i=0, ic=_this.extra_columns.length; i < ic; i++) {
					var col = _this.extra_columns[i];
					if (col.heading == heading) mycol = col;
				}
				if (!mycol) mycol = { 'heading' : heading };

				if (mycol) {
					var req = _this.get_request();
					try { 
						var params = "heading=" + encodeURIComponent(mycol.heading);
						if (mycol.name) 
							params = params + "&name=" + encodeURIComponent(mycol.name);
						if (mycol.type)
							params = params + "&type=" + encodeURIComponent(mycol.type);
						var url = "/connect/add_column/" + topic;
						req.onreadystatechange = function() { };
						req.open("POST", url, true);
						req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
						req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
						req.send(params);
					} catch(err) {
						alert('Error: ' + err);
					} 
				}
				closeDialogue();
			},
			'Cancel' : function(e) {
				closeDialogue();
			}
		}, {
			'onload' : function() {
				Elem('colname').focus();
			}
		});
	},

/* Wall / plan etc. generation + content population  */

	populate : function() { /* Tabular only */
		var maxrow = {};
		var position = [];
		for (var key in this.content) {
			if (key.indexOf('position') == 0) {
				var row = key.substring(9);
				var split = row.indexOf('_');
				var topic = row.substring( split + 1);
				row = row.substring(0, split);
				position[ topic + '/' + this.content[key] ] = Number(row) + 1;
				continue;
			}
			var split = key.indexOf('_');
			var row = key.substring(split + 1);
			key = key.substring(0, split);
			split = row.indexOf('_');
			var topic = row.substring(split + 1);
			row = Number(row.substring(0, split));
			if (!position[topic + '/' + row]) position[topic + '/' + row] = row + 1;
			if (!maxrow[topic] || maxrow[topic] < row) 
				maxrow[topic] = row;
		}
		for (var t=0, tc=this.topics.length; t < tc; t++) {
			var topic = this.topics[t];
			if (!maxrow[topic]) maxrow[topic] = 0;
			for (var i=0; i <= maxrow[topic]; i++) {
				if (position[topic + '/' + i]) {
					this.add_row({ 'topic' : topic, 'rowno' : position[ topic + '/' + i] - 1 });
				} else {
					this.add_row({ 'topic' : topic });
				}
			}
		}
	},
	display_tabular : function() {
		var plan = Elem('plan');
		if (this.editable) {
			plan.appendChild(
				newElem('div', { 'class' : 'planControls' },
					newElem('button', { 'id' : 'addSceneBtn' }, 'Add scene')
				)
			);
			var _this = this;
			Elem('addSceneBtn').onclick = function(e) { 
				_this.add_scene();
			};
		}
		for (var topic_i = 0, topic_c = this.topics.length; topic_i < topic_c; topic_i++) {
			var topic = this.topics[topic_i];
			this.add_scene_block(topic, plan, true);
		}
		this.populate();
		this.in_playback = 0;
		this.set_mode('static');
		this.current = {};
	},
	display_wall : function() {
		var plan = Elem('plan');
		var _this = this;

		var topic = this.topics[0];

		/* Place notes on wall */

		var left = 0;
		var top = 20;
		for (var c=0, cc=this.columns.length; c < cc; c++) {
			var column = this.columns[c];
			for (var key in this.content) {
				if (key.indexOf(column.name + '_') == 0 && 
					!this.content['DEL_' + key]) {

					var cell = this.new_cell({ 'id' : key, type : column.type });
					plan.appendChild(cell);
					cell.style.position = 'absolute';
					if (this.content['XY_' + key]) {
						var arr = this.content['XY_' + key].split('/');
						cell.style.top = arr[1] + 'px';
						cell.style.left = arr[0] + 'px';
					} else {
						cell.style.top  = top  + 'px';
						cell.style.left = left + 'px';
						left = left + 250;
					}
					if (this.content['WH_' + key]) {
						var arr = this.content['WH_' + key].split('/');
						cell.style.width = arr[0] + 'px';
						cell.style.height = arr[1] + 'px';
						var ta = cell.getElementsByTagName('TEXTAREA');
						if (ta.length) {
							//ta[0].style.width = arr[0] - 30 + 'px';
							ta[0].style.width = arr[0] - 20 + 'px';
							var height = arr[1] - 70;
							var imgco = Elem('imagecontainer_' + key);
							if (imgco.scrollHeight)
								height = height - imgco.scrollHeight - 5 - 30;
							if (height < 0) height = 10;
							ta[0].style.height = height + 'px';
						}
					}  else {
						/* Needed specifically for IE7 */
						cell.style.width = '220px';
						cell.style.height = '200px';
					}
					if (left > 500) {
						left = 0;
						top = top + 220;
					}
				}
			}
		}

		/* Add [column name] buttons for each column */

		if (!this.is_member) return;

		for (var c=0, cc=this.columns.length; c < cc; c++) {
			var column = this.columns[c];
			/* var note = newElem('span', { id : 'add_' + column.name, class : 'noteWallBtns' }, 'Add ' + column.heading); */
			// TODO: This isn't just note, but varies depending on each column. However, only used for notes now
			var note = newElem('span', { 'id' : 'add_' + column.name, 'class' : 'noteWallBtns' }, ' Add note +');
			note.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var column = null;
				var col = elem.id.substring(4);
				for (var i=0, ic=_this.columns.length; i<ic; i++) {	
					if (_this.columns[i].name == col)
						column = _this.columns[i];
				}
				var i = 1; 
				while (_this.content[col + '_' + i + '_' + _this.topics[0]]) {
					i++;
				}
				var cell = _this.new_cell({ 
					id : col + '_' + i + '_' + _this.topics[0], 
					type : column.type
				});
				_this.content[ col + '_' + i + '_' + _this.topics[0]] = ' ';
				_this.submit_message(_this.topics[0], ' ', col, i);
				_this.submit_message(_this.topics[0], '0/0', 'XY_' + col, i);
				_this.submit_message(_this.topics[0], '220/200', 'WH_' + col, i);
				Elem('plan').appendChild(cell);
				cell.style.position = 'absolute';
				cell.style.top = '20px';
				cell.style.left = '20px';
				cell.style.width = '220px';
				cell.style.height = '200px';
				cell.style.zIndex = _this.top_of_it_all++;
			};
			plan.appendChild( note );
		}

		/* Tidy notes button */

		var butt = newElem('span', { 'id' : 'tidyBtn', 'class' : 'noteWallBtns' }, 'Tidy notes');
		var _this = this;

	/*
	  	butt.onmouseover = Elem('tidyBtn').style.backgroundImage='url(/images/plan_button_hover.gif)';
		butt.onmouseout = Elem('tidyBtn').style.backgroundImage='url(/images/plan_button.gif)';
	*/
		butt.onclick = function(e) {
			var notes = getElementsByClass("mell");
			var x = 0;
			var y = 20;
			for (var i=0, ic=notes.length; i < ic; i++) {
				var ta = notes[i].getElementsByTagName('TEXTAREA');
				if (ta.length) {
					if (!ta[0].scrollHeight) continue; // Ignore deleted nodes
					notes[i].style.left = x + 'px';
					notes[i].style.top = y + 'px';
					notes[i].style.width = '220px';
					notes[i].style.height = '200px';
					ta[0].style.width = '190px';

					var height = notes[i].clientHeight - 70;
					var imgco = Elem('imagecontainer_' + ta[0].id);
					if (imgco && imgco.scrollHeight)
						height = height - imgco.scrollHeight - 5 - 30;
					if (height < 0) height = 10;
					ta[0].style.height = height + 'px';
					var arr = ta[0].id.split('_');
					_this.submit_message(arr[2], x + '/' + y, 'XY_' + arr[0], arr[1]);
					_this.submit_message(arr[2], '220/200', 'WH_' + arr[0], arr[1]);
					x = x + 250;
					if (x > 500) {
						x = 0;
						y = y + 220;
					}
				}
			}
		};
		plan.appendChild(butt);
	},
	display : function() { /* Display content according to layout class */
		var plan = Elem('plan');
		if (!plan) return;
		while (plan.childNodes.length) {
			plan.removeChild(plan.childNodes[0]);
		}
		if (this.layout.style == 'wall') {
			this.display_wall();
		} else { // this.layout.style == 'tabular'
			this.display_tabular();
		}
	},

/* Row manipulation */

	hiderow : function(id, height) { /* Tabular only */
		var elem = Elem(id);
		if (elem) {
			if (height == null) height = 90;
			if (height <= 0) {
				elem.style.display = 'none';
			} else {
				height = height - 10;
				//elem.innerHTML = '';
				var cell = getElementsByClass("cell", elem);
				for (var i=0, ic=cell.length; i<ic; i++) {
					cell[i].style.background = 'rgb(255,33,33)';
				}
				var _this = this;
				setTimeout( function() { _this.hiderow(id, height) }, 50);
			}
		}
	},

/* Playback */

	playback_cell : function (c) {
		var _this = this;

		var act = this.updates[c.session].activities[c.idx];

		if (!act) return;

		var scene = Elem('s' + act['topic']);
		if (scene) { scene.style.display = 'block'; }

		if (act['name'] == 'delete') {
			var id = 's' + act['topic'] + 'r' + act['row'];
			if (c.delay > 0) {
				this.hiderow(id);
			} else {
				var elem = Elem(id);
				if (elem) elem.style.display = 'none';
			}
		} else if (act['content'].indexOf('_add_column') == 0) {
			var split = act['content'].indexOf('|');
			var name = act['content'].substring(split + 1);
			var type = 'text';
			split = name.indexOf('|');
			var heading  = name.substring(split + 1);
			name = name.substring(0, split);
			split = heading.indexOf('|');
			if (split) {
				type = heading.substring(0,split);
				heading = heading.substring(split+1);
			}
			var scenes = getElementsByClass('scene');
			if (scenes.length) {
				for (var i=0, ic = scenes.length; i < ic; i++) {
					var topic = scenes[i].id.substring(1);
					this.add_column_html(topic, { 'name' : name, 'type' : type, 'heading' : heading }, 1);
				}
			} else {
				this.add_column_html(act['topic'], { 'name' : name, 'type' : type, 'heading' : heading }, 1);
			}
			if (window.autoresize) { window.autoresize(); }
		} else if (act['content'].indexOf('_hide_column') == 0) {
			var split = act['content'].indexOf('|');
			var name = act['content'].substring(split + 1);
			/* Special case for plan -- apply to all scenes */
			var scenes = getElementsByClass('scene');
			if (scenes.length) {
				for (var i=0, ic = scenes.length; i < ic; i++) {
					var topic = scenes[i].id.substring(1);
					this.hide_column_html(topic, { 'name' : name, 'type' : 'text', 'heading' : name });
				}
			} else {
				this.hide_column_html(msg.topic, { 'name' : name, 'type' : 'text', 'heading' : name });
			}

		} else {
			var id = act['name'] + '_' + act['row'] + '_' + act['topic'];
			this.current[id] = act['content'];
			var elem = Elem(id);
			if (!elem) {
				var scene = Elem('s' + act['topic']);
				var first = Elem(act['name'] + '_0_' + act['topic']);
				if (first) {
					while (!elem) {
						this.add_row({ 'topic' : act['topic'], 'ignore_content' : 1 });
						elem = Elem(id);
					}
				}
			}
			var revert = 1;
			if (c.reset) revert = 0;
			if (elem) {
				elem.value = act['content'];
				var flash = Elem(id + '-flash');
				if (flash) {
					if (flash.tagName == 'IMG') {
						flash.src = act['content'];
					} else {
						this.flashUpdate(id, act['content']);
					}
					//window.setTimeout( function() { flash.inputImageReplacerUrl( act['content'] ) }, 500);
				}
				this.ag_keyup({ keycode: 32, currentTarget: elem });
				if (c.hidden == null) 
					newin(elem.id, 's' + c.session + 'a' + c.idx, revert );
			}
		}
	},
	playback_cells : function(c) {
		while (1) {
			if (this.updates.length <= c.session) {
				if (c.refresh != null) {
					this.display();
				}
				this.set_mode('static');
				this.current = {};
				return 0;
			}

			if (c.session == 0) c.session = 0; // IE7 (!)
			if (this.updates[c.session].activities.length <= c.idx) {
				c.session = c.session + 1;
				c.idx = 0;
				if (c.lastsession == null || c.session <= c.lastsession) {
					continue;
				} else if (c.refresh != null) {
					this.display();
					this.set_mode('static');
					this.current = {};
				}
				return;
			}
			var pbc_idx = Elem('pbc_current_idx');
			if (pbc_idx) {
				pbc_idx.innerHTML = c.idx + 1;
			}
			this.playback_cell(c);
			c.idx = c.idx + 1;

			if (c.lastidx == null || c.idx <= c.lastidx || c.session < c.lastsession) {
				if (c.delay > 0) {
					var _this = this;
					setTimeout(function() { _this.playback_cells(c); }, c.delay);
					return;
				} else {
					continue;
				}
			} else {
				if (c.refresh != null) {
					this.display();
				}
				this.set_mode('static');
				this.current = {};
				return;
			}
		}
	},
	flashUpdate : function( id, content ) {
		/* Flash needs to load before inputImageReplacerUrl is available; 
		   this function delays setting the content until Flash is available */
		var flash = Elem(id + '-flash');
		if (flash.inputImageReplacerUrl) { 
			if (content.indexOf('object:') == 0) {
				flash.inputImageReplacerUrl( '/images/Processing.gif' );
				setTimeout("checkImage(\"" + id + "\")", 5000);
			} else {
				flash.inputImageReplacerUrl( content );
			}
		} else {
			setTimeout( 'com.flashUpdate("' + id + '", "' + content.split('"').join("&quot;").split("\n").join("") + '")', 500 );
		}
	},
	reset : function(c) { /*
		Resets plan to specific revision
		-------------------
		c.session : Session number
		c.idx     : Activity number */
		var oldplan = Elem('plan');
		if (oldplan) {
			oldplan.parentNode.removeChild(oldplan);
		}
		var parent = Elem('container');
		var plan = newElem('div', { 'class' : 'plan', 'id' : 'plan' });
		plan.style.display = 'none';
		parent.appendChild(plan);
		for (var topic_i = 0, topic_c = this.topics.length; topic_i < topic_c; topic_i++) {
			var topic = this.topics[topic_i];
			var scene = this.add_scene_block(topic, plan, true);
			scene.style.display = 'none';
			this.add_row({ 'topic' : topic, 'ignore_content' : 1 });
		}
		if (c.session > 0 || c.idx > 0) {
			if (c.idx > 0) {
				this.playback_cells({
					'delay' : 0,
					'session' : 0,
					'ignore_content' : true,
					'idx' : 0,
					'lastsession' : c.session,
					'lastidx' : c.idx - 1,
					'hidden' : true,
					'reset' : 1
				});
			} else {
				this.playback_cells({
					'delay' : 0,
					'session' : 0,
					'ignore_content' : true,
					'idx' : 0,
					'lastsession' : c.session - 1,
					'lastidx' : this.updates[c.session - 1].activities.length - 1,
					'hidden' : true,
					'reset' : 1
				});
			}
		}
		plan.style.display = 'block';
	},
	playback : function(c) {
		if (!this.updates) return;
		var offset = document.getElementsByTagName('body')[0].scrollTop;
		this.current = {};
		this.in_playback = 1;
		this.set_mode('playback');
		if (c.delay == null) c.delay = 1500;
		if (c.lastsession == null) c.lastsession = c.session;
		if (c.lastidx == null) c.lastidx = c.idx;
		if (c.session == null) c.session = 0;
		if (c.idx == null) c.idx = 0;
		if (c.reset) {
			c.hidden = 1;
			var refresh = c.refresh;
			c.refresh = 0;
			this.reset(c);
			c.hidden = null;
			c.refresh = refresh;
		}
		var _this = this;
		if (c.delay > 0) {
			var soc = Elem('social');
			if (soc) {
				soc.innerHTML = '';
				soc.style.display = 'none';
			}
			var pb = Elem('playback');
			if (pb) {
				pb.style.display = 'block';
				//pb.appendChild( newElem('div', { 'class' : 'socialhead' }, 'Playback') );
				this.display_session({ 'parent' : pb, 'session' : this.updates[c.session], 'expand' : 1, 'noheader' : 1 });
			}
			setTimeout(function() { _this.playback_cells(c); }, c.delay);
		} else {
			this.playback_cells(c);
		}
	},
	/* EVENTS */
	ag_focus : function(e) {

		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;

		if (!this.is_member) {
			elem.blur();
			return false;
		}
		if (!this.is_member) {
			if (elem && elem.tagName == 'TEXTAREA') {
				elem.blur();
			}
			return;
		}
		if (elem && elem.tagName == 'DIV') {
			var arr = elem.getElementsByTagName("textarea");
			if (!arr) arr = elem.getElementsByTagName("input");
			if (arr.length) 
				arr[0].focus();
			return;
		}

		var p = elem.parentNode;
		if (p && p.getAttribute("class") != "mell") {
			p = p.parentNode;
		}
		if (p.getAttribute("class") == 'mell') {
			p.style.zIndex = this.top_of_it_all++;
		}

		this.update_plan();

		if (elem) 
			lock = this.fetch_lock(elem);
	},
	ag_keyup : function (e) {
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;

		if (this.layout.style != 'tabular') {
			elem.style.height = elem.scrollHeight;
			if (elem.parentNode.parentNode.className == 'mell') {
				elem.parentNode.parentNode.scrollTop = 0;
			}
			return;
		}

		elem.style.overflow = "hidden";
		elem.style.resize = "none"; //for webkit

		var wasy;
		if (window.pageYOffset) {
			wasy = window.pageYOffset;
		} else {
			wasy =(document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
		}
		
		var y = (elem.originalHeight) ? elem.originalHeight : 25; //default minimum height
		var uploader = getElementsByClass("imageurl", (elem.parentNode).parentNode.parentNode);
		if (uploader.length && y < 90) y = 90;

		if (e && e.keyCode == 8) elem.style.height = y + 'px';
		if (elem.clientHeight >= elem.scrollHeight + 5 && elem.clientHeight > y) 
			elem.style.height = y + 'px';
		
		if (elem.clientHeight < elem.scrollHeight)
			elem.style.height = elem.scrollHeight + "px";					
		
		var arr = getElementsByClass("grow", (elem.parentNode).parentNode.parentNode);
		var size = elem.clientHeight;
		if (size < y) size = y;

		for (var i=0, j=arr.length; i<j; i++) {
			if (arr[i].clientHeight > size) size = arr[i].clientHeight;
		}
		arr = getElementsByClass("cell", (elem.parentNode).parentNode.parentNode);
		for (var i=0, j=arr.length; i<j; i++) {
			arr[i].style.height = size + 'px';
		}
		elem.style.overflow = "hidden";
		window.scrollTo(0,wasy);
		return elem;
	},
	ag_blur : function(e) {
		if (!e) e = window.event;
		var elem = e.srcElement || e.currentTarget;

		if (!this.is_member) return;

		if (this.currelem && elem.id == this.currelem.id) {
			this.oldelem = elem.id;
			this.currelem = null;
			if (elem.value == this.content[this.oldelem]) {
				this.release_lock(elem);
				return;
			}
			var _this = this;
			setTimeout(function() { _this.update_plan(); }, 1500);
		}
	},
	ag_onunload : function(e) {
		if (!e) e = window.event;

		if (this.currelem) {
			var elem = this.currelem;
			this.oldelem = elem.id;
			this.currelem = null;
			if (elem.value == this.content[this.oldelem]) {
				this.release_lock(elem);
				return;
			}
			this.update_plan(); 
		}
	},
	ag_delete_row : function(row, topic) {
		if (!this.is_member) return;

		this.submit_message(topic, 'true', 'delete', row);
	},
	ag_delete_scene : function(topic) {
		if (!this.is_member) return;

		this.del_scene(topic);
	},
	/* Timeline */
	activity_toggle : function(on, id) {
		if (on) {
			Elem('activity' + id).style.display = 'inline';
			Elem('activityOnBtn' + id).style.display = 'none';
			Elem('activityOffBtn' + id).style.display = 'inline';
		} else {
			Elem('activity' + id).style.display = 'none';
			Elem('activityOnBtn' + id).style.display = 'inline';
			Elem('activityOffBtn' + id).style.display = 'none';
		}
	},
	button_hover : function(on, sessionid, elementid) {
		if (on) {
			Elem(elementid + sessionid).style.backgroundImage='url(/images/plan_button_hover.gif)';
		} else {
			Elem(elementid + sessionid).style.backgroundImage='url(/images/plan_button.gif)';
		}
	},
	display_session : function ( args ) {
		var par = args['parent'];
		var session = args['session'];
		var expanded = args['expand'];

		var sess = newElem("div", { 'class' : 'session' });
		var div = null;

		if (!args['noheader']) {
			div = newElem("div", { 'class' : 'sessiontime' });
			div.appendChild( newElem("b", null, 'Session: ') );
			div.appendChild( newElem("br") );
			/* div.appendChild( newElem("br") ); */
			if (session.ended) {
				div.appendChild( document.createTextNode( session.started ) );
				div.appendChild( document.createTextNode( ' to ' + session.ended ) );
			} else {
				div.appendChild( document.createTextNode( 'Started ' + session.started + ', ongoing' ) );
			}
			sess.appendChild(div);

			div = newElem("div", { 'class' : 'sessionpeople' });
			div.appendChild( newElem("b", null, 'Participants') );
			div.appendChild( newElem("br") );
			for (var i=0, ic=session.people.length; i < ic; i++) {
				var p = session.people[i];
				if (!p) continue; // Needed for IE
				if (p.avatar == null) p.avatar = '/images/default/profile_70.gif';
				div.appendChild( newElem('img', { 'src' : p.avatar || '/images/default/profile_70.gif', 'alt' : p.screenname, 'width' : '16', 'height' : '16' }) );
				div.appendChild( document.createTextNode ( ' ' + p.screenname ) );
				div.appendChild( newElem("br") );
			}

			div.appendChild( newElem("b", null, 'Scenes modified') );
			div.appendChild( newElem("br") );
			
			for (var i=0, ic=session.scenes.length; i<ic; i++) {
				div.appendChild( document.createTextNode( session.scenes[i] || 'Old data' ) );
				div.appendChild( newElem("br") );
			}
			div.appendChild( newElem("br") );

			var _this = this;
			var button;

			button = newElem("span", { 'id' : 'showChangesBtn' + session.id, 'class' : 'historyBtns' }, 'Show changes');
			button.onmouseover = function(e) { _this.button_hover(1, session.id, 'showChangesBtn'); };
			button.onmouseout = function(e) { _this.button_hover(0, session.id, 'showChangesBtn'); };
			button.onclick = function(e) { _this.playback({ 'delay' : 0, 'session': session.id }); };
			div.appendChild( button );
			button = newElem("span", { 'id' : 'playBackBtn' + session.id, 'class' : 'historyBtns' }, 'Play back');
			button.onmouseover = function(e) { _this.button_hover(1, session.id, 'playBackBtn'); };
			button.onmouseout = function(e) { _this.button_hover(0, session.id, 'playBackBtn'); };
			button.onclick = function(e) { _this.playback({ 'refresh' : 1, 'reset' : 1, 'session': session.id }); };
			div.appendChild( button );
			var toggleCont = newElem("div", { 'class' : 'toggle' });

			if ( expanded ) {
				toggle = newElem("div", { 'id' : 'activityOnBtn' + session.id, 'class' : 'activityOnBtn' }, 'Show log');
				toggle.style.display = 'none';
				toggle.onclick = function(e) { _this.activity_toggle(1, session.id); };
				toggleCont.appendChild( toggle );
				toggle = newElem("div", { 'id' : 'activityOffBtn' + session.id, 'class' : 'activityOffBtn' }, 'Hide log');
				toggle.onclick = function(e) { _this.activity_toggle(0, session.id); };
				toggleCont.appendChild( toggle );
			} else {
				toggle = newElem("div", { 'id' : 'activityOnBtn' + session.id, 'class' : 'activityOnBtn' }, 'Show log');
				toggle.onclick = function(e) { _this.activity_toggle(1, session.id); };
				toggleCont.appendChild( toggle );
				toggle = newElem("div", { 'id' : 'activityOffBtn' + session.id, 'class' : 'activityOffBtn' }, 'Hide log');
				toggle.style.display = 'none';
				toggle.onclick = function(e) { _this.activity_toggle(0, session.id); };
				toggleCont.appendChild( toggle );
			}

			div.appendChild(toggleCont);
			sess.appendChild(div);
			div = sess;
		} else {
			//debugger;
			div = sess.appendChild( newElem("div", { "class" : "playbackcont" } ) );
			pbc = div.appendChild( newElem("div", { "class" : "playbackcontrol" } ) );
			pbc.appendChild( newElem("b", { }, 'Playback: ' ) );
			pbc.appendChild( newElem("span", { }, 'Change ' ) );
			pbc.appendChild( newElem("span", { 'id' : 'pbc_current_idx' }, '0' ) );
			pbc.appendChild( newElem("span", { }, ' of ' ) );
			pbc.appendChild( newElem("span", { 'id' : 'pbc_current_cnt' }, session.activities.length ) );
			//pbc.appendChild( newElem("span", { }, ' changes' ) );
		}

		this.lasttopic = null;
		var topicclass = "topicitem";
		var uldiv = div.appendChild( newElem("div", { "id" : "activity" + session.id }));
		if (!expanded) uldiv.style.display = 'none';
		var ul = uldiv.appendChild( newElem('ul', { 'class' : 'sessionactivities', 'id' : 's' + session.id + 'list' }) );
		
		par.appendChild(sess);
		this.display_activity( session.id, session.activities );
	}, 
	display_activity: function( session_id, activities ) {
		var _this = this;
		var ul = Elem('s' + session_id + 'list');
		if (!ul) return;

		var idx_offset = 0;
		while (Elem('s' + session_id + 'a' + idx_offset))	
			idx_offset++;

		var index = 0;
		for (var i=0, ic=activities.length; i < ic; i++) {
			act = activities[i];
			if (!act) continue;

			var idx = index;
			if (idx_offset) idx = i + idx_offset;

			var li = newElem('li', { 'id' : 's' + session_id + 'a' + idx, 'class' : this.topicclass, 'idx' : i });
			if (act.content != null && act.content.indexOf('__') == 0) { li.style.display = 'none'; }
			this.updates[session_id].activities[ i + idx_offset ] = act;
			li.onclick = function(e) {
				if (!e) e = window.event;
				var elem = e.srcElement || e.currentTarget;
				var session = elem.id.substring(1);
				var split = session.indexOf('a');
				var idx = session.substring( split + 1 );
				session = session.substring( 0, split );
				_this.playback({ 'session' : session, 'idx' : '' + idx, 'delay' : 0, 'refresh' : 0 }); 
			};
			if (this.topicclass == "topicitem") {
				var lidiv = li.appendChild( newElem("div", { 'style': 'float: right; color: gray' }, act.time_of_day ) );
				lidiv.style.float = 'right';
				lidiv.style.color = 'gray';
				lidiv.style.width = 'auto';
				if (!act.name && act.content.indexOf('_') == 0) {
					if (act.content.indexOf('_hide_column') == 0) {
						var split = act.content.indexOf('|');
						var col = act.content.substring( split + 1 );
						li.appendChild( newElem("b", null, act.screenname + ' disabled the ' + this.col_hash[col].heading + ' column') );
					} else if (act.content.indexOf('_add_column') == 0) { 
						var split = act.content.indexOf('|');
						var col = act.content.substring( split + 1 );
						split = col.indexOf('|');
						col = col.substring(0, split);
						li.appendChild( newElem("b", null, act.screenname + ' enabled the ' + this.col_hash[col].heading + ' column') );
					}  else {
						li.appendChild( newElem("b", null, act.content + '?' ) );
					}
				} else if (act.name == 'delete') {
					li.appendChild( newElem("b", null, act.screenname + ' deleted a row ') );
				} else if (act.name && this.col_hash[act.name]) {
					li.appendChild( newElem("b", null, act.screenname + ' changed ' + this.col_hash[act.name].heading ) );
					li.appendChild( newElem("br") );
					if (this.col_hash[act.name].type == 'image') {
						li.appendChild( newElem("img", { 'src' : act.content, 'width' : '80', 'height' : '45' }) );
					} else {
						li.appendChild( newText(unescapeHTML(act.content)) );
					}
				} else {
					continue; // Skip unrecognized info
					li.appendChild( newElem('b', {}, act.name, ' = ', act.content) );
				}
			} else if (this.topicclass == "topicchat") {
				li.appendChild( newElem("div", { 'style': 'float: right; font-size: 8pt; color: silver' }, act.time_of_day ) );
				li.appendChild( newElem("b", null, act.screenname + ' says:') );
				li.appendChild( newElem("br") );
				li.appendChild( newElem("div", { 'style' : 'padding-left: 15px' }, act.content ) );
				var v = ul.parentNode.parentNode.parentNode;
				v.scrollTop = v.scrollHeight;
				if (act.who != this.user)
					this.activeChat();
			} else {
				li.appendChild( newText( 'Information not available' ) );
			}
			if (!this.lasttopic || this.lasttopic != act.topic) {
				if (act.topic == this.page_topic) {
					ul.appendChild( newElem('li', { 'class' : 'topicchathead' }, 'Story notes' ) );
					this.lasttopic = act.topic;
					this.topicclass = "topicchat";
				} else {
					var title = Elem('topictitle_0_' + act.topic);
					if (title) { title = title.value } else { title = act.title; }
					ul.appendChild( newElem('li', { 'class' : 'topichead' }, title ) );
					this.lasttopic = act.topic;
					this.topicclass = "topicitem";
				}
			}
			ul.appendChild(li);
			index++;
		}
		if (ul.childNodes.length == 0) {
			ul.parentNode.parentNode.style.display = 'none';
		}
		ul.scrollTop = ul.scrollHeight;

	},
	blink : function( id, value, numtimes) {
		var e = Elem(id);
		if (!e) return;
		e.style.display = value;
		if (value == 'none') { value = 'block' } else { value = 'none' }
		numtimes--;

		var _this = this;
		if (numtimes > 0) {
			setTimeout(function(e) { _this.blink( id, value, numtimes ) }, 500);
		} else {
			e.style.display = 'none';
		}
	},
	activeChat : function() {
		if (this.get_mode() == 'playback') return;
		var notify = Elem('activeChat');
		if (!notify) return;
		notify.style.display = 'block';

		var _this = this;
		setTimeout(function(e) { _this.blink( 'activeChat', 'none', 15 ) }, 500);
	},
	display_timeline : function() {	
		if (!this.layout.timeline) return;
		var list = Elem('topic' + this.page_topic);
		if (list) return;

		var social = Elem('social');
		if (!social) return;

		social.appendChild( newElem("div", { 'id' : 'activeChat', 'style' : 'display: none' }, "New chat messages") ).style.display = 'none';
		social.appendChild( newElem("div", { 'class' : 'socialhead' }, 'Story timeline' ) );
		list = social.appendChild( newElem("div", { 'class' : 'sociallist', 'id' : 'topic' + this.page_topic } ));
		var socialin = social.appendChild( newElem("div", { 'class' : 'socialin' }) );
		var form = socialin.appendChild( newElem("form", { 'action' : '#' }) );
		var _this = this;
		form.onsubmit = function(e) {
			_this.send('socialnote', _this.page_topic, 'storynotes'); 
			return false;
		};
		form.appendChild( newElem('div', { }, 'Insert story notes:') );
		var ta = form.appendChild( newElem('textarea', { 'id' : 'socialnote' }) );
		ta.onkeyup = function(e) {
			if (!e) e = window.event;
			var elem = e.srcElement || e.currentTarget;
			if (e.keyCode == 13 && elem.value != '') { // Return
				_this.send('socialnote', _this.page_topic, 'storynotes'); 
				elem.value = '';
			}
		};

		var sessions = this.updates;
		var expanded = 0;
		this.set_mode('playback');
		for (var i = 0, ic = sessions.length; i < ic; i++) {
			var session = sessions[i];
			if (i == ic - 1) expanded = 1;
			this.display_session({ 'parent' : list, 'session' : session, 'expand' : expanded });
		}
		this.set_mode('static');
		list.scrollTop = list.scrollHeight;
	},
	show_history: function() {
		if (Elem('social')) {
			emptyElem( Elem('paneholder') );
			emptyElem( Elem('historyBtn') );
			Elem('historyBtn').appendChild( newText("Show history") );
			Elem('container').style.marginRight = '0px';
			return;
		}
		var ph = Elem('paneholder');
		ph.appendChild( newElem( 'div', { 'id' : 'playback', 'class' : 'playback' }) );
		ph.appendChild( newElem( 'div', { 'id' : 'social', 'class' : 'social' }) );
		emptyElem( Elem('historyBtn') );
		Elem('historyBtn').appendChild( newText("Hide history") );
		Elem('container').style.paddingRight = '250px';
		this.display_timeline();
	}
};





    /* Flash */
	function miniNewImage(id, url) { _miniNewImage(id, url); }
	/* Allow this method to be overriden, then call this private one: */
    function _miniNewImage(id, url) {
		/* Updated from Flash */
		warn("MININEWIMAGE " + id + " - " + url);
		id = id.substring(3);
		var ta = Elem(id);
		if (!ta) return;
		var cell = ta.parentNode;

		var vis_url = url;
		warn(vis_url);
		warn(url);
		if (vis_url.indexOf("object:") == 0) {
			vis_url = '/images/Processing.gif';
			setTimeout("checkImage(\"" + id + "\")", 5000);
		}

		var img = newElem('img', { 'src' : vis_url, 'id' : 'imgel_' + id });
		//img.style.float = 'left';
		img.style.border = '1px outset black';
		img.style.margin = '0px 5px 0px 0px';
		img.style.width = '100%';

		// Get the objrep ID from the URL, e.g. http://create.five.ymogen.net/files/2882/22894.jpeg

		if (vis_url == url) {
			var orep = url;
			orep = orep.substring(orep.indexOf('files') + 6);
			orep = orep.substring(orep.indexOf('/') + 1);
			orep = orep.substring(0, orep.indexOf('.'));

			img.onclick = function(e) { 
				if (window.parent) {
					window.parent.location.href = '/lib/edit/' + orep;
				} else {
					document.location.href = '/lib/edit/' + orep; 
				}
			};
		}
		var imgco = Elem('imagecontainer_' + id);
		if (imgco) {
			for (var i=imgco.childNodes.length - 1; i >= 0; i--) {
				if (imgco.childNodes[i].tagName == 'IMG') {
					imgco.removeChild( imgco.childNodes[i] );
				} else if (imgco.childNodes[i].tagName == 'OBJECT') {
					var butt = imgco.childNodes[i];
					butt.changeLabel("Change media");
					butt.style.left = null;
					butt.style.right = '10px';
					butt.style.bottom = '10px';
				}
			}
			imgco.appendChild( img );
		}

		var height = cell.parentNode.clientHeight - 70 - imgco.scrollHeight - 5 - 30;
		if (height < 0) height = 10;
		ta.style.height = height + 'px';

		if (Elem('IMG_' + id)) {
			var str = Elem('IMG_' + id).value;
			str = url;
			Elem('IMG_' + id).value = str;
			var arr = id.split('_');
			com.submit_message(arr[2], str, 'IMG_' + arr[0], arr[1]);
		}
    }

function getProperty(el, cssproperty, csspropertyNS){
	if (el.currentStyle) {
		return el.currentStyle[cssproperty];
	} else if (window.getComputedStyle){
		var elstyle=window.getComputedStyle(el, "");
		if (elstyle)
			return elstyle.getPropertyValue(csspropertyNS);
		return 0;
	}
}

function ensureSizesForPlan() {
    var row = document.getElementById('plan');
	if (!row) return;
	if (!row.clientHeight) { // Not ready yet
		window.setTimeout("ensureSizesForPlan()", 100);
		return;
	}

	var target = row.getElementsByTagName("TEXTAREA");
	if (target.length) {
		for (var t=0, tc=target.length; t < tc; t++) {
			com.ag_keyup({ keycode: 32, currentTarget: target[t] });
		}
	}
}

window.present = function() {
	var mells = getElementsByClass("mell");
	for (var i=0, ic=mells.length; i < ic; i++) {
		var ta = mells[i].getElementsByTagName("TEXTAREA");
		if (ta.length) {
			ta = ta[0];
			var imgco = Elem('imagecontainer_' + ta.id);
			var cell = ta.parentNode;
						
			var arr = [ 220, 200 ];
			if (com.content['WH_' + ta.id]) 
				arr = com.content['WH_' + ta.id].split('/')

			var height = arr[1] - 70 - 30;
			if (imgco) height = height - imgco.scrollHeight - 5;
			if (height < 0) height = 10;
			ta.style.height = height + 'px';
		}
	}
	ensureSizesForPlan();

};

window.onunload = function(e) {
	if (window.com && window.com.ag_onunload) {
		com.ag_onunload(e);
	}
};

function checkImage(id) {
	var img = com.content['IMG_' + id];
	http_request('/connect/image/' + com.storyboard + '/' + id, 'GET', '', function(obj) {
		if (obj.image) {
			var elem = Elem('imgel_' + id);
			if (elem) { elem.src = obj.image; }
		} else {
			setTimeout("checkImage(\"" + id + "\")", 5000);
		}
	});
}

document.documentElement.onmousemove = document.onkeydown = function() {
	var ts = new Date().getTime();
	if (!com) return;
	com.lastactivity = ts;
	if (com.isactive == 0) {
		com.isactive = 1;
		com.update();
	}
}
