// constants & globals
var rpanelWidth = 250;
var minBubblWidth = 250;
var helpTopics = new Object();
var lastHelpTopic = '';
var helpVisible = true;
var beditor;
var savedSheets;
var selectedSheetId = null;
var selectedRenameSheetId = null;
var selectedSheetName = '';
var selectedRenameSheetName = '';
var sheetSelectionDisabled = false;
var activeDialog = null;
var activeDialogEnter = null;
var activeDialogCancel = null;
var isIE6 = (navigator.appName.indexOf("Microsoft") != -1 /*&& navigator.appVersion.indexOf('MSIE 6') != -1*/);
var isOpera = (navigator.appName.indexOf("Opera") != -1);
var monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var badfield = null;
var saveSessionAfterNewUser = false;
var activeDialog = null;
var sessionKeepAliveMin = 10;
var shareperms = null;
var getsharesinprogress = false;
var friends = new Array();
var friendIdToDelete = null;
var loadedSessionId = null;
var loadedSessionMode = 0;
var sheetmode = 0;
var errorTimer = 0;
var noTabSwitches = false;
var bIgnoreUnload = false;
var flashEditorVersion = '0.5.9c';
var bFullScreen = false;
// initialize page
function init(){
	// editor object
	beditor = isIE6 ? $('editor') : document['editor'];

	// events
	Event.observe(window, 'resize', evResizeWindow, false);
	Event.observe($('sessionName'), 'keydown', evCheckEnterAndSave, false);
	Event.observe(document, 'keydown', evKeyDown, false);
	//
	
	setTimeout(evResizeWindow, 100);

	// page set up
	initControls();	
	
	// init display
	//ajGetSavedSheets();
	showHelp("getting started");

	preloadImages(["gettingstarted.gif"], 'images/help/', function(){preloadImages(preloadEdit, 'images/home/');});
	
	if(!document.initHelpVisible){
		setTimeout(function(){
			helpVisible = false;
			dsUpdateHelp();
			setTimeout(evResizeWindow, 100);
		},500);
	}
	SetSheetMode('mysheets');
	ajUnlockSheet();
	ajGetHelp();
	ajKeepAlive();
	if(document.ANNOUNCEMENT && !document.noAnnouncements){
		dsShowAnnouncement();
	}
	beditor.focus();
}

function initControls(){
	setLinkUnload();
	utMakeButton($('btnSave'), function(){ saveSheet(); }, 'save');
	utMakeButton($('btnLoad'), function(){ loadSheet(); }, 'load', true);
	utMakeButton($('btnLoadYes'), function(){ dsHideConfirmLoadSheet(); if(loadedSessionId) ajUnlockSheet(loadedSessionId);beditor.doAction('savethenload'); }, 'load_yes');
	utMakeButton($('btnLoadNo'), function(){ dsHideConfirmLoadSheet(); if(loadedSessionId) ajUnlockSheet(loadedSessionId); loadSheet(true); }, 'load_no');
	utMakeButton($('btnLoadCancel'), function(){ dsHideConfirmLoadSheet();}, 'load_cancel');
	utMakeButton($('btnNew'), function(){ newSheet(); }, 'new', true);
	utMakeButton($('btnNewYes'), function(){ dsHideConfirmNewSheet(); beditor.doAction('savethennew'); if(loadedSessionId) ajUnlockSheet(loadedSessionId); SetSheetMode('mysheets'); }, 'new_yes');
	utMakeButton($('btnNewNo'), function(){ dsHideConfirmNewSheet(); beditor.doAction('new'); if(loadedSessionId) ajUnlockSheet(loadedSessionId); SetSheetMode('mysheets');}, 'new_no');
	utMakeButton($('btnNewCancel'), function(){ dsHideConfirmNewSheet();}, 'new_cancel');
	utMakeButton($('btnDelete'), function(){ deleteSheet(); }, 'delete', true);
	utMakeButton($('btnDeleteYes'), function(){ dsHideConfirmDeleteSheet(); ajDeleteSession(); }, 'delete_yes');
	utMakeButton($('btnDeleteNo'), function(){ dsHideConfirmDeleteSheet(); }, 'delete_no');
	utMakeButton($('btnRename'), function(){ renameSheet(); }, 'rename', true);
	utMakeButton($('btnSubmit'), function(){ createAccountSubmit(); }, 'createaccount');
	utMakeButton($('btnSubmitCancel'), function(){ dsHideNewUser(); }, 'createaccountcancel');
	utMakeButton($('btnsiSubmit'), function(){ SignIn(); }, 'signin');
	utMakeButton($('btnsiSubmitCancel'), function(){ dsHideSignIn(); }, 'signincancel');
	utMakeButton($('btnfpSubmit'), function(){ ResetPassword(); }, 'resetpass');
	utMakeButton($('btnfpSubmitCancel'), function(){ dsHideForgotPass(); }, 'resetpasscancel');
	utMakeButton($('btneaSubmit'), function(){ editAccountSubmit(); }, 'editaccount');
	utMakeButton($('btneaSubmitCancel'), function(){ dsHideEditAccount(); }, 'editaccountcancel');
	utMakeButton($('btncSubmit'), function(){ ContactUsSend(); }, 'contactussend');
	utMakeButton($('btncCancel'), function(){ dsHideContactUs(); }, 'contactuscancel');
	utMakeButton($('btniSubmit'), function(){ InviteFriendSend(); }, 'invitefriendsend');
	utMakeButton($('btniCancel'), function(){ dsHideInviteFriend(); }, 'invitefriendcancel');
	if($('btnaDismiss')) utMakeButton($('btnaDismiss'), function(){ dsHideAnnouncement(); }, null);
	utMakeButton($('btnLinkSubmit'), function(){ LinkSheetSubmit(); }, null);
	utMakeButton($('btnLinkCancel'), function(){ dsHideLink(); }, null);
	utMakeButton($('btnEmbedCancel'), function(){ dsHideEmbed(); }, null);	
	utMakeButton($('btnShare'), function(){ dsShowSharing(); }, 'sharing', true);
	utMakeButton($('btnShareAllEdit'), function(){ shareSelect('allEdit'); }, null, true);
	utMakeButton($('btnShareAllRead'), function(){ shareSelect('allRead'); }, null, true);
	utMakeButton($('btnShareNone'), function(){ shareSelect('none'); }, null, true);
	utMakeButton($('btnShareSubmit'), function(){ shareSheetSubmit(); }, 'sharesheet');
	utMakeButton($('btnShareCancel'), function(){ dsHideSharing(); }, 'sharesheetcancel');
	utMakeButton($('btnFindFriend'), function(){ findFriend(); }, 'findfriend');
	utMakeButton($('btnDeleteFriendNo'), function(){ dsHideDeleteFriend(); }, 'deletefriendcancel');
	utMakeButton($('btnDeleteFriendYes'), function(){ ajDeleteFriend(); }, 'deletefriend');
	Event.observe($('ffQuery'),'focus',function(){ activeDialogEnter=findFriend; }, false);// enter submits
	Event.observe($('ffQuery'),'blur',function(){ activeDialogEnter=null; }, false);
	utMakeButton($('btnExportOk'), function(){ saveSheet(); }, 'exportok', false);
	utMakeButton($('btnExportCancel'), function(){ dsHideExport(); }, 'exportcancel', false);
	utMakeButton($('btnImportCancel'), function(){ dsHideImport(); }, 'eimportcancel', false);
	Event.observe($('exportAsXML'), 'click', function(){ dsShowExportOptions('XML');}, false);
	Event.observe($('exportAsHTML'), 'click', function(){ dsShowExportOptions('HTML');}, false);
	Event.observe($('exportAsImage'), 'click', function(){ dsShowExportOptions('Image');}, false);
	Event.observe($('helpstep'),'click',function(ev){ 
		Event.stop(ev);
		HelpStep(-1);
		return true;
	},true);
	Event.observe($('helpHead'),'click',function(){ 
		helpVisible = !helpVisible;
		var dt = new Date();
		dt.setMonth(dt.getMonth()+1);
		document.cookie = 'helpexpanded='+helpVisible+';expires='+dt.toGMTString();
		dsUpdateHelp();
		setTimeout(evResizeWindow, 100);
	},false);
	// donate lnk
	Event.observe($('donateLink'),'mouseover',function(ev){
		Element.setOpacity($('donatePopup'), 0.0);
		new Effect.Opacity($('donatePopup'), {duration: 0.25, from: 0.0, to:1.0});
		$('donatePopup').style.display = 'block';
		return true;
	},true);
	Event.observe($('donateLink'),'mouseout',function(ev){
		$('donatePopup').style.display = 'none';
		return true;
	},true);
	// active field highlighting
	var inputs = document.body.getElementsByTagName('input');
	for(var i in inputs) {
		if(inputs[i].type == 'text' || inputs[i].type == 'password'){
			Event.observe(inputs[i],'focus',evFocusTextField, false);
			Event.observe(inputs[i],'blur',evBlurTextField, false);
		}
	}
	Event.observe(window,'beforeunload',onUnloaded,true);
	// browser specific
	if(!isIE6){
		if(!isOpera) 
			$('sessionName').style.paddingTop = '4px';
	} else {
		$('sessionList').style.backgroundAttachment = 'fixed';
	}
	enableMainButtons();
}
function setLinkUnload(){
	var links = document.body.getElementsByTagName('a');
	for(var i in links) {
		if(links[i].id != 'linkSignout') Event.observe(links[i],'mouseup',function(ev){bIgnoreUnload=true;}, false);
	}
}
function onUnloaded(evt) {
	window.onunload = null;
	if(!evt) evt = window.event;
	var bShowWarning = beditor.doAction('getChangedStatus');
	if(isIE6 && bIgnoreUnload){
		bIgnoreUnload = false;
		return;
	}
	if(bShowWarning) {
		/*var s ='';
		for(i in evt){
			s+= i+"="+evt[i]+";\n";
		}*/
		evt.returnValue = "You have made changes to "+$('sessionName').value+".\nIf you leave this page now, the changes will NOT SAVED.";
		
		return evt.returnValue;
	}
}
// ================================================================		General functions

function ImportSheet(){
	if($('sessionName').readOnly) return dsHideImport();
	
}

var selectSheetClickTimer = 0;
function selectSheetId(id){
	if(sheetSelectionDisabled) return;
	if(id == selectedSheetId && $('btnRename').className != 'disabled' && !$('sheetRename')) {
		if(window.getSelection){
			window.getSelection().removeAllRanges();
		}
		if(!selectSheetClickTimer) {
			selectSheetClickTimer = setTimeout(function(){	selectSheetClickTimer = 0; renameSheet();},500);
					
		} else {
			loadSheet();
			if(selectSheetClickTimer) {
				clearTimeout(selectSheetClickTimer);
				selectSheetClickTimer = 0;
			}
		}
		return;
	}
	if(selectSheetClickTimer) clearTimeout(selectSheetClickTimer);
	selectSheetClickTimer = setTimeout(function(){	selectSheetClickTimer = 0;},500);
	
	var oldId = selectedSheetId;
	selectedSheetId = id;
	if($('sess'+oldId))
		dsSessionListHighlightId(oldId, 0);
	
	dsSessionListHighlightId(id, 2);
	selectedSheetName = sheetObjectById(id).name;
	dsRevealSelectedSheet();
	enableMainButtons();
}
function EnableAnnouncements(v){
	var dt = new Date();
	dt.setMonth(dt.getMonth()+1);
	document.cookie = 'noannouncements='+(0 + (!v))+';expires='+dt.toGMTString();
	document.noAnnouncements = !v;
}
function DblClickLoad(id){
	loadSheet();
	if(selectSheetClickTimer) {
		clearTimeout(selectSheetClickTimer);
		selectSheetClickTimer = 0;
	}
	if(document.selection) document.selection.empty();
}
function PreviewEmailLink(){
	var wnd = window.open($('makeemaillink').value, "linkpreview");

}
function AdClick(sponsorid){
	var w = window.open("sys/sponsor.php?sid="+sponsorid);
	// thanks!
}
/*
function CopyText(ta){
	ta = $(ta);
	if(ta.createTextRange){
		var textRange = ta.createTextRange();
		textRange.execCommand("RemoveFormat");
		textRange.execCommand("Copy");
	}
	new Effect.Pulsate(ta, {duration: 1, pulses: 2, from: 0.3, queue:'end'});
}
*/
function ForgotPassword(){
	dsShowForgotPass();
}
function ResetPassword(){
	ajResetPassword();
}
function inviteFriend(){
	dsShowInviteFriend();
	$('FriendEmail').focus();
}
function InviteFriendSend(){
	if($('FriendEmail').value == '') return $('FriendEmail').focus();
	ajInviteFriend();
}

function ContactUsSend(){
	if(document.USERID == "0" && $('ReplyEmail').value == '') return $('ReplyEmail').focus();
	if($('EmailMessage').value == '') return dsHideContactUs();
	ajContactUs();
}
function shareSheetSubmit(){
	ajShareSheetSave();
}
function LinkSheetSubmit(){
	if($('lsEmail').value != ''){
		if(! (new RegExp("^(.+)@(.+)\\.(\\S+)$","g")).test($('lsEmail').value)) {
			$('lsEmail').focus();
			$('lsEmail').select();
			return;			
		}
	}
	ajLinkSheetSend();
}
// val: 0 = read, 1=write, -1=delete (none)
function setShareFriend(fid, val, aicon){
	if(getsharesinprogress) return;
	if(!shareperms) shareperms = new Array();
	var i = shareperms.length;
	while(--i >= 0) {
		if(shareperms[i].fid == fid) break;
	}
	if(i == -1 && val != -1) shareperms.push({fid:fid,rw:val});
	else if(i >= 0 && val == -1) shareperms.splice(i,1);
	else if(i >= 0 && val != -1) {
		if(aicon){
			if(shareperms[i].rw == val) return setShareFriend(fid, -1);
		}
		shareperms[i].rw = val;
	}
	dsUpdateSharePermissions();
}
function enableShareCheckboxes(bHide){
	for(var i = 0; i<friends.length; i++){
		if(bHide){
			$('shareRead'+friends[i].fid).style.display = 'none';
			$('shareEdit'+friends[i].fid).style.display = 'none';
		} else {
			$('shareRead'+friends[i].fid).style.display = 'block';
			$('shareEdit'+friends[i].fid).style.display = 'block';
			$('shareRead'+friends[i].fid).className = 'shareRead0';
			$('shareEdit'+friends[i].fid).className = 'shareEdit0';
		}
	}
}
function addFoundFriend(id){
	dsShowFriendFound(null);
	if(id == Number(document.USERID)) return;
	for(var i = 0; i<friends.length; i++){
		if(friends[i].fid == id){
			setShareFriend(id, true);
			return;
		}
	}
	ajAddFriend(id);
}
function ContactUs(){
	$('EmailMessage').value = '';
	dsShowContactUs();
	if($('ReplyEmail').value == '' && document.USERID != '0') {
		$('ReplyEmail').value = document.EMAIL;
		$('EmailMessage').focus();
	} else if(document.USERID == '0') $('ReplyEmail').focus();
	else $('EmailMessage').focus();
}
function findFriend(){
	if($('ffQuery').value != '' && !$('ffQuery').readOnly){
		dsShowFriendFound('Searching...');
		$('friendsFound').style.height = '16px';
		$('ffQuery').readOnly = true;
		ajFindFriend();
	}
}
function deleteFriend(id){
	for(var i = 0; i < friends.length; i++){
		if(friends[i].fid == id){
			dsShowDeleteFriend(id,
				((friends[i].fname)?(friends[i].fname+" <i>("+friends[i].funame+")</i>"):("<i>"+friends[i].funame+"</i>")));
			break;
		}
	}	
}

function shareSelect(what){
	var i;
	var f = (what=='allRead') ? (0) : (1);
	shareperms = null;
	if(what != 'none')
		for(i = 0; i < friends.length; i++)
			setShareFriend(friends[i].fid, f);
	
	dsUpdateSharePermissions();
}
function editAccount(){
	dsShowEditAccount();
}
function enableMainButtons(){
	var nc = '', lc = '', rc = '', dc = '', sc = '';
	if(!savedSheets || !savedSheets.length || !selectedSheetId)
		lc = rc = dc = sc = 'disabled';
	if(document.USERID == '0')
		rc = dc = sc = 'disabled';
	if(sheetmode == 1) {
		nc = 'disabled';
		if(savedSheets && savedSheets.length && selectedSheetId){
			sc = dc = 'disabled';
		}
	}
	if(selectedSheetId){
		var so = sheetObjectById(selectedSheetId);
		if(so.lockedby != 0 && so.lockedby != document.USERID){
			lc = rc = dc = 'disabled';
		}
		if(sheetmode == 1 && so.rw == 0) {
			rc = 'disabled';
			lc = '';
		} 
	}
	$('btnNew').className = nc;
	$('btnLoad').className = lc;
	$('btnRename').className = rc;
	$('btnDelete').className = dc;
	$('btnShare').className = sc;
}
function signinFromNewUser(){
	dsHideNewUser();	
	dsShowSignIn();
}
function signinFromHeader(){
	dsShowSignIn();
	saveSessionAfterNewUser = false;
}
function SignIn(){
	if(badfield) return badfield.fld.focus();
	dsClearBadFieldsSignIn();
	if($('siUsername').value.length == 0) return dsHighlightBadField('Username','Enter your username','si');
	if($('siPassword').value.length == 0) return dsHighlightBadField('Password','Enter your password','si');
	ajSignIn();
}
function renameSheet(){
	if(!selectedSheetId || document.USERID == '0' || $('btnRename').className == 'disabled') return;
	selectedRenameSheetId = selectedSheetId;
	selectedRenameSheetName = selectedSheetName;
	dsShowRenameInput();
	$('sheetRename').focus();
	$('sheetRename').select();
}
function renameSheetKeyDown(ev){
	if(ev.keyCode){
		if(ev.keyCode == 13) {
			renameSheetApply();
		} else if(ev.keyCode == 27) { 
		// cancel
			Element.remove($('sheetRename'));
			$('lbl'+selectedRenameSheetId).show();
		}
	}
}
function renameSheetApply(){
// make sure the new name isn't already in the list
	var i;
	if(!$('sheetRename')) return;
	var newname = $('sheetRename').value;
	$('lbl'+selectedRenameSheetId).innerHTML = '<span>Renaming...</span>';
	Element.remove($('sheetRename'));
	$('lbl'+selectedRenameSheetId).show();
	ajRenameSession(selectedRenameSheetId, newname);
}
function deleteSheet(){
	if(!selectedSheetId || document.USERID == '0' || $('btnDelete').className == 'disabled') return;
	dsShowConfirmDeleteSheet();
}
function newSheet(){
	if($('btnNew').className == 'disabled') return;
	if(document.USERID==='0' || !beditor.doAction('getChangedStatus')){
		beditor.doAction('new');
		if(loadedSessionId) ajUnlockSheet(loadedSessionId);
		loadedSessionId = 0;
		SetSheetMode('mysheets',false);
		loadedSessionMode = 0;
		dsSessionModeChanged();
		newSheetName();
	} else { // confirm
		confirmNewSheet();
	}
}
function loadSheet(bBypassCheck){
	if(!selectedSheetId || (!beditor.doAction('getChangedStatus') && loadedSessionId == selectedSheetId)) return;
	// check if locked
	var so = sheetObjectById(selectedSheetId);
	/*if(so.lockedby != '0' && so.lockedby != document.USERID && so.rw == '1'){
		// locked
		return;
	}*/
	if(!bBypassCheck && document.USERID != '0' && beditor.doAction('getChangedStatus'))
		return confirmLoadSheet();
	// replace name in sessionName
	$('sessionName').value = sheetObjectById(selectedSheetId).name;
	if(loadedSessionId) ajUnlockSheet(loadedSessionId);
	else ajUnlockSheet();
	dsShowLoading();
	ajLoadSession();
}
function containsUnicode(s){
	var len = s.length;
	for(var i=0; i<len; i++){
		if(s.charCodeAt(i) >= 128) return true;
	}
	return false;
}
function saveSheet(){
	if(containsUnicode($('sessionName').value)){
		alert("The sheet name contains non-Latin characters.\nPlease use only ASCII characters for sheet name.");
		$('sessionName').focus();
		return;
	}
	if($('exportSheet').className != 'hidden') return beditor.doAction('save',true);
	if($('btnSaveCont').className == 'disabled') return;
	
	if(document.USERID == '0'){
		if(bFullScreen) {
			beditor.doAction('togglefullscreen',1);
			setTimeout(function(){dsShowNewUser(saveSessionAfterNewUser = true);},500);
			return;
		}
		return dsShowNewUser(saveSessionAfterNewUser = true);
	}

	saveSessionAfterNewUser = false;	
	beditor.doAction('save');
}
function newSheetName(){
	$('sessionName').value = 'New Sheet';
}
function editAccountSubmit(){
	if(badfield) return badfield.fld.focus();
	dsClearBadFieldsEditAccount();
// validate fields
	var cv = $('eaUsername').value;
	if(cv.length <= 2) return dsHighlightBadField('Username','Username is too short (min. 3 char)','ea');

	cv = $('eaPassword').value;
	if(cv.length > 0 && cv.length < 2) return dsHighlightBadField('Password','Password is too short (min. 3 char)','ea');

	cv = $('eaPassword2').value;
	if($('eaPassword').value.length > 0 && cv != $('eaPassword').value) { dsHighlightBadField('Password2','Password doesn\'t match','ea'); $('eaPassword2').value = ''; return;}

	cv = $('eaEmail').value;
	if(! (new RegExp("^(.+)@(.+)\\.(\\S+)$","g")).test(cv)) return dsHighlightBadField('Email','Bad email','ea');

// send info
	EnableAnnouncements($('eaAnnouncement').checked);
	ajEditAccount();
}
function createAccountSubmit(){
	if(badfield) return badfield.fld.focus();
	dsClearBadFieldsNewUser();
// validate fields
	var cv = $('nuUsername').value;
	if(cv.length <= 2) return dsHighlightBadField('Username','Username is too short (min. 3 char)','nu');

	cv = $('nuPassword').value;
	if(cv.length <= 2) return dsHighlightBadField('Password','Password is too short (min. 3 char)','nu');

	cv = $('nuPassword2').value;
	if(cv != $('nuPassword').value) { dsHighlightBadField('Password2','Password doesn\'t match','nu'); $('nuPassword2').value = ''; return;}

	cv = $('nuEmail').value;
	if(! (new RegExp("^(.+)@(.+)\\.(\\S+)$","g")).test(cv)) return dsHighlightBadField('Email','Bad email','nu');

// send info
	ajCreateAccount();
}
function LoggedIn(){
	document.body.className = 'loggedin';
	beditor.doAction('loggedin', document.USERID, document.NAME, false);
	$('headercontent').innerHTML = 'Loading...';
	selectedSheetId = null;
	selectedSheetName = '';
	selectedRenameSheetId = null;
	selectedRenameSheetName = '';
	//$('sharedSheets').className = '';
	ajReloadHeader();
}
function SetSheetMode(mode, bNoReload){
	if(noTabSwitches) return;
	if(activeDialogCancel) activeDialogCancel();
	selectedSheetId = selectedSheetName = null;
	if(mode == 'mysheets'){
		$('list').className = '';
		$('friendsTab').className = 'hidden';
		if($('mySheets').className != 'hidden') $('mySheets').className = 'selected';
		if(document.USERID == '0') {
			$('friendsList').className = 'hidden';
			$('sharedSheets').className = 'hidden';
		} else {
			$('friendsList').className = '';
			$('sharedSheets').className = '';
		}
		$('mySheets').blur();
		sheetmode = 0;
	} else if(mode == 'sharedsheets' && document.USERID != '0'){
		$('list').className = '';
		$('friendsTab').className = 'hidden';
		$('mySheets').className = '';
		$('friendsList').className = '';
		$('sharedSheets').className = 'selected';
		$('sharedSheets').blur();
		sheetmode = 1;
	} else if(mode == 'friends'){
		sheetmode = 3;
		$('list').className = 'hidden';
		$('friendsTab').className = '';
		$('mySheets').className = '';
		$('friendsList').className = 'selected';
		$('sharedSheets').className = '';
		$('friendsFound').className='hidden';
		ajGetFriends();
		return;
	} else return SetSheetMode('mysheets');
	$('sessionList').innerHTML = '<h4>Loading...</h4>';
	ajGetSavedSheets();
	enableMainButtons();
}

// ================================================================		Help
var topicstep = new Array();
function showHelp(topic, nopush){
	if(topic === null) return dsShowHelp(null);
	if(!topic && lastHelpTopic) return showHelp(lastHelpTopic);
	lastHelpTopic = topic;
	dsShowHelp(topic);
	if(!nopush){
		if(topicstep.length >= 20){
			topicstep.splice(0, 1);
		}
		topicstep.push(topic);
	}
}
function HelpStep(dir){
	if(topicstep.length){
		showHelp(topicstep.pop(), true);
	}
	
	return true;
}
// ================================================================		Confirmation Dialogs

function confirmNewSheet(){
	activeDialogCancel = dsHideConfirmNewSheet;
	activeDialogEnter = function(){ dsHideConfirmNewSheet(); beditor.doAction('savethennew'); SetSheetMode('mysheets');}
	dsShowConfirmNewSheet();
}
function confirmLoadSheet(){
	activeDialogCancel = dsHideConfirmLoadSheet;
	activeDialogEnter = function(){ dsHideConfirmLoadSheet(); beditor.doAction('savethenload'); }
	dsShowConfirmLoadSheet();
}
// ================================================================		Flash hook
function flIsSaved(){
	return (loadedSessionId > 0);
}
function flCanLink(){
	return (loadedSessionMode == 0);
}
function flImportUploadComplete(fname){
	ajImport(fname);
}

function flRenameSession(newName){
	if(!$('sessionName').readOnly) 
		$('sessionName').value = newName;
}
function flFullScreen(bFS){
	bFullScreen = bFS;
	setTimeout(evResizeWindow, 100);
	return {sessionname:$('sessionName').value, nochange: $('sessionName').readOnly};
}
function flSetSoundSetting(bSound){
	var dt = new Date();
	dt.setMonth(dt.getMonth()+1);
	document.cookie = 'soundenabled='+((bSound)?(1):(0))+';expires='+dt.toGMTString();
	document.bSoundEnabled = bSound;
}
function flGetSoundSetting(){
	return document.bSoundEnabled;
}
function flSetDetailSetting(bFx){
	var dt = new Date();
	dt.setMonth(dt.getMonth()+1);
	document.cookie = 'fxenabled='+((bFx)?(1):(0))+';expires='+dt.toGMTString();
	document.bDetailEnabled = bFx;
}
function flGetDetailSetting(){
	return document.bDetailEnabled;
}
function flSetPaperSetting(bPaper){
	var dt = new Date();
	dt.setMonth(dt.getMonth()+1);
	document.cookie = 'pprenabled='+((bPaper)?(1):(0))+';expires='+dt.toGMTString();
	document.bPaperEnabled = bPaper;
}
function flGetPaperSetting(){
	return document.bPaperEnabled;
}
function flLoadSessionSuccess(){
	dsHideLoading();
}
function flSaveSession(topBaloonText, sessionData, tAction){
	if($('exportSheet').className != 'hidden'){
		return ajExport(sessionData);
	}
	document.sessionData = sessionData;
	document.topBaloonText = topBaloonText;
	dsHideConfirmNewSheet();
	dsShowSaving();
	ajSaveSession(tAction);
}
// ================================================================		Display functions
function dsShowExportOptions(t){
	$('exportOptionsXML').className = $('exportOptionsHTML').className = $('exportOptionsImage').className = 'hidden';
	$('exportOptions'+t).className = '';
	var ft;
	if(t == 'XML'){
		ft = 'XML Format';
	} else if(t == 'HTML'){
		ft = 'HTML Format';
	} else {
		ft = 'Image Format';
	}
	$('exporttitle').innerHTML = ft;
}

function dsShowImportProgress(){
	$('importbuttons').className = 'hidden';
	$('importprogress').className = '';
}
function dsHideImportProgress(){
	$('importbuttons').className = '';
	$('importprogress').className = 'hidden';
}
function dsShowExport(){
	if(bFullScreen) {
		beditor.doAction('togglefullscreen',1);
		setTimeout(dsShowExport,500);
		return;
	}
	dsHideActiveDialog();
	dsHideImportProgress();
	activeDialog = $('exportSheet');
	$('exportSheet').className = '';
	$('list').className = 'hidden';
	activeDialogEnter = null;
	activeDialogCancel = dsHideExport;
}
function dsHideExport(){
	activeDialogCancel = null;	
	$('exportSheet').className = 'hidden';
	$('list').className = '';
}
function dsShowImport(){
	if(bFullScreen) {
		beditor.doAction('togglefullscreen',1);
		setTimeout(dsShowImport,500);
		return;
	}
	dsHideActiveDialog();
	if(document.USERID == '0') return;
	activeDialog = $('importSheet');
	$('importSheet').className = '';
	$('list').className = 'hidden';
	activeDialogEnter = null;
	activeDialogCancel = dsHideImport;
}
function dsHideImport(){
	activeDialogCancel = null;	
	$('importSheet').className = 'hidden';
	$('list').className = '';
}
function dsShowError(text){
	if(errorTimer){
		clearTimeout(errorTimer);
	}
	$('errormsg').className = '';
	$('errortext').innerHTML = text;
	errorTimer = setTimeout(function(){
		errorTimer = 0;
		new Effect.Opacity($('errormsg'), {duration: 0.5, from: 1.0, to:0.0,
				queue: 'end',
				afterFinish:function(){$('errormsg').style.filter='';$('errormsg').style.opacity='';$('errormsg').className='hidden';} });
	}, 2500);
}
function dsSessionModeChanged(){
	if(loadedSessionMode == 0){
		$('sessionName').readOnly = false;
	} else {
		$('sessionName').readOnly = true;
	}
}
function dsUpdateSharePermissions(){
	enableShareCheckboxes();
	if(shareperms != null) {
		for(var i = 0; i < shareperms.length; i++){
			if(shareperms[i].rw == 1){ // edit
				$('shareRead'+shareperms[i].fid).className = 'shareRead0';
				$('shareEdit'+shareperms[i].fid).className = 'shareEdit1';
			} else { // readonly
				$('shareRead'+shareperms[i].fid).className = 'shareRead1';
				$('shareEdit'+shareperms[i].fid).className = 'shareEdit0';
			}
		}
	}
}
function dsShowFriendFound(what, isList){
	if(what && !isList){
		$('friendsFound').innerHTML = what;
		$('friendsFound').className = '';
	} else if(!isList){
		new Effect.BlindUp($('friendsFound'),{ duration: 0.5, afterFinish:function(){$('friendsFound').show();$('friendsFound').className='hidden';} });
		$('ffQuery').value = '';
	} else {
		var html = '';
		for(var i=0;i<what.length;i++){
			html += '<a onclick="javascript:addFoundFriend('+what[i].id+');" title="ADD '
				+ what[i].uname + ' / '+what[i].email
				+'">'+((what[i].name)?(what[i].name):(what[i].uname))+'</a>';
		}
		if(what.length > 4) $('friendsFound').style.height = '85px';
		else $('friendsFound').style.height = (what.length * 20) + 'px';

		$('friendsFound').innerHTML = html;
		$('friendsFound').scrollTop = 0;
	}
}
function dsShowGetFriendsProgress() {
	$('ssFriends').innerHTML = $('ftFriends').innerHTML = '<div id="loadingFriends">Loading...</div>';
}
function dsPopulateFriends(){
	var i;
	var txt, txt0;
	if(friends.length > 0)
		friends = friends.sort(function(a,b){
		var v1 = ((a.fname!='')?(a.fname):(a.funame));
		var v2 = ((b.fname!='')?(b.fname):(b.funame));
		if(v1 > v2) return -1;
		else if(v1 < v2) return 1;
		else // add invitation sort here
			return 0;
	});
	
	var itemheight = 20;
	if(friends.length <= 4) {
		$('ssFriends').style.height = $('ftFriends').style.height = (4*itemheight) + 'px';
	}
	else if(friends.length <= 6) {
		$('ssFriends').style.height = $('ftFriends').style.height = (friends.length*itemheight) + 'px';
	}
	else {
		$('ssFriends').style.height = $('ftFriends').style.height = (6*itemheight) + 'px';
	}
	
	if(friends.length == 0){
		$('ssFriends').innerHTML = '<div class="smallgrey"><strong>Empty Friends List</strong><br/>&nbsp;<br/>You can add some friends by clicking on <a onclick="bIgnoreUnload=true;" href="javascript: SetSheetMode(\'friends\');">Friends</a> tab.</div>';
		$('ftFriends').innerHTML = '<div class="smallgrey"><strong>Empty Friends List</strong><br/>&nbsp;<br/></div>';
	} else {
		var html1 = '';
		var html2 = '';
		for(i = 0; i < friends.length; i++){
			txt = ((friends[i].fname)?(friends[i].fname+" <i>("+friends[i].funame+")</i>"):("<i>"+friends[i].funame+"</i>"));
			txt0 = ((friends[i].fname)?(friends[i].fname+" ("+friends[i].funame+")"):(friends[i].funame));
			html1 += '<div id="friendItem" '+
					((friends[i].li=='1')?('title="Active within last 10 minutes" class="friendActive" '):(''))+
					'><label id="friend'+friends[i].fid+'" title="'+txt0+'">'+txt+'</label>'+
					'<a onclick="setShareFriend('+friends[i].fid+', 0, this);" id="shareRead'+friends[i].fid+'" class="shareRead0" title="Set/Unset read only access"></a>'+
					'<a onclick="setShareFriend('+friends[i].fid+', 1, this);" id="shareEdit'+friends[i].fid+'" class="shareEdit0" title="Set/Unset full edit access"></a>'+
					'</div>';
			html2 += '<div id="friendItem" '+
					((friends[i].li=='1')?('title="Active within last 10 minutes" class="friendActive" '):(''))+
					'><label id="ftfriend'+friends[i].fid+'" title="'+txt0+'">'+txt+'</label>'+
					'<a onclick="deleteFriend('+friends[i].fid+');" id="deleteFriend'+friends[i].fid+'" class="deleteFriend" title="Delete from friends"></a>'+
					'</div>';
			
		}
		$('ssFriends').innerHTML = html1;
		$('ftFriends').innerHTML = html2;
	}
}
function dsHideActiveDialog(){
	if(activeDialog != null){
		if(activeDialogCancel) activeDialogCancel();
		else activeDialog.className = 'hidden';
		activeDialog = null;
	}
}
function dsRevealSelectedSheet(){
	Position.prepare();
	var conty = Position.cumulativeOffset($('sessionList'))[1];
	var sy = Position.cumulativeOffset($('sess'+selectedSheetId))[1] - Position.realOffset($('sess'+selectedSheetId))[1] - conty;
	if(sy < -2){ // scroll up
		$('sessionList').scrollTop += sy;
	} else if(sy > Element.getHeight($('sessionList')) - 23) { // scroll down
		$('sessionList').scrollTop -= (sy - Element.getHeight($('sessionList')));
	}
}
function dsRevealFriend(fid){
	Position.prepare();
	var conty = Position.cumulativeOffset($('ftFriends'))[1];
	var sy = Position.cumulativeOffset($('ftfriend'+fid))[1] - Position.realOffset($('ftfriend'+fid))[1] - conty;
	if(sy < -2){ // scroll up
		$('ftFriends').scrollTop += sy;
	} else if(sy > Element.getHeight($('ftFriends')) - 23) { // scroll down
		$('ftFriends').scrollTop -= (sy - Element.getHeight($('ftFriends')));
	}
}
function dsAnimateFriendBackground(fid){
	// get label next to it
	var elem = $('ftfriend'+fid).parentNode;
	new Effect.Highlight(elem, {startcolor:'#CDE8F4', endcolor:'#FFFFFF',restorecolor:'transparent',duration:0.8});
}
function dsShowInviteFriend(){
	dsHideActiveDialog(); activeDialog = $('inviteFriend');
	activeDialogEnter = null;
	activeDialogCancel = dsHideInviteFriend;
	$('FriendEmail').value = $('FriendMessage').value = '';
	
	$('friendsTab').className = 'hidden';
	$('inviteFriend').className = '';
	$('inviteFriendThankyou').className = 'hidden';
	$('inviteFriendButtons').className = '';
	$('inviteFriendProgress').className = 'hidden';
}
function dsHideInviteFriend(bShowThanks){
	activeDialog = null;
	$('friendsTab').className = '';
	if(!bShowThanks){
		$('inviteFriend').className = 'hidden';
	} else {
		$('inviteFriendButtons').className = 'hidden';
		$('inviteFriendThankyou').className = '';
		new Effect.SlideUp($('inviteFriend'),{ duration: 1.5, fps:24, afterFinish:function(){$('inviteFriend').style.display = ''; $('inviteFriend').className = 'hidden'; $('inviteFriendCont').style.bottom = ''; } });	
	}
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowContactUs(){
	dsHideActiveDialog(); activeDialog = $('contactBubblus');
	activeDialogEnter = null;
	activeDialogCancel = dsHideContactUs;
	if(sheetmode == 3){
		$('friendsTab').className = 'hidden';
	} else {
		$('list').className = 'hidden';
	}
	$('contactBubblus').className = '';
	$('contactUsThankyou').className = 'hidden';
	$('contactUsButtons').className = '';
}
function dsHideContactUs(bShowThanks){
	activeDialog = null;
	dsHideContactUsProgress();
	if(sheetmode == 3){
		$('friendsTab').className = '';
	} else {
		$('list').className = '';
	}
	if(!bShowThanks){
		$('contactBubblus').className = 'hidden';
	} else {
		$('contactUsButtons').className = 'hidden';
		$('contactUsThankyou').className = '';
		new Effect.SlideUp($('contactBubblus'),{ duration: 1, afterFinish:function(){$('contactBubblus').style.display = ''; $('contactBubblus').className = 'hidden'; $('contactBubblusCont').style.bottom = ''; } });	
	}
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowAnnouncement(){
	dsHideActiveDialog(); activeDialog = $('announcement');
	activeDialogEnter = null;
	activeDialogCancel = dsHideAnnouncement;
	if(sheetmode == 3){
		$('friendsTab').className = 'hidden';
	} else {
		$('list').className = 'hidden';
	}
	$('announcement').className = '';
}
function dsHideAnnouncement(){
	$('announcement').className = 'hidden';
	activeDialog = null;
	if(sheetmode == 3){
		$('friendsTab').className = '';
	} else {
		$('list').className = '';
	}
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowLinkSheetProgress(){
	$('linkSheetButtons').className = 'hidden';
	$('linkSheetProgress').className = '';
}
function dsHideLinkSheetProgress(){
	$('linkSheetButtons').className = '';
	$('linkSheetProgress').className = 'hidden';
}
function dsShowLink(){
	if(bFullScreen) {
		beditor.doAction('togglefullscreen',1);
		setTimeout(dsShowLink,500);
		return;
	}
	dsHideActiveDialog(); activeDialog = $('linkSheet');
	activeDialogEnter = null;
	activeDialogCancel = dsHideLink;
	var so = sheetObjectById(loadedSessionId);
	$('sheetName8').innerHTML = so.name;
	$('list').className = 'hidden';
	$('linkSheet').className = '';
	var pww = document.PW+so.pw;
	$('makeemaillink').value = "http://bubbl.us/view.php?sid="+selectedSheetId+"&pw="+escape(pww);
	$('lsEmail').value = ''; $('lsMessage').value = '';
	
}
function dsHideLink(){
	activeDialog = null;
	dsHideLinkSheetProgress();
	$('list').className = '';
	$('linkSheet').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;	
}
function dsShowEmbed(){
	if(bFullScreen) {
		beditor.doAction('togglefullscreen',1);
		setTimeout(dsShowEmbed,500);
		return;
	}
	dsHideActiveDialog(); activeDialog = $('embedSheet');
	activeDialogEnter = null;
	activeDialogCancel = dsHideEmbed;
	var so = sheetObjectById(loadedSessionId);
	$('sheetName9').innerHTML = so.name;
	$('list').className = 'hidden';
	$('embedSheet').className = '';
	var pww = document.PW+so.pw;
	var fvar = '_sid='+escape(loadedSessionId)
			+'&_title='+escape(so.name)
			+'&_z=75'
			+'&_pw='+escape(pww);
	var eurlp = 'sid='+escape(loadedSessionId)
			+'&pw='+escape(pww);
	$('makeembedlink').value
		= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="450" height="340" id="bblviewer">\n'
		+'<param name="movie" value="http://bubbl.us/sys/view.swf?'+eurlp+'" />\n'
		+'<param name="quality" value="high" />\n'
		+'<param name="SeamlessTabbing" value="false" />\n'
		+'<param name="AllowScriptAccess" value="always" />\n'
		+'<param name="FlashVars" value="'+fvar+'" />\n'
		+'<embed src="http://bubbl.us/sys/view.swf?'+eurlp+'" FlashVars="'+fvar+'" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="450" height="340" allowscriptaccess="always" SeamlessTabbing="false" name="bblviewer"></embed>\n</object>\n';
	
}
function dsHideEmbed(){
	activeDialog = null;
	$('list').className = '';
	$('embedSheet').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;	
}
function dsShowSharing(){
	if(!selectedSheetId || document.USERID == '0' || sheetmode != 0) return;
	dsHideActiveDialog(); activeDialog = $('shareSheet');
	activeDialogEnter = null;
	activeDialogCancel = dsHideSharing;
	$('sheetName7').innerHTML = selectedSheetName;
	$('list').className = 'hidden';
	$('shareSheet').className = '';
	/*
	var so = sheetObjectById(selectedSheetId);
	var pww = document.PW+so.pw;
	$('makeemaillink').value = "http://bubbl.us/view.php?sid="+selectedSheetId+"&pw="+escape(pww);
	var fvar = '_sid='+escape(selectedSheetId)
			+'&_title='+escape(selectedSheetName)
			+'&_z=75'
			+'&_pw='+escape(pww);
	var eurlp = 'sid='+escape(selectedSheetId)
			+'&pw='+escape(pww);
	$('makepostlink').value
		= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="450" height="340" id="bblviewer">\n'
		+'<param name="movie" value="http://bubbl.us/sys/view.swf?'+eurlp+'" />\n'
		+'<param name="quality" value="high" />\n'
		+'<param name="SeamlessTabbing" value="false" />\n'
		+'<param name="AllowScriptAccess" value="always" />\n'
		+'<param name="FlashVars" value="'+fvar+'" />\n'
		+'<embed src="http://bubbl.us/sys/view.swf?'+eurlp+'" FlashVars="'+fvar+'" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="450" height="340" allowscriptaccess="always" SeamlessTabbing="false" name="bblviewer"></embed>\n</object>\n';
	*/
	ajGetFriends();
}
function dsHideSharing(){
	activeDialog = null;
	dsHideSaveShareProgress();
	$('list').className = '';
	$('shareSheet').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowDeleteFriend(friendId, fName){
	if(document.USERID == '0') return;
	activeDialog = $('deleteFriend');
	$('friendsTab').className = 'hidden';
	activeDialogEnter = null;
	activeDialogCancel = dsHideDeleteFriend;
	friendIdToDelete = friendId;
	$('friendName').innerHTML = fName;
	$('deleteFriend').className = '';
}
function dsHideDeleteFriend(){
	activeDialogCancel = null;	
	$('deleteFriend').className = 'hidden';
	$('friendsTab').className = '';
	//dsShowSharing();
	//setTimeout(function(){activeDialogCancel=dsHideSharing;}, 100);
}
function dsShowInviteFriendProgress(){
	$('inviteFriendButtons').className = 'hidden';
	$('inviteFriendProgress').className = '';
}
function dsHideInviteFriendProgress(){
	$('inviteFriendButtons').className = '';
	$('inviteFriendProgress').className = 'hidden';
}

function dsShowContactUsProgress(){
	$('contactUsButtons').className = 'hidden';
	$('contactUsProgress').className = '';
}
function dsHideContactUsProgress(){
	$('contactUsButtons').className = '';
	$('contactUsProgress').className = 'hidden';
}
function dsShowDeleteFriendProgress(){
	$('deleteFriendButtons').className = 'hidden';
	$('deleteFriendProgress').className = '';
}
function dsHideDeleteFriendProgress(){
	$('deleteFriendButtons').className = '';
	$('deleteFriendProgress').className = 'hidden';
}
function dsRemoveFriendRow(fid){
	var div = $('ftfriend'+fid).parentNode;
	new Effect.BlindUp(div,{ duration: 0.2, afterFinish:function(){Element.remove(div);} });	
}
function dsShowSignIn(){
	dsHideActiveDialog(); activeDialog = $('signinAccount');
	dsClearBadFieldsSignIn();
	activeDialogEnter = SignIn;
	activeDialogCancel = dsHideSignIn;	
	$('list').className = 'hidden';
	$('signinAccount').className = '';
	$('siUsername').value = $('siPassword').value = '';
	$('siUsername').focus();
}
function dsHideSignIn(){
	activeDialog = null;
	$('list').className = '';
	$('signinAccount').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowSignInProgress(){
	$('signinAccountButtons').className = 'hidden';
	$('signinAccountProgress').className = '';
	$('siUsername').readOnly = $('siPassword').readOnly = true;
}
function dsHideSignInProgress(){
	$('signinAccountButtons').className = '';
	$('signinAccountProgress').className = 'hidden';
	$('siUsername').readOnly = $('siPassword').readOnly = false;
}
//
function dsShowForgotPass(){
	dsHideActiveDialog(); activeDialog = $('forgotPassword');
	activeDialogEnter = ResetPassword;
	activeDialogCancel = dsHideForgotPass;	
	$('list').className = 'hidden';
	$('forgotPassword').className = '';
	$('fpEmail').value = '';
	$('fpEmail').focus();
}
function dsHideForgotPass(){
	dsClearBadFieldsForgotPassword();
	$('fpEmail').blur();
	activeDialog = null;
	$('forgotPassword').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
	dsShowSignIn();
}
function dsShowForgotPassProgress(){
	$('forgotPasswordButtons').className = 'hidden';
	$('forgotPasswordProgress').className = '';
	$('fpEmail').readOnly = true;
}
function dsHideForgotPassProgress(){
	$('forgotPasswordButtons').className = '';
	$('forgotPasswordProgress').className = 'hidden';
	$('fpEmail').readOnly = false;
}
//
function dsShowEditAccountProgress(){
	$('editAccountButtons').className = 'hidden';
	$('editAccountProgress').className = '';
	$('eaUsername').readOnly = $('eaEmail').readOnly = $('eaPassword').readOnly = $('eaPassword2').readOnly = $('eaName').readOnly = true;
}
function dsHideEditAccountProgress(){
	$('editAccountButtons').className = '';
	$('editAccountProgress').className = 'hidden';
	$('eaUsername').readOnly = $('eaEmail').readOnly = $('eaPassword').readOnly = $('eaPassword2').readOnly = $('eaName').readOnly = false;
}
function dsShowSaveShareProgress(){
	$('shareSheetButtons').className = 'hidden';
	$('shareSheetProgress').className = '';
}
function dsHideSaveShareProgress(){
	$('shareSheetButtons').className = '';
	$('shareSheetProgress').className = 'hidden';
}

function dsShowRenameInput(){
	if(!selectedRenameSheetId) return;
	var label = $('lbl'+selectedRenameSheetId);
	label.hide();
	var editbox = '<input type="text" id="sheetRename" />';
	new Insertion.After(label, editbox);
	editbox = $('sheetRename');
	editbox.value = selectedRenameSheetName;
	Event.observe(editbox, 'blur', renameSheetApply);
	Event.observe(editbox, 'keydown', renameSheetKeyDown);
}
function dsShowSavedSheets(){
	enableMainButtons();
	if(savedSheets.length == 0){
		$('sessionList').innerHTML = '<h4>Empty</h4>';
		return;
	}
	var html = '';
	var chunk = '';
	var ss, eb;
	$('sessionList').innerHTML = '';
	for(var i = 0; i < savedSheets.length; i++){
		ss = savedSheets[i];
		chunk = dsGetSessionItemHTML(ss, false);
		new Insertion.Bottom($('sessionList'), chunk);
	}
	dsSessionListHighlightId(selectedSheetId, 2);
}
function dsShowSharedSheets(obj){
	enableMainButtons();
	if(!obj){
		$('sessionList').innerHTML = '<h4>Empty</h4><div class="smallgrey">No one shares any sheets<br/>with you yet</div>';
		return;
	}
	var html = '';
	var chunk = '';
	var ss, eb;
	$('sessionList').innerHTML = '';
	var fdesc;
	for(nfo in obj){
		fdesc = '<div id="usershares" '+
			((obj[nfo].finfo.li=='1')?('class="active"'):(''))+
			'><span>'+obj[nfo].finfo.fname+"</span></div>";
		new Insertion.Bottom($('sessionList'), fdesc);
		for(var i = 0; i < obj[nfo].sess.length; i++){
			ss = obj[nfo].sess[i];
			chunk = dsGetSessionItemHTML(ss, true);
			new Insertion.Bottom($('sessionList'), chunk);
			$('sess'+ss.id).title = ((ss.shared=='1')?('SHARED * '):(''))+ss.name+((!isIE6)?(' * '):('\n'))+'Last Saved: '+ss.mod;
		}
	}
	dsSessionListHighlightId(selectedSheetId, 2);
}
function dsUpdateSheetItem(so){
	selectedSheetName = selectedRenameSheetName = so.name;
	// update item
	var html = dsGetSessionItemHTML(so, (sheetmode==1));
	var pnode = $('sess'+selectedSheetId).previousSibling;
	Element.remove($('sess'+selectedSheetId));
	if(pnode){
		new Insertion.After(pnode, html);
	} else {
		new Insertion.Top($('sessionList'), html);
	}
	var temp = selectedSheetId;
	selectedSheetId = 0;
	selectSheetId(temp);
}
function dsGetSessionItemHTML(ss, bPerms){
	var eb;
	var chunk = '<div id="sess'+ss.id
			+'" onClick="selectSheetId('+ss.id
			+');" onMouseOver="dsSessionListHighlightId('+ss.id+',1);" '
			+'ondblclick="DblClickLoad('+ss.id+');" '
			+'onMouseOut="dsSessionListHighlightId('+ss.id+',0);" '
			+ ' title="'+((ss.shared=='1')?('SHARED * '):(''))+ss.name+((!isIE6)?(' * '):('\n'))+'Last Saved: '+ss.mod+'"'
			+'>';
	if(ss.shared == '1'){	
		if(ss.lockedby != '0' && ss.lockedby != document.USERID){
			eb = 'another user';
			if(friends) for(var j=0; j < friends.length; j++){
				if(friends[j].fid == ss.lockedby) {
					eb = ((friends[j].fname)?(friends[j].fname+" ("+friends[j].funame+")"):(friends[j].funame))
					break;
				}
			}
			chunk+= '<div id="iconsharedlocked" title="Shared sheet - being edited by '+eb+'"></div>';
		} else 	chunk+= '<div id="iconshared" title="Shared sheet"></div>';
	} else	chunk+= '<div id="icon"></div>';
	
	chunk+= '<label id="lbl'+ss.id+'">'+(ss.name ? ss.name : '')+'</label>';
	if(bPerms){
		if(ss.rw == 1){
			chunk+= '<div id="iconcanwrite" title="Edit access"></div>';
		} else {
			chunk+= '<div id="iconcanread" title="Read only access"></div>';
		}
	}
	chunk+= '</div>';
	
	return chunk;
}
function dsSessionListHighlightId(id, state){
	var item = $('sess'+id);
	if(!item) return;
	if(state == 2) {
		item.className = 'selected';
		// scroll to
	} else if(state == 1 && selectedSheetId != id){
		item.className = 'over';
	} else if(state == 0 && selectedSheetId != id){
		item.className = '';
	}
}
function dsShowSaving(){
	sheetSelectionDisabled = true;
	$('editingSession').className = 'hidden';
	$('sheetName2').innerHTML = $('sessionName').value;
	$('savingSession').className = '';
}
function dsHideSaving(){
	sheetSelectionDisabled = false;
	$('editingSession').className = '';
	$('savingSession').className = 'hidden';	
}
function dsShowDeleting(){
	sheetSelectionDisabled = true;
	$('editingSession').className = 'hidden';
	$('sheetName4').innerHTML = selectedSheetName;
	$('deletingSession').className = '';
}
function dsHideDeleting(){
	sheetSelectionDisabled = false;
	$('editingSession').className = '';
	$('deletingSession').className = 'hidden';	
}
function dsShowLoading(){
	sheetSelectionDisabled = true;
	$('editingSession').className = 'hidden';
	$('sheetName3').innerHTML = $('sessionName').value;
	$('loadingSession').className = '';
}
function dsHideLoading(){
	sheetSelectionDisabled = false;
	$('editingSession').className = '';
	$('loadingSession').className = 'hidden';	
}
function dsUpdateHelp(){
	if(!helpVisible){
		$('helpHead').className = 'closed';
		Element.hide($('help'));
	} else { 
		$('helpHead').className = 'open';
		Element.show($('help'));
	}	
}
function dsShowConfirmLoadSheet(){
	$('list').className = 'hidden';
	$('sheetName6').innerHTML = $('sessionName').value;
	$('confirmLoad').className = '';
}
function dsHideConfirmLoadSheet(){
	$('list').className = '';
	$('confirmLoad').className = 'hidden';
	showHelp(null);
}
function dsShowConfirmNewSheet(){
	$('list').className = 'hidden';
	$('sheetName1').innerHTML = $('sessionName').value;
	$('confirmNew').className = '';
}
function dsHideConfirmNewSheet(){
	$('list').className = '';
	$('confirmNew').className = 'hidden';
	showHelp(null);
}
function dsShowConfirmDeleteSheet(){
	$('list').className = 'hidden';
	activeDialogEnter = null;
	activeDialogCancel = function(){ dsHideConfirmDeleteSheet(); };
	$('sheetName5').innerHTML = selectedSheetName;
	$('confirmDelete').className = '';
}
function dsHideConfirmDeleteSheet(){
	$('list').className = '';
	$('confirmDelete').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowHelp(topic){
	$('help').innerHTML = ((topic!=null&&helpTopics[topic]!=undefined)?(helpTopics[topic]):(''));
	$('help').scrollTop = 0;
}
function dsShowEditAccount(bSaving){
	$('eaAnnouncement').checked = !document.noAnnouncements;
	dsClearBadFieldsEditAccount();
	dsHideActiveDialog(); activeDialog = $('editAccount');
	activeDialogEnter = null;
	activeDialogCancel = dsHideEditAccount;	
	if(sheetmode != 3)
		$('list').className = 'hidden';
	else 
		$('friendsTab').className = 'hidden';
	$('eaUsername').value = document.USERNAME;
	$('eaEmail').value = document.EMAIL;
	$('eaPassword').value = '';
	$('eaPassword2').value = '';
	$('eaName').value = document.NAME;
	$('editAccount').className = '';
	$('eaUsername').focus();
}
function dsHideEditAccount(){
	dsClearBadFieldsEditAccount();
	activeDialog = null;
	if(sheetmode != 3)
		$('list').className = '';
	else 
		$('friendsTab').className = '';
	$('editAccount').className = 'hidden';
	$('changePass').className = '';
	$('changePassInput').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowChangePassword(){
	$('changePass').className = 'hidden';
	$('changePassInput').className = '';
	$('eaPassword').focus();
}
function dsShowNewUser(bSaving){
	dsClearBadFieldsNewUser();
	dsHideActiveDialog(); activeDialog = $('createAccount');
	activeDialogEnter = null;
	activeDialogCancel = dsHideNewUser;	
	$('list').className = 'hidden';
	$('needNewUser').className = ((bSaving) ? ('') : ('hidden'));
	$('nuUsername').value = $('nuEmail').value = $('nuPassword').value = $('nuPassword2').value = $('nuName').value = '';
	$('createAccount').className = '';
	$('nuUsername').focus();
}
function dsHideNewUser(){
	dsClearBadFieldsNewUser();
	activeDialog = null;
	$('list').className = '';
	$('needNewUser').className = 'hidden';	
	$('createAccount').className = 'hidden';
	showHelp(null);
	activeDialogEnter = null;
	activeDialogCancel = null;
}
function dsShowNewUserProgress(){
	$('createAccountButtons').className = 'hidden';
	$('createAccountProgress').className = '';
	$('nuUsername').readOnly = $('nuEmail').readOnly = $('nuPassword').readOnly = $('nuPassword2').readOnly = $('nuName').readOnly = true;
}
function dsHideNewUserProgress(){
	$('createAccountButtons').className = '';
	$('createAccountProgress').className = 'hidden';
	$('nuUsername').readOnly = $('nuEmail').readOnly = $('nuPassword').readOnly = $('nuPassword2').readOnly = $('nuName').readOnly = false;
	dsClearBadFieldsNewUser();
}
function dsHighlightBadField(fld, msg, pfx){
	if(!pfx) pfx = 'nu';
	badfield = {lbl:$('lbl'+pfx+fld), fld:$(pfx+fld), err:$(pfx+'Err'+fld),clearfunc:null};
	badfield.lbl.className = 'error';
	badfield.err.className = 'error';
	badfield.err.innerHTML = msg;
	badfield.fld.focus();
	badfield.fld.select();
	if(pfx == 'nu')
		Event.observe(badfield.fld, 'keyup', badfield.clearfunc = dsClearBadFieldsNewUser, false);
	else if(pfx == 'si')
		Event.observe(badfield.fld, 'keyup', badfield.clearfunc = dsClearBadFieldsSignIn, false);
	else if(pfx == 'ea')
		Event.observe(badfield.fld, 'keyup', badfield.clearfunc = dsClearBadFieldsEditAccount, false);
	else if(pfx == 'fp')
		Event.observe(badfield.fld, 'keyup', badfield.clearfunc = dsClearBadFieldsForgotPassword, false);
}
function dsClearBadFieldsNewUser(){
	if(badfield) Event.stopObserving(badfield.fld, 'keyup', dsClearBadFieldsNewUser, true);
	$('nuErrUsername').className = $('nuErrEmail').className = $('nuErrPassword').className = $('nuErrPassword2').className = '';
	$('lblnuUsername').className = $('lblnuEmail').className = $('lblnuPassword').className = $('lblnuPassword2').className = '';
	badfield = null;
}
function dsClearBadFieldsEditAccount(){
	if(badfield) Event.stopObserving(badfield.fld, 'keyup', dsClearBadFieldsEditAccount, true);
	$('eaErrUsername').className = $('eaErrEmail').className = $('eaErrPassword').className = $('eaErrPassword2').className = '';
	$('lbleaUsername').className = $('lbleaEmail').className = $('lbleaPassword').className = $('lbleaPassword2').className = '';
	badfield = null;
}
function dsClearBadFieldsSignIn(){
	if(badfield) Event.stopObserving(badfield.fld, 'keyup', dsClearBadFieldsSignIn, true);
	$('siErrUsername').className = $('siErrPassword').className = '';
	$('lblsiUsername').className = $('lblsiPassword').className = '';
	badfield = null;
}
function dsClearBadFieldsForgotPassword(){
	if(badfield) Event.stopObserving(badfield.fld, 'keyup', dsClearBadFieldsForgotPassword, true);
	$('fpErrEmail').className = '';
	$('lblfpEmail').className = '';
	badfield = null;
}
// ================================================================		Ajax functions
function ajExport(sessionData){
	var f = $('postform');
	var tp = '';
	var opt = '';
	if($('exportAsXML').checked) {
		tp = 'xml';
		opt = 'nested';//($('exportAsXMLFlat').checked)?('flat'):('nested');
		
	} else if($('exportAsHTML').checked) {
		tp = 'html';
		opt = ($('exportAsHTMLPlain').checked)?('plain'):('colors');
	}
	else if($('exportAsImage').checked) {
		tp = 'image';
		opt = ($('exportAsImagePNG').checked)?('png'):('jpg');
	}

	// use form
	f.nm.value = $('sessionName').value;
	f.dt.value = sessionData;
	f.opt.value = opt;
	f.tp.value = tp;
	f.action = 'sys/exportsheet.php';
	f.target = '_blank';
	f.submit();
	
	dsHideExport();
}

function ajImport(fname){
	dsShowImportProgress();
	new Ajax.Request(
	"sys/importsheet.php",
	{
		method: 'post',
		parameters: 'receive='+escape(fname),
		onSuccess: ajImportSuccess,
		onFailure: ajImportFail
	});	
}
function ajImportSuccess(req){
	dsHideImportProgress();
	var res = req.responseText;
	if(res.substr(0,6)=='ERROR:'){
		alert("XML IMPORT ERROR:\n\n"+res.substr(6));
	} else {
		beditor.doAction('import',(($('importOptionAppend').checked)?('append'):('replace')),res);
		dsHideImport();
	}
}
function ajImportFail(req){
	dsHideImportProgress();
}
function ajInviteFriend(){
	dsShowInviteFriendProgress();
	new Ajax.Request(
	"sys/invitefriend.php",
	{
		method: 'post',
		parameters: 'e='+escape($('FriendEmail').value)+"&m="+escape($('FriendMessage').value)+"&n="+(($('FriendNotify').checked)?(1):(0)),
		onSuccess: ajInviteFriendSuccess,
		onFailure: ajInviteFriendFail
	});	
}
function ajInviteFriendSuccess(req){
	var res = req.responseText;
	if(res.substr(0,6)=='ERROR:'){
		dsHideInviteFriendProgress();
		id = Number(res.substr(6,999));
		if(!isNaN(Number(id))){ // friend id
			dsHideInviteFriend();
			dsRevealFriend(id);
			dsAnimateFriendBackground(id);
			return dsShowError("Already your friend");
		} else {
			if(res.substr(6,999) == 'BadEmail'){
				$('FriendEmail').focus();
				$('FriendEmail').select();
				return dsShowError("Bad email address");
			} else if(res.substr(6,999) == 'Exists'){
				dsHideInviteFriend();
				setTimeout(function(){
								$('ffQuery').value = $('FriendEmail').value;
								findFriend();
							}, 100);
				return dsShowError("User already exists, use search");
			} else if(res.substr(6,999) == 'AlreadySent'){
				return dsShowError("User already invited by you");
			}			
		}
		return;
	}		
	
	dsHideInviteFriend(true);
}
function ajInviteFriendFail(){
	dsShowError("Server unavailable");
	dsHideInviteFriend();
}

function ajLinkSheetSend(){
	dsShowLinkSheetProgress();
	new Ajax.Request(
	"sys/sendlink.php",
	{
		method: 'post',
		parameters: 'e='+escape($('lsEmail').value)+"&m="+escape($('lsMessage').value)
					+"&l="+escape($('makeemaillink').value)+"&n="+escape(sheetObjectById(loadedSessionId).name),
		onSuccess: ajLinkSheetSuccess,
		onFailure: ajLinkSheetFail
	});	
}
function ajLinkSheetSuccess(req){
	dsHideLink();
}
function ajLinkSheetFail(){
	dsHideLink();
}
function ajContactUs(){
	dsShowContactUsProgress();
	new Ajax.Request(
	"sys/contact.php",
	{
		method: 'post',
		parameters: 'ra='+escape($('ReplyEmail').value)+"&m="+escape($('EmailMessage').value),
		onSuccess: ajContactUsSuccess,
		onFailure: ajContactUsFail
	});	
}
function ajContactUsSuccess(req){
	dsHideContactUs(true);
}
function ajContactUsFail(){
	dsHideContactUs(true);
}

function ajDeleteFriend(){
	dsShowDeleteFriendProgress();
	new Ajax.Request(
	"sys/deletefriend.php",
	{
		method: 'post',
		parameters: 'fid='+friendIdToDelete,
		onSuccess: ajDeleteFriendSuccess,
		onFailure: ajDeleteFriendFail
	});	
}

function ajDeleteFriendSuccess(req){
	var res = req.responseText;
	dsHideDeleteFriendProgress();
	
	if(res.substr(0,6)=='ERROR:'){
		ajGetFriends();
		// friend already deleted
	} else {
		// remove row
		dsRemoveFriendRow(res);
		for(var i = 0; i<friends.length; i++){
			if(friends[i].fid == res){
				friends.splice(i, 1);
				break;
			}
		}		
	}
	activeDialogCancel();
}
function ajDeleteFriendFail(){
}
function ajAddFriend(id){
	new Ajax.Request(
	"sys/addfriend.php",
	{
		method: 'post',
		parameters: 'id='+id,
		onSuccess: ajAddFriendSuccess,
		onFailure: ajAddFriendFail
	});	
}
function ajAddFriendSuccess(req){
	var res = req.responseText;
	var id;
	if(res.substr(0,6)=='ERROR:'){
		id = Number(res.substr(6,999));
		// xxx already in list
		dsRevealFriend(id);
		dsAnimateFriendBackground(id);
	} else {
		var chunk = res.parseQuery();
		friends.push({id:chunk.id, fid:chunk.fid, fname:chunk.fname, funame:chunk.funame, li:chunk.li});
		dsPopulateFriends();
		dsRevealFriend(chunk.fid);
		dsAnimateFriendBackground(chunk.fid);
	}
	dsUpdateSharePermissions();
	enableShareCheckboxes();
}
function ajAddFriendFail(){
}
function ajFindFriend(){
	new Ajax.Request(
	"sys/getfriends.php", 
	{
		method: 'post',
		parameters: 'q='+escape($('ffQuery').value),
		onSuccess: ajFindFriendSuccess,
		onFailure: ajFindFriendFail
	});	
}
function ajFindFriendSuccess(req){
	var res = req.responseText;
	if(res == '0'){
		dsShowFriendFound('<div id="ffnotfnd" onMouseOver="new Effect.BlindUp($(\'friendsFound\'),{ duration: 0.5, afterFinish:function(){$(\'friendsFound\').show();$(\'friendsFound\').className=\'hidden\';} });">Nothing found, sorry</div>');
		$('ffQuery').readOnly = false;
		$('ffQuery').blur();
		$('ffQuery').focus();
		return;
	}
	var chunk, i = 0;
	var chunks = res.split(';');
	var entries = new Array();
	while((chunk = chunks[i++])!='0'){
		chunk = chunk.parseQuery();
		entries[i-1] = {id:chunk.id, name:chunk.name, uname:chunk.uname, email:chunk.email};
	}
	// populate
	dsShowFriendFound(entries, true);	
	$('ffQuery').readOnly = false;
	$('ffQuery').blur();
	$('ffQuery').focus();
}
function ajFindFriendFail(){
}
function ajGetFriends(){
	dsShowGetFriendsProgress();
	new Ajax.Request(
	"sys/getfriends.php", 
	{
		method: 'post', 
		onSuccess: ajGetFriendsSuccess,
		onFailure: ajGetFriendsFail
	});	
}
function ajGetFriendsSuccess(req){
	var res = req.responseText;
	if(res == '0'){
		friends = null;
		friends = new Array();
		dsPopulateFriends();
		return;
	}
	var chunk, i = 0;
	var chunks = res.split(';');
	if(friends && friends.length){
		while(friends.length){ friends[0] = null; friends.pop(); }
	}
	friends = new Array();
	while((chunk = chunks[i++])!='0'){
		chunk = chunk.parseQuery();
		friends[i-1] = {id:chunk.id, fid:chunk.fid, fname:chunk.fname, funame:chunk.funame, li:chunk.li};
	}
	// populate
	//
	dsPopulateFriends();
	if(selectedSheetId && sheetmode == 0) ajGetSharePermissions(selectedSheetId);
}
function ajGetFriendsFail(){
}
function ajShareSheetSave(){
	if(!selectedSheetId) return;
	dsShowSaveShareProgress();
	var sp;
	if(shareperms && shareperms.length > 0) {
		var temp = new Array();
		for(var i = 0; i < shareperms.length; i++){
			temp.push(shareperms[i].fid+":"+shareperms[i].rw);
		}
		sp = temp.join(';');
	} else sp = '0';
	
	new Ajax.Request(
	"sys/saveshareperms.php", 
	{
		method: 'post',
		parameters: 'sid='+escape(selectedSheetId)+'&fids='+escape(sp),
		onSuccess: ajShareSheetSaveSuccess,
		onFailure: ajShareSheetSaveFail
	});		
}
function ajShareSheetSaveSuccess(req){
	var res = req.responseText;
	var obj = sheetObjectById(selectedSheetId);
	obj.shared = res;
	dsShowSavedSheets();
	dsHideSharing();
}
function ajShareSheetSaveFail(){
}
function ajGetSharePermissions(sid){
	enableShareCheckboxes(true);
	getsharesinprogress = true;
	new Ajax.Request(
	"sys/getshareperms.php", 
	{
		method: 'post',
		parameters: 'sid='+escape(sid),
		onSuccess: ajGetSharePermissionsSuccess,
		onFailure: ajGetSharePermissionsFail
	});	
}
function ajGetSharePermissionsSuccess(req){
	getsharesinprogress = false;
	var res = req.responseText;
	var ir;
	// parse perms
	if(res == "0") shareperms = null;
	else {
		var temp = res.split(";");
		shareperms = null;
		shareperms = new Array();
		for(var i=0; i < temp.length; i++){
			ir = temp[i].split(':');
			shareperms.push({fid:Number(ir[0]), rw:Number(ir[1])} );
		}
	}
	dsPopulateFriends();
	dsUpdateSharePermissions();
}
function ajGetSharePermissionsFail(){
	getsharesinprogress = false;
}
function ajReloadHeader(){
	new Ajax.Request('sys/header.php',{ onSuccess: ajReloadHeaderSuccess });
}
function ajReloadHeaderSuccess(req){
	$('headercontent').innerHTML = req.responseText;
	setLinkUnload();
	setTimeout(function(){SetSheetMode('mysheets');},100);
}
function ajUnlockSheet(id){
	new Ajax.Request('sys/unlocksession.php', {
		method:'post',
		parameters:((id!=undefined)?('id='+id):(''))
	});
}
function ajSignIn(){
	dsClearBadFieldsSignIn();
	dsShowSignInProgress();
	new Ajax.Request(
	"sys/signin.php", 
	{
		method: 'post', 
		parameters: 'un='+escape($('siUsername').value)+'&ps='+escape($('siPassword').value)+(($('siRemember').checked)?('&re=1'):(''))+'&inline=true',
		onSuccess: ajSignInSuccess,
		onFailure: ajSignInFail
	});
}
function ajSignInSuccess(req){
	var res = req.responseText;
	dsHideSignInProgress();
	if(res == '0'){
		dsHighlightBadField('Username','Bad username or password','si');
		return;
	}
	var info = res.split(';');
	document.USERID = unescape(info[0]);
	if(info[2].length > 0)
		document.NAME = unescape(info[2]);
	else
		document.NAME = unescape(info[1]);
	document.EMAIL = unescape(info[3]);
	document.USERNAME = unescape(info[1]);
	document.PW = unescape(info[4]);
	dsHideSignIn();
	LoggedIn();
	ajGetSavedSheets();
	showHelp("getting started");	
}
function ajSignInFail(){
}
function ajResetPassword(){
	dsClearBadFieldsForgotPassword();
	dsShowForgotPassProgress();
	new Ajax.Request(
	"sys/resetpass.php", 
	{
		method: 'post', 
		parameters: 'em='+escape($('fpEmail').value),
		onSuccess: ajResetPassSuccess,
		onFailure: ajResetPassFail
	});
}
function ajResetPassSuccess(req){
	var res = req.responseText;
	dsHideForgotPassProgress();
	if(res == '0'){
		dsHighlightBadField('Email','Email not found','fp');
		return;
	}
	dsHideForgotPass();
	alert("Please check your email to get your username and your shiny new password.\n\nDo not leave this page if you want to be able to save your work after you sign in.");	
}
function ajResetPassFail(){
}
//
function ajEditAccount(){
	dsShowEditAccountProgress();
	new Ajax.Request(
	"sys/edituser.php", 
	{
		method: 'post', 
		parameters: 'un='+escape($('eaUsername').value)
					+'&em='+escape($('eaEmail').value)
					+'&na='+escape($('eaName').value)
					+'&pa='+escape($('eaPassword').value),
		onSuccess: ajEditAccountSuccess,
		onFailure: ajEditAccountFail
	});	
}
function ajEditAccountSuccess(req){
	dsHideEditAccountProgress();
	var res = req.responseText;
	if(res.substr(0, 6) == 'ERROR:'){
		var fm = res.substr(6).split(';');
		dsHighlightBadField(fm[0], fm[1],'ea');
		return;
	}
	document.USERNAME = $('eaUsername').value;
	if($('eaName').value.length > 0)
		document.NAME = $('eaName').value;
	else
		document.NAME = $('eaUsername').value;
	document.EMAIL = $('eaEmail').value;
	LoggedIn();
	dsHideEditAccount();	
}
function ajEditAccountFail(){
	dsHideEditAccountProgress();
}

function ajCreateAccount(){
	dsShowNewUserProgress();
	new Ajax.Request(
	"sys/newuser.php", 
	{
		method: 'post', 
		parameters: 'un='+escape($('nuUsername').value)
					+'&em='+escape($('nuEmail').value)
					+'&na='+escape($('nuName').value)
					+'&pa='+escape($('nuPassword').value),
		onSuccess: ajCreateAccountSuccess,
		onFailure: ajCreateAccountFail
	});	
}
function ajCreateAccountSuccess(req){
	dsHideNewUserProgress();
	var res = req.responseText;
	if(res.substr(0, 6) == 'ERROR:'){
		var fm = res.substr(6).split(';');
		dsHighlightBadField(fm[0], fm[1],'nu');
		return;
	}
	var tmp = res.split(';');
	document.USERID = tmp[0];
	document.PW = tmp[1];
	if($('nuName').value.length > 0)
		document.NAME = $('nuName').value;
	else
		document.NAME = $('nuUsername').value;
	document.EMAIL = $('nuEmail').value;
	document.USERNAME = $('nuUsername').value;
	dsHideNewUser();
	savedSheets.length = 0;
	LoggedIn();
	dsShowSavedSheets();
	showHelp('welcomenewuser');
	if(saveSessionAfterNewUser) saveSheet();
	saveSessionAfterNewUser = false;
}
function ajCreateAccountFail(){
	dsHideNewUserProgress();
}
function ajKeepAlive(){
	new Ajax.Request("sys/keepalive.php", 
						{ 	method:'post',
							parameters: '_r='+Math.round(9999999 * Math.random()),
							onSuccess:ajKeepAliveResponse,
							onFailure:ajKeepAliveResponse});	
}

function ajKeepAliveResponse(req){	
	setTimeout(ajKeepAlive, 60 * 1000 * 7);
}
function ajGetHelp(topic){
	new Ajax.Request("sys/help.htm", 
						{ 	method:'get',
							onSuccess:ajHelpReceived });	
}
function ajHelpReceived(req){
	var res = req.responseText;
	var chunks = res.split("<!--");
	var pos = 0;
	var topic;
	for(var i = 0; i < chunks.length; i++){
		pos = chunks[i].indexOf("-->",0);
		if(pos > 0){
			topic = chunks[i].substr(0,pos);
			helpTopics[topic] = chunks[i].substr(pos+3);
		}
	}
	if(document.justJoined) showHelp('welcomenewuser');
	else showHelp(lastHelpTopic);
}
function ajRenameSession(id, newname){
	var sid;
	if(sheetmode == 0) sid = "id="+id;
	else sid = "ssid="+id;
	sheetSelectionDisabled = true;
	new Ajax.Request(
	"sys/renamesession.php", 
	{
		method: 'post', 
		parameters: sid+'&name='+escape(newname), 
		onSuccess: ajRenameSuccess,
		onFailure: ajRenameFail
	});	
}

function ajRenameSuccess(req){
	sheetSelectionDisabled = false;
	var res = req.responseText;
	var so = sheetObjectById(selectedSheetId);
	if(res.substr(0,6)=='ERROR:') {
		if(res.substr(6,8)=='LockedBy'){
			so.lockedby = (res.substr(13,999));
			dsShowError("Sheet is now locked");
			dsUpdateSheetItem(so);
			return;			
		} else	if(res.substr(6,8)=='SameName'){
			dsShowError("Sheet with the same name exists");
			dsUpdateSheetItem(so);
			return;
		} else	if(res.substr(6,8) == 'ReadOnly'){
			return dsShowError('Session is read-only');
		} else if(res.substr(6,9) == 'NotShared'){
			if(so) {
				so.shared = '0';
				dsUpdateSheetItem(so);
			}
			return dsShowError('Session is no longer shared');
		}
		// unknown error?
		else if(sheetmode == 0) dsShowSavedSheets();
		else if(sheetmode == 1) dsShowSharedSheets();
		return;
	}
	var id = res.substr(0, res.indexOf(';'));
	var nn = res.substr(id.length + 1);
	if(selectedRenameSheetId == loadedSessionId){
		$('sessionName').value = nn;
	}
	so.name = nn;
	dsUpdateSheetItem(so);
}
function ajRenameFail(){
	sheetSelectionDisabled = false;
	dsShowSavedSheets();
}
function ajLoadSession(){
	noTabSwitches = true;
	new Ajax.Request(
	"sys/loadsession.php", 
	{
		method: 'post', 
		parameters: ((sheetmode==1)?('sh'):(''))+"id="+selectedSheetId, 
		onSuccess: ajLoadSuccess,
		onFailure: ajLoadFail
	});
	loadedSessionId = selectedSheetId;
}
function ajLoadSuccess(req){
	noTabSwitches = false;
	res = req.responseText;
	var so;
	if(res.substr(0,6)!='ERROR:'){
		loadedSessionId = selectedSheetId;
		loadedSessionMode = sheetmode;
		dsSessionModeChanged();
		if(sheetmode == 1 && sheetObjectById(selectedSheetId).rw == 0) 
			beditor.doAction('setReadonly', true);
		else 
			beditor.doAction('setReadonly', false);
		beditor.doAction('load', res);
	} else {
		dsHideLoading();
		if(res.substr(6,8)=='LockedBy'){
			so = sheetObjectById(selectedSheetId);
			if(so){
				var sheetstart = res.indexOf(';',14) + 1;
				so.lockedby = (res.substr(14, sheetstart - 15));
				dsUpdateSheetItem(so);
				beditor.doAction('setReadonly', true);
				beditor.doAction('load', res.substr(sheetstart));
			}
			dsShowError("Sheet is locked");
		}
	}
}
function ajLoadFail(){
	noTabSwitches = false;
}
function ajDeleteSession(){
	noTabSwitches = true;
	new Ajax.Request(
	"sys/deletesession.php", 
	{
		method: 'post', 
		parameters: "id="+selectedSheetId, 
		onSuccess: ajDeleteSuccess,
		onFailure: ajDeleteFail
	});
	dsShowDeleting();
}
function ajDeleteSuccess(req){
	noTabSwitches = false;
	dsHideDeleting();
	var res = req.responseText;
	// remove sheet from list, select next
	var i;
	if(res.substr(0,6)=='ERROR:'){
		if(res.substr(6,8)=='LockedBy'){
			var so = sheetObjectById(selectedSheetId);
			if(so){
				so.lockedby = (res.substr(13,999));
				dsUpdateSheetItem(so);
			}
			dsShowError("Sheet is being edited");
		} 
		return;
	}
	for(i = 0; i < savedSheets.length; i++){
		if(savedSheets[i].id == selectedSheetId) break;
	}
	new Effect.BlindUp($('sess'+selectedSheetId),{ duration: 0.5, afterFinish:dsShowSavedSheets });
	// remove element from array
	if(i == savedSheets.length-1){ // last
		if(savedSheets.length == 1){ // no more
			selectedSheetId = null;
		} else {
			selectSheetId(savedSheets[i-1].id);
		}
	} else { // more below
		selectSheetId(savedSheets[i+1].id);
	}
	savedSheets.splice(i,1);
}
function ajDeleteFail(){
	noTabSwitches = false;
}

function ajSaveSession(tAction){
	noTabSwitches = true;
	var ssid = '';
	if(loadedSessionMode == 1 && loadedSessionId) ssid = '&ssid='+loadedSessionId;
	else if(loadedSessionId) ssid = '&id='+loadedSessionId;
	new Ajax.Request(
	"sys/savesession.php", 
	{
		method: 'post', 
		parameters: "name="+escape($('sessionName').value)+"&tm="+getSqlTimestamp()+"&data="+escape(document.sessionData)+ssid, 
		onSuccess: ((tAction=='new')?(ajSaveSuccessNowClear):((tAction=='load')?(ajSaveSuccessNowLoad):(ajSaveSuccess))),
		onFailure: ajSaveFail
	});	
}

function ajSaveSuccess(req, bNoRefresh){
	noTabSwitches = false;
	dsHideSaving();
	var oid = req.responseText;
	var so;
	if(oid.substr(0,6)=='ERROR:'){
		if(bFullScreen) {
			beditor.doAction('togglefullscreen',1);
		}		
		
		var e = oid.substr(6,999);
		var so = sheetObjectByName($('sessionName').value);
		if(e.substr(0,8) == 'LockedBy') {
			if(so){
				so.lockedby = (e.substr(8,999));
				dsUpdateSheetItem(so);
			}
			return dsShowError('Session is locked by another user');
		} else if(e == 'ReadOnly'){
			return dsShowError('Session is read-only');
		} else if(e == 'NotShared'){
			if(so) {
				so.shared = '0';
				dsUpdateSheetItem(so);
			}
			return dsShowError('Session is no longer shared');
		} else if(e == 'NotSharedSavedLocal'){
			ajGetSavedSheets();
			dsShowError('Saved locally. No longer shared.');
			return;
		} else if(e == 'Not logged in'){
			dsShowError('Session expired');
			var expmsg = "YOUR SESSION HAS EXPIRED\n";
			expmsg += "=========================\n";
			expmsg += "This means you became logged out in the process of editing.\n";
			expmsg += "Please log in and try to save again.\n";
			alert(expmsg);
			dsShowSignIn();
		}
		return;
	}
	
	var sessName = $('sessionName').value;

	if(loadedSessionMode != sheetmode) return;

	if(!bNoRefresh){
		selectedSheetId = selectedRenameSheetId = oid;
		selectedSheetName = selectedRenameSheetName = sessName;
	}
	
	if(sheetmode == 0){	
		// loaded sheet replace name & mod
		if(loadedSessionId && loadedSessionId == oid){
			var so;
			so = sheetObjectById(loadedSessionId);
			so.name = sessName;
			so.mod = getTimestamp();
		} else if(li = sheetObjectById(oid)){
			li.mod = getTimestamp();
			selectSheetId(oid);
			dsUpdateSheetItem(li);
		// new item
		} else {
			loadedSessionId = oid;
			return ajGetSavedSheets();
		}
		dsShowSavedSheets();
		
	// shared sheets
	} else {
		// update modtime
		if(loadedSessionId){
			var so;
			so = sheetObjectById(loadedSessionId);
			so.mod = getTimestamp();
			dsUpdateSheetItem(so);
		}
	}
}
function ajSaveSuccessNowClear(req){
	ajSaveSuccess(req);
	beditor.doAction('new');
}
function ajSaveSuccessNowLoad(req){
	ajSaveSuccess(req, true);
	loadSheet(true);
}
function ajSaveFail(req){
	noTabSwitches = false;
	// display warning - server down
}
function ajGetSavedSheets(){
	noTabSwitches = true;
	if(sheetmode == 0){
		new Ajax.Request(
		"sys/getsessions.php", 
		{
			method: 'post', 
			onSuccess: ajGetSuccess,
			onFailure: ajGetFail
		});
	} else if(sheetmode == 1){
		new Ajax.Request(
		"sys/getsharedsessions.php", 
		{
			method: 'post', 
			onSuccess: ajGetSharedSuccess,
			onFailure: ajGetSharedFail
		});
	}
}
function ajGetSharedSuccess(req){
	noTabSwitches = false;
	var res = req.responseText;
	savedSheets = new Array();
	
	if(res == '0') return dsShowSharedSheets(null); // shows empty
	
	// format:
	// f=rawurlencode(fid=USERID&fname=NAME/USERNAME)&s=
	//		rawurlencode(rawurlencode(id=ID,name=NAME,lb=LOCKEDBY,mod=MODIFIED);...);
	res = res.split(';');
	var fs, ss;
	var obj = new Object();
	for(var i = 0; i < res.length; i++){
		fs = res[i].parseQuery();
		fs['f'] = fs['f'].parseQuery(); // fid,fname,li etc
		fs['s'] = fs['s'].split(';'); // rawurlencode(id=ID,name=NAME,lb=LOCKEDBY,mod=MODIFIED)[]
		
		obj['friend'+fs['f']['fid']] = {finfo: fs['f'], sess: new Array()};
		
		for(var j = 0; j < fs['s'].length; j++){
			ss = (unescape(fs['s'][j])).parseQuery();
			savedSheets.push({id:ss.id, rw:ss.rw, name:ss.name, shared:true,lockedby: ss.lb, mod: getTimestamp(sqlDate2Date(ss.mod))});
			obj['friend'+fs['f']['fid']].sess.push({id:ss.id, rw:ss.rw, name:ss.name, shared:true,lockedby: ss.lb, mod: getTimestamp(sqlDate2Date(ss.mod))});
		}
	}
	dsShowSharedSheets(obj);
}
function ajGetSharedFail(){
	noTabSwitches = false;
}
function ajGetSuccess(req){
	noTabSwitches = false;
	var res = req.responseText;
	savedSheets = new Array();
	if(res == '0') return dsShowSavedSheets();
	var chunk, i = 0;
	var chunks = res.split(';');
	while((chunk = chunks[i++])!='0'){
		chunk = chunk.parseQuery();
		savedSheets[i-1] = {id:chunk.id, name:chunk.name, pw:chunk.pw, shared:chunk.sh, lockedby: chunk.lb, mod: getTimestamp(sqlDate2Date(chunk.mod))};
	}
	
	dsShowSavedSheets();
	if(document.openOnLoad){
		selectSheetId(document.openOnLoad);
		DblClickLoad(document.openOnLoad);
		document.openOnLoad = null;
	}
}
function ajGetFail(){
	noTabSwitches = false;
}

// ================================================================		Events
function evFocusTextField(ev){
	var input = Event.element(ev);
	if(input) input.className = 'focus';	
}
function evBlurTextField(ev){
	var input = Event.element(ev);
	if(input) input.className = '';	
}
function evCheckEnterAndSave(e){
	if(e.keyCode == 13) beditor.doAction('save');
}
function evKeyDown(ev){
	if(ev.keyCode == 13 && activeDialogEnter) { activeDialogEnter(); activeDialogEnter = null; return; }
	if(ev.keyCode == 27 && activeDialogCancel) { activeDialogCancel(); activeDialogCancel = null; return; }
	var kc = ((ev.charCode)?(ev.charCode):(ev.keyCode));
	var ctrl = ev.ctrlKey;
	// CTRL + S
	if(ctrl && kc == 83){
		Event.stop(ev);
		if(!activeDialog)
			saveSheet();
		return false;
	}
}
function evResizeWindow(){
	var windowHeight, windowWidth;
	if(window.innerHeight) { 
		windowHeight = window.innerHeight;
		windowWidth = window.innerWidth;
	} else {
		windowHeight = document.documentElement.clientHeight;
		windowWidth = document.documentElement.clientWidth;
	}
	//windowWidth -= 125;
	if(bFullScreen){
		$('header').style.display = 'none';
		$('rpanel').style.display = 'none';
		//if($('advertisewithus')) $('advertisewithus').style.display = 'none';
		$('bubbles').style.top = '5px';
		$('bubbles').style.width = (windowWidth-10)+'px';
		$('bubbles').style.height = (windowHeight-10)+'px';
		if(document.body){
			document.body.style.backgroundImage = 'none';
		}
	} else {
		if(document.body){
			document.body.style.backgroundImage = '';
		}
		$('bubbles').style.top = '70px';
		$('header').style.display = '';
		$('rpanel').style.display = '';
		//if($('advertisewithus')) $('advertisewithus').style.display = '';
		var headerHeight = Element.getHeight($('header'));
		var sponsorsHeight = 0;//Element.getHeight($('sponsors')) + 22; // sponsorsHead
		var rpanelHeight = windowHeight - headerHeight - 10;
		var helpHeight = Math.floor(rpanelHeight * 0.25 * (Number(helpVisible))); // helpHead
		if(helpHeight > 0 && helpHeight < 180 && windowHeight > 500) helpHeight = 180;
		var bubblesWidth = windowWidth - rpanelWidth;
		var controlHeight = rpanelHeight - sponsorsHeight - helpHeight - 110;
		if(controlHeight < 91) controlHeight = 91;
		
		$('bubbles').style.height = rpanelHeight + "px";
		$('help').style.height = helpHeight + "px";
		$('rpanel').style.height = rpanelHeight + "px";
		$('control').style.height = controlHeight + "px";
		$('sessionList').style.height = (controlHeight - 65) + "px"; // save, btns etc.
		$('rpanel').style.width = rpanelWidth + "px";
		$('bubbles').style.width = (bubblesWidth - 10) + "px";
	}
}

// ================================================================		Util

function utMakeButton(element, onClick, buttonHelpTopic, bNoRollovers){
	if(bNoRollovers == undefined) bNoRollovers = false;
	Event.observe(element,'focus',function(ev){ if(!bNoRollovers && Event.element(ev) && Event.element(ev).className!='down') Event.element(ev).className = 'over'; if(buttonHelpTopic) showHelp(buttonHelpTopic);},false);
	Event.observe(element,'mouseover',function(ev){ if(!bNoRollovers && Event.element(ev))Event.element(ev).className = 'over'; if(buttonHelpTopic) showHelp(buttonHelpTopic);},false);
	Event.observe(element,'mouseout',function(ev){ if(!bNoRollovers && Event.element(ev))Event.element(ev).className = 'button';},false);
	Event.observe(element,'blur',function(ev){ if(!bNoRollovers && Event.element(ev))Event.element(ev).className = 'button';},false);
	Event.observe(element,'mousedown',function(ev){ bIgnoreUnload = true; if(!bNoRollovers && Event.element(ev))Event.element(ev).className = 'down';},false);
	Event.observe(element,'mouseup',function(ev){ bIgnoreUnload = true; if(!bNoRollovers && Event.element(ev)) Event.element(ev).className = 'over'; onClick(); },false);
	Event.observe(element,'keydown', function(ev){ bIgnoreUnload = true; if(Event.element(ev) && Event.element(ev).className != 'disabled' && ev.keyCode == 13 || ev.keyCode == 32) onClick(); }, false);
}

function getTimestamp(dt){
	if(!dt)
		dt = new Date();
	var am = 'am';
	var time;
	if(dt.getHours() > 12) { time = dt.getHours()-12; am = 'pm'; }
	else time = dt.getHours();
	time += ':'+((dt.getMinutes()<10)?('0'+dt.getMinutes()):(dt.getMinutes()))+am;
	return monthNames[dt.getMonth()-1]+' '+dt.getDate()+', '+dt.getFullYear()+' at '+time;
}
function sqlDate2Date(sqldt){
	var dt = sqldt.split(' ');
	if(dt.length != 2) return null;
	var d = dt[0].split('-');
	var t = dt[1].split(':');
	var dy = Number(d[0]);
	var dm = Number(d[1]);
	var dd = Number(d[2]);
	var th = Number(t[0]);
	var tm = Number(t[1]);
	var ts = Number(t[2]);
	return new Date(dy, dm, dd, th, tm, ts, 0);	
}
function getSqlTimestamp(){
	var dt = new Date();
	return dt.getFullYear()+'-'+(dt.getMonth()+1)+'-'+dt.getDate()+' '+dt.getHours()+':'+dt.getMinutes()+':'+dt.getSeconds();
}
function sheetObjectById(id){
	var i;
	for(i = 0; i < savedSheets.length; i++){
		if(savedSheets[i].id == id) return savedSheets[i];
	}
	return null;
}
function sheetObjectByName(name){
	var i;
	for(i = 0; i < savedSheets.length; i++){
		if(savedSheets[i].name == name) return savedSheets[i];
	}
	return null;
}