# ****************************************************************************
# Surgeweb javascript - Primary Surgeweb javascript code
# supported by:
#	- sw_ui.js			: User interface handler functions		
#	- sw_core.js 		: Core "webmail" logic / server io code
# 	- sw_windowing.js	: Windowing / layout and display reformatting
#	- sw_util.js		: Utility functions
#	- sw_betapane.js	: Various things that should not be in the final product
#	+ a whole lot of supporting self contained javascript modules 
#   note: all files are optimised into a single compressed download "combined.js"
# ----------------------------------------------------------------------------
#  - Application initialisation
#  - Popup window only funcitons
#  - Various bits left over from development that still need tidying
# ****************************************************************************

dbg("surgeweb js loaded");

||if_set(MARIJN_DEBUG)||
||endif||

# Webmail client logic
var enMSG=1, enFLD=2;

#Global surgeweb object for storage of mailclient level info
var sw = new Object;

# Primary Surgeweb "application intialisation" called after "interface outline" page is
# loaded but has not been populated with any user data yet.
function do_init()
{
	dbg('primary application init function');
	browser_id();
	ajax_init();
	prefs_validate();
	endless_init();
	extend_init(1);
	column3_init();
	panelise();
	cache_dom_nodes();
	menubar_init('menu_bar_main');
	window_manager_init();
	app_menu_init();
	info_panel_init();
	list_fns_init();
	lcol_init();
	init_ui_elements();
	extend_init(2);
#	// This does first and primary resize
	do_layout();
#	// This intentionally goes through timer (else eg sizers do not get correctly placed sometimes)
	do_resize();
	background_init();
	tweak_unfinished_stuff();
	sig_defaults();
	due_soon_init();
	newlook_init();
	window_manager_lateinit();

	do_init_data();

	events_init();
	touch(1);
	check_new_timed();
	check_cal_timed();
	autologout_check();
	xmenu_init();
	lm_init();
	misc_init();
	bookmarking_init();
	compat_warn();
	imgdrop_init();
	policy_init();

#	xol_init_test();
#	qpick_init_test();
#	notify_test();
#	url_hash_test();

	safe_call('dev_test');

||if_set(MARIJN_DEBUG)||
#	safe_call('ink_test');
||endif||

||if_set(newlook_ui)||
	safe_call('custom_bg_init');
	safe_call('custom_bg_drop_init');
||endif||

	fancy_scroll_init();
}


function prefs_validate()
{
	if (!pref.mode) pref.mode='app';
	if (!pref.preview) pref.preview=(pref.mode=='app'?'vert':'none');
	if (!pref.windows) pref.windows=(pref.mode=='app'?'popup':'inline');
	if (!pref.sounds) pref.sounds='all'; 	//pref_sounds
#	pref['confirm_no_ndelete']=false;
	sw.sort_type='date';
	sw.sort_rev='true';
	sw.ajax=true;
	sort_init(pref.sort_order,pref.sort_rev);
	sw.identities_unread={};
	sw.ident_order=[];
	sw.fldnames={};
	sw.conv_limit='';
	sw.conv_search_email='';
	sw.location_warn='';
	if(isIOS) pref.editor_textonly=true;
	sw.cloud_layout='grid';
	if(pref.newcal_view) zc.cur_view=pref.newcal_view;
||iftrue(filter_dev)||
	view_filter_init();
||endif||

||if_set(newlook_ui)||
	pref.preview = new_to_old_layout(pref.newlook_structure);	
||endif||
}


function cache_dom_nodes()
{
	sw.msgs_pane=dge("messages"); //get_panel_node("messages","outer");
	sw.msgs_panelist=dge("messages_list");
	sw.msgs_preview=dge("message_preview");
#	sw.msg_pane=dge("message");

	sw.util = dge("utility");
#	sw.util2 = U;

	sw.menubar=dge("menubar");
	
	sw.search_input=dge("search_input");
	sw.search_limit=dge("search_limit");
	
	sw.status=dge("status");
	sw.busy=dge("busy");
}

function init_fld_inbox()
{
	sw.fld_type=1;
	sw.fld_id='INBOX';
}

function do_init_data(force)
{
	if(!force && sw.data_init_done) return;
	sw.data_init_done = true;
	
	var extra='&tz='+(-((new Date()).getTimezoneOffset())/60*100);
	init_fld_inbox();
	history_init();	
	if(initial_folder.fld_id.length>0){
		sw.fld_id=initial_folder.fld_id;
		sw.fid=initial_folder.fid;
	}	
	if(disable_markread_fld){
		extra+='&disable_markread='+disable_markread_fld;
	}
	if(asap_mid){
		extra+='&msg_id='+asap_mid+'&asap_mid='+asap_mid;
	}
	extra+=clientside_layout();
||iftrue(using_api)||
	apiGet('core/surgeweb_init?v=sw&ident='+sw.ident+'&fld_id='+sw.fld_id+extra+'&sort='+sw.sort_type+'&rev='+sw.sort_rev, function(chan){
||else||
	sndReq('cmd=show&page=~login.js&ident='+sw.ident+'&fld_id='+sw.fld_id+extra+'&sort='+sw.sort_type+'&rev='+sw.sort_rev, function(chan){
||endif||
		actionReqJs(chan);
		switch_selfld(sw.fld_id);
		check_callbacks();
		if(isChrome3 && sw.dnd_disabled==undefined) return;
		msgdnd_init();
		do_resize();
	});
}

function events_init()
{
	document.onkeydown=global_keydown;
	document.onkeyup=global_keyup;
#	dge("messages").onkeydown=msglist_keydown;
#	dge("messages").onkeyup=msglist_keyup;
#	dbg('REG KEYDOWN *************')
	dge("message_preview").onkeydown=preview_keydown;
	
# register manually as a new feature of chrome (v19.0.1084.52) seems to be that it sometimes loses
# html based resize event registration??
	window.onresize=do_resize;
}
function global_keydown(e)
{
#	dbg('document onkeydown'); // KBC: global 
	var ret=true, skipcheck=false;
	var last_mid;
	if (!e) e = window.event;
	if (!e) return;
	touch(2);
# 	Keycode identification code
#	if (true){
#	dbg("keycode="+e.keyCode+" shiftKey="+e.shiftKey+" ctrlKey="+e.ctrlKey+" altKey="+e.altKey+" metaKey="+e.metaKey );
#		stop_def_action(e);
#		return false;
#	}

	// Apply app switching if needed
	if(window.switcher_keydown){
		if(switcher_keydown(e)){
			return false;
		}
	}

	if (!sw.active) return;

	if (modal_dialog()) return;

#	// TODO: sometime check whether below is really needed
	if(class_contains(sw.active,'cloud') || class_contains(sw.active,'calendar')) skipcheck=true;	
	if(!isMac && (e.metaKey||e.altKey) && !e.ctrlKey && !skipcheck) return;

#	if (e.shiftKey==true && class_contains(sw.active,'fldmsg')){
#	Chrome 1.0 returns metakey on altKey!!
	var metakey=e.metaKey && !e.altKey;

	if (pref.mode=='app' && class_contains(sw.active,'fldmsg')/*&&!metakey*/ ){
		ret = msglist_keydown(e);
	}else if (pref.mode=='app' && class_contains(sw.active,'message')){
		ret = message_keydown(e);
	}else if (pref.mode=='app' && class_contains(sw.active,'contacts')){
		ret = contactlist_keydown(e);
	}else if(class_contains(sw.active,'cloud')){
		ret = cloud_list_keydown(e);
	}else if(class_contains(sw.active,'calendar')){
		ret = cal_keydown(e);
	}else{
		ret = msgmenu_keydown(e);
	}

	return ret;
}

var vkUpArrow=38, vkDownArrow=40, vkLeftArrow=37, vkRightArrow=39, vkPgUp=33, vkPgDown=34, vkSpace=32, vkEnter=13, vkTab=9, vkDelete=8, vkBspDel=46, vkEsc=27, vkEquals=187, vkEqualsFF=107,
	vkA=65,vkB=66,vkC=67,vkD=68,vkE=69,vkF=70,vkG=71,vkI=73,vkL=76,vkM=77,vkN=78,vkP=80,vkQ=81,vkR=82,vkS=83,vkU=85,vkV=86,vkY=89,vkZ=90,
	vk1=49,vk2=50,vk3=51,vk4=52,vk5=53,vk6=54, vkDot=190, vkBTick=192, vkColon=186,
	vkMinus=189, vk9=57,vk0=48,vkOpen=219,vkClose=221,
	vkShift=16, vkCtl=17; 
	

function msglist_keydown(e)	// gs_keydown
{
	var ret=true;

	ret = gs_keydown(sw.ml,e);

	switch (e.keyCode){
/*
	case vkUpArrow:
			...
			break;
	case vkDownArrow:
			...
			break;
*/
#	r / Ctrl+R - reply
	case vkR: 
			if(e.metaKey) break;
			do_reply(e);
			ret=false;
			break;
#	f - forward
#	Ctl+Shift+F - quick search					
	case vkF: if (!ctrl_key(e)) {do_forward(e);ret=false;}
			if (ctrl_key(e) && e.shiftKey) {dge('search_input').focus();ret=false;}
			break;
#	G - forward attach
	case vkG: 
			if(e.metaKey) break;
			do_forward_attach(e);
			ret=false;
			break;
#	Ctl+s - search					
	case vkS: 
			if (!ctrl_key(e)) break;
			search_init(undefined,'folder');
			dge('search_input').focus();
			ret=false;
			break;
#	l - Label message
	case vkL:
			if(ctl_cmd_key(e)) {
				 edit_comment(e,'kbd');
				 ret=false;
				 break;
			}
||ifndef||labels_disable||
			labels_menu(e,'kbd');
||endif||
			break;
#	i - Annotate message
	case vkI:
			edit_scomment();
			ret=false;
			break;
			
#	n - Compose new message
	case vkN: 
			if (ctl_cmd_key(e)) return ret;
			if (!ctrl_key(e)) {do_compose(e);ret=false;}
			break;

#	q - quick search (or / or Ctl+Shift+F)
	case vkQ:
	case 191:
			if(ctl_cmd_key(e)) return ret;
			search_init(undefined,'quick');
			if(sw.altui){
				dge('alt_ui_search').focus();
			}else{
				dge('search_input').focus();
			}
			ret=false;
			break;
#	A - Reply All
	case vkA: 
			 if (!ctl_cmd_key(e)) {
				do_reply_all(e);
			 }
			 break;
	case vkEsc:
			 msglist_unsearch();
			 search_init(undefined,pref.search_type);
			 break;
#	M - Move message
	case vkM: 
||if_set(newlook_ui)||
			 if(ctl_cmd_key(e)) {
			 	do_more_show(e, el_by_mode('mnu_more','altmenu_more'));
			 	break;
			 }
||else||
			 if(ctl_cmd_key(e)) return ret;
||endif||
			 move_menu(e,'kbd');
			 break;

	case vkColon:
||if_set(newlook_ui)||
			 if(shift(e)) {
			 	do_more_show(e, el_by_mode('mnu_more','altmenu_more'));
			 	break;
			 }
||endif||
			 break;

#	D - Defer message
	case vkD:
			 if(pref.defer_disable) break;
			 if(ctl_cmd_key(e)) return ret;
			 defer_menu(e,'kbd');
			 break;

#	backtick - QuickPick Compose
	case vkBTick:
# QQTODO			
#			 qpick_menu(e,'kbd');
			 break;
			 
||iftrue(xol_connect)||
	case vkY:
			xol_clicked(e);
			break;
||endif||	

#	ctl Z - Cache messages
	case vkZ: 
			 if (ctl_cmd_key(e)) {
				 if (e.shiftKey){
					 do_select('all');
					 do_cache();
					 do_select('none');
					 msglist_select(gs_cursor_mid(sw.ml));
				 }else{
					do_cache();
				 }
			 }
			 break;

#	enter - show message (in keydown as keyup received after pressing enter on a dialog)
	case vkEnter:
			var c_mid = gs_cursor_mid(sw.ml);
			if (c_mid){
				show_msg(c_mid,e);	
			}
			break;	

#	Stop OSX Delete / backspace based back browsing
	case vkDelete: 
	case vkBspDel:
			if(e.ctrlKey&&e.altKey) break;
			stop_def_action(e);
			ret=false;
			break;

#	ctl shift 1-6 - single keystroke filing
	case vk1:		 
	case vk2:		 
	case vk3:		 
	case vk4:		 
	case vk5:		 
	case vk6:
			if(!(e.shiftKey&&e.ctrlKey)) break;
			var fld=keymap[e.keyCode-48];
			if(fld && fld.length>0)do_move_actual(fld);
			break;
			
	case vkMinus:
			if(ctrl_key(e)) break;
			if(single_modifier(e)){
				focus_toggle('subject');
			}else{
				focus_toggle('from');
			}
			break;

	case vkDot:
		var t=dge(sw.altui?'altmenu_more':'mnu_more');
		do_more_show({target:t});
		break;
	}
	
	return ret;
}


function message_keydown(e)
{
	var ret=true;
	ret = gs_keydown(sw.active.rl /*sw.cl*/,e);
	switch (e.keyCode){
#	Stop OSX Delete / backspace based back browsing
	case vkDelete: 
	case vkBspDel:
			if(ignore_done()) break;
			if(e.ctrlKey&&e.altKey) break;
			stop_def_action(e);
			ret=false;
			break;
	}
	
	return ret;
}

function contactlist_keydown(e)	// gs_keydown
{
	var ret=true;

	ret = gs_keydown(sw.cl,e);
	
	switch (e.keyCode){

#	Stop OSX Delete / backspace based back browsing
	case vkDelete: 
	case vkBspDel:
			if(ignore_done()) break;
			if(e.ctrlKey&&e.altKey) break;
			stop_def_action(e);
			ret=false;
			break;

	}
	
	return ret;
}

function global_keyup(e)
{
	var ret=true;
	if (!e) e = window.event;
	if (!sw.active) return;
	if (pref.mode!='app') return;
	
	if(class_contains(sw.active,'fldmsg')){
		switch (e.keyCode){
#		delete / backspace - delete message(s)
		case vkDelete:
		case vkBspDel: 
				if(e.ctrlKey&&e.altKey) break;
				do_delete(e.shiftKey);
				ret=false;
				stop_def_action(e)
				break;
		case vkEquals:
		case vkEqualsFF:
				if(any_modifier(e)) break;
				do_move_actual(pref.special_done);
				break;
		}			
	} else 	if(class_contains(sw.active,'contacts')){
		switch (e.keyCode){
#		delete / backspace - delete contact(s)
		case vkDelete:
		case vkBspDel: 
				if(ignore_done()) break;
				if(e.ctrlKey&&e.altKey) break;
				contact_remdel(e);
				ret=false;
				stop_def_action(e)
				break;
		}			
	} else 	if(class_contains(sw.active,'message')){
		switch (e.keyCode){
#		delete / backspace - delete message(s)
		case vkDelete:
		case vkBspDel: 
				if(e.ctrlKey&&e.altKey) break;
				do_delete(e.shiftKey);
				ret=false;
				stop_def_action(e)
				break;
		case vkEqualsFF:
		case vkEquals:
				if(any_modifier(e)) break;
				do_move_actual(pref.special_done);
				break;
		}			
	}

	return ret;
}
var ignore_one_del=false;
function ignore_del()
{
	ignore_one_del = true;
}
function ignore_done()
{
	if(!ignore_one_del) return false;
	ignore_one_del=false;
	return true;
}

function preview_keydown(e)
{
	var ret=true;
	if (!e) e = window.event;
	if (!sw.active) return;
	
	if (pref.mode=='app' && class_contains(sw.active,'fldmsg')){
		switch (e.keyCode){
		case vkA:
				 select_el(preview_to_body(dge("message_preview")));
				 ret=false;
				 stop_def_action(e)
				 break;
		}			
	}
	return ret;
}



function msgmenu_keydown(e)
{		
	dbg('msgmenu onkeydown'); // KBC: msgmenu 
#	if('message window' check) - not ideal but this will do for now
	if (!sw.menubar.current) return;
	var isMessage=(sw.menubar.current.id=="menu_message");
	var isEdit=(sw.menubar.current.id=="menu_compose");

	if(isEdit) {
		switch (e.keyCode){
#		escape:
		case 27: 
				if(sw.active.unsaved){
					edit_discard();
					break;
				}
				if (sw.active.tab_ref)
					tab_close(sw.active.tab_ref.id);
				break;
#		Enter
		case 13: 
				if (e.ctrlKey && e.shiftKey)
					do_send();
				if (e.ctrlKey && e.altKey)						
					do_send_move(e);
				break;
#		Ctrl+S - save draft
		case vkS: 
				if (ctrl_key(e)){
					do_save_draft(undefined,function(){sw.active.unsaved=false});
				}
				break;
		}		
	}

	if(isMessage) {
		switch (e.keyCode){
#		escape:
		case 27: 
				if (sw.active.tab_ref)
					tab_close(sw.active.tab_ref.id);
				break;

#		r / Ctrl+R - reply
		case 82: 
				do_reply(e);
				break;
#		f - forward
		case 70: if (!ctrl_key(e)) do_forward(e);
				break;
#		a - reply all
		case 65: 
				 if (!ctl_cmd_key(e)) do_reply_all(e);
				 break;
#		Ctrl+up arrow - prev message
		case 38: 
				 if (ctrl_key(e)) show_prev(sw.is_popup?sw.mid:gs_cursor_mid(sw.ml));
				 break;
#		Ctrl+down - next message
		case 40: 
				 if (ctrl_key(e)) show_next(sw.is_popup?sw.mid:gs_cursor_mid(sw.ml));
				 break;
		}
	}
}

function editor_keypress(e)
{
	if (!e) e = ew.event;
#	dbg("keypress in editor window - code="+e.keyCode);		// NOKEYS!!
#	alert(e.keyCode)
	switch (e.keyCode){
#		Enter
		case 13:
				if(quote_breakout()){
					stopEvent(e);
					return false;				
				}
#				stopEvent(e);
#				return false;
				break;
	}
}

function editor_keydown(e)
{
	if (!e) e = ew.event;
	dbg("keydown in editor window - code="+e.keyCode);			// NOKEYS!!
	switch (e.keyCode){
#		Enter
		case 13: 
#				quote_breakout(e);
				break;
#	Make tab in editor indent text / move to subject edit field
		case 9:
				if (e.shiftKey){
					sw.active.field_subject.focus();
				}else{
					if(isSafari){
#						//Safari on OSX must not stop this event!! 
						return;
					}
					editor_add_html('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
				}
				stopEvent(e);
				return false;
				break;
		case vkV:
				if (ctl_cmd_key(e)) {
					break
					paste_window = get_edit_win();
					toggle_editor("eframe"+sw.active.instance);
					var el=dge('text_paste');
					el.value='a';
					el.focus();
#					stopEvent(e);
#					return false;
				}
				break;
		case vkS: 
				if (ctl_cmd_key(e)){
					stopEvent(e);
					return false;
				}
				break;
				
	}
}

var paste_window=null;
var qq=false;
function editor_keyup(e)
{
	if (!e) e = ew.event;

#	dbg("keyup in editor window - code="+e.keyCode);			// NOKEYS!!
	touch(4);
	switch (e.keyCode){
		case vkEnter: 
				spellcheck_markup_removeall();
				if (e.ctrlKey && e.shiftKey)
					do_send();
				if (e.ctrlKey && e.altKey)						
					do_send_move(e);
#				quote_breakout();
				break;
		case vkEsc: 
#					Grab focus back from iframe and then discard
				window.focus();
				edit_discard();
				break;

#		shift tab
#		case 9:
#				if (e.shiftKey){
#						window.focus();
#					sw.active.field_subject.focus();
#				}else{
#					dbg("*** tab in editor");
#				}
#				break;
#		Ctrl+S - save draft
		case vkS: 
				if (ctrl_key(e)){
					do_save_draft(undefined,function(){sw.active.unsaved=false});
				}
				break;

		case vkI:
		case vkB:
		case vkE:
		case vkL:
				if (ctl_cmd_key(e)){
					set_sendmode_html();
				}
				break

#		space character
#		case 32:
#				spellcheck_markup_remove(e);
#				drop through to default				
		default:
#				clear_spellcheck_squiggle(e);
#				dbg('** default unsaved='+sw.active.unsaved)
				sw.active.unsaved=true;
				if(!autosave_timer){
					dbg('** starting autosave timer')
					autosave_timer=setTimeout(draft_autosave,(pref.devt_mode?4:120)*1000);
				}
				break;
	}
//		updateTimer();
}
function editor_paste(e)
{
	if(false){
		paste_window = get_edit_win();
		var el=dge('text_paste');
		el.value='b';
		el.focus();
		toggle_editor("eframe"+sw.active.instance);
	}else{
#		stopEvent(e);
		if(isFF){
			wait_for_paste1();
		}else if(isSafari || isChrome){
			if(isChrome){		
				var items = (e.clipboardData || e.originalEvent.clipboardData).items;
				var blob = items[0].getAsFile();
			}else{
#				Does not seem to work on safari??				
				var blob = e.clipboardData.getData(e.clipboardData.types[1]);
			}
			if(blob){
				var reader = new FileReader();
				reader.onload = function(evt){		// cf:check_mpr_images
					pre_images = editor_images();
					editor_add_img(paste_uploading());
					var el = image_added(pre_images);
					prcc_image_url(evt.target.result,el);
				}; // data url!
				reader.readAsDataURL(blob);
				e.preventDefault();
			}
		}
	}
}
var pre_images, pre_time;
function wait_for_paste1()
{
	// Store img nodes
	pre_images = editor_images();
	pre_time = mtime();
	wait_for_paste2()	
}
function wait_for_paste2()
{
	if(mtime()-pre_time>1500) return;
	var el = image_added(pre_images);
	if(el==null){
		setTimeout(function(){wait_for_paste2();}, 20);
		return;
	}
	prcc_image_url(el.src, el);	
	el.src=paste_uploading();
}
function paste_uploading()
{
	return "||www||img/busy.gif?||vz||";
}
function editor_images()
{
	var xwin=get_edit_win();
	var images = xwin.document.getElementsByTagName('img');
	var actualImages = new Array();
	for(var i = 0, n = images.length; i < n; i++) {
	    var row = images[i];
	    actualImages.push(row);
	}
	return actualImages;
}
function image_added(pre)
{
	var post_images = editor_images();
	if(pre.length==post_images.length) return null;
	for(var i=0;i<post_images.length;i++){
		var found = false;
		for(var j=0;j<pre.length;j++){
			if(post_images[i]===pre[j]){
				found=true;
				break;
			}
		}
		if(!found){
			return post_images[i];
		}
	}
	return null;
}

function prcc_image_url(url,el)
{
	var node,win,src_win;
	if(sw.is_popup){
		node=sw.active;
		node.sw_win = sw_win;
		node.is_popup=true;
		win=sw_win;// Pass the send through the parent frame if we can
	}else{
		win=window;
		node=sw.active;
	}
	src_win=window;

	var i = url.indexOf(',');
	if(i==-1) return false;
	var img = atob(url.substring(i+1));
	var l = img.length;
	var jmsg = sw.active.jmsg;
	set_sendmode_html();
	win.ajax_paste_upload(jmsg, img, function(att,att_mpr){
		attach_init(jmsg);
		check_mpr_images(jmsg,win.g_new_attach);
		remove_node(el);
	});			
}


function textpaste_keyup(e)
{
	if (!e) e = ew.event;
	touch(4);
	switch (e.keyCode){
		case vkV:
				if (false&&ctl_cmd_key(e) && paste_window!=null) {
					var el=dge('text_paste');
					paste_window.focus();
					var pasted = lf_2_br(clean_double_lf(el.value));
					editor_add_html(pasted)
					paste_window=null;
					toggle_editor("eframe"+sw.active.instance);
					break;
				}
				break;
	}
}


var autosave_timer;
function draft_autosave()
{
	autosave_timer=null;
	if(sw.menubar.current.id!="menu_compose") return;
	if(sw.active.unsaved){
		do_save_draft(true,function(){sw.active.unsaved=false});
	}
}



function popup_keydown(e)
{
	if (!e) e = window.event;
	if (!e) return;
	msgmenu_keydown(e);

#	dbg("keycode="+e.keyCode);		// NOKEYS!!
}
var ignore_one_hide=false;
document.onclick=function(e){
	if (!e) e = window.event
	if (!e) return;

	
#	t=target(e);
	dbg('*Q* document.onclick hide='+ignore_one_hide)
#	if(class_contains(t,'shadow')) return;
	if (global_active_menu){
		if(ignore_one_hide){
			ignore_one_hide=false;
			return;
		}
		dbg('ONCLICK DOCUMENT hiding menu')
		menu_hide2(global_active_menu);
	}

	var t = target(e);
	if (t.tagName=="A"){
		dbg('clicked on link id='+t.id+' href='+t.href);

		return;
		if (t.href.substring(0,7)=='http://' && !confirm('$$st_external_link$$')){
			return stopEvent(e);
		}
	}
}

function edit_subject_keydown(e)
{
	switch (e.keyCode){
#	enter - eat enter keys to prevent default form actions in edit fields
	case 13:
			focus_next_surgeweb_edit_ctl(target(e));
			stopEvent(e);
			return false;
			break;	
	}
}

# ***** Functions for use from popup msg / edit window only *****

function do_popup_init()
{	
	sw_win = window.opener;
#	// Make sure that the object in or calling window has been instanciated
	var pp=sw_win.pending_popups[window];
	if(!pp){
#	//	Just for what seems to be bug in Microsoft Edge!!		
		pp=sw_win.pending_popups[sw_win];
	}
	if (!pp){
		setTimeout(do_popup_init,20);
		return;
	}

	dbg('attaching debug output to main window for central logging');
	dbg=sw_win.dbg;
	dbg('*** POPUP message window attached ***');
	
	browser_id();

	sw.util=document.getElementById("utility");
	sw.menubar=document.getElementById("menubar");

	var container=document.getElementById('message_container');
	container.popup_message=document.getElementById('message_panel');
	container.popup_compose=document.getElementById('compose_panel');
	container.popup_message.container=container.popup_compose.container=container;

	set_sw_active(container.popup_message);

	if ('||panel_mode||'=='orig_x'){
		panelise_roundtop(document.getElementById('menubar'),enHdr);
		panelise_square(container.popup_message,enBody3);
		panelise_square(container.popup_compose,enBody3);
		panelise_square(document.getElementById('sw_footer'),enBot);
	}else{
		panelise_plain(document.getElementById('menubar'),enHdr);
		panelise_plain(container.popup_message,enBody3);
		panelise_plain(container.popup_compose,enBody3);
		panelise_plain(document.getElementById('sw_footer'),enBot);
	}

#	document.getElementById("sid").innerHTML = sw_win.sid;
	sw.is_popup=true;
	sw.ajax=true;
	
	sid = sw_win.sid;
	sw.type = pp['type'];
	sw.jmsg = pp.jmsg;
	// Possible remove these two (still being used by popup switch to edit)
	sw.mid = pp.jmsg.cache_mid;
	sw.ident = pp.jmsg.ident;
	sw.fld_id = pp.jmsg.fld_id;
	sw.fid = pp.jmsg.fid;
	sw.fld_type = pp.jmsg.fld_type;

	if(sw_win.skin_location.length>0){
		load_dynamic_css(sw_win.skin_location+'/skin.css?||vz||');
	}

#	this all seems a bit juck and maybe should be store in one place??	
	pref_reply=sw_win.pref_reply;
	class_add(document.body,sw_win.pref_colour);
	email=sw_win.email;
	sw.signatures=sw_win.sw.signatures;			//QQSIG
	sw.sig_order=sw_win.sw.sig_order;
	sw.identities=sw_win.sw.identities;
	pref.cur_signature=sw_win.pref.cur_signature;
	pref.compose_sticky=sw_win.pref.compose_sticky;
	pref.hide_fdnd_info=sw_win.pref.hide_fdnd_info;
	pref.editor_textonly=sw_win.pref.editor_textonly;
	pref.vault_lock=sw_win.pref.vault_lock;
	pref.vault_ifnew=sw_win.pref.vault_ifnew;
	pref.hide_surgevault=sw_win.pref.hide_surgevault;
	pref.sim_enable=sw_win.pref.sim_enable;
	pref.send_mode=sw_win.pref.send_mode;
	pref.attach_flash=sw_win.pref.attach_flash;

	sw.jmsg.instance=sw_win.instance;
	unique_instance(document.getElementById('message_container'), sw_win.instance++);

	if(pref.devt_test!='nounload'){
		window.onbeforeunload=function(){if(sw.type=='edit'&&!sw.closing) return "";}
	}
	document.onkeydown=popup_keydown;

	show_xxx_complete_popup();
	init_ui_elements();
	popup_resize();
	setTimeout(function(){
		popup_resize();
	},100);
	
	window.history.replaceState({}, 'title', '/surgeweb/message_info?id='+clean_folder_text(sw.fld_id)+'/'+sw.mid);
}

function clean_folder_text(folder_text)
{
	var fld_parts=folder_text.split('/');
	if(fld_parts[0]=='INBOX') fld_parts[0]='Inbox';
	return fld_parts.join('/');
}

function popup_resize(){
	xx['mnu_h']=panel_correct(sw.menubar).offsetHeight+3;
	xx['screen_h']=ClientHeight();
	
	if (sw.type=='msg'){
		sw.active.style.height=px(xx['screen_h']-(xx['mnu_h']+footer)); 
	}else{
		xx['chdr_h']=sw.active.compose_header.offsetHeight;
		var ef = sw.active.field_xeframe.firstChild;
		ef.style.height=px(xx['screen_h']-(xx['mnu_h']+xx['chdr_h']+footer)-||panel_gap||);
		
		if(pref.editor_textonly){
			ef.style.height=px(xx['screen_h']-(xx['mnu_h']+xx['chdr_h']+footer)-||panel_gap||-24);
			ef.style.width=px(ClientWidth()-panel_gap*2-24-4);
		}else{
			ef.style.height=px(xx['screen_h']-(xx['mnu_h']+xx['chdr_h']+footer)-||panel_gap||);
		}
		
	}
}
function do_delete2(id,fld_id,refresh)
{
	if(!fld_id) fld_id=sw.fld_id;
	var sel=make_sel(sw.fld_id,id);
	if(refresh) sel.refresh=true;
	set_status("$$st_stat_del$$","info");
	ajax_delete(sel);
}

function do_move2(id)
{
	var sel=make_sel(sw.fld_id,id);
	set_move_status(sel,t.fname);
	ajax_msg_move(sel,t.fname);
}

function set_move_status(sel,fld,forever)
{
	if(forever){
		set_status('$$st_stat_forever$$',"info");
	}else{
		set_status($('$$st_stat_moving_to$$',fld_id2name(fld)),"info");
	}
}


# ****************************************************************
# Stuff left over from development I've not cleaned up yet... Not sure how much is essential


var temp_stuff;
var window_list;
var window_uid=0;

var banner_height=||banner_height||;
#var left_column=145;
var right_column=0;
var footer=0;	//22
#var pane_ratio=0.5;

var instance=1;
inline_loading='msg';

x_M_param=false;

# Original show message code - only still used for preview display I believe old function M(
function msg_show_preview(mid, extra, type, nofocus, nostatus, disable_markread)
{
	// hack for now!! see if we can fix properly sometime??
	if(pref.newlook_layout=='modern1'){
		var el = dge('message_preview');
		class_remove(el,'hidden');
	}

	dbg("Message id=="+mid+" display 1");
	if (seen_timer) clearTimeout(seen_timer);

	prescroll_reset();
	
	var destination=(pref.mode=='app'?'message_preview':'message');	
	dbg("destination="+destination)
	if (x_M_param) {destination='message';x_M_param=false;}

	destination='message_preview';
	
	if (destination!='message_preview') {
		fldmsg_display(enMSG);
		sw.msg_pane.menu_ref=sw.menubar.menus["menu_message"];
		window_manager_newtab(sw.msg_pane,'message');
	}
	gs_set_cursor_mid(sw.ml,mid);
	var xid = cache_id(sw.ident,sw.fid,mid);
	preload_find_next(mid);

	var recent = retrieved_recently(mid);
	var cached = sw_cache && cache_find(xid);
	if(recent && !cached){
		// Need to wait for separate outstanding web request to complete
		set_loading(destination);
		await_msg(sw.fld_id,mid,function(){
				var qmsg=cache_find(xid);
				assign_destination_html(destination,mid,html_from_qmsg(qmsg,'1 '+xid));
				special_processing(destination,qmsg);	

				if(!disable_markread && !pref.markread_onopen) mark_read(gs_cursor_mid(sw.ml),true,type);	
				check_rrcpt(qmsg);
				update_replyedit(qmsg);
				animate_in_msg();
				prescroll_msg(qmsg);				
				preload_cache_next();
		
			},extra,nostatus,1000);
								
	}else if(cached){
		dbg("attempting to load message id="+mid+" from cache");
		var qmsg=cache_find(xid);
		assign_destination_html(destination,mid,html_from_qmsg(qmsg,'1 '+xid));
		special_processing(destination,qmsg);	
# _scroll_not_yet_
#		dge("message_preview").scrollTop=dge("msg_headers").scrollHeight;

		if(!disable_markread && !pref.markread_onopen) mark_read(gs_cursor_mid(sw.ml),true,type);	
		check_rrcpt(qmsg);
		update_replyedit(qmsg);
		animate_in_msg();
		prescroll_msg(qmsg);				
//		xol_activity('reading',qmsg2rcpt(qmsg),'none');	
		preload_cache_next();
	}else{
		if (!extra) extra="";
		set_loading(destination);
		retrieve_msg(sw.fld_id,mid,function(chan){
				M_cb(chan,destination,type,mid,disable_markread);
				var xid=cache_id(sw.ident,sw.fid,mid);
				var qmsg=cache_find(xid);
				
				check_rrcpt(qmsg);				
				update_replyedit(qmsg);
				animate_in_msg();
				prescroll_msg(qmsg);				
//				xol_activity('reading',qmsg2rcpt(qmsg),'none');			
			},extra,nostatus);
	}
	if (pref.mode=='web') 
		do_select('none');
	if(type!='initial')
		msglist_select(mid,undefined,nofocus);	
}

function M_cb(chan,destination,type,mid,disable_markread)
{
	doneloading();
	var success=actionReqJsStat(chan);
	var xid=cache_id(sw.ident,sw.fid,mid);

	cache_add(xid,amsg);
	var qmsg=cache_find(xid);
	assign_destination_html(destination,mid,html_from_qmsg(qmsg,'2 '+xid));
#	dge(destination).innerHTML=amsg.html;
#	actionReqSethtmlStat(chan.responseText,destination);
#	if (global_auth_error) {
#		global_auth_error=false;
#		return;
#	}
	special_processing(destination,qmsg);	
	if(!disable_markread && !pref.markread_onopen) mark_read(mid,true,type);
}

function Mx(txt)
{
	fldmsg_display(enMSG);
	message_preview_real_el(sw.msg_pane).innerHTML='<div class="nomessages">'+txt+'</div>';
}

function preview_from_cache(sel,type,disable_markread)
{
	if(!sel) return false;
	var mid=sel[0];
	var destination=(pref.mode=='app'?'message_preview':'message');	
	var xid=cache_id(sel.ident,sel.fid,mid);
	if(!(sw_cache && cache_find(xid))) return false;
	dbg("attempting to load message id="+mid+" from cache");
	var qmsg=cache_find(xid);
	if(!qmsg) return false;
	assign_destination_html(destination,mid,html_from_qmsg(qmsg,'3 '+xid));
	special_processing(destination,qmsg);	
	if(!disable_markread && !pref.markread_onopen) mark_read(gs_cursor_mid(sw.ml),true,type);	
	check_rrcpt(qmsg);
	update_replyedit(qmsg);
	return true;
}


# Old style display layout - still partly used

// (Restore the fldmsg display if something else is shown)
// (and make sure that an acceptable msg / fld pane is actually visible)
function fldmsg_display(type)
{
	var a
	var util=sw.util;

	dbg('fldmsg_display');

#	Minimise any other displays
	if(util.active && !class_contains(util.active,'fldmsg'))
		window_manager_minimise(util.active);

#	class_remove(dge('sizer2'),'hidden');
#	If no request, just switch back to last
	if (type==undefined){
		type=util.fldmsg_current;
	}
# 	If there is a request but last is on, just switch back to last	
	if (type&util.fldmsg_current)
		type=util.fldmsg_current;
#	Actually layout the panes		
	layout_fldmsg(type);
	if(sw.msglist_refresh){
		sw.msglist_refresh=false;
		FolderShow(sw.fld_id);
	}
}
// Arranges the folderlist and message display mode dependant on preferences
function layout_fldmsg(mode)
{
	var oldmode=sw.util.fldmsg_current;

	if (sw.altui){
		altui_hide_utility();
	}

	var maintab=sw.msgs_pane.tab_ref;
	if(!(class_contains(panel_correct(maintab),'selected'))){
		window_manager_minimise(sw.active,true);
		restoreMsgFromTab(maintab);			// <<<<
	}	
#	dbg('layout_fldmsg early');
	if (!sw.msgs_pane) {alert("not init");return;}
	
	if (mode>0) 
		sw.util.fldmsg_current=mode;

	dbg('layout_fldmsg mode='+mode);

#	// All hidden
	if (mode==0){
		class_add(panel_correct(sw.msgs_pane),'hidden');
#		class_add(panel_correct(sw.msg_pane),'hidden');
		set_sw_active(U);
	}
#	// List only display	
	else if(mode==enFLD){					
		menu_set("menu_bar_main");
		class_remove(panel_correct(sw.msgs_pane),'hidden');
		sw.msgs_panelist.style.height="";
#		class_add(panel_correct(sw.msg_pane),'hidden');
		set_sw_active(sw.msgs_pane);		// <<<<
	}
#	// Message only display	
	else if(mode==enMSG){
		menu_set("menu_message");
		class_add(panel_correct(sw.msgs_pane),'hidden');
#		class_remove(panel_correct(sw.msg_pane),'hidden');
#		sw.msg_pane.style.height="";
#		set_sw_active(sw.msg_pane);
	}
}

# This is a bit of a hack... but will do for now, lets see if we can improve later
function tweak_unfinished_stuff(){
	var o;
	o=dge("app_menu"); if (o) set_panel_bottom_border_color(o,"#8FC1E6")
	o=dge("beta_panel"); if (o) set_panel_bottom_border_color(o,"#FFFFD1")
}

# ** Still used to update the main central pane **
var util_body_style = enBody3;
function panel_show_old(id,resize)
{
	if(sw.altui){
		var util_pane = dge('utility_alt');
		if(id=='calendar' || id=='contacts'){
			class_remove(util_pane,'utility_show_scrollbar');		
		}else{
			class_add(util_pane,'utility_show_scrollbar');
		}

		var menu_container =  dge('utility_menubar');
		menu_container.innerHTML='';
		if(sw.menubar && sw.menubar.current && sw.menubar.current.id!='menu_bar_main'){
			sw.menubar.current=U;
			if(sw.menus && sw.menus[id]) sw.menus[id]=U;
		}
	}
	var menu=dge(id+"_menu")
	if(menu) class_remove(menu,'hidden')
	var menu=menu_set(id+"_menu");
	if(sw.altui){
		var menu_container =  dge('utility_menubar');
		menu_container.appendChild(menu);
	}
	
	var panel=document.getElementById(id+'_panel');
	if (pref.panelise && !sw.altui)
		panelise_square(panel,util_body_style);
	panel.menu_ref=menu;
	set_sw_active(panel);
	
	sw.active.resize=resize;
	do_resize_real();
}
# TODO(marijn) remove panel_show_old2 codepath
function panel_show_old2(id)
{
#	var menu=menu_set(id+"_menu");
	var message=document.getElementById('message_panel');
	var compose=document.getElementById('compose_panel');

	message.parentNode.sw_message=message;
	compose.parentNode.sw_compose=compose;

	if (pref.panelise){
		panelise_square(message,util_body_style);
		panelise_square(compose,util_body_style);
	}
	message.menu_ref=sw.menubar.menus["menu_message"];
	compose.menu_ref=sw.menubar.menus["menu_compose"];
	menu_set("menu_message");
#	setTimeout('init_editor("eframe");',100);	
	set_sw_active(message);
	do_resize_real();
}


# *** Core layout switching routine (NEEDS TIDYING) ***

# Window layout variables
var layout_type;
var preview=false;

var list_h=0;
var last_cc_h=-1;

function do_layout()
{
	dbg('>> do_layout');

#	if (type.length<1) type="a2v";
#	if (type==layout_type) return;

	var mnu=document.getElementById("layout_menu");
	var ml=document.getElementById("messages_list");
	var ml_bx=document.getElementById("msglist_box");

	var msg_p=document.getElementById("message_preview");
	var sz2=document.getElementById('sizer2')
#	var div3=document.getElementById("message_preview");
	class_add(mnu,'hidden');

# 	convert new preferences into old set call (function below should be rewritten, to not need this)
	var type='';
	switch(pref.mode){
		case'app':type+='a';break;
		case'web':type+='w';break;
	}
	switch(pref.preview){
		case'horiz':type+='2h';break;
		case'vert':type+='2v';break;
		case'none':type+='1';break;
	}
		
	if (type=='w1') { 
		layout_fldmsg(enFLD); 
		class_add(msg_p,'hidden'); 
		class_remove(ml_bx,'a2h_list'); 
		ml_bx.style.height="";
		ml_bx.style.width="";
	}
	if (type=='a1') { 
		layout_fldmsg(enFLD); 
		class_add(msg_p,'hidden'); 
		class_remove(ml_bx,'a2h_list'); 
		ml_bx.style.width="";
#		preview=false;
	} 
	if (type=='a2h') { 
		layout_fldmsg(enFLD); 
		class_remove(msg_p,'hidden'); 
#		class_add(sz2,'hidden'); 
		class_add(ml_bx,'a2h_list'); class_remove(msg_p,'a2v_msg');
	}
	if (type=='a2v') { 
		layout_fldmsg(enFLD); 
		class_remove(msg_p,'hidden'); class_remove(sz2,'hidden'); 
		class_remove(ml_bx,'a2h_list'); class_add(msg_p,'a2v_msg');
	}
	
#	if (layout_type){
#		pref_layout=type;
#		ajax_pref_save('pref_layout='+pref_layout);
#	}
	layout_type=type;

	if (type.indexOf('2')!=-1){
#		class_remove(sz2,'hidden');
		var x_list=document.getElementById('msglist_box')
		var x_ban=document.getElementById('top_banner')
		var x_mnu=panel_correct(document.getElementById('menubar'))
#		x.style.top=(q.offsetTop+x_list.offsetHeight)+'px';
		if (type=='a2v') {
#			sz2.style.top=(x_ban.offsetHeight+x_mnu.offsetHeight+x_list.offsetHeight+2)+'px';			
			dbg("*** ban="+x_ban.offsetHeight+' mnu='+x_mnu.offsetHeight+' list='+x_list.offsetHeight)
			preview='v';
		}else{
			preview='h';
		}
	}else{
		class_add(sz2,'hidden');
		preview=false;
	}
	
	var switcher=document.getElementById('switcher');
	if (pref.windows=='tabbed'){
		class_remove(switcher,'hidden');
	}else{
		class_add(switcher,'hidden');
	}	

	// temporary for debugging
	if (pref.windows=='inline'){		
		class_remove(document.getElementById('msg_menu_back'),'hidden');
		if(pref.devt_mode){
			class_remove(switcher,'hidden');
		}
	}

	do_resize_real();
}

function app_menu_init()
{
	var el, want_cal=false;;
	if (pref.no_blogs){
		var el = document.getElementById("app_blogs");
		if(defined(el)){
			class_add(el, 'hidden');
		}
	}
	if(pref.newcal){
		want_cal=true;
	}

	if (pref.no_surgeplus){
		class_add_id('app_filestore','hidden');
		class_add_id('app_photos','hidden');
	}else{
		want_cal=true;
	}
	if(!want_cal){
		class_add_id('app_calendar','hidden');
	}
	app_menu('mail',dge('app_mail'));
}

var first_message='';
function set_first_message(id,keep_selection,disable_markread,no_select,nostatus,type,opt)
{
	if(!opt) opt={};
	if(opt.endless) return;
	if(type=='opanel'){
		var node=sw.active;
		if(!node || !node.rl) return;
		gs_select_bymid(node.rl,id);
	}else{
		if(istrue(keep_selection)||(sw.search_input.valid)){
			first_message=id;
		}else{
			message_preview_real_el(dge('message_preview')).innerHTML='<div class="nomessages">$$st_info_nomsg_sel$$</div>';	

			if(no_select) return;
			if(id.length>0 && pref['message_done_action']!='none'){
				msglist_select(id);
				if(pref.preview!='none' && !pref.alt_ui || pref.newlook_layout=='modern1'){
					setTimeout(function(){msg_show_preview(id,'','initial',undefined,nostatus,disable_markread);},0);
				}
			}
		}
	}
}
function set_folders(txt)
{
	var el=dge('folders');
	el.innerHTML=txt;
	el.onclick=folder_click;
	clear_folder_menu('folder_menu');
}
function check_accounts()
{
	if(idents()<2) return;
	check_new_mail(true);
}

var last_check_new = time();
function check_new_mail(first)
{
	if(last_check_new>time()-2 && !first) return;
	queued_req_add( enBG, 'check_mail', function(first){
		var extra = '';
		if(disable_markread_fld){
			extra+='&disable_markread='+disable_markread_fld;
		}
		extra+=clientside_layout()+'&bg=true';
||iftrue(using_api)||
		apiGet('core/check_mail?v=sw&idle=true&fld_id='+sw.fld_id+'&conv_limit='+sw.conv_search_email+extra+iid()+(first?'&init_accounts=true':''), function(chan){
||else||
		sndReq('cmd=check_mail,show&page=~result.js&idle=true&fld_id='+sw.fld_id+'&conv_limit='+sw.conv_search_email+extra+iid()+(first?'&init_accounts=true':''), function(chan){
||endif||
			if (chan.status!=200){
				success_string=err_general(chan,1);
				set_status('$$st_newchk_fail$$ '+success_string,'warning');
				update_ssb_status(-1);
				if(!first) check_new_timed_complete();
				return;
			}
			var success=actionReqJsStat(chan);
			if(!success){
				update_ssb_status(-1);
				if(!first) check_new_timed_complete();
				return;
			}
			if(first){
				checknew_last=time();
				return;
			}else{
				check_new_timed_complete();
			}
			if (sw.folder_check && sw.folder_check<time()-10*60)
				refresh_flds();
				
		},ch[enBG]);
	},first);
}

function new_mail(n,ids,updating)
{
	var txt=(updating?'':$('$$st_newchk_refresh2$$',' <a href="#" onclick="FolderShow(\'INBOX\',{fld_type:1,refresh:true})">','</a>'));
	set_status( $('$$st_newchk_refresh$$',n,plural(n),txt),'success');
	if(pref.alert_eml=='popup'){
		new_mail_popup(n,ids);
	}
	if (pref.sounds=='new' || pref.sounds=='all') 
		new_mail_sound();
	
#	var sel=make_sel(fld,mid);
	var sel=[ids];
 	sel.fld_id='INBOX';
 	sel.fld_type=1;
	ajax_cache_messages(sel,true);
}

var checknew_timer;
var checknew_next;
var checknew_last=time();
function check_new_timed()
{
	if (pref.nocheck) return;
	if (pref.devt_test=='nobg') return;

	dbg('***** check_new_timed');
	var t=time();
	dbg('last_check='+(t-checknew_last) +' untouched='+(t-sw.last_action));
	var untouched=t-sw.last_action;
	if (need_backoff(t)){
		wait=backoff_time-t;
		dbg('***** backing off for '+wait+'s');
	}else if (t-checknew_last>(15*60)) {
#		Computer has probably been asleep or something, pretend we touched it to 
#   	get status updates coming again asap.
		touch(9);
		wait=4;
	}else if (untouched<(5*60)){
		wait=20;
	}else if (untouched<30*60){
		wait=60;
	}else{
		wait=5*60;
	}
#	wait=30;

	checknew_next=t+wait;
	dbg('Last user action '+untouched+'s ago, new mail check in '+wait+'s');
	checknew_timer = setTimeout(function(){
		dbg('checking new mail')
		if(window.swlogin_pending){
			check_new_timed_complete();
			return;
		}
		check_new_mail();
	},wait*1000);
}
function check_new_timed_complete()
{
	check_new_timed();
	checknew_last=time();
}

var backoff_time;
function set_backoff(wait)
{
	dbg('*************** backoff request for '+wait+'s');
	backoff_time=time()+wait;	
}
function need_backoff(tm)
{
	if(!backoff_time) {
		dbg('********* NO backoff needed');
		return false;
	}
	if(tm>backoff_time){
		dbg('********* NO backoff needed');
		return false;
	}
	return true;
}


function check_idle()
{
	return time()-sw.last_action>60?true:false;
}
function upgraded_and_safe()
{	
	dbg('fluid check: upgrade_pending='+sw.upgrade_pending+' check_idle='+check_idle()+' ('+sw.last_action+')'+' tabs='+dge('switcher').childNodes.length);
	return sw.upgrade_pending&&check_idle() && dge('switcher').childNodes.length==1?true:false;
}

var autologout_timer;
var autologout_ignore_once = false;
function autologout_check()
{
	if(pref.autologout_type=='off') return;
	var t=time();
	var untouched=t-sw.last_action;
	if (untouched>(pref.autologout_period*60)){
		if(t-checknew_last>(15*60) && !autologout_ignored_once){
			autologout_ignored_once = true;
		}else{
			var mins = Math.round(untouched/60);
			do_logout($('$$st_autologout_info1$$',mins)+'<br>$$st_autologout_info2$$');
			return;
		}
	}else{
		autologout_ignored_once = false;
	}

	autologout_timer = setTimeout(function(){
		autologout_check();
	},10000);
}

# ***



function vtab_init(prefix,item)
{
	var divs=document.getElementById("options_tabs").getElementsByTagName('div');
	for(var i=0;i<divs.length;i++){
		id=divs[i].id;
		if(id.substring(0,2)=="ot") class_remove(divs[i],"selected");
		if(id.substring(0,2)=="ob")	class_add(divs[i],"hidden");
	}
	class_add(document.getElementById("ot"+item),"selected");
	class_remove(document.getElementById("ob"+item),"hidden");
	if(item==1 && class_contains(dge('usercgi_general_iframe_other'),'hidden')){
		options_show_iframe('usercgi_general_iframe',false);
	} else if(item==2 && class_contains(dge('usercgi_filter_iframe_other'),'hidden')){
		options_show_iframe('usercgi_filter_iframe',false);
	} else if(item==5 && class_contains(dge('usercgi_extra_iframe_other'),'hidden')){
		options_show_iframe('usercgi_extra_iframe',false);
	}
}


# **** 
function pct_clean(s) {
	return s.replace(/%%/g,'%')
}
function quota_info() {
	if(!sw.quota) return('$$st_quota_unlimited$$');
	return pct_clean($('$$st_quota_pct$$',sw.quota.pct,sw.quota.limit));
}

function do_extra_status()
{
	info = '<div style="height:450px;">';
	info +='<div id="status_debug" style="float:right;width:50%;">';
	info += '$$st_status_browser$$ '+UA;
	info += '<p>$$st_status_history$$ ';
	info += '<div style="height:350px; overflow-y:scroll;overflow-y:scroll;padding:3px;border:1px solid #999;">'+status_debug()+'</div>';
	info +='</div>';	
	
	
	info += '<p>$$st_status_quota$$ '+quota_info()+'<br>';
	info +='$$st_status_ident$$ '+idents()+'<br>';
	info +='$$st_status_cached$$ '+sw_xcache.length+'<br>';
	info +='$$st_status_contacts$$ ';
	for(i=0;i<abooks.read_books.length;i++){
		abook=abooks.read_books[i];
		info += abook+'='+abooks[abook].data.length+' ';
	}
	info +='<br>';
	info +='$$st_status_calls$$ mtime()='+time_calls+' BAD='+time_bad+'<br>';	
	info +='$$st_status_flash$$ '+sw.swf_version;	
	info +='<p>$$st_status_channels$$ ';
	info +='<div style="height:287px; width:45%;overflow-y:scroll;padding:3px;border:1px solid #999;margin-right:20px;">'+qchan_debug()+'</div>';	
	info += '</div>';
	x_custom_dlg('',info,
		function(btn){
			if(!btn) return;
			if(btn==2) setTimeout(do_extra_status,0);
			if(btn==1) status_reportall()
		}, function(){
			btn_set(dge('dlg_ok'),'$$st_status_report$$',U,150);
			class_add(dge('dlg_ok'),'fault_report_button');
			btn_set(new_button('name',2,dge('dlg_ok')),'$$st_status_refresh$$','mr');
			btn_set(dge('dlg_cancel'),'$$st_cmd_close$$');		
		}, {'tall':true,'width':0.9,'nopad':true});
}

function attachment_add_jmsg(node,att)
{
	if(sw.is_popup) return sw_win.attachment_add_jmsg(node,att);
	aq_attachment_jmsg_addone(node,att);
}

function do_attach_init(button)
{
	if(sw.active.jmsg.action=='redirect'){
		alert('$$st_redirect_locked$$');
		return;
	}
	var ret=aq_init(sw.active);
	if (button && !ret)
		alert('$$st_info_attach_new$$');
}

function do_attach_removeall()
{
	aq_removeall(sw.active);
}
function do_attach_remove_plain(id)
{
	aq_remove(sw.active, id);
}


function get_cookie(name) {
#alert(document.cookie)

    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    } else {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1) {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}


function xmenu_init(){
	xmenu_register_jshover(dge('top_menu_options'));
	xmenu_register_jshover(dge('pg_menu_select'));
	xmenu_register_jshover(dge('pg_menu_sort'));
	xmenu_register_jshover(dge('pg_menu_display'));
}

function update_folder(fid,search)
{
	if(fid) sw.fid=fid;
	sw.xfolder=search?true:false;
||if_not(newlook_ui)||
	show_hint();
||endif||
||if_set(newlook_ui)||
#	if(fid==0){	// The inbox
#		show_duesoon();	
#	}
||endif||	
}
function update_unread(fld_id,txt)
{
	var el=dge('unread_'+fld_id);
	if (!el) return;
	el.innerHTML=txt;
}
function update_unread_folders(o)
{
	var el,len=o.length, due_soon;
	for(var i=0;i<len;i++){
		if(o[i].fld_id=='INBOX') {
			update_ssb_status(o[i].unread);
# 	also see update_folder called from message list full display update
			if(o[i].due_soon){
				due_soon = o[i].due_soon;
			}
		}
		el=dge('unread_'+o[i].fld_id);
		if (!el) return;
		el.innerHTML=o[i].unread==0?'':'('+o[i].unread+')';
	}
	update_due_soon(due_soon);
#	set_status('Unread messages updated in '+len+' folder'+plural(len),'success');
}
function update_ssb_status(count)
{
	if (window.fluid){
		var txt='';
		if(count>0) txt=count;
		if(count<0) txt='???';
		window.fluid.dockBadge=txt;
		dbg('fluid status update=['+txt+'] count='+count);
		
		if(window.surgeweb_fluid_version && window.surgeweb_fluid_version!=1 && !window.fluid_warned){
			alert('A newer Fluid SurgeWeb user script is available');
			window.fluid_warned=true;
		}
	}
}

function navigator_set(first,count,total,txt)
{
	var o;
	if (pref.preview=='horiz') {
		o=dge('msg_navigator_wide'); 
		if(o && total<10) class_add(o.parentNode,'hidden');
	}else{
		o=dge('msg_navigator'); 
	}
	if(!endless.added){
		sw.nav_first=first;
		sw.nav_count=count;
		sw.nav_total=total;
	}
	if (o){
		o.innerHTML = txt;
	}		
}

function navigator_set2(o)
{
	var first=o.first-1;
	var last=o.last-1;
	var count = o.last-o.first+1;
	var total = o.total;
	var req_num = o.req_num;
	var html='';
	if(first>req_num)
		html+='<a href="#" onclick="nav('+(0)+')"><<</a> ';
	if(first>0)
		html+='<a href="#" onclick="nav('+(first-req_num)+')"><</a> ';

	if(total>0){
		html+= o.first+' - <span id="nav_last">'+o.last+'</span> <span style="font-size:0.9em;">$$st_pages_of$$</span>';
		if(o.downloading){ 
			html+= ' <b><i title="'+$('$$st_pages_calc_tt$$',total)+'">'+$('$$st_pages_calc$$',total)+'</i></b> ';
		} else if(o.maxhit>0){
			html+= ' <b><i title="$$st_pages_max_tt$$"> '+$('$$st_pages_max$$',total)+'</i></b> ';
		} else { 
			html+= ' <b><span id="nav_total">'+total+'</span></b> ';
		}

#		||msgs_first|| - <span id="nav_last">||msgs_last||</span>
#		<span style="font-size:0.9em;">$$st_pages_of$$</span>
#		  ||ifdef||still_downloading|| <b><i title="||$((st_pages_calc_tt),msgs_total)||">||$((st_pages_calc),msgs_total)||</i></b>
#		  ||else|| ||ifdef||search_maxhit|| <b><i title="$$st_pages_max_tt$$"> ||$((st_pages_max),msgs_total)||</i></b>
#		  ||else|| <b><span id="nav_total">||msgs_total||</span></b>
#		  ||endif|| ||endif||
	}
	if(last<total-1)
		html+='<a href="#" onclick="nav('+(first+req_num)+')">></a> ';
	if(last<total-req_num)
		html+='<a href="#" onclick="nav('+(total-req_num)+')">>></a> ';


	if (endless.added){
		sw.nav_count+=count;
		sw.nav_total=total;
		html = sw.nav_first+' - <span id="nav_last">'+(sw.nav_first+sw.nav_count-1)+'</span> of '+sw.nav_total;
	}

	navigator_set(o.first, count, total, html, o.endless_id);
	
	var more_available = (count==req_num && total>=req_num);
	endless_list_init(more_available, o.endless_id, o.endless_t);	
}


function navigator_update()
{
	var o;
	if(sw.nav_total>0){
		o=dge('nav_first'); if (o) o.innerHTML=sw.nav_first;
		o=dge('nav_total'); if (o) o.innerHTML=sw.nav_total;
		o=dge('nav_last'); if (o) o.innerHTML=sw.nav_first+sw.nav_count-1;
	}else{
		o=dge('msg_navigator'); if (o) o.innerHTML='';
		no_msgs_fld();
		no_msg_sel(ibz_is_inbox());
	}
	if(sw.nav_count==0&&sw.nav_total>0 /*|| sw.nav_count<50&&sw.nav_total!=sw.nav_count*/){
		var start = (sw.nav_first+100<sw.nav_total) ? sw.nav_first-1 : sw.nav_total - 100;
		FolderShow(sw.fld_id,{fld_type:sw.fld_type,start:start,noreset:true});
	}

#	dbg("*** Nav_update "+sw.nav_first+':'+sw.nav_count+':'+sw.nav_total)
#	if(dge('nav_first')) dbg("*** Nav_update "+dge('nav_first').innerHTML+' - '+dge('nav_last').innerHTML+' of '+dge('nav_total').innerHTML  )
}

function touch(id)
{
#	dbg("** touch "+id);
	sw.last_action=time();
	var wait=checknew_next-sw.last_action
	if(wait>20&&!need_backoff(sw.last_action)){
		dbg("touch "+id+" - changing checknew_timer from "+wait+"s to 20s");
		clearTimeout(checknew_timer);
		check_new_timed();
	}
	if (id>=5 && id<=8) 
		refresh_ad()
}

# Mostly seems to stop the one pixel shift which clicking links in IE sometimes has
#   todo look for better fix	
function stop_shift()
{
	if(isIE) {
		e=window.event;
		if (!e) return;
		stopEvent(e);
	}
}

function contact_click_send(email,name)
{
	if(sw.is_popup) return sw_win.contact_click_send(email,name);
	do_new_email(name,email);
}
function contact_click_add(email,name,vaultsafe)
{	
	if(sw.is_popup) return sw_win.contact_click_add(email,name);
	var extra='&old_nickname=&contact_nickname='+xescape(encode_quotes(email))+'&contact_email='+xescape(encode_quotes(email))+'&contact_name='+xescape(encode_quotes(name));
#	queued_req_add( enBG, 'contact_add', function(){
		sndReq('cmd=contact_add,show&page=~result.js'+extra, function(chan){
#			if(chan.responseText.indexOf('no such template')!=-1){
#				set_status("Contact save failed (probably already in addressbook)",'warning');
#			}else{
				var success=actionReqJsStat(chan);
				if(success){
					set_status($('$$st_ct_save_success$$',email),"success")
				}else{
					set_status('$$st_ct_save_fail$$ ('+success_string+')','warning');
				}
#			}
		});
#		},ch[enBG]);
#	});	
}
function contact_vault_update(cx_contact,type)
{	
	if(sw.is_popup) return sw_win.contact_vault_update(cx_contact,type);
	var extra='&contact_email='+xescape(encode_quotes(cx_contact.email_only))+'&contact_name='+xescape(encode_quotes(cx_contact.name_only))+'&contact_vaultaction='+type;
	sndReq('cmd=lock_update,show&page=~result.js'+extra, function(chan){
		var success=actionReqJsStat(chan);
		if(!success){
			set_status(success_string,"warning")
			return;
		}
		vcheck_add(cx_contact,type=="vaultunlock");
		vcheck_run();		
	});
}


function shiftkey()
{
	var o=window.event;
	if (!o) return false;
	return o.shiftKey;
}

function no_msgs_fld()
{
	setMessages('<span><div class="nomessages">$$st_info_nomsg_fld$$</div></span>');
}
function no_msg_sel(use_ibz)	//ibz
{
	if(ibz_reward(use_ibz)){
		return;
	}

	message_preview_real_el(dge('message_preview')).innerHTML='<div class="nomessages">$$st_info_nomsg_sel$$</div>';	
}
function no_msg_nopreview()
{
	message_preview_real_el(dge('message_preview')).innerHTML='<div class="nomessages">$$st_info_noprev$$<br><br><br><span style="color:#999">$$st_info_noprev2$$</span></div>';
}

# Javascript based UI extension functionality

function extend_init(type)
{
	if(type==1 && window.js_extend_init_early)
		js_extend_init_early()
	if(type==2 && window.js_extend_init_late)
		js_extend_init_late()
}

function init_ui_elements()
{
	footer=dge('sw_footer').offsetHeight;
}


# ----------------------
# Implementation of client side panel "look and feel"
# valid: 'orig', 'plain', 'none'; 
var panel_mode='||panel_mode||';
var panel_gap=||panel_gap||;
function panelise()
{
	if (!pref.panelise) return;

#	Always round the corners of the status
	panelise_round(document.getElementById('status'),enBoth);

// Nothing at all panelised
	if(panel_mode=='none'){	
		panelise_none(dge('menubar'),enHdr);
		panelise_none(dge('lpanel_hdr'),enHdr);
		panelise_none(dge('messages'),util_body_style);
		panelise_none(dge('lpanel_body'),enBody);
		panelise_none(dge('app_menu'),enHdr);
		panelise_none(dge('contacts'),enHdr);
		var o=dge('custom_lpanel'); if (o) panelise_none(o,enPlain);
		panelise_none(dge('sw_footer'),enBot);
		o=dge('rcol'); if(o) panelise_none(o);

# Left column not panelised
	}else if (panel_mode=='plain') { 
		panelise_plain(dge('lpanel_hdr'),enHdr2);
		panelise_plain(dge('lpanel_body'),enBody2);
		panelise_plain(dge('app_menu'),enBody2);
		panelise_plain(dge('contacts'),enHdr2);
		var o=dge('custom_lpanel'); if (o) panelise_none(o,enPlain);
#		Center column and status
		panelise_roundtop(dge('menubar'),enHdr);
		class_add(dge('menubar_outer'),'top_line');
		panelise_plain(dge('messages'),util_body_style);
		panelise_plain(dge('sw_footer'),enBot);
		panelise_plain(dge('todo_hdr'),enHdr2);
		panelise_plain(dge('todo_noscroller'),enBody2);
		panelise_plain(dge('rcol'),enBot);
	
#	Original design
	}else{
#		Left column panels
		panelise_roundtop(dge('lpanel_hdr'),enHdr);
		panelise_square(dge('lpanel_body'),enBody);
		panelise_pad(dge('app_menu'),enHdr);
		panelise_round(dge('contacts'),enHdr);
		var o=dge('custom_lpanel'); if (o) panelise_square(o,enPlain);
#		Center column and status
		panelise_roundtop(dge('menubar'),enHdr);
		class_add(dge('menubar_outer'),'top_line');
		panelise_square(dge('messages'),util_body_style);
		panelise_square(dge('sw_footer'),enBot);
		o=dge('rcol'); if(o) panelise_roundtop(o,enHdr);
	}
}

# Add new custom panels on the left
var panel_ids=1;
function new_panel_basic(content_body, top)
{
	var a=new_anchor_before("foobar", top=='top'?"lpanel_hdr":"contacts");
	a.className="left_pane";
	a.innerHTML='<div class="lpanel_style" style="background:||lpanel_color||;padding:3px;">'+content_body+'</div>';	
	if(panel_mode=='orig'){
		panelise_round(a,enBoth);
	}else if(panel_mode=='plain'){
		panelise_plain(a,enBody2);
	}else{
		panelise_none(a,enBoth);
	}
}
function new_panel_fancy(content_header, content_body, top, plain)
{		
	var a=new_anchor_before("foobar", top=='top'?"lpanel_hdr":"contacts");
	a.className="left_pane";
	a.innerHTML='<div class="left_panel_header"> <span style="padding-left:5px">'+content_header+'</span></div><div style="background:white;'+(plain==true?'':'padding:3px;')+'">'+content_body+'</div>';
	var xhdr=a.firstChild;
	var xbody=a.firstChild.nextSibling;
	if(panel_mode=='orig'){
		panelise_roundtop(xhdr,enHdr);
		panelise_square(xbody,enBody);
	}else if(panel_mode=='plain'){
		panelise_plain(xhdr,enHdr2);
		panelise_plain(xbody,enBody2);
	}else{
		panelise_none(xhdr,enHdr);
		panelise_none(xbody,enBody);
	}
}

// Possibly combine this function with some of our own background downloads
function prefetch_init(msgs)
{
||iftrue(html5_audio_disable)||
	flash_embedSWF2("||www_base||shared/modules/flash_audio.swf?||vz||");
||endif||	

	check_accounts();
	download_contacts();
	download_dialogs();
	cache_inbox(msgs);
	prefetch_images();
	refresh_flds();
	
	sw.done_prefetch=true;
#	var head = document.getElementsByTagName('head')[0];
#	var node = document.createElement('embed');
#	head.appendChild(node);
#	node.setAttribute('src', url);
}

var prefetch_img_urls=['ajax/img/dlg_alert.png','ajax/img/gradient.gif','ajax/img/dlg_confirm.png','shared/img/shadow_cnr.png','shared/img/shadow_vert.png','shared/img/shadow_horiz.png','shared/img/alert.png'], 
	prefetch_img_images=[];
function prefetch_images()
{
	for(var i=0;i<prefetch_img_urls.length;i++){
		prefetch_img_images.push(new Image());
		prefetch_img_images[i].src=wwwbase+prefetch_img_urls[i]+'?||vz||';
	}	
}


function cache_inbox(msgs)
{
	if(pref.devt_test=='nobg') return;
	if (pref['nocache'] || msgs.length==0) return;

	if (done_cache) return;

	done_cache=true;
	ajax_cache_messages(msgs);	
}



function download_contacts()
{
	if(pref.devt_test=='nobg') return;
	queued_req_add( enBG, 'download_contacts', function(){
		sndReq('cmd=show&page=~contacts.js&bg=true', function(chan){
			var success
			success=actionReqJsStat(chan);
#				contact_error();
		},ch[enBG]);
	});
}

function download_dialogs()
{
	queued_req_add( enBG, 'download_dialogs', function(){
		sndReqCached('cmd=show&page=~dialogs.htm&dialog=contact_picklist&if=ajax&static=||web_ref_path||&||vz||', function(chan){			
			new_anchor('div',chan.responseText);			
			cp_init();
		},ch[enBG]);
	});
}

function refresh_flds(all)
{
	if(pref.devt_test=='nobg') return;

	queued_req_add( enBG, 'refresh_flds', function(all){
||iftrue(using_api)||
		apiGet('core/refresh_folders?v=sw&idle=true'+iid()+(all?'&refresh_allflds=true':''), function(chan){
||else||
		sndReq('cmd=folders_refresh,show&page=~result.js&idle=true'+iid()+(all?'&refresh_allflds=true':''), function(chan){
||endif||
			var success=actionReqJsStat(chan);
			sw.folder_check=time();
			if(all) set_status('$$st_stat_rfrall_complete$$','success')
		},ch[enBG]);
	},all);
}


function info_panel_init()
{
	if(info_panel.length>0)
		new_panel_basic(info_panel,'top');
}


function switch_selfld(fld_id,opt)
{
	var el;
	var fld_id_old=sw.fld_id;

	if(!opt) opt={};

	sw.fld_id=fld_id;
	var fld_id_txt=fld_id2name(fld_id);
	if (opt.multiple) fld_id_txt='<i>Multiple folders</i>';
	sw.multiple=opt.multiple;

	document.getElementById("foldername1").innerHTML=fld_id_txt;
	document.getElementById("foldername2").innerHTML=fld_id_txt;
	el=document.getElementById("foldername_tab");
	if (el) el.innerHTML=fld_id_txt;

	el=dge('unread_'+fld_id_old);
	if (el) class_remove(ancestor_by_class(el,'full_cursor'),"selected");
	if(!opt.multiple){
		el=dge('unread_'+fld_id);
		if (el) class_add(ancestor_by_class(el,'full_cursor'),"selected");
	}
}

var showing_column3=false;
function column3_init()
{
	if(pref.alt_ui) return;
	if(column3.length>0 && column3!='none' || pref.todo){
		var w=pref.todo ? pref.sizer3 : ||right_column_width||;
		right_column=w+panel_gap+2;
		var x=document.getElementById('right_column');
		class_remove(x,'hidden');
		showing_column3=true;
	}
# the below does not work ??	
#	dge('right_column').innerHTML=''+
#	  	'<span style="font-size:10px">advertisement</span>'+
#	  	<div style="border:1px solid ||border_color||;width:120px;height:600px;text-align:left;"><div style="padding:3px">Div for <br>arbitrary use: <br> - Information <br> - hints <br> - advertising??</div></div>
#	  	'<div style="border:1px solid ||border_color||;width:120px;height:600px;text-align:left;">||ad2_html||</div>';
#	alert('||ad2_html||');
	right_column_init();
}
function user_cgi_iframe(id,type)
{
	var el=dge(id);
	el.src=cgibase+'cmd=doauto_login&product=usercgi&sid='+sid+'&surgeweb=true&type=spam2';
	
#	user_mode=user&domainid=0&utoken=marijn@mybox7_1958604543&cmd_user_fsimple=Spam
	
}
function user_cgi_dlg(type)
{
	var cmd='cmd=doauto_login&product=usercgi&sid='+sid;
	var txt='$$st_user_cgi$$';
	var extra='';
	
	if(usercgi_status) extra+='&combine_spam_friends=true'
			+ '&rating_probable='+ pref.rating_probable+'&rating_certain='+pref.rating_certain
			+ '&spam_hide_advanced='+pref.spam_hide_advanced+'&use_late='+usercgi_status['use_late'];

debugger
	switch(type){
		case 'responder': 	
		case 'forwarding':
		case 'filtering':
		case 'whitelist':	
		case 'spam': 		
		case 'spam2': 		
		case 'friends':
		case 'password':
		case 'legal':
		case 'notify':
		case 'lists':
		case 'import':
		case 'aliases':
		case 'cleanup':
		case 'detach':
							cmd+='&type='+type+extra; break;
		case 'log': 
		case 'log_only': 
							cmd+='&type='+type; break;

		case 'raw': 
			txt='Raw user.cgi interface';		
			cmd+='lcmd='; 
			break;
	}
	
	if(type!='raw')
		cmd+='&surgeweb=true';
		
	cmd+='&utoken='+utoken;
	
||if(not(istrue(consolidated_prefs_disable)))||
	do_usercgi_inline(type, cmd);
	return;
||endif||
	
	x_custom_dlg2(txt+' ($$st_user_cgi2$$) ',
				 '<iframe src="'+cgibase+cmd+'" style="width:100%;height:'+px(ClientHeight()*0.9-100)+'"></iframe>',
		function(btn){
			if(sw.active.classname!='options') return;;
			ie_fixfocus();
			usercgi_summary();
	}, U, {'tall':true,'width':0.9});
}

function user_cgi_popup(type)
{
#	open_popup2(backend+'cgi/user.cgi?utoken='+utoken+type);
	open_popup2(cgibase+'cmd=doauto_login&product=usercgi&type=&sid='+sid);
}

function subject_init(){
	var ctl=sw.active.field_subject; 
	add_event(ctl,'blur',function(){
		set_tab_text(ctl.value.length>0?ctl.value:'$$st_new_message$$');
	});
}


// see: get_addresses_sw for dialog outer prefetch
//		show_contacts for dialog initialisation

# *** msglist D&D :-)

var dnd,Browser,Loc;
function msgdnd_init(){
	var isFFok = (isFF && isVersion>=3);
	var isIEok = (isIE && isVersion>=7);
	
	Browser = {isIE  : isIEok, isIE6 : false, isIE7 : true, isIE8 : false, isFF: isFFok};
	Loc = {isBidi : false, LEFT : "left",RIGHT : "right",LRM : "\u200e",RLM : "\u200f"};
	
    if(sw.dnd_disabled) return;
    if(dnd) { dnd.dispose(); dnd=null; }
    DND.RegisterDropTarget(dge("folders").parentNode, dnd1dst_OnDragOver, dnd1dst_OnDragOut, dnd1dst_OnDragDrop);
	if(pref.defer_disable){
		dnd=new DND(dge('messages_list'), dnd1src_OnDragStart, dnd1src_OnDragEnd, dnd1src_OnNoTarget);	
	}else{
		DND.RegisterDropTarget(dge("messages_list"), dnd1dst_OnDragOver2, dnd1dst_OnDragOut2, dnd1dst_OnDragDrop2);
		dnd=new DND(dge('messages_list'), dnd1src_OnDragStart, dnd1src_OnDragEnd, dnd1src_OnNoTarget, true);	
	}
}

function dnd1src_OnDragStart(jc,o){

	dbg("CUSTOM D&D dragstart 1");
    o.data = {validStart: false};
	var row=ancestor_by_class(o.overElement,'msgs_line');
	if (!row) return;
	var cell=ancestor_by_tag(o.overElement,'td');
	if(cell==row.childNodes[0] || (cell==row.childNodes[1] && !new_wide())) return;

	if (isMac&&event.ctrlKey) {return;}
	gs_dnd_start(sw.ml, row);

	var sel=find_sel(true);
	if (!sel) return false;

    o.data = {validStart: true, sel: sel, toDiv: null, fromDiv: row, copy: event.ctrlKey, forever: event.shiftKey&&!event.ctrlKey };
	for_each_msg(o.data.sel,'pending');
    dnd1_iconCreate(o.data,sel.sel_all?sw.nav_total:sel.length);
    dnd1_iconUpdate(o.data,false);
}
function dnd1src_OnDragEnd(jc,o){
    var d = o.data;
    if (!d.validStart) return;
	dbg('CUSTOM D&D dragend (***) end='+log_element(o.fromElement)+' to='+log_element(o.toElement));
	
	if(!o.success || d.copy)
		for_each_msg(o.data.sel,'nopending');
	dnd_iconRemove(d.drag_div);
	for (var i=0;i<collapse_restore.length;i++){
		fld_expand(undefined,undefined,collapse_restore[i]);
	}
	collapse_restore=[];
} 
function dnd1src_OnNoTarget(jc,o){
    var d = o.data;
    if (!d.validStart) return;
    dnd1_iconUpdate(o.data,false,true);
}
var collapse_timer, collapse_restore=[];
function dnd1dst_OnDragOver(jc,o){
    var d = o.data;
    var el = ancestor_by_class(o.overElement, "full_cursor");
    if (!el || !d.validStart) {
        if (d.toDiv) class_remove(d.toDiv,'dnd_sel');
        d.toDiv = null;
	    dnd1_iconUpdate(d,false);
        return;
    }
    dnd1_iconUpdate(d,true);
    if (el == d.toDiv) return;
    if (d.toDiv) class_remove(d.toDiv,'dnd_sel');
    if (el.id == d.currFid) {
        d.toDiv = null;
        return;
    }
    d.toDiv = el;
	class_add(d.toDiv,'dnd_sel');
	
	if(collapse_timer){
		clearTimeout(collapse_timer);		
		collapse_timer=null;
	}
	if(class_contains(el.parentNode,'closed')){
		var node=el.parentNode;
		collapse_timer=setTimeout(function(){
			fld_expand(undefined,undefined,node);
			DND._UpdateDropTargetRegions();
			collapse_restore.push(node);
		},1000)
	}
}
function dnd1dst_OnDragOut(jc,o){
    var d = o.data, fld = d.toDiv;
    if (!d.validStart) return;
   	dnd1_iconUpdate(d,false);
    if (d.toDiv) class_remove(d.toDiv,'dnd_sel');
    d.toDiv = null
    clearTimeout(collapse_timer);
    collapse_timer=null;
}
function dnd1dst_OnDragDrop(jc,o){
    var d = o.data;
    if (!d.toDiv || !d.validStart) return;
    if (d.toDiv) class_remove(d.toDiv,'dnd_sel');

	dbg('Actioning message DND '+(d.copy?'COPY':'MOVE')+' to folder ['+fld_id+']');
	var fld_id=d.toDiv.parentNode.getAttribute('fld_id')

	dbg('**2 copy='+d.copy+' forever='+d.forever);

	if(d.copy&&!d.forever){
		set_status('$$st_stat_copying$$',"info");
		ajax_msg_copy(d.sel,fld_id,false,event.shiftKey);
	}else{
		set_move_status(d.sel,fld_id,d.forever);
		ajax_msg_move(d.sel,fld_id,false,event.shiftKey,d.forever);
		do_select('none');
		if(!d.forever){
			message_done_action(d.sel);
		}
	}        
    o.success = true
}

function dnd_select_tb(el,top)
{
	if(top){
		class_add(el,'dnd_sel_top');
		class_remove(el,'dnd_sel_btm');
	}else{
		class_remove(el,'dnd_sel_top');
		class_add(el,'dnd_sel_btm');
	}
}
function dnd_unselect_tb(el)
{
	class_remove(el,'dnd_sel_top');
	class_remove(el,'dnd_sel_btm');
}
function dnd_hline(d,outer)
{
	var el=new_anchor('div', '', outer);
	class_add(el,'hline');
	return el;
}
function dnd_hline_position(d,r,is_top)
{
	var s = d.hline.style;
	s.left=px(0);
	s.top=px((is_top?r.top:r.bottom)-4);
	s.width=px(r.right-r.left);
	s.height=px(3);
}
function dnd_hline_remove(d)
{
	if(d.hline==null) return;
	remove_node(d.hline);
	d.hline=null;
}
function dnd1dst_OnDragOver2(jc,o){
		
    var d = o.data;
    var el = ancestor_by_class(o.overElement, "msgs_line");
    mlist = dge('messages_list');

	if(!allow_inbox_order()) {
		dnd1_iconUpdate(d,false,true);
		return;
	}
    var r = get_location(el);
# 	console.log('el->p.top='+el.parentNode.offsetTop+ ' el->p(x2).top='+el.parentNode.parentNode.offsetTop+ ' el->p(x3).top='+el.parentNode.parentNode.parentNode.offsetTop+ ' el->p(x4).top='+el.parentNode.parentNode.parentNode.parentNode.offsetTop+ ' el->p(x5).top='+el.parentNode.parentNode.parentNode.parentNode.parentNode.offsetTop);	
    if(pref.newlook_layout=='modern1'){
		r.top -= 44;
		r.bottom -= 44;
    }else if(pref.newlook_layout=='standard' && sw.using_fancy_scroller){
		r.top -= 98;
		r.bottom -= 98;
 	}
	r.top -= mlist.offsetTop;
	r.bottom -= mlist.offsetTop;
 
# 	console.log('r.top='+r.top);
 
	var y = y_relative_to(event.clientY,mlist);
	var x = x_relative_to(event.clientX,mlist);
	d.is_top = (y<(r.top+r.bottom)/2);
	var near_orig = el && ((el==d.fromDiv) || (el.previousSibling==d.fromDiv && d.is_top) || (el.nextSibling==d.fromDiv && !d.is_top));

#    //dbg('region=['+r.left+','+r.top+','+r.right+','+r.bottom+'] o='+el.parentElement.scrollTop+' e=['+x+','+y+'] '+ d.is_top)

    if (!el || !d.validStart || near_orig) {
        if (d.hline) dnd_hline_remove(d) //dnd_unselect_tb(d.toDiv);
        d.toDiv = null;
	    dnd1_iconUpdate(d,false, true);
        return;
    }
    
    dnd1_iconUpdate(d,true);
    d.toDiv = el;
    if(!d.hline) d.hline=dnd_hline(d,mlist);
	dnd_hline_position(d,r,d.is_top);
}
function dnd1dst_OnDragOut2(jc,o){
    var d = o.data, fld = d.toDiv;
    if (!d.validStart) return;
   	dnd1_iconUpdate(d,false);
    if (d.hline) dnd_hline_remove(d); //dnd_unselect_tb(d.toDiv);
    d.toDiv = null
}
function el2time(el)
{
	return parseInt(el.getAttribute('timestamp'))
}
function dnd1dst_OnDragDrop2(jc,o){
    var d = o.data;
    if (!d.toDiv || !d.validStart || !allow_inbox_order()) return;
    if (d.hline) dnd_hline_remove(d); //dnd_unselect_tb(d.toDiv);

	if(d.sel.length>1){	
		x_alert('$$st_stat_arrange_one$$');
		return;
	}
	
	var moving = d.fromDiv;
	var parent = d.toDiv.parentNode;
	var after = d.toDiv;
	var before = d.toDiv;
	if(!d.is_top) before = before.nextSibling;
	if(before) after = before.previousSibling;
	var tnew = el2time(moving);
	if(before && after){
		var t1 = el2time(after);
		var t2 = el2time(before);
		tnew = Math.round(t1 + t2)/2;
		if(t1==t2){
			x_alert('$$st_stat_arrange_warn$$');
		}
	}else if(after){
		tnew = el2time(after)-30;
	}else if(before){
		tnew = el2time(before)+30;
	}

	parent.insertBefore(moving,before);
	a = moving.getAttribute('timestamp');
	moving.setAttribute('timestamp',tnew);
	b = moving.getAttribute('timestamp');

	ajax_arrange(d.sel,tnew);
}



var dnd2;
function dnd2_init(){
    if(sw.dnd_disabled) return;
    if(dnd2) { dnd2.dispose(); dnd=null; } 
    DND.RegisterDropTarget(dge("cm_groups"), dnd2dst_OnDragOver, dnd2dst_OnDragOut, dnd2dst_OnDragDrop);
	dnd2=new DND(dge('cm_contacts'), dnd2src_OnDragStart, dnd2src_OnDragEnd, dnd2src_OnNoTarget);	
}

var hack_nosize=false;
var hack_el;
function dnd2src_OnDragStart(jc,o){
	dbg("CUSTOM D&D dragstart 2");
    o.data = {validStart: false};
	var el=cl_find_row(sw.cl,o.overElement);// ancestor_by_class(o.overElement,'cm_contact');
	if (!el) return;
	gs_dnd_start(sw.cl, el);
	
	var csel=contact_sel(U,true);
	if (!csel) return false;

	var c=abooks[el.getAttribute('cm_abk')].data[el.getAttribute('cm_cid')];
	if (!class_contains(el,'selected')) cm_select_contact(el,event);
    o.data = {validStart: true, csel:csel, sel: el, toDiv: null, fromDiv: el, c: c };
    dnd2_iconCreate(o.data,1);
    var v=dnd2_validity(U,o.data);
    dnd2_iconUpdate(o.data,v.icon_ok,undefined,v.icon_text);
#	if(!contact_editable(c)){
#    	o.data.nodrag=true;
#    }
    o.data.do_shared=c.shared;
    hack_nosize=true;
}
function dnd2src_OnDragEnd(jc,o){
    var d = o.data;
    if (!d.validStart) return;
	dbg('CUSTOM D&D dragend (***) end='+log_element(o.fromElement)+' to='+log_element(o.toElement));
	dnd_iconRemove(d.drag_div);
    hack_nosize=false;
} 
function dnd2src_OnNoTarget(jc,o){
    var d = o.data;
    if (!d.validStart) return;
    dnd2_iconUpdate(o.data,false,true);
}

function dnd2_ToIconText(c,g,el,id)
{
	if(!contact_editable(c)){
    	return '$$st_ct_dndbad$$';
    }
	if(id=='all') return '$$st_ct_dnd_alreadyall$$';
	if(!g) return '$$st_ct_dnd_adding$$';
	if(g.webmail) return '$$st_ct_dnd_noweb$$';
	
	if(g.shared && !c.shared){
		if(group_editable(g))
			return '$$st_ct_dnd_shared$$';
		else
			return '$$st_ct_dnd_no_p2s$$';
	}else if(c.shared && !g.shared){
		return '$$st_ct_dnd_no_s2p$$';
	}else if (el && class_contains(el,'selected')){
		return $('$$st_ct_dnd_already$$',g.name);
	}else{			
		return $('$$st_ct_dnd_adding2$$',g.name);
	}
}
var ic_grey=0,ic_green=1,ic_red=2;
function dnd2_validity(el,d)
{
	var r={};
	r.valid=false;
	var extra1 = (d.csel.length>=2)?' ('+d.csel.length+')':'';

	r.icon_text='$$st_ct_dnd_organise$$'+extra1;	// QQZ dnd2 text
	r.icon=ic_grey;

#	dbg('*** d.validStart='+d.validStart+' d.nodrag='+d.nodrag);

	if(d.c.webmail){
		r.icon_text='$$st_ct_no_webmail$$'; 
		return r;
	}
	if(!el || !d.validStart /*|| d.nodrag*/){
		return r;
	}
	
	if (el) {
		var id=el.getAttribute('cm_gid');
		var book=el.getAttribute('cm_abook');
		var g=group_find(abooks[book],id);
	}

	if(g.webmail){
		r.icon=ic_red; r.icon_text='$$st_ct_no_wgroup$$';
		return r;
	}

	var cid=d.fromDiv.getAttribute('cm_cid');
	var abk_src=d.fromDiv.getAttribute('cm_abk');

#	dbg('*** bk='+abk_src+' -> bk2='+book+' ('+id+') g.isabook='+g.isabook+' g.is_group='+g.is_group);
	
	if(book==''&& g.name=='All Addresses'){
		r.icon=ic_red; r.icon_text=$('$$st_ct_no_modify$$','$$st_ct_all_addresses$$');
		return r;
	}
	if(!group_editable(g) && book!='User'){
		r.icon=ic_red; r.icon_text=$('$$st_ct_readonly$$',book);
		return r;
	}

#	// Try and add to group in current abk
	if(book==abk_src){
		if(g.isabook || class_contains(el.firstChild,'selected') ||
					book=='User'&&g.name=='All Contacts'){
			r.icon=ic_red; r.icon_text=$('$$st_ct_dnd_already$$',g.name);
			return r;
		}
		r.icon=ic_green; r.icon_text='$$st_ct_togroup$$ '+g.name+extra1;		
		d.type='group';
		return r;
	}	
	
#	// try copy between addressbooks
	if(book!=abk_src){
		if(book==''&&g.name=='All Addresses'){
			r.icon=ic_red; r.icon_text=$('$$st_ct_togroup$$',g.name);
			return r;
		}
		var extra='';
		if(!g.isabook){
			extra+=$('$$st_ct_groupin$$ ',g.name);
		}
		if (g.name=='User'){
			extra+='$$st_ct_personal_abk$$';
		}else{
			extra+=book;
		}
		r.icon_text='$$st_ct_copy_contact$$ '+extra+extra1;
		r.icon=ic_green;
		d.type='copy';
		return r
	}

	return r;		// => yes / no valid drop target		
}

function dnd2dst_OnDragOver(jc,o){
    var d = o.data;
    var el = ancestor_by_class(o.overElement, "cm_group");	
	var v=dnd2_validity(el,d);
	dnd2_iconUpdate(d,v.icon,undefined,v.icon_text);
	if(v.icon!=ic_green){
        if (d.toDiv) class_remove(dnd2_row2cursor(d.toDiv),'dnd_sel');
        d.toDiv = null;
        return;
    }
    if (el == d.toDiv) return;
    if (d.toDiv) class_remove(dnd2_row2cursor(d.toDiv),'dnd_sel');
    if (el.id == d.currFid) {
        d.toDiv = null;
        return;
    }
    d.toDiv = el;
	class_add(dnd2_row2cursor(el),'dnd_sel');
}
function dnd2dst_OnDragOut(jc,o){
    var d = o.data, fld = d.toDiv;
    if (!d.validStart) return;
   	dnd2_iconUpdate(d,false);
    if (d.toDiv) class_remove(dnd2_row2cursor(d.toDiv),'dnd_sel');
    d.toDiv = null
}
function dnd2dst_OnDragDrop(jc,o){
    var d = o.data;
 	if (!d.toDiv || !d.validStart) return;
    if (d.toDiv) class_remove(dnd2_row2cursor(d.toDiv),'dnd_sel');

	var abk_src=d.fromDiv.getAttribute('cm_abk');
	var cid=d.fromDiv.getAttribute('cm_cid');
	var gid=d.toDiv.getAttribute('cm_gid');
	var abk_to=d.toDiv.getAttribute('cm_abook');

	dbg('QQQ abk_src='+abk_src+' cid='+cid+' gid='+gid+' abk_to='+abk_to);

	if(true||d.csel.length>1){
		contact_regroup(abk_src,d.csel,abk_to,gid);
	}else if(abk_to==abk_src){
		dbg('Actioning contact DND add to group ['+gid+']');
		cm_contact_add2group(abk_src,cid,gid)
	}else{
		dbg('Actioning contact DND copy ['+abk_to+':'+gid+']');
		contact_copy_one(abooks[abk_src].data[cid],abk_to,gid);
	}
    o.success = true
}

function dnd2_row2cursor(el){return el.firstChild.childNodes[2]}

function dnd_iconRemove(a) { 
	document.body.removeChild(a.parentNode);
};
function dnd1_iconCreate(d,count)
{
	var a=new_anchor('div','<div class="dnd_info"><span>'+$(ctl_opt_key(event)?'$$st_msgdnd_copying$$':'$$st_msgdnd_moving$$')+'</span> '+$('$$st_msgdnd_count$$',count,plural(count))+'</div>');
    d.drag_div = a.firstChild;
    d.style = d.drag_div.style;
    d.xoffset = Loc.isBidi ? d.drag_div.offsetWidth : 0;
	fdnd_text(d,d.drag_div.firstChild,event,true);
    return a.firstChild;
};
function dnd1_iconUpdate(d,ok,bad)
{
    if (d.validStart) {
        d.style.top = px(event.clientY + 20);
        d.style.left = px(event.clientX + (Loc.isBidi ? -10 : 10) - d.xoffset);
		if(ok){
			class_add(d.drag_div,"dnd_drop");
			class_remove(d.drag_div,"dnd_bad");
		}else if(bad){
#			// A slightly nasty test, but allows us to modify cursor without major changes to core DND code :-)
			if(document.body.style.cursor=='pointer'){
				class_remove(d.drag_div,"dnd_bad");
				class_remove(d.drag_div,"dnd_drop");
			}else{			
				class_add(d.drag_div,"dnd_bad");
				class_remove(d.drag_div,"dnd_drop");
			}
		}
		fdnd_text(d,d.drag_div.firstChild,event);
    }
};
function fdnd_text(d,dd,e,force)
{
	var copy = ctl_opt_key(event);
	var forever = ||iftrue(filters_disable)|| false ||else|| shift(event) ||endif||;
	if(sw.fld_id!='INBOX') forever=false;
	if(d.copy==copy && d.forever==forever&&!force) return;

	var txt='$$st_msgdnd_moving$$';
	if(forever) txt='$$st_msgdnd_forever$$';
	if(copy) txt='$$st_msgdnd_copying$$';

	dd.innerHTML = txt;
	d.copy=copy; 
	d.forever=forever;
	dbg('**1 copy='+d.copy+' forever='+d.forever);
}
function dnd2_iconCreate(d)
{
	var a=new_anchor('div','<div class="dnd_info"></div>');
    d.drag_div = a.firstChild;
    d.style = d.drag_div.style;
    d.xoffset = Loc.isBidi ? d.drag_div.offsetWidth : 0;
    return a.firstChild;
};
function dnd2_iconUpdate(d,icon,bad,txt)
{
    if (d.validStart) {
        d.style.top = px(event.clientY + 20);
        d.style.left = px(event.clientX + (Loc.isBidi ? -10 : 10) - d.xoffset);
		
		if(icon==ic_green){
			class_add(d.drag_div,"dnd_drop");	// green
			class_remove(d.drag_div,"dnd_bad");
		}else if (icon==ic_red){
			class_add(d.drag_div,"dnd_bad");	// red
			class_remove(d.drag_div,"dnd_drop");
		}else{
#			// A slightly nasty test, but allows us to modify cursor without major changes to core DND code :-)
			if(document.body.style.cursor=='pointer'){
				class_remove(d.drag_div,"dnd_bad");
				class_remove(d.drag_div,"dnd_drop");
			}else{			
				class_add(d.drag_div,"dnd_bad");
				class_remove(d.drag_div,"dnd_drop");
			}
		}
	}
	if (txt && d.drag_div) d.drag_div.innerHTML = txt;
};

# ****

function default_font_size()
{
	if (sw.is_popup)
		return sw_win.font_size;
	else
		return font_size;
}

function list_refresh_allowed(fld_id)
{
	if (sw.fld_id!=fld_id) return false;
	var sel=find_sel(true);
	if (sel && sel.length>1) return false;
	if (sw.search_input && sw.search_input.valid) return false;
	if (sw.nav_first>1) return false;
	return true;
}
function delayed_refresh(fn,fld_id)
{
	if(!list_refresh_allowed(fld_id)) return false;
	setTimeout(function(){
			var nofocus;
			var sel=find_sel(true);
			var pending=find_pending();
			if(!sel || sel && sel.length==1)
				fn();
			for_each_msg(pending,'pending');
			for_each_msg(pending,'pending_hide');
			if(isIE && pref.windows=='popup') nofocus=true;
			msglist_select(sel?sel[0]:first_message,U,nofocus);
		},120);
	return true;
}

function plural(len){
	return len>1?'s':'';
}
function set_from(node,val)
{
	var o;
	node.value=val;
	o=node.nextSibling;
	o.innerHTML=encode_lt_gt(val);
	if(idents()>1) class_remove(o.nextSibling,'hidden');
}
var popup_spellcheck;
function spellchecker_said(o)
{
	if(!o || o.length==0) {
		set_status('$$st_spell_err_none$$','success');
		return;
	}
	var len=o.length;
	set_status($('$$st_spell_err$$',len,plural(len)),"info");
	
	if(!popup_spellcheck || popup_spellcheck==window)
		check_spelling_cb(o)
	else
		popup_spellcheck.check_spelling_cb(o);
}

function msg_from_editor(node)
{
	var txt;
	if(node.field_eframe.viewMode==2 && !node.is_popup)
		toggleMode(undefined,dge('etbar'+node.instance));

	if (node.sc){
#		// cleanup from spellchecker
		txt=node.sc.getTextToCheck()
	}else{
		txt=oddball_cleanup(node.field_eframe.contentWindow.document.body.innerHTML);
	}

	return txt;
}

function oddball_cleanup(txt)
{
#	Webkit browsers (safari etc) editor converts &nbsp; to high end characters, so convert back. OK to do for all browsers
#	if (isSafari);
	txt = txt.replace(/\u00A0/g, '&nbsp;');
#	Opera sends odd things like \r\r and \r which server processing does not like, as \r characters get 
#	junked during serverside processing anyway lets just outright remove them for all browsers
	txt = txt.replace(/\r/g, '');

	return txt;	
}
//	just do a savedraft with integral spellcheck ;-)
function main_message_spellcheck(scid)
{
    var scid=sw.active.instance;
    var win=sw.active.field_eframe.contentWindow;
    
    var SC = Spell.getInstance(scid);
    if (!SC) {
        SC = new Spell(scid, win);
        sw.active.sc=SC;
		add_event(win.document,"mousedown", editor_mousedown);
		win.document.oncontextmenu=editor_contextmenu;
		document.oncontextmenu=editor_contextmenu;
		
#		win.document.onmousemove=function(e){dbg("++MOVE & forwarding target="+target(e).tagName);xx_menu.dispatchEvent(e)}
#		win.document.onmousemove=function(){dbg("++MOVE")}
#		win.document.onselectstart=function(){if(no_edit_contextmenu_once) return false;};
    }
	sw.run_spellcheck_once=true;
	do_save_draft(undefined,function(){sw.active.unsaved=false});
	
#	document.oncontextmenu=new Function("return false;")
}
function check_spelling_cb(o)
{
    var scid=sw.active.instance;
    var SC = Spell.getInstance(scid);
    if (!SC) return;
    
    SC.correctAll(true, null, true);
   
	SC.ajaxResultApply(o);
#	SC.g8(aa());			// Setup language related stuff
	SC.highlightWords();
}
function ed_spell_check_x1(e)
{
	var el=target(e);
	if (!class_contains(el,'mark')) return;
    var SC = Spell.getInstance(sw.active.instance);
//	SC.correctAll(true, null, true);
#	var el=xdoc.getElementById('misspell-1');
	return SC.showElementsMenu(el)
//	SC.showMenu(el)
}

function spellcheck_markup_remove(e)
{
    var SC = Spell.getInstance(sw.active.instance);
    if(!SC) return;

    var el = SC.bothRangeFn(e);
    var id = el ? el.id : null;

	SC.applyCorrection(el);

	// Just remove them all for now!!
//	SC.correctAll(true, null, true);
//	SC.applyCorrection(target(e),true);
}

function spellcheck_markup_removeall(flag)
{
	if(flag!=undefined && flag!=true) return;
	if(!sw||!sw.active) return;
    var SC = Spell.getInstance(sw.active.instance);
    if(!SC) return; 
    SC.correctAll(true, null, true);
}
function editor_mousedown(e)
{
	if(ed_spell_check_x1(e)){
		no_edit_contextmenu_once=true;
		stopEvent(e);
		return false;
	}
}

function spell_menu_click(e)
{
	if(!e) e=window.event; 
 	var SC = Spell.getInstance(sw.active.instance);
    if(!SC) return;

	var el=target(e);
	if(!el) return;
	if(class_contains(el,'shadow')) return;
	
	var mnu=ancestor_by_class(el,"xmenu");	
	var tag=el.tagName.toLowerCase();
	if(tag!='a') el=el.parentNode;

	switch(el.getAttribute("cmd")){
		case 'spell_menu_correct':
			SC.applyCorrection(mnu.el,true,el.innerHTML);
			break;
		case 'spell_menu_ignore':
			SC.applyCorrection(mnu.el,true);
			break;
		case 'spell_menu_learn':
			learn_word(mnu.el.innerHTML);
			SC.applyCorrection(mnu.el,true);
			break;
	}
	menu_hide2(mnu)
	no_edit_contextmenu_once=true;
	stopEvent(e);
	return false;
#    SC.correctAll(true, null, true);
}

var no_edit_contextmenu_once=false;
function editor_contextmenu(e)
{
	if(no_edit_contextmenu_once){
		no_edit_contextmenu_once=false;
		return false;
	}
}
# Click on folder pane resulting in folder display, label display or search display
function folder_click(e)	
{
	var id,type,fld_nm;
	if(!e) e=window.event;
	var t=target(e);
	var row=ancestor_by_tag(t,'li');
	if (class_contains(row,'fake')){		
		fld_expand(undefined,undefined,row);
		if(row.childNodes.length==1){
			manage_folders(e);
		}
		return;
	}

	var type=row.getAttribute('fld_type')
	if(type==enMissing){
		x_alert('$$st_fld_noexist$$');
		return;
	}
	close_conv();

	fld_short=row.getAttribute('fld_short');
	id=row.getAttribute('fld_id');
	if(id && id.length>0){	
		return  FolderShow(id,{fld_type:type,disable_markread:keys_2horiz(e)});	
	}
	
	id=row.getAttribute('labelid'),row;
	if(id && id.length>0){	
		return L(id);	
	}
	
	id=row.getAttribute('srchid');
	if(id && id.length>0){	
		var txt;
		if(id=='star'){	
			txt='flag:'+id+' folders:recent';
		}else if(id=='label'){	
			txt='label:* folders:recent';
		}else if (id=='comment') {
			txt='comment:1';
		}else if (id=='custom') {
			txt=row.getAttribute('search_rule');
		}
		search_init(txt);
		FolderShow(sw.fld_id,{noreset:true});
		return;
	}
	
}
function full_cursor2link(el)
{
	return el.childNodes[2].childNodes[0];
}

function learn_word(txt)
{
	queued_req_add( enQ, 'learn_word', function(){
		sndReq('cmd=spellcheck_learn,show&page=~result.js&new_word='+xescape(txt), function(chan){
			var success=actionReqJsStat(chan);
			if(success){
				set_status($('$$st_spell_learnt$$',txt),"success");
			}else{
				set_status('$$st_spell_learn_bad$$ '+success_string,'warning');
			}
		},ch[enQ]);
	});
}
function check_version(ver)
{
	if(ver==version||version==undefined) return true;
	set_status('$$st_stat_upg$$','warning');
	x_alert('$$st_dlg_upg$$');
	sw.upgrade_pending=true;
	update_ssb_status(-1);
	version=undefined;
	return false;
}


# Create a "jmsg" object ie. javascript message object that lasts until the message is successfully sent or message is discarded
# lives in the context of the main window even for popup windows so it does not need to cloned
function compose_jmsg(eml,ident)
{
	var jmsg=new Object();
	jmsg.to=eml;jmsg.cc=[];jmsg.bcc=[];
	jmsg.sel_mids=[]
	jmsg.params=jmsg.subject=jmsg.msg_html=jmsg.msg_text=jmsg.cache_mid=jmsg.fld_id='';
	jmsg.action='compose';
	jmsg.send_mode=pref.send_mode!='auto'?pref.send_mode:'plain_text';
	jmsg.ident=ident?ident:sw.ident;
#	jmsg.sig_id=decide_sig(jmsg.ident);
	return jmsg;
}
function jmsg_reset(jmsg)
{
	jmsg.cb=jmsg_check_ready;
	jmsg.msg_html=jmsg.msg_text='';
	jmsg.cb_requested=U;
}
function sel_to_jmsg(sel, action)
{
	var jmsg=new Object();
	dbg('sel_to_jmsg '+action);

#	// Automatically switch "forward" to "forward attach" for multiple messages
	if (sel.length>1 && action=='forward') action='forward_attach';

#	// The bare minimum information we need to identify a message :-)
	jmsg.action=action;
	if(sel.ident){
		jmsg.ident=sel.ident;
		jmsg.ident_orig=sel.ident;
		jmsg.fld_id=sel.fld_id;	
		jmsg.fid=sel.fid;	
		jmsg.fld_type=sel.fld_type;	
	}else{
		jmsg.ident=sw.ident;
		jmsg.fld_id=sw.fld_id;	
		jmsg.fid=sw.fid;	
		jmsg.fld_type=sw.fld_type;	
	}
#	jmsg.sig_id=decide_sig(jmsg.ident);
	jmsg.cache_mid=sel[0];
	jmsg.sel_mids=sel;
	
# 	// Now actually get the message details if we have it
	if(!cache_find(cache_id(jmsg.ident,jmsg.fid,jmsg.cache_mid))){
		dbg('don\'t actually have the source message yet so setting up callback to poll later');
		jmsg.cb=jmsg_check_ready;
		return jmsg;
	}

	if (action=='view') return jmsg;

	return jmsg_complete(jmsg);
}
function jmsg_check_ready(jmsg)
{
	if(!cache_find(cache_id(jmsg.ident,jmsg.fid,jmsg.cache_mid))) return false;
	if(jmsg.action=='view') return true;
	jmsg_complete(jmsg);
	return true;
}
function jmsg_complete(jmsg)
{
	var action=jmsg.action;
	qmsg=cache_find(cache_id(jmsg.ident,jmsg.fid,jmsg.cache_mid));
	if(!qmsg) {alert('msg error, should never get here!!');return jmsg;}

	var from=cloneObject(qmsg.data['from']);
	var to=cloneObject(qmsg.data['to']);
	var cc=cloneObject(qmsg.data['cc']);
	var bcc=cloneObject(qmsg.data['bcc']);
	var reply_to=cloneObject(qmsg.data['reply_to']);

	jmsg.related=qmsg.data['related'];
	jmsg.send_mode=(pref.send_mode=='auto')?qmsg.data['send_mode']:pref.send_mode;
	jmsg.subject=qmsg.data['subject'];
	jmsg.date=qmsg.data['date'];

	jmsg.nattach=val_int(qmsg.data['attachments']);
	jmsg.mpr_as=qmsg.data['mpr_as'];
	jmsg.encryption=qmsg.data['encryption'];

	jmsg.ref_messageid=qmsg.data['ref_messageid'];
	
	var clean_resend = (action=='resend') && pref.clean_resend;
	
	if(from[0].indexOf('$$Surge Note$$')!=-1 || (jmsg.fld_id=='$$Notes$$')) jmsg.note=true;
	
#	// Work out what part of the old message body to display
	jmsg.msg_html=jmsg.msg_text='';
	if(action=='redirect'){
		jmsg.msg_html=qmsg.msg_html;
	}else if((action=='edit') || (action=='send_asnew') || clean_resend){
		if(pref.editor_textonly){
			jmsg.msg_text=qmsg.msg_txt;
		}else{
			jmsg.msg_html=qmsg.msg_html;
		}
	}else if(action=='forward_attach'){
#		nothing to set...
	} else if (!clean_resend){
		if(((action=='reply') || (action=='resend')) && !pref.no_short_reply_hdr){
		  var when = date_reformat1(jmsg.date)+' '+contact_string_short(text2contact(clean_whitespace(from[0])))+' $$st_reply_wrote$$ ';
		  if(pref.editor_textonly){
		    jmsg.msg_text= when + '\n' + qmsg.msg_txt;
		  }else{
		    jmsg.msg_html= '<div>'+when +'</div>'+(pref.no_replycolor?'':'<blockquote type="cite">') + qmsg.msg_html + (pref.no_replycolor?'':'</blockquote><br>');
		  }
		}else{
		  if(pref.editor_textonly){
			jmsg.msg_text=
				'$$st_txt_hdr_orig$$\n'
				+'> $$st_hdr_subject$$ '+jmsg.subject+'\n'
				+'> $$st_hdr_from$$ '+rcpts_as_plain(from)+'\n'
				+'> $$st_hdr_to$$ '+rcpts_as_plain(to)+'\n'
				+(cc.length>0 ? '> $$st_hdr_cc$$ '+rcpts_as_plain(cc)+'\n': '')
				+'> $$st_hdr_date$$ '+jmsg.date+'\n'
				+'> \n> \n'
				+qmsg.msg_txt;
		  }else{
			jmsg.msg_html=
				(pref.no_replycolor?'':'<blockquote type="cite">')
				+'$$st_txt_hdr_orig$$'
				+' <br><b>$$st_hdr_subject$$</b> '+encode_lt_gt(jmsg.subject)
				+' <br><b>$$st_hdr_from$$</b> '+rcpts_as_html(from)
				+' <br><b>$$st_hdr_to$$</b> '+rcpts_as_html(to)
				+(cc.length>0 ? ' <br><b>$$st_hdr_cc$$</b> '+rcpts_as_html(cc) : '')
				+' <br><b>$$st_hdr_date$$</b> '+jmsg.date
				+'<br><br>'
				+qmsg.msg_html
				+(pref.no_replycolor?'':'</blockquote><br>');
		  }
		}
	}
#	// Now work out addressing	
	if (action=='redirect') to=[];
	jmsg.cc=[];
	jmsg.bcc=[];	
	if (action=='reply' || action=='reply_all'){
		if (jmsg.subject.substring(0,2)=="~ " && pref.sim_enable) jmsg.autosubject = true;
		if (jmsg.subject.substring(0,3).toLowerCase()!="re:") jmsg.subject='Re: '+jmsg.subject;
		jmsg.to=(jmsg.fld_type==enSent?to:reply_to);
		if(action=='reply_all'){		
			jmsg.cc=to;
			if(cc.length>0) jmsg.cc=jmsg.cc.concat(cc);
		}
	}else if (action=='resend') {
		jmsg.to=(jmsg.fld_type==enSent?to:reply_to);
		jmsg.cc=cc;
		jmsg.bcc=bcc;
		if(clean_resend){
			jmsg.not_new=true;
		}else{
			if (jmsg.subject.substring(0,4).toLowerCase()!="re:") jmsg.subject='Re: '+jmsg.subject;
		}
	}else if ((action=='forward') || (action=='forward_attach')) {
		if (jmsg.subject.substring(0,4).toLowerCase()!="fwd:") jmsg.subject='Fwd: '+jmsg.subject;
		jmsg.to=[];
	}else if (action=='send_asnew') {
		jmsg.to=[];
		jmsg.not_new=true;
	}else if (action=='focus') {
		jmsg.from = contact_string_email(text2contact(clean_whitespace(from[0])));
	}else{
#		Re-edit a draft or other message etc
		jmsg.to=to;
		jmsg.cc=cc;
		jmsg.bcc=bcc;
		jmsg.not_new=true;
		jmsg.edit_uid=cache_id(jmsg.ident,jmsg.fid,jmsg.cache_mid);
	}
	return jmsg;
}


#// See [function ajax_send]
#// Used to be [function msg_for_sending(node)]

function jmsg_update(node)
{
#	Make sure allocs are done in the context of the main window	
	if(sw.is_popup) {
		return sw_win.jmsg_update(node);
	}
	var jmsg=node.jmsg;
	if (!jmsg) {alert('invalid jmsg please report this fault');return;}
	
	jmsg.to=fancy_edit_value(node.field_to);
	jmsg.cc=fancy_edit_value(node.field_cc);
	jmsg.bcc=fancy_edit_value(node.field_bcc);
	jmsg.priority=node.field_priority.value;
	jmsg.confirm=node.field_confirm.value;
	jmsg.encrypt=node.field_encrypt.value;
	jmsg.ifnew=node.field_ifnew.value;
	if (node.field_encrypt.override) jmsg.encrypt=(jmsg.encrypt=='surgevault'?'always':'never');		// QQENC
	jmsg.subject=node.field_subject.value;
	if(pref.editor_textonly){
		jmsg.msg_text=node.field_xeframe.firstChild.value;
		jmsg.msg_body_type='text';
	}else{
		jmsg.msg_html=msg_from_editor(node);
	}
	jmsg.from=[node.field_from.value];	
	jmsg.params='&from='+rcpts_as_param(jmsg.from)+'&priority='+jmsg.priority+'&confirm='+jmsg.confirm+'&encrypt='+jmsg.encrypt;
	if(jmsg.action!='reply' && jmsg.action!='replyall'){
		jmsg.ref_messageid='';
	}
	
	if(pref.vault_lock||pref.vault_ifnew) jmsg.params += '&vaultlock_ifnew='+jmsg.ifnew;
	if(jmsg.mpr_as=='attach') jmsg.params+='&mpr_as=attach';

	if(jmsg.attach_ids||(jmsg.attach_ids_mpr&&(jmsg.attach_ids_mpr.length>0))){
		jmsg.params+='&attach_mid='+jmsg.attach_mid;
		if(jmsg.attach_ids || jmsg.attach_ids2){
			var combined = '';
			if(jmsg.attach_ids.length>0){
				combined+=jmsg.attach_ids.join(',');			// SW_CLOUDFILE
			}
			if(jmsg.attach_ids2 && jmsg.attach_ids2.length>0){
				if(combined.length>0) combined+=',';
				combined+=jmsg.attach_ids2.join(',');
			}
			jmsg.params+='&attach_ids='+combined;
		}
		if(jmsg.attach_ids_mpr&&(jmsg.attach_ids_mpr.length>0)){
			jmsg.params+='&attach_ids_mpr='+jmsg.attach_ids_mpr;
		}
	}
	if (jmsg.edit_uid){
		jmsg.params+='&edit_uid2='+jmsg.edit_uid;
	}
	jmsg.params+='&send_mode='+jmsg.send_mode;
||ifdef||_note_not_yet_||
	if(jmsg.note){
		jmsg.note_keeptime=node.field_keeptime.value;
		jmsg.params+='&keep_time='+jmsg.note_keeptime;
	}
||endif||
	// Turn this into or conditions??
	jmsg.from_popup=node.is_popup;
	jmsg.node=node;
	
	return jmsg;
}
function main_window_check(node)
{
	var ok;
#	// try catch based check (I can't think of anything nicer for now) 
	try{var dummy=node.jmsg.to; ok=true;}catch(e){ ok=false;}

	if(!ok || !window.opener || window.opener.closed){
		alert('$$st_nomain_warn1$$\n\n $$st_nomain_warn2$$');
		return false;
	}
	
	return true;
}

function jmsg_display_class(jmsg){
	return (jmsg.action=='redirect'?'do':'no')+'redirect';
}

function compare_folders(fld1,fld2)
{
	if(fld1==fld2) return true;
	x_alert($('$$st_fld_compare$$', fld1, fld2));
	return false;
}
function bookmarking_init()
{
	if(pref.devt_test=='nounload') return;

	window.onbeforeunload=function(e){
		if(sw.closing) return;
		if(sw.active.unsaved) 
			return '$$st_warn_message_lost$$';
		var want_warn = false;

		var have_compose = false, have_message=false;
		var switcher = dge('switcher');
		for(i=1;i<switcher.childNodes.length;i++)
		{
			var tab = switcher.childNodes[i].panelised_inner;
			if(class_contains(tab.node_ref,'compose')) have_compose = true;
			if(class_contains(tab.node_ref,'message')) have_message = true;
		}
		if(have_message || have_compose)
		{
			want_warn = true;
		}
		var url = document.activeElement.href;
		var probably_attachment = url!=U && url.indexOf('attachment=true')!=0;
		if(probably_attachment)
		{
			want_warn = false;
			setTimeout(function(){
				dge("mnu_more2").focus();
				dge("mnu_more").focus();
			},1);
		}
		if(want_warn)
			return '$$st_warn_message_closed$$';
			
	}
}
function fancy_edit_hidden(el)
{
	el=ancestor_by_class(el,'compose_hdr_row');	
	return class_contains(el,'hidden');
}
function focus_next_surgeweb_edit_ctl(el)
{
	var o=sw.active;
	var next;
	if(el==o.field_to)
		next=o.field_cc;
		
	if((el==o.field_cc) || (next==o.field_cc && fancy_edit_hidden(o.field_cc)))
		next=o.field_bcc;

	if((el==o.field_bcc) || (next==o.field_bcc && fancy_edit_hidden(o.field_bcc)))
		next=o.field_subject;

	if(el==o.field_subject)
		next=o.field_eframe.contentWindow;

	if(!next) return;

	next.focus();	
}

#var q=[]
#for (var i=0;i<100;i++)
#	q[i]='012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';

function do_test()
{
#	benchmark_begin('1');
#	for (var i=1;i<10000;i++)
#		dbg(q[1]+q[2]+q[3]+q[4]+q[5]+q[6]+q[7]+q[8]+q[9]+q[0]);
#		dbg();
#	alert(benchmark_end('1'));
	
}
# Do one of several spam processing action: notspam, once, spam, block
function spam_info(type,fld,mid,full_msg,from_popup)
{
	var full_msg=false;
	if(!full_msg && !class_contains(sw.active,'fldmsg')) full_msg=true;

	if(sw.is_popup){
		sw_win.spam_info(type,fld,mid,full_msg,true);		
		window.close();
		return;
	}
	if(!full_msg){
#		If on msglist allow multiple selections
		var sel=find_sel(true);
		if(sel.length>1){
			x_confirm('$$st_spam_multi$$',function(n){
				if(!n) return;
				spam_info_step2(type,sel);
				if(/*full_msg &&*/ !from_popup){
					message_done_action(sel);			
				}
			});
			return;
		}
	}
	var sel=make_sel(fld,mid);
	spam_info_step2(type,sel);
	if(/*full_msg &&*/ !from_popup){
		message_done_action(sel);			
	}
}
function spam_info_step2(type,sel)
{
	ajax_spam_rating(sel,type,function(){});
	
#	// Do stuff dependant on location
	if(class_contains(sw.active,'fldmsg')){
		// preview
		no_msg_sel();
	}else if(sw.is_popup){
		// popup
	}else{
		// inline	
	}
}

function partial_update_results(o)
{
	partial_updates = o;
}
function folder_refresh_results()
{
	folder_refresh=true;
}

function misc_init()
{
	search_init(undefined,pref.search_type);
	
	Dbg.report_cb=function(txt){
		x_prompt("This will send matching browser and server SurgeWeb debug logs to surgeweb-support@netwinsite.com. Please add a comment to identify the reason for sending this report :","comment",function(val){
			if (!val) return;
			var jmsg=compose_jmsg(['surgeweb-support@netwinsite.com']);
			jmsg.params='&to='+rcpts_as_param(jmsg.to)+'&subject='+xescape('SurgeWeb fault report')+'&attach_debug_log=true';
			jmsg.report=true;
			jmsg.msg_html=	'Fault reported by: '+work_out_from()+'<br>'+
							'Comment:'+val+'<br>'+
							'<br>'+
							'Surgweb browser log:<br>'+
							txt;
			ajax_send(jmsg);
		});
	}
	if('true'=='||online_status_dev||'){
		var el;
		surge_chat_init();
		el=dge('personal_info'); Drag.init(el, el);
		el=dge('oli1'); Drag.init(el, el);
		el=dge('oli2'); Drag.init(el, el, null,null,10,10, U,U);
		el=dge('oli3'); Drag.init(el, el);
	}
	accounts_init();
	if(do_fdnd()){
		fdnd_init(dge('sw_body'),'none',fdnd_global_hover,fdnd_global_drop);
		fdnd_init(dge('lpanel_body_outer'),'copyMove',fdnd_compose_hover,fdnd_compose_drop);
		fdnd_init(dge('msglist_box'),'copyMove',fdnd_list_hover,fdnd_list_drop);
	}
	swf_id();
	sw.hint_at = time()+60;
}

# defined fuctions this way else some browsers do not allow you to call them
var map_sw_2_core, map_core_2_sw, map_ctls_to_ctl0, ctl0_mapping, ctl_text, ctl2_allow, extra_info;
var usercgi_status, usercgi_raw, usercgi_working, usercgi_messages=['',''];
var opt_xx=['respond','fwd_early','filter','whitelist','spam','unknown','fwd_late'];

function usercgi_summary()
{
#return;
	usercgi_status={'respond':'(unknown)', 'fwd_early':'(unknown)', 'filter':'(unknown)', 
					'whitelist':'(unknown)', 'spam':'(unknown)', 'unknown':'(unknown)',	'fwd_late':'(unknown)'};

	for(var i=0;i<opt_xx.length;i++){
		el=dge('filt_'+opt_xx[i]);
		if(el) el.innerHTML=usercgi_status[opt_xx[i]];
	}
	
	queued_req_add( enQ, 'usercgi_summary', function(){
		var url=backend+'cgi/user.cgi?cmd=auto_login%26lcmd=user_summary_info%26show=sw_summary.js%26utoken='+utoken;
		sndReq('cmd=proxy&sid='+sid+'&add_auto_login=true&url='+url, function(chan){
#			// check validity of response... 
			var success=actionReqJsStat(chan);
			if(usercgi_raw) apply_summary_info();
		},ch[enQ]);
#		cgibase=tmp;
	});
}
#			var usercgi_status={
#					'respond':'ENABLED', 'fwd_early':'UNKOWN', 'filter':'STATUS', 'whitelist':'STATUS',
#					'spam':'<font color="green">ENABLED</font>', 'unknown':'<font color="red">DISABLED</font>', 'fwd_late':'STATUS'};

function set_ctl0(event,ctl)
{
	var onestep=ctl.value;

	ctl_dynamic_select(ctl,ctl0_options(ctl.value),ctl_text);
	ctl.value=onestep;
	ctl_dynamic_info(ctl);
	
	var state=ctl0_mapping[onestep];	
	map_sw_2_core(state[0],state[1],usercgi_working);
	
	var w=usercgi_working;
	var url=backend+'cgi/user.cgi?cmd=auto_login%26lcmd=user_spam_save%26combine_spam_friends=true%26lcmd_ex=user_summary_info%26show=sw_summary.js';
	url += '%26friend_mode='+w.friend_mode+'%26friend_smite='+w.friend_smite+'%26recent_out_auto='+w.recent_out_auto
			+'%26spam_subject='+w.spam_subject+'%26spam_body='+w.spam_body+'%26spam_bounce='+w.spam_bounce
			+'%26spam_ddpriv='+w.spam_ddpriv+'%26spam_ddfrom='+w.spam_ddfrom+'%26spam_store='+w.spam_store+'%26spam_vanish='+w.spam_vanish;

	sndReq('cmd=proxy&sid='+sid+'&add_auto_login=true&url='+url, function(chan){
		var success=actionReqJsStat(chan);
		apply_summary_info();
	})
}

function apply_summary_info()
{
	var val;
	var lookup=[];
#	Do any complicated workings out...

debugger

	if(usercgi_status['respond']=='not available'){
		var txt=usercgi_messages.join(', ');
		if(txt.length<=2) txt='unknown error';
		set_status('$$st_stat_usercgi_bad$$ - '+txt,'warning');
		for(var i=0;i<opt_xx.length;i++){
			el=dge('filt_'+opt_xx[i]);
			if(el) el.innerHTML='(not available)';
		}
		return;
	}

	if(true){
		usercgi_working=cloneObject(usercgi_raw);	
		var state=map_core_2_sw(usercgi_working);
		var onestep=map_ctls_to_ctl0(state);
		ctl=dge("spam_onestep");
		if(ctl){
			ctl_dynamic_select(ctl,ctl0_options(onestep),ctl_text);
			ctl.value=onestep;
			ctl_dynamic_info(ctl);
		}
		switch(onestep){
			case 'disabled': 		val='disabled';break;
			case 'little_spam': 	val='markonly';break;
			case 'little_spam2':
			case 'lots_spam':
			case 'lots_spam2': 		val='enabled';break;					
			case 'child_account': 	val='kidsafe';break;
			default:				val='custom';break;
		}
		if(usercgi_working.spam_store>0 || usercgi_working.spam_vanish>0)
			val='warn';
		lookup['spam']=val;

		if(usercgi_working.friend_mode!='disabled'){
			if(usercgi_working.recent_out_auto=='checked')
				val='enabled';
			else
				val='part';
		}else{
			val='disabled';
		}
		lookup['whitelist']=val;

		switch(usercgi_working.friend_mode){
			case 'smite':
			case 'ask':	val='enabled'; break;
			case 'safe':val='kidsafe';break;
			default: val='disabled';break;
		}
		lookup['unknown']=val;				
	}
	for(var i=0;i<opt_xx.length;i++){
		if (!usercgi_status || !usercgi_status[opt_xx[i]]) continue;
		if(opt_xx[i]=='whitelist' || opt_xx[i]=='spam' || opt_xx[i]=='unknown'){
			val=usercgi_status[opt_xx[i]][lookup[opt_xx[i]]];
		}else{
			val=usercgi_status[opt_xx[i]];
		}
		el=dge('filt_'+opt_xx[i]);
		if(el) el.innerHTML=val;
	}
	if(dge('forward_early')){
		if(usercgi_status['use_late']=='checked'){

			class_add(dge('forward_early'),'hidden');
			class_remove(dge('forward_late'),'hidden');
		}else{
			class_add(dge('forward_late'),'hidden');
			class_remove(dge('forward_early'),'hidden');
		}
	}
	extra_info('extra_info2',usercgi_working);
	if(usercgi_status['g_imap_friends']=='false')
		class_remove(dge('warning_g_imap_friends'),'hidden');

	var extras = usercgi_status['extras'];
	var some = false;
	var keys = ['legal','notify','lists','import','alias','cleanup','detach'];
	for(keyid in keys){
		var key = keys[keyid];
		if(extras[key]!='true') continue;
		if((key=='alias'||key=='lists') && extras[key+'_quota']==0) continue;
		if(pref.extras_disable.indexOf('all')!=-1 || pref.extras_disable.indexOf(key)!=-1) continue;
		class_remove(dge('options_'+key),'hidden');
		some=true;
	}
	if(some){
		class_remove(dge('ot5'),'hidden');
	}else{
		class_add(dge('ot5'),'hidden');
	}	
}
function ctl0_options(val)
{
	var arr=['disabled','little_spam','little_spam2','lots_spam'];
	if (val=='child_account' || val=='custom') arr.push(val);
	return arr;
}
function newpass(pass)
{
	sndReq('cmd=session_update,show&page=~result.js&newpass='+xescape(pass), function(chan){
		var success=actionReqJsStat(chan);
		if(!success){
			set_status('$$st_stat_passwd_bad$$','warning');
		}
	});
}

function cur_quota(o)
{
	if(sw.is_popup) return sw_win.cur_quota(o);
	
	var refresh=false;
	if(!sw.quota || sw.quota.pct!=o.pct) refresh=true;
	sw.quota=cloneObject(o);
	if (refresh && class_contains(sw.active,'fldmsg')) 
		app_menu('mail',dge('app_mail'));
}

# Also defined in surgemail source code (and may still be some hardcoded numbers in the source)
var enFldInbox=1, enFldDrafts=2, enFldSent=3, enFldTrash=4, enFldUser=5, enFldSpam=6;

# Active Selection handling code locations 
# n retrieve_msg
# sw.search_type
# sw.multiple
# show_thread > search_init > do_stype
# search_keyup > do_search_folders > F > switch_selfld
# onclick > do_search_folders > F > switch_selfld


# OSX colors: blue color="#144fae" | green color="#006312" | brown color="#540000"
# TB colors: blue color="#0000ff" | brown color="#800000" | blue/green color="#008080" | purple color="#800080" | green color="#008000"

function quote_styles()
{
	return 	' .sw_message blockquote{margin-left:5px;padding-left:5px;border-left:2px solid #144fae;color: #144fae;}\n'+
			' .sw_message blockquote blockquote{border-left:2px solid #006312;color: #006312;}\n'+
			' .sw_message blockquote blockquote blockquote{border-left:2px solid #8e5656;color: #8e5656;}\n'+
			' .sw_message blockquote blockquote blockquote blockquote{border-left:2px solid #888;color: #888;}\n';
}

function quote_breakout(e)
{
	var el, ret, sel;
	if(pref.no_replycolor) return false;

	var xwin=get_edit_win();
	var xdoc=xwin.document;

	if(isIE){
		el=selectedElementIe(xdoc);
		ret=quoteBreakoutIe(xdoc,el);
	}else{	
		sel=selectedElementStd(xwin);
		ret=quoteBreakoutStd(xwin,sel)
	}
	return ret;	
}

function selectedElementIe(xdoc)
{
	var r,id,el;
	r=xdoc.selection.createRange();
	id=uniqueId();
	r.pasteHTML('<span id="'+id+'"></span>');
	el=xdoc.getElementById(id);
	el.id='';
	return el;
};
function selectedElementStd(xwin)
{
	var el,frag,sel,mysel;
	sel=get_selection_std(xwin)
	if(!sel) return null;
	mysel=get_range_std(sel);
	if(mysel.start_el.nodeType==1 && mysel.start_el.tagName=="BLOCKQUOTE"){
		frag=mysel.start_el.childNodes[mysel.offset];
		el=xwin.document.createTextNode('');
		mysel.start_el=frag.appendChild(el);
		mysel.offset=0;
	}
	return mysel;
};

function quoteBreakoutIe(xdoc,el)
{
	var pivot,g,r,frag;
	pivot=quote_root(el);
	if(!pivot) return false;
	frag=el.cloneNode(false);
	frag=dom_split(el,frag,pivot);
	special_insert_before(frag,pivot);
	g=xdoc.createElement('div');
	pivot.parentNode.insertBefore(g,frag);
	g.innerHTML='&nbsp;';
	r=xdoc.selection.createRange();		// 
	r.moveToElementText(el);
	r.move('character',2);
	r.select();
	g.innerHTML='';
	r.pasteHTML('');	
	return true;
};
function quoteBreakoutStd(xwin,sel)
{
	var el,pivot,i,frag;
	if (!sel) return false;
	el=sel.start_el;
	pivot=quote_root(el);
	i=false;
	if(pivot){
		if(el.nodeType==3){
			frag=el.splitText(sel.offset);
		}else{ 
			dbg('warnign non DOM node quote breakout - may not work');
			i=true;
		}
	}
	// deal with not landing on a textNode by adding textnodes etc
	if(!pivot)return false;
	frag=dom_split(el,frag,pivot);
	special_insert_before(frag,pivot);
	el=xwin.document.createElement('div');
	el.innerHTML='&nbsp;';
	pivot.parentNode.insertBefore(el,frag);
	xwin.getSelection().collapse(el,0);
	return true;
};


function quote_root(node)
{
	var pivot=null;
	for(var el=node.parentNode;el;el=el.parentNode)
		if(el.tagName=='BLOCKQUOTE') 
			pivot=el;
	return pivot;
}

var unique_id_n=0;
function uniqueId(){
	return 'swq_'+unique_id_n++;
}

function special_insert_before(b,a)
{
	a.parentNode&&a.parentNode.insertBefore(b,a.nextSibling)
}
function get_selection_std(xwin)
{
	if(xwin.getSelection){
		return xwin.getSelection();
	}else{
		var xdoc=win.document;	
		return xdoc.selection || xdoc.getSelection && xdoc.getSelection();
	}
}
function get_range_std(b)
{
	var r,c=false;
	if(b.createRange){
		try{
			r=b.createRange()
		}catch(d){
			return null
		}
	} else if(b.rangeCount){
		if(b.rangeCount>1){
			dbg('BAD: multiple ranges defined - unhandled')
			return null;
		}else{
			r=b.getRangeAt(0);
		}
	} else {
		return null;
	}
	if(r.addElement) {
		dbg('BAD: unhandled case');
		return null;
	}
	var ret={};
	ret.start_el=r.startContainer;
	ret.offset=r.startOffset;
	return ret;
}


# -----

function set_sendmode_html()
{
	if(!sw || !sw.active || !sw.active.field_send_mode) return;
    var el=sw.active.field_send_mode;
	if(pref.send_mode!='auto') return;
	
	el.innerHTML="$$st_opt_sendmode_html$$"
    sw.active.jmsg.send_mode='html';
}
function toggle_sendmode()
{
	if(!sw.active.field_send_mode) return;
    var el=sw.active.field_send_mode;	
	var jmsg=sw.active.jmsg;
	if(jmsg.send_mode=='html'){
		el.innerHTML='$$st_opt_sendmode_text$$';
		jmsg.send_mode='plain_text';
	}else{
		el.innerHTML='$$st_opt_sendmode_html$$';
		jmsg.send_mode='html';
	}
}
function vault_lock_override(icon,el,from_icon)
{
	if(el.n_override==U) el.n_override=0;
	el.n_override++;
	if(from_icon && el.n_override>2){
		el.n_override=0;
		el.override = false;
		return false;
	}else{
		el.override = true;
	}
	if(!from_icon) el.n_override=1;
	return true;
}

function toggle_encrypt_menubar(el)
{
    var enc=sw.active.field_encrypt;
#	if(enc.rcpt_count>1) {
#		x_alert('$$st_cmd_menc_warn1$$');
#		return;
#	}
    var reset = false;
    if(pref.vault_lock){
    	reset=!vault_lock_override(el,enc,true);
    }
    if(reset){
		vcheck_update_icon(el);
    }else{
		encrypt_set(el,enc,(enc.value==''?'surgevault':''),enc.rcpt_count);
	}
	if(pref.vault_lock) return;
	save_sticky();
}
function toggle_encrypt_select(el)
{
    var icon=dge('send_encrypt');
    if(pref.vault_lock) vault_lock_override(icon,el);
	encrypt_set(icon,el,el.value,el.rcpt_count);
	if(pref.vault_lock) return;
	save_sticky();
}
function toggle_encrypt_ifnew(el)
{
	save_sticky();
}

function toggle_encrypt_vaultlock(enable)
{
#	encrypt_set(dge('send_encrypt'),sw.active.field_encrypt,(enable?'surgevault':''));
}
function encrypt_set(el_icon,el_select,type,nrcpt)
{
	if(type=='surgevault'){
		el_select.value='surgevault';
		class_remove(el_icon,'surgevault_multi');
		class_add(el_icon,'surgevault');
		el_icon.title='$$st_cmd_menc_vault_tt2$$';
	}else if (type=='surgevault_multi'){
		el_select.value='surgevault';
		class_remove(el_icon,'surgevault');
		class_add(el_icon,'surgevault_multi');	
		el_icon.title='$$st_cmd_menc_vault_tt3$$';
	}else{
		el_select.value='';
		class_remove(el_icon,'surgevault');
		class_remove(el_icon,'surgevault_multi');
		el_icon.title='$$st_cmd_menc_vault_tt1$$';
	}
	if(el_select.override && nrcpt==1){	// QQENC
		class_add(el_icon,'override');
	}else{
		class_remove(el_icon,'override');
	}
	if(nrcpt==U)return;
	el_select.rcpt_count=nrcpt;
	if(nrcpt>1){
		el_select.disabled=true;
	}else{
		el_select.disabled=false;
	}
}
function encrypt_set_multi(el_icon,el_select,info)
{
	var nrcpt=info[0]+info[1];
	var state;
	if (info[0]>0 && info[1]>0){
		state='surgevault_multi';
	}else if(info[0]>0){
		state='';
	}else{
		state='surgevault';
	}
	encrypt_set(el_icon,el_select,state,nrcpt);
}

function row_shown(el)
{
	var po=ancestor_by_class(el,'compose_hdr_row');
	return !class_contains(po,'hidden'); 
}
function save_sticky(sticky)
{
	var val,js_val;
	if(!sw.active.field_sticky.checked && !sticky) return;
	if(sticky && !sticky.checked){
		js_val=undefined;
		val='';
	}else{
		js_val=[row_shown(sw.active.field_cc),row_shown(sw.active.field_bcc),row_shown(sw.active.field_priority),sw.active.field_priority.value,sw.active.field_confirm.value,sw.active.field_encrypt.value,sw.active.field_signature.value,'false',sw.active.field_ifnew.value];
		val='['+js_val[0]+','+js_val[1]+','+js_val[2]+',"'+js_val[3]+'","'+js_val[4]+'","'+js_val[5]+'","'+js_val[6]+'","'+js_val[7]+'","'+js_val[8]+'"]';  // QQQSIM 
	}

	if(sw.is_popup)
		return sw_win.save_sticky_frompopup(js_val,val)
	pref.compose_sticky=js_val;
	ajax_pref_save('pref_compose_sticky='+val);
}
function save_sticky_frompopup(js_val,val)
{
	pref.compose_sticky=cloneObject(js_val);
	ajax_pref_save('pref_compose_sticky='+val);
}
function signature_dbgout(txt)
{
	return txt.length+':'+encode_lt_gt(txt);
}
function signature_select(el,val,xwin)
{
	if(el) el.innerHTML=val;
	if(xwin) xwin.orig_sig=val;
	if(val.indexOf('<')!=-1 && sw.active.jmsg.send_mode!='html'){
		toggle_sendmode();
	}
	dbg('** SIGSET xwin.orig_sig='+signature_dbgout(val))
}
function toggle_signature(ctl) // QQQSIM 
{
	var xwin=get_edit_win();
	var xdoc=xwin.document;
	var el=xdoc.getElementById('editor_signature');
	if(!el){
		var i,frag;
		for (var i=0;i<3;i++){
			frag=xdoc.createElement('br');
			xdoc.body.appendChild(frag);
		}
		el=xdoc.createElement('div');
		el.id='editor_signature';
		xwin.orig_sig='';
		xdoc.body.appendChild(el);
	}
	var new_sig_id = ctl.value;
	dbg('*** SIGCHANGE ['+signature_dbgout(xwin.orig_sig)+'] ['+signature_dbgout(el.innerHTML)+']')
	x_confirm('$$st_sig_edited_replace$$',function(n){
		if(!n) return;
		var val=(ctl.value==''?'':sw.signatures[new_sig_id].body);	//QQSIG
		signature_select(el,val,xwin);
	}, sametext_nc(xwin.orig_sig,el.innerHTML));
}

function signature_dlg(type)
{
	var cmd='cmd=show&page=signature.htm&sid='+sid;
||if(not(istrue(consolidated_prefs_disable)))||
	do_usercgi_inline_step2('usercgi_general_iframe',cgibase+cmd);
	return;
||endif||
	x_custom_dlg2('$$st_sig_edit_sigs$$',dialog_iframe(cgibase+cmd),
		function(btn){
			//ie_fixfocus();
			//usercgi_summary();
			sig_refetch();
	}, U, {'width':660,'tall':true});
}

function dialog_iframe(url)
{
	return '<iframe src="'+url+'" style="width:100%;height:'+px(ClientHeight()*0.9-100)+'"></iframe>'
}

function get_edit_win()
{
	return sw.active ? sw.active.field_eframe.contentWindow : document.getElementById('eframe1').contentWindow;
}

function ed_insert_smarts()
{
	var xwin=get_edit_win();
	var xdoc=xwin.document;
	if(isIE){
		el=selectedElementIe(xdoc);
	}else{	
		sel=selectedElementStd(xwin);
		el=sel.start_el;
		if(el.nodeType==3){
			el=el.splitText(sel.offset);
		}
	}
	var type='link';
	if (type=='img'){
		var frag=document.createElement('img');
		frag.src='http://netwinsite.com/img2/box_surgemail.jpg';
		el.parentNode.insertBefore(frag,el);
	}else if (type=='link'){
		var frag=document.createElement('a');
		frag.href='http://netwinsite.com';
		frag.innerHTML='Link Description';
		el.parentNode.insertBefore(frag,el);
	}		
	return true;
}


function tweak_ie7_msglist(el)
{
	var row, rows, labels, icons, i, w;
	rows=el.getElementsByTagName('tr');
	for(row=0;row<rows.length;row++){		
		labels=row_to_labels(rows[row]);
		icons=labels.previousSibling;
		for(i=0,w=0;i<icons.childNodes.length;i++) w+=icons.childNodes[i].offsetWidth;
		icons.style.width=px(w);
		for(i=0,w=0;i<labels.childNodes.length;i++) w+=labels.childNodes[i].offsetWidth;
		labels.style.width=px(w);
	}

}

function date_reformat1(txt)
{
	var parts=txt.split(' ');
	var day=parts[0].split(',');
	var tstart=(parts[2]==''?3:2);
	return 'On '+day[0]+' '+parts[1]+' at '+parts[tstart]+(parts.length-1>tstart?(' '+parts[tstart+1].toLowerCase()):'')+',';
}

function preview_to_body(el)
{
	return el.childNodes[1];
}

#function cxx_image(){
#	return 'background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAoElEQVR42pWRQQ7CIBBFuZsn8BJezAN4BI/goqx0p4lpIwtNaVIowy8zIKmr1kl+/v/DYzVKpTmezliT+oJbRj78DXuKmELEbn/AJBnwpfvSK2xdRO8AO0IA7uz9WPZuARsbYYaIVxGDZqDa+a3C9zdlfTLIOXvEI2VWhW+GRAzkHGq/ll5h3QboLqklNCk3HUnW7LJfwJdnWNXPYbZccAaPd5VkvusvLAAAAABJRU5ErkJggg==)';
#}

var menu_icon;

function cxx_mouseover(e)
{
	var t=target(e);
	if(!class_contains(t,'rcpt')) return;

	if(menu_icon/* && menu_icon.parentNode!=t*/)
		hide_soon(menu_icon,true);
	
	var el=document.createElement('img');
	el.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAoElEQVR42pWRQQ7CIBBFuZsn8BJezAN4BI/goqx0p4lpIwtNaVIowy8zIKmr1kl+/v/DYzVKpTmezliT+oJbRj78DXuKmELEbn/AJBnwpfvSK2xdRO8AO0IA7uz9WPZuARsbYYaIVxGDZqDa+a3C9zdlfTLIOXvEI2VWhW+GRAzkHGq/ll5h3QboLqklNCk3HUnW7LJfwJdnWNXPYbZccAaPd5VkvusvLAAAAABJRU5ErkJggg==';
	el.style.position='absolute';
	el.style.left=px(t.offsetLeft + t.offsetWidth - 11)
	el.style.top=px(t.offsetTop-1);
	el.onmousedown=cxx_action_click;
	el.className='qqq';
	t.appendChild(el);	
	menu_icon=el;
}
function cxx_mouseout(e)
{
	var t=target(e);
	dbg('HIDE 1 [parent]'+el_info(t.parentNode))
	dbg('HIDE 1 [el]'+el_info(t))
	if(!class_contains(t,'rcpt')){
		dbg('HIDE 2')
		return;
	}
	if(class_contains(t.parentNode,'rcpt')) {
		dbg('HIDE 3 *************')
		return;
	}
	dbg('HIDE 4')


	if(t.childNodes.length>1){
		dbg('HIDE 5')
		hide_soon(t.childNodes[1]);
		
	}
}
function hide_soon(el,now)
{
	if(!el||!el.parentNode) return;
	if(!now) return setTimeout(function(){hide_soon(el,true)},1000);

	remove_node(el);
	menu_icon=null;
}

function cxx_action_click(e)
{
	if(!e) e=window.event;
	rcpt_contact=target(e).parentNode;
	do_menu_show('context_menu_rcpt',e,undefined,undefined,{cursor:true})
}

||ifdef||_junk_||
//rcpt_mousedown
addEventHandler(document.body, "beforepaste", reroutePasteEvent);
var rp={};
function reroutePasteEvent() 
{
  if (rp.capturingPaste || window.opera) return;
  rp.capturingPaste = true;
  var te = document.createElement("TEXTAREA");
  te.style.position = "absolute";
  te.style.left = "-500px";
  te.style.width = "10px";
  te.style.top = "10px";
  document.body.appendChild(te);
#  parent.focus();
  te.focus();

  var self = this;
  setTimeout(function() {
	rp.capturingPaste = false;
	rm.win.focus();
//	if (self.selectionSnapshot) // IE hack
//	  self.win.select.selectCoords(self.win, self.selectionSnapshot);
	var text = te.value;
	if (text) rp.replaceSelection(text);
	removeElement(te);
  }, 10);
}
||endif||


function compat_warn()
{
	if(pref.devt_test=='nodnd') sw.dnd_disabled=true;
	if(isChrome3){
		x_custom_dlg('Chrome 3.0 has bugs that may result in odd surgeweb behaviour if drag &amp; drop is enabled. We recommend you use Chrome 4.0, IE, Firefox, or Safari.',
					 'For more information see: <a href="http://netwinsite.com/surgeweb/help/browser_bugs.htm" target="_popup">browser issues</a>',
			function(btn){
				if(!btn) {
					sw.dnd_disabled=true;
					return;
				}
				msgdnd_init();
			},
			function(){
				var o;
				o=dge('dlg_ok'); o.style.width=px(150); o.value='I understand, continue';					
				o=dge('dlg_cancel'); o.style.width=px(150); o.value='Disable drag & drop';
			}
		);
	}
}

var keywords=[];
var kw_id=0;
function refresh_ad()
{
	var el,tmp,url,txt;
	if(!pref.ad1_updates) return;
	el=dge('right_column');
	if(!el) return;
	el=el.getElementsByTagName('iframe');	
	if(!el || el.length==0) return;

	if(!sw.google_ads_url){
		sw.google_ads_url=el[0].src;
		keywords=pref.ad1_keywords.split(',');
	}

	if(pref.ad1_updates=='update'){
		url=sw.google_ads_url;
	}else{
		if(pref.ad1_updates=='target_subject' && sw.google_ads_target){
			txt=xencode(sw.google_ads_target);
			sw.google_ads_target=null;
		}else {
			if(keywords.length) {
				txt=keywords[kw_id++];
				if(kw_id>keywords.length) kw_id=0;
			}else{
				txt='surgeweb&dt=';
			}
		}
		dbg('** Trying to target google ad to:['+txt+']');
		url=sw.google_ads_url.replace(/surgeweb&dt=/,txt+'&dt=');
	}
	el[0].src=url+'&'+mtime();
	return true;
}
function set_ads_targeted(txt)
{
	sw.google_ads_target=txt;
}


function select_lang(input)
{
	if(input.value!='more...') return;
	x_confirm('$$st_lang_showall$$', function(n){
		if(!n) return;
		do_options(true);
	});	
}

# Multiple accoutns & identities related functionality
function accounts_init()
{
	sw.ident=initial_ident;
}

function accounts_show()
{
	if(!sw.identities) return;
	if(pref.newlook_layout=='modern1' && sw.global_newlook_searchactive) return;
	var el=dge('accounts');
  	if(idents()>1) {
  		class_remove(el,'hidden');
  	}else{
  		class_add(el,'hidden');
  	}
	
	el.innerHTML=accounts_html(sw.ident,sw.identities,el.toggle_open);
}
function set_identities(val,order,show_email)
{
	if(object_length(val)<1) val=U;
	sw.identities=val;
	sw.ident_order=order;
	sw.ident_show_email=show_email;
	accounts_show();
}
function accounts_toggle(type)
{
	var el=dge('accounts');
	el.toggle_open=!el.toggle_open;
	accounts_show();
}

function account_sel(ident,e)
{
	if(!e) e = window.event;
	var identity,fld,fld_type;
	if(e&&any_modifier(e)&&!keys_2horiz(e)){
		return do_compose(e,ident);
	}
	var xiid = sw.ident;
	var xfld = sw.fld_id;	
	var xfid = sw.fid;
	sw.ident=ident;
	identity=sw.identities[ident];
	fld=identity.fld;
	if(!fld) {
		fld='INBOX';
		fld_type=enInbox;
	}else{
		fld_type=enUser;
	}
		
	switch_selfld(fld);
	sw.fld_type=fld_type;
	menu_arrange(fld_type);
	menu_custom_fld(fld_type,fld);

	accounts_show();

	set_status('$$st_actmng_selected$$ <b><i>'+identity.name+' &lt;'+identity.email+'&gt; </i></b>','success')
	
	if(!class_contains(sw.active,'fldmsg')){
		window_manager_minimise(sw.active);
		window_manager_restore();
	}

	var extra='';
	disable_markread_fld=keys_2horiz(e);
	if(disable_markread_fld){
		extra+='&disable_markread=true';
	}
	extra+=clientside_layout();

	set_folders('<div class="folders_loading" style="padding-left:40px">$$st_pane_loading$$</div>');
		
	update_alt_account('true','');
||iftrue(using_api)||
	xcmd='core/select_account?v=sw'+iid()+'&fld_id='+fld+extra+'&refresh=true&output_folders=true&output_messages=true';
||else||
	xcmd='cmd=show&page=~result.js&fld_id='+fld+iid()+extra+'&refresh=true&output_folders=true&output_messages=true';
||endif||
	FolderShow(fld,{fld_type:fld_type,disable_markread:keys_2horiz(e),xcmd:xcmd,xiid:xiid,xfld:xfld,xfid:xfid});	
	stopEvent(e);
}


function accounts_html(ident, identities, show_open)
{
	var x, acct_item, n, pp, sel,i,j;
	var q1,q2;

	if(show_open){
#	  // A list of accounts	
	  x= '<div id="accounts_open" class="act_panel" style="padding-bottom:3px;">'
	  	+'<ul style="padding-left:1px;padding:0px;margin:0;list-style:none;">'
	  	+'<li style="padding:3px;"><div style="height:16px;">'
		+'<div><div class="tog open" onclick="accounts_toggle()" style="margin-top:2px;"></div></div>'
		+'<div style="padding-left:20px;">$$st_ident_accounts$$ <a href="#" class="flist_link" onclick="do_identity()">$$st_ident_manage$$</a></div>'
		+'</div></li>';
	  for (j=0;j<idents();j++) {
	  	i=sw.ident_order[j];
		o=identities[i];
		if(o.type=='ident') continue;
		acct_item='';
		var unread=sw.identities_unread[i];
		if(sw.ident==i) {
			q1='<b>'; q2='</b>';
		}else{
			q1=q2='';
		}
		x += '<li class='+acct_item+'><div style="height:16px;"><div style="float:left;"><div style="width:15px;height:15px;background:url(||www_base||shared/img/'+(pref.folderlist_flat?'identity_icons_flat.png':'identity_icons.png')+'?||vz||);background-position:-'+(o.icon*20+2)+'px -20px;padding:0;margin-left:20px;margin-right:3px;"></div></div>'
			  +'<div style="margin-left:42px;" class="account_horiz" onmousedown="return stopEvent(event)" onclick="account_sel('+i+',event)">'+q1+(istrue(sw.ident_show_email)?o.email:o.name)+q2+' '+(unread>0?'<b>('+unread+')</b>':'')+'</div></div></li>';
	  }
	  x+='</ul></div>';
	  x+='<span style="clear:both"></span>';

	}else{
	  var extraflat = pref.newlook_layout == 'modern1';
	
#	  // Row of account icons
	  x='<div id="accounts_closed" class="">'
		+'<div id="accounts_closed_l1" class="act_panel" style="padding-bottom:1px">'
		 +'<div class="tog closed" onclick="accounts_toggle()" style="margin-top:5px;"></div>';
	  if(extraflat){
		 x+='<div style="margin-left:13px;padding-left:1px;height:25px;">';
	  }else{
		 x+='<div style="margin-left:20px;padding-left:1px;height:25px;">';
	  }
	  
	  if(false){
		x+='<div oncontextmenu="if (keys_2horiz(event)) return false;" onmousedown="return stopEvent(event)" onclick="account_sel('+i+',event);" title="'+o.name+'" style="cursor:pointer;width:19px;height:19px;float:left;0px;margin:3px 7px -5px 0px;background:url(||www_base||shared/img/'+(pref.folderlist_flat?'identity_icons_flat.png':'identity_icons.png')+'?||vz||);background-position:-'+6*20+'px 0;position:relative;">';
		var unread=2;
		if(unread>0)
			x+= '<div class="ar2 as" label_id="id" style="position:absolute;top:-7px;right:-3px;"><div class="at" style="background: #e3343d '+(pref.folderlist_flat?'':'url(||www_base||shared/img/alert.png?||vz||);')+' border-color: #d40009; _border-bottom-color:#f6bdc0"><div class="au" style="border-color:#d40009;"><div class="av2" style="color: white;">'+unread+'</div></div></div></div>';
		x+='</div>';
	  }
	  
	  var std_colors = ['#848484', '#42c66d', '#ecc54d', '#e5504b', '#bb44e3', '#1c4aec', '', '','', '#4ca7e8'];
	  n=pp=0; sel=U;
	  for (j=0;j<idents();j++) {
	  	i=sw.ident_order[j];
		o=identities[i];
		if(o.type=='ident') continue;
		// add ctl_and_cmd_key(e) to prevent abberant mac behaviour?
		var pos = o.icon*20;
		var style='width:19px;height:19px;margin:3px 7px -5px 0px;';
		if(extraflat){
			pos = 8 * 20;
			style='width:20px;height:20px;margin:1px 2px 0px 0px;padding:2px 0px 1px 4px;';
			x+='<div oncontextmenu="if (keys_2horiz(event)) return false;" onmousedown="return stopEvent(event)" onclick="account_sel('+i+',event);" title="'+o.name+'" style="cursor:pointer;'+style+'float:left;0px;background:'+std_colors[o.icon]+'; position:relative;"><span style="font-size:16px;color:white;">@</span>';
		}else{
			x+='<div oncontextmenu="if (keys_2horiz(event)) return false;" onmousedown="return stopEvent(event)" onclick="account_sel('+i+',event);" title="'+o.name+'" style="cursor:pointer;'+style+'float:left;0px;background:url(||www_base||shared/img/'+(pref.folderlist_flat?'identity_icons_flat.png':'identity_icons.png')+'?||vz||);background-position:-'+pos+'px 0;position:relative;">';
		}
		var unread=sw.identities_unread[i];
		if(unread>0){
			if(extraflat){
				x+= '<div class="ar2 as" label_id="id" style="position:absolute;top:0px;right:0px;"><div class="at" style="background: #e3343d '+(pref.folderlist_flat?'':'url(||www_base||shared/img/alert.png?||vz||)')+'; border-color: #d40009; _border-bottom-color:#f6bdc0"><div class="au" style="border-color:#d40009;"><div class="av2" style="color: white;">'+unread+'</div></div></div></div>';
			}else{
				x+= '<div class="ar2 as" label_id="id" style="position:absolute;top:-7px;right:-3px;"><div class="at" style="background: #e3343d '+(pref.folderlist_flat?'':'url(||www_base||shared/img/alert.png?||vz||)')+'; border-color: #d40009; _border-bottom-color:#f6bdc0"><div class="au" style="border-color:#d40009;"><div class="av2" style="color: white;">'+unread+'</div></div></div></div>';
			}
		}
		x+='</div>';
		if(sw.ident==i){
			sel=o; pp=n;
		}
		n++;
	  }
	  if(!sel) sel=identities[1];
	  x+= '</div>'
		+'</div>'
		+'<div id="accounts_closed_l2" class="act_panel" style="position:relative;padding:1px 0;">'
		 +'<div id="accounts_ptr" class="dropup" style="position:absolute;top:-9px;left:'+(22+26*pp)+'px;"></div>'
		 +'<div id="accounts_name" style="padding-left:1px;padding-bottom:2px;margin-left:20px;">'+(istrue(sw.ident_show_email)?sel.email:sel.name)+'</div>'
		+'</div>'
	   +'</div>';
	}
	return x;
	
}
# +++ compose functionality +++
function identities_html(ident)
{
	var i,j;
	if(sw.is_popup) return sw_win.identities_html(ident);
	var x='<select style="margin-left:-3px" onchange="msg_identity(this);from2sig(this)">'
	for (j=0;j<idents();j++) {
	  	i=sw.ident_order[j];
		o=sw.identities[i];
		var sel=(ident==i?'selected':'');
		x+='<option value="'+i+'" '+sel+' >'+o.name+' &lt;'+o.email+'&gt;</option>';
	}
	x+='</select>';
	return x;
}
function show_identities()
{
	var el=sw.active.field_from.nextSibling;
	el.innerHTML=identities_html(sw.active.jmsg.ident);
	remove_node(el.nextSibling);
}
function msg_identity(input)
{
	var ident=input.value;
	var o=sw.is_popup?sw_win.sw.identities[ident]:sw.identities[ident];
	if(!o) return;
	sw.active.field_from.value=o.name+' <'+o.email+'>';
	sw.active.jmsg.ident=ident;
}
# --- compose functionality ---

function identity_move(ident,move)	// cf. do_identity
{
	identity_show_manage('&ident='+ident+'&move_ident='+move);
}
function identity_delete(ident,desc)		// cf. do_identity
{
	x_confirm('$$st_ident_remove_warn$$ <b><i>'+encode_lt_gt(desc)+'</i></b><br><br>$$st_confirm_generic$$', function(n){
		if(!n) return;
		identity_show_manage('&ident='+ident+'&delete_ident='+ident);
	});	
}
function identity_show_manage(extra)
{
	sndReq('cmd=identity_manage,show&page=~identities.htm'+extra, function(chan){
		node=actionReqSethtml(http.responseText,'utility');
		if(!sw.identities[sw.ident])
			account_sel(1)
	});
}

function identity_create(type)
{
	var title;
	if(type=='acct'){
		title='$$st_ident_add_acct$$';
	}else{
		return x_alert('$$st_ident_ident_ni$$')
		title='$$st_ident_add_ident$$';
	}
	identity_dialog('new_'+type,'new',title,'')
}
function identity_edit(ident,type)
{
	if(type=='acct'){
		title='$$st_ident_edit_acct$$';
	}else{
		title='$$st_ident_edit_ident$$';
	}
	identity_dialog('edit_'+type,'edit',title,'&ident='+ident)
}
function identity_dialog(seq,step,title,extra)
{
	var cmd='cmd=identity_manage,show&page=hdialogs.htm&dlg_type=identity_edit&dlg_seq='+seq+'&dlg_step='+step+'&sid='+sid+extra;
	x_custom_dlg2(title,'<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(300)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
			if(btn!='ok') return;
			identity_show_manage('&ident='+sw.ident);
		}, function(){}, {'width':570,'nopad':true,'nobtns':true});
}
function update_unread_accounts(arr,alt_new) // cf update_unread_folders
{
	var i;
	var tmp=arr.join(',');
	
	for (i=0;i<arr.length;i+=2){
		sw.identities_unread[arr[i]]=arr[i+1];	
	}
	accounts_show();
	if(alt_new>0){
		set_status('$$st_ident_newmail$$'+ident_account_desc(sw.identities[alt_new]),'success');
		new_mail_popup_other(alt_new);
		new_mail_sound();
	}
}
function new_mail_sound()
{
	if(xol_skip_alert>time()-20){
		xol_skip_alert=0;
		return;
	}
	play_sound('new');
}

function ident_account_desc(o)
{
	return '<b><i>'+o.name+' &lt;'+o.email+'&gt;'+'</i></b>';
}

function imap_sharing(o)
{
	var extra='';
	if(o) extra='&fld_id='+ancestor_by_tag(o,'tr').getAttribute('fld_id');
	var cmd='cmd=config_acl,show&page=hdialogs.htm&dlg_type=config_acl&dlg_seq=&dlg_step=&sid='+sid+extra;
	x_custom_dlg2('$$st_acl_edit$$','<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(300)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
			sndReq('cmd=show&output_folders=true&page=~folders.htm'+iid(), function(chan){
				node=actionReqSethtml(chan.responseText,'utility');
			});		
		}, function(){}, {'width':560,'nopad':true,'nobtns':true});
}
var error_handler=function(err)
{
	set_status(err,'warning')	
}

function status_reportall()
{
#	dlg_clk('cancel');
	var abk_txt='';
	for(i=0;i<abooks.read_books.length;i++){
		abook=abooks.read_books[i];
		abk_txt += abook+'='+abooks[abook].data.length+' ';
	}

	var jmsg=compose_jmsg([]);
	var info=
		'<style>.success{background: lightgreen;} .info{background: #EDED91;} .warning{background: #EDB2BC;} </style>'+
		'<p> &nbsp; <p> &nbsp; ' +
		'<p><b> Surgeweb problem report </b><p> &nbsp;'+
		'<p> Please describe the problem you are having with surgeweb, what actions preceded the problem, and whether it is repeatable:<p> &nbsp;<p> &nbsp;<p> &nbsp;<p> &nbsp;'+
		'<p><b> Debugging information:  </b>'+
		'<p>Reported by '+email+' at '+time_str2()+
		'<p>Status and error messages: '+
		'<div style="padding:3px;background:#eee;border:1px solid #dddddd;">'+status_debug()+'</div>'+
		'<p>Calls to mtime()='+time_calls+' BAD='+time_bad+
		'<p>Flash version='+sw.swf_version+
		'<p>Server ajax communication channels:'+
		'<div style="padding:3px;background:#eee;border:1px solid #dddddd;">'+qchan_debug()+'</div>'+
		'<p>Browser: '+UA+'<p> <hr>'+
		'<p>Windowing preferences: windows='+pref.windows+' | preview='+pref.preview+' | mode='+pref.mode+
		'<p>Identities: '+idents()+
		'<p>Cached emails: '+sw_xcache.length+
		'<p>Contacts: '+abk_txt+
		'<p>Current Quota: '+quota_info();

	jmsg.subject='Surgeweb problem - reported by '+email; 		
	jmsg.msg_html=info;
	jmsg.not_new=true;
	jmsg.send_mode='html';
	show_edit(jmsg);
}

function idents()
{
	if(sw.is_popup) return sw_win.idents();
	return sw.ident_order.length;
}
function iid(jmsg)
{
	var ident;
	if(!sw.identities) return '';
	if(jmsg && jmsg.ident){
		ident=jmsg.ident;
	}else{
		ident=sw.ident;
	}
	return '&ident='+ident;
}
function iid_orig(jmsg)
{
	var ident;
	if(!sw.identities) return '';
	if(!jmsg.ident_orig || jmsg.ident==jmsg.ident_orig) return '';
	return '&ident_orig='+jmsg.ident_orig;
}
function plain()
{
	if(!pref.editor_textonly) return ''; 
	return '&with_plain=yes';
}
function eil()
{
	if(!pref.show_inline) return '';
	return '&show_attach_inline=true';
}


function fld_id2name(id)
{
	if(!sw.fldnames) return id;
	var s=sw.fldnames[id];
	if(!s) return id;
	return s;
}
function update_fld_names(names)
{
	sw.fldnames=names;
}

function check_rrcpt(qmsg)
{
	if(qmsg==U || !qmsg.data.rrcpt) return;
	fn_send=(sw.is_popup?sw_win.ajax_send_rrcpt:ajax_send_rrcpt);		
	var sel=make_sel(sw.fld_id,qmsg.mid)
	if(qmsg.data.rrcpt=='auto') {
		fn_send(sel);
	}else{
		x_confirm($('$$st_rrcpt_ask$$', qmsg.data.rrcpt), function(n){
			if(!n) return;
			fn_send(sel);
		});
	}
	qmsg.data.rrcpt='';
}

function do_fdnd()
{
	if(sw.fdnd_checked){
		return sw.fdnd;
	}
	sw.fdnd_checked=true;
	sw.fdnd=false;
	if(isIE) {
#		sorry no filednd supported		
	}else if(isChrome){
		if(isVersion>=5) sw.fdnd=true;
	}else if(isSafari){
		if(isVersion>=4) sw.fdnd=true;
	}else if(isFF){
		if(isVersion>=3.5) sw.fdnd=true;
	}
	dbg('*** desktop file drag and drop is '+(sw.fdnd?'ENABLED':'DISABLED')+' ***');
	return sw.fdnd;
}
function fdnd_init(el, type, fn_hover, fn_drop)
{
   el.ondragenter=fdnd_drag_enter;
   el.ondragleave=fdnd_drag_leave;
   el.ondragover=fdnd_drag_over;
   el.ondrop=fdnd_drag_drop;
   class_add(el,'fdnd_root');
   el.fdnd=true;
   el.fdnd_type=type;
   el.fdnd_hover=fn_hover;
   el.fdnd_drop=fn_drop;
}

# browser implementation of file drag & drop is still kind of in its infancy and non standard,
#  but I think I can mostly make it do what I want now :-)
#  only windows Safari remains a little dodgy
var fdnd_current;
function fdnd_valid_file(e)
{
	var valid=false;
	var types=e.dataTransfer.types;	
	if(types){
		for(var i=0;i<types.length;i++){
			if(types[i]=='Files') valid=true;
			dbg("VALID = "+valid);
		}
	}else{
		if(isSafari){
			if(e.dataTransfer.files && e.dataTransfer.files.length>0) valid=true;
		}else{
			// probably IE with no file dnd
		}
	}
	return valid;
}
function fdnd_drag_enter(e)
{
	var o,old,t;	
	o=e.dataTransfer;
	old=o.effectAllowed;
	t=ancestor_by_class(target(e),'fdnd_root');
	if(!t || !t.fdnd || t==fdnd_current) {
		dbg('fdnd_drag_enter IGNORING : '+t.tagName +' id='+t.id);
		return stopEvent(e);
	}
#	setting effectAllowed does not seem to do anything in Safare / Chrome. Unncessary inFF, but apply anyway.
	o.effectAllowed='copyMove';
	dbg('fdnd_drag_enter: PRE dropEffect='+o.dropEffect+' effectAllowed=('+old+')'+o.effectAllowed)
	if(!fdnd_valid_file(e)) return stopEvent(e);
	fdnd_current=t;
	dbg('file_drag: its a file');
	if(t.fdnd_hover) t.fdnd_hover(e,t,true);
	return stopEvent(e);	
#	stopped event supposed to mean drop is allowed
}
function fdnd_drag_over(e)
{
	var o,old,t;	
	var o=e.dataTransfer;
    if(o.dropEffect=='none') o.dropEffect = 'copy';
	var old=o.dropEffect;
	var t=ancestor_by_class(target(e),'fdnd_root');
	if(t&&t.fdnd_type) o.dropEffect = t.fdnd_type;
	dbg('fdnd_drag_over MID dropEffect=('+old+')'+o.dropEffect+'('+t.fdnd_type+') effectAllowed='+o.effectAllowed)
	if(!fdnd_valid_file(e)) return stopEvent(e);
	if(!t || !t.fdnd /*|| t==fdnd_current*/) return stopEvent(e);
	if(t.fdnd_hover) t.fdnd_hover(e,t,true)
	return stopEvent(e);
#	stopped event supposed to mean that we have set dropEffect
}
function fdnd_drag_leave(e)
{
	var t=ancestor_by_class(target(e),'fdnd_root');
	if(!t || !t.fdnd /*|| t==fdnd_current*/) {
		dbg('fdnd_drag_leave  : '+t.tagName +' id='+t.id +'txt=['+t.innerText+']');
		return;
	}
	dbg('file_drag_leave');
	if(t.fdnd_hover) t.fdnd_hover(e,t,false)
	return stopEvent(e);
}
function fdnd_drag_drop(e)
{
	dbg('drop handler');

#	var t=ancestor_by_class(target(e),'fdnd_root');
#	if(!t || !t.fdnd) return;
	t=fdnd_current;
	var files=e.dataTransfer.files;
	if(!files) return;
	dbg('drop handler ACTION DROP');
	if(t.fdnd_drop) t.fdnd_drop(e,t,files)
	fdnd_current=null;	
	return stopEvent(e)
}

function fdnd_global_hover(e, t, hovering)
{
	dbg('fdnd_global_hover hover='+hovering);
}
function fdnd_global_drop(e, t, files)
{
	dbg('fdnd_global_drop files='+files.length);
}

function fdnd_list_hover(e,t,hovering)
{

}
function fdnd_list_drop(e,t,files)
{
	var i, fld_id=sw.fld_id; 
	for (i=files.length-1;i>=0;i--){
		ajax_upload(files[i],fld_id, function(success,final){ 
				if (!success || !final) return;
				FolderShow(fld_id,{refresh:true,refresh_allmsgs:true});
			}, function(bytesLoaded,bytesTotal){
				var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
				set_status(pct_clean($('$$st_att_uploading_pct$$',percent)),'info');
			},i==0,ctl_cmd_key(e));
	}
}
var unhover_timer;
function fdnd_msg_hover(e, t, hovering)
{
	dbg('fdnd_msg_hover hover='+hovering);
	if(unhover_timer) {clearTimeout(unhover_timer);unhover_timer=null;}
	var node=sw.active;
	if(hovering){
		if(!node.attachments_init) do_attach_init();
		if(!node.attachments_init) return;
		class_add(node.aq_files.parentNode,'fdnd_drag');
	}else{
		time_unhover=setTimeout(function(){class_remove(node.aq_files.parentNode,'fdnd_drag')},20);
	}
}
function fdnd_msg_drop(e, t, files) 	// SW_CLOUDFILE
{
	dbg('fdnd_msg_drop files='+files.length);
	var node=sw.active;
	class_remove(node.aq_files.parentNode,'fdnd_drag');
	
	if(pref.cloudfile_dnd){
		fdnd_msg_drop_step2(e, files, 0, true);	
		return;
	}
	
	bigfile_dialog(files, {e:e, files:files}, function(data, detach_big_expire){
		fdnd_msg_drop_step2(data.e, data.files, detach_big_expire);
	});	
}
	
function fdnd_msg_drop_step2(e, files, detach_big_expire, detach_all)	
{
	
	for(var i=0;i<files.length;i++){
		file=files[i];
		file.cloudfile_expire= bigfile_expire(file.size, detach_big_expire, detach_all);
		aq_fdnd_add(file);		
	}	
	aq_fdnd_upload()
}

function fdnd_compose_hover(e,t,hovering)
{

}
function fdnd_compose_drop(e,t,files)
{
	do_compose(e);
}

function hide_fdnd_info()
{
	class_add(sw.active.aq_container.previousSibling,'hidden');
	var win=(sw.is_popup?sw_win:window);
	win.pref.hide_fdnd_info=true;
	win.ajax_pref_save('pref_hide_fdnd_info=true');
	do_resize();
}

function attach_dialog(type)
{
	var node=sw.active;
	var jmsg=node.jmsg;
	attach_init(jmsg);
	
	var param='&attach_mid='+sw.active.jmsg.attach_mid+'&attach_ids='+(jmsg.attach_ids.join(','));
	var title='Upload attachments';
	var cmd='cmd=show&page=hdialogs.htm&dlg_type=attach_upload'+param+'&dlg_seq=&dlg_step=&sid='+sid;
	x_custom_dlg2(title,'<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(300)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
			if(btn!='ok') return;
			aq_attachments_set(sw.active,g_new_attach);			
		}, function(){}, {'width':560,'nopad':true,'nobtns':true});
}

function slide_show(iid,fld_id,mid,mpr_attach)
{
	var param='&ident='+iid+'&fld_id='+xescape(fld_id)+'&msg_id='+mid;
	var hh=Math.round(ClientHeight()*0.9-85);
	var h2=hh-80; if(h2<200) h2=200;
	var ww=Math.round(ClientWidth()*0.9);
	var w2=ww-200; if(w2<200) w2=200;
	param+='&view_width='+w2+'&view_height='+h2;
	if(mpr_attach) param+='&mpr_as=attach';

	var cmd='cmd=show&page=slideshow.htm&dlg_type=attach_upload'+param+'&dlg_seq=&dlg_step=&sid='+sid;
	x_custom_dlg2('$$st_att_slideshow$$','<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(hh)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
			if(btn!='ok') return;
			aq_attachments_set(sw.active,g_new_attach);			
		}, function(){}, {'tall':true,'wide':true,'width':0.9/*,'nopad':true,'nobtns':true*/});
}



function sw_format_address(name, email)
{
	if (!name || name.length==0) return email;
	if (name == email) return email;
	if (name.indexOf(',')!=-1 && name.charAt(0)!='"'){
		name = '"'+name+'"';
	}
	return name+' <'+email+'>';
}
function cmd_ctl_as_text()
{
	return isMac?'Cmd':'Ctl'
}
function copy_popup(txt)
{
	x_prompt2($('$$st_prompt_copy$$',cmd_ctl_as_text()),txt,function(val){
		if (!val) return;
		filtermenu_action(mnu,val,true);
	}, {'nocancel':true});
}
function edit_popup(node,cx_contact,txt)
{
	x_prompt2('$$st_prompt_name_addr$$',txt,function(val){
		if (!val) return;
		dbg("update node with newly split address");
		var c2 = text2contact(val);
		cl_update_contact(cx_contact,c2);
		vcheck_add(cx_contact,U);
		vcheck_run();		
	}, {});
}

# run in context of dialog window ie no access to standard sw etc.
function sigedit_init()
{
	var tb=dge("etbar");
	if(!tb) return;
	var ed=dge("eframe");
	tb.id='etbar_sig';
	ed.id='eframe_sig';
	var xed=ed.parentNode;
	xed.id='xeframe_sig';
	xed.tbar=tb;
	
	if(pref.editor_textonly){
		init_editor('eframe_sig');
		var et=xed.firstChild;
		setTimeout(function(){
			et.style.width=px(xed.offsetWidth-24);
			et.value=dge('pref_signature').value; 
		},5);
		
	}else{
		tb.eframe=ed;
		tb.field_switch=dge('editor_switch_button');
		setTimeout(function(){
			var xwin = init_editor('eframe_sig');
			var xdoc=xwin.document;
			if(isWebkit){
#				Hack to fix weird "not scrolling" bug in Safari & chrome 
				xdoc.body.innerHTML = dge('current_sig_body').value;			
			}else{
				xdoc.open();
				xdoc.write('<html><head>');
				xdoc.write('<style>');
				xdoc.write(' P {margin:0px;padding:0px;}');
				xdoc.write(' body {FONT-SIZE: 11pt;FONT-FAMILY:Arial,Helvetica,sans-serif;background:white;}');
				xdoc.write('</style></head>');
				xdoc.write('<body>'+dge('current_sig_body').value+'</body></html>')
				xdoc.close();
			}

		},5);
	}
}

function populate_signature_early(el)
{
	for (j=0;j<sigs();j++) {
	  	i=sw.sig_order[j];
		el.options[el.options.length] = new Option(sw.signatures[i].name, i);
	}
}
function populate_signature_late()
{
}

function sig_defaults()
{
	sw.signatures={};
	sw.sig_order=[];	
	pref.cur_signature = "none";
}
function set_signatures(sigs, order, cur_signature)
{
	sw.signatures=sigs;
	sw.sig_order=order;	
	pref.cur_signature = cur_signature;
}

function sigs()
{
	if(sw.is_popup) return sw_win.sigs();
	return sw.sig_order.length;
}
function decide_sig(ident)
{
	if(!ident||!sw.identities[ident]) return U;
	var sig_id = sw.identities[ident].sig_id;
	return sig_id;
}

function from2sig(input)
{
	var sig_id = decide_sig(input.value)
	if(!sig_id) return;
	var jmsg = sw.active.jmsg;
	jmsg.sig_id = sig_id;
	var realsig = sw.signatures[sig_id].body;
	var rt=sw.active.field_eframe;
	var xwin=get_edit_win();
	var xdoc=xwin.document;
	var el=xdoc.getElementById('editor_signature');
	signature_select(el,realsig,U);
}
function sig_refetch()
{	
	queued_req_add( enQ, 'sig_refetch', function(){	
		dbg('sig_refetch - actioning request')
		sndReq('cmd=show&page=~result.js&output_sig=true', function(chan){
			dbg('~inline.tpl - request completed')
			var success=actionReqJsStat(chan);
		},ch[enQ]);
	});
}

function image_dialog()
{
	var node=sw.active;
	var jmsg=node.jmsg;
	attach_init(jmsg);

	var param='&attach_mid='+sw.active.jmsg.attach_mid+'&attach_ids='+(jmsg.attach_ids.join(','));
	var cmd='cmd=show&page=hdialogs.htm&dlg_type=image_attach'+param+'&dlg_seq=&dlg_step=&sid='+sid;
	x_custom_dlg2('$$st_prompt_image$$','<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(300)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
			if(btn!='ok') return;
#			if(g_new_attach.length>0 && !node.attachments_init) do_attach_init();
#			aq_attachments_set(sw.active,g_new_attach);			
			check_mpr_images(sw.active.jmsg,g_new_attach);
		}, function(){}, {'width':560,'nopad':true,'nobtns':true});
}

function check_mpr_images(jmsg,attachments)
{
	var xwin=get_edit_win();
	xwin.focus();

	var old_images = xwin.document.getElementsByTagName('img');
	var found, old_image, url;
	for (i=0;i<attachments.length;i++){
		var attachment = attachments[i];
		if(!attachment || attachment.length<5) continue;
		var cid=attachment[4];
		if(!cid || cid.length==0) continue;
		var url=attachment[5];
		dbg('do whatever we need to to update the mpr images');
		editor_add_img(url);
		if(!jmsg.attach_ids2) jmsg.attach_ids2=[];
		jmsg.attach_ids2.push(attachment[1]);
		jmsg.attach_ids_mpr='true';
	}
}

// SINGLE attach: QQQ DND ATTACH


function add_link()
{
	var xx='<img class="win_width" cid="image001.jpg@01CBB283.83F82A10" border="0" width="251" height="338" id="" src="/surgeweb?cmd=msgpart&amp;sid=198269359&amp;ident=1&amp;fld_id=INBOX&amp;msg_id=18&amp;part_id=1.2.2&amp;static=private" alt="welson">';
}

function editor_add_html(html)
{
	if(isIE){
		var xwin=get_edit_win();
		var sel = xwin.document.selection.createRange();
		sel.pasteHTML(html);
	}else{
		editor_do('insertHTML',html);
	}	
}
function editor_add_img(url)
{
	var img_html = '<img src="'+url+'">';
	if(isIE){
		var xwin=get_edit_win();
		var sel = xwin.document.selection.createRange();
		xwin.document.execCommand('InsertImage', false, url); 
		return;
#was working to here
		var el = selectedElementIe(xwin.document);
		g=xdoc.createElement('div');
		g.innerHTML='<b>Li</b>nk '+txt+'Description';
		el.parentNode.insertBefore(g,el);

	}else{
		editor_do('insertHTML',img_html);
	}	
}

function smiley_selected()
{
	var jmsg = sw.active.jmsg;
	jmsg.attach_ids_mpr='true';
}



# ** vaultlock verification **
var to_check=[];
var vcheck_op;
var need_vcheck; // yucky global flag

function vcheck_add(node,vaultsafe)
{
	if(!pref.vault_lock) return;
//	if(sw.is_popup) return sw_win.vcheck_add(node,vaultsafe); 
	var o = new Object;
	o.unique=uniqueId();
	o.vaultsafe=vaultsafe;
	o.node=node;
	o.win=window;
	node.id=o.unique;
	to_check.push(o);
}
function vcheck_run()
{
	if(!pref.vault_lock || to_check.length==0) return;

	var checking = to_check;
	to_check=[];
	var arr=[];
	for (var i=0;i<checking.length;i++) {
		var o=checking[i];
		arr.push(o.node.email_only);
	}
	var win=(sw.is_popup?sw_win:window);
	var lock_icon=dge('send_encrypt');
	win.vcheck_run_step2(arr,checking,function(vcheck_op){
		var unlocked;
		for (var i=0;i<checking.length;i++) {
			var node=checking[i].node;
			unlocked=vcheck_op[node.email_only].unlocked;
			class_remove(node,'rcpt_invalid');
			class_add(node,'rcpt_valid');		//QQQLOCK
			if(unlocked){
				class_add(node,'rcpt_valid');
			}else{
				class_add(node,'rcpt_invalid');
			}
		}
		vcheck_update_icon(lock_icon);
		need_vcheck=false;
	});
}
function vcheck_run_step2(arr,checking,cb)
{
	queued_req_add( enQ, 'vcheck', function(){	
		sndReq('cmd=show&page=~result.js&output_vcheck=true&addresses='+xescape(arr.join(',')), function(chan){
			dbg('vcheck - request completed')
			var success=actionReqJsStat(chan);
			if(cb) cb(vcheck_op);
		},ch[enQ]);
	});
}
function vcheck_result(result)
{
	vcheck_op=result;
}
function vcheck_update_icon(lock_icon)
{
	var info = fancy_edits_validity([sw.active.field_to,sw.active.field_cc,sw.active.field_bcc]);
	var el_select = sw.active.field_encrypt;
	el_select.override = false;
	encrypt_set_multi(lock_icon,el_select,info);	// QQENC
}

function replace_menu(mnu_id)
{
	var el = dge(mnu_id);
	el.innerHTML='\
			<a href="#" onmouseup="do_mark_unread()">$$st_cmd_markunread$$</a>\
			<a href="#" onmouseup="do_mark_read()"><i>$$st_cmd_markread$$</i></a>\
			<a href="#"><hr></a>\
			<a href="#" onmouseup="do_delete()">$$st_cmd_delmsg$$</a>';
}


function more_menu_remove(mnu_id, item_fname)
{
	var el = dge(mnu_id);
	for(var i=0;i<el.options.length;i++){
		if(el.options[i].value!=item_fname) continue;
		el.options[11] = null;
	}
}
function cx_menu_remove(mnu_id, item_fname)
{
	var el = dge(mnu_id);
	for(var i=0;i<el.childNodes.length;i++){
		var el2=el.childNodes[i];
		if(!el2.outerHTML || el2.outerHTML.indexOf(item_fname)==-1) continue;
		remove_node(el2);
		break;
	}
}
function cx_menu_addsep(mnu_id, item_fname)
{
	var el = dge(mnu_id);
	for(var i=0;i<el.childNodes.length;i++){
		var el2=el.childNodes[i];
		if(!el2.outerHTML || el2.outerHTML.indexOf(item_fname)==-1) continue;
		var frag=document.createElement('a');
		frag.href='#';
		frag.appendChild(document.createElement('hr'));
		el2.parentNode.insertBefore(frag,el2);
		break;
	}
}
function lm_init()
{
	var gsel=new Object();
	gs_init(gsel,"sel",sw.msgs_panelist);
	gs_callbacks(gsel,msglist_rows,row_to_sel,sel_to_row,sel_to_mid,ml_find_row,ml_show_soon);
	sw.ml=gsel;
}

function ml_show_soon(mid,nofocus,nostatus)
{
	if (pref.preview=='none') return;
	msg_show_preview(mid,U,U,nofocus,nostatus,disable_markread_fld);
}	

function check_callbacks()
{
	var need_hide=true;
	if(oauth_success=='true' && oauth_type=='dropbox'){
		sw.cld_store = 'DropBox';
		app_menu('cloud',dge('app_cloud'));
	}
	if(!string_empty(asap_pending)){
		if(sw.nav_total==0 ){
			asap_pending=U;
		}else{
			need_hide=false;
			show_msg(asap_mid);
		}
	}

	if(need_hide){
		hide_loading();
	}
}

function options_size_panel(o,h,w)
{
	if(!o || class_contains(o,'hidden')) return;
	var s=o.style;
	s.height=px(h-32 );
	s.width=px(w-15-||panel_gap||);
}
function options_resize(h,w)
{
	if (sw.active.id!='options_panel') return;

	options_size_panel(dge('usercgi_general_iframe'),h-2,w);
	options_size_panel(dge('usercgi_spam_iframe'),h-2,w);
	options_size_panel(dge('usercgi_filter_iframe'),h-2,w);
	options_size_panel(dge('usercgi_extra_iframe'),h-2,w);
}


function asap_init(asap_mid)
{	
	if(!amsg) return;
	cache_add(cache_id(1/*amsg.ident*/,amsg.fid,amsg.mid),amsg);
}

var cal_spinner;
function cal_spinner_run()
{
	var sp=cal_spinner;
	if(!sp){
		sp={};
		sp.pos=0;
		sp.outer=dge("cal_spinner");
		class_remove(sp.outer,"hidden");
		sp.node=sp.outer.firstChild;
		cal_spinner=sp;
	}
	sp.pos--;
	if(sp.pos<1) sp.pos=12;
	sp.node.style.backgroundPositionY=px(42*sp.pos);
	sp.timer = setTimeout(cal_spinner_run,60);
}
function cal_spinner_start()
{
	if(cal_spinner){
		clearTimeout(cal_spinner.timer);
	}
	cal_spinner_run();
	var sp=cal_spinner;
	sp.outer.style.left=px((ClientWidth()-pref.sizer1)/2+pref.sizer1-38);
	sp.outer.style.top=px(ClientHeight()/2);
}
function cal_spinner_stop()
{
	var sp=cal_spinner;
	if(!sp)return;
	clearTimeout(sp.timer);
	class_add(sp.outer,"hidden");
	cal_spinner=U;
}

function xx()
{
/*
<div id="playerHolder" style="position:absolute; right:0;top:-10px;width:170px;height:40px;z-index:5;">
      <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="165" height="37" id="musicPlayer" align="">
		    <param name="movie" value="/webui/js/niftyplayer.swf">
		    <param name="quality" value="high">
		    <param name="bgcolor" value="#FFFFFF">
		    <param name="wmode" value="transparent">
		    <embed src="/webui/js/niftyplayer.swf" quality="high" bgcolor="#FFFFFF" width="165" height="37" name="musicPlayer" align="" type="application/x-shockwave-flash" swliveconnect="true" pluginspage="http://www.macromedia.com/go/getflashplayer">
		  </object>
    </div>
*/
}

function lcol_init()
{
	||iftrue(no_spam_panel)||	
	return;
	||endif||
	if(!pref.allow_spam) return;
	new_panel_basic('<div id="log_links" class="log_links"><a href="#" onclick="user_cgi_dlg(\'log_only\')" class="flist_link link_blue" >$$st_fld_link_log$$</a>,<a href="#" onclick="user_cgi_dlg(\'spam2\')" class="flist_link link_blue" >$$st_fld_link_spam$$</a></div>','','bottom',true);
    var el=ancestor_by_class(dge('log_links'),'border_plain');
    if(!el) return;
    class_add(el,'border_plain_notop');
}
function pin_toggle_star()
{
	pref.pin_star=!pref.pin_star;
	ajax_pref_save('pref_pin_star='+pref.pin_star);
	FolderShow(sw.fld_id);
}
function pin_toggle_lbl()
{
	pref.pin_lbl=!pref.pin_lbl;
	ajax_pref_save('pref_pin_lbl='+pref.pin_lbl);
	FolderShow(sw.fld_id);
}

// do_menu_show('pg_menu_sort

function sort_menu_show(e)
{
	class_update(dge('mnu_pin_star'),'sel',pref.pin_star);
	class_update(dge('mnu_pin_lbl'),'sel',pref.pin_lbl);
	do_menu_show('pg_menu_sort',e);
}

function filter_menu_show(e)
{
	do_menu_show('pg_menu_view',e);
}

function save_pin_labels()
{
	var ctl=dge('pin_labels');
	ajax_pref_save("pref_pin_labels="+xescape(ctl.value));
}

function todo_xc()
{
	return xc={};
}
function todo_ev()
{
	return xc={};
}
var x_todo_cal='';
var x_todo_tasks=[];
var x_todo_timer;
function todo_cal()
{
	var rcal=x_todo_cal;
	if(!rcal) cal_find_cal('Reminders');
	if(!rcal) x_alert('No reminder calendar defined yet');
	return rcal;
}
function todo_edit_html()
{
	return '<input id="todo_param_input" value="description"><br>\
	XXXX<input name="remember" type="checkbox"><br>\
	YYYY<input name="remember" type="checkbox"><br>\
	<br>Tags<input id="todo_param_mtags" value="'+pref.todo_focus+'">';
}
function todo_edit()
{
	if(true){
#		cal_edit_date()
#		cal_showpopover(true,true);
 		var ev={};
 		ev.is_todo=true;
		todo_showpopover(ev);
		return;
	}
	var rcal=todo_cal();
	if(!rcal) return;
	
	x_custom_dlg('Add to do item',todo_edit_html(),function(btn){
		var val=dge("todo_param_input").value;
		if(!btn || !val) return;
 		var ev={};
		ev.cal_id=rcal;
		ev.uid=next_keepid();
		ev.desc=val;
		ev.mtags=dge("todo_param_mtags").value;
		save_edited_todo(todo_xc(),ev, function(){
			todo_refresh();		
		});
	}, function(){
		var el=dge('todo_param_input');
		el.focus();
	}, {});
}

function todo_done(cal_id,event_uid)
{
	var ev={};
	ev.cal_id=cal_id;
	ev.uid=event_uid;
	event_delete_cb(todo_xc(),ev);
}

function todo_showpopover(ev)	// cf cal_showpopover
{
	var xc={}, edit=true;	
	txt=cal_popover_large(xc,ev,edit);
	
	var frag=new_anchor('div', txt, document.body);
	frag.edit_detail=true;
	frag.id='cal_popover';
	frag.calhint=el;
	frag.style.height=px(frag.firstChild.offsetHeight+15);
	frag.ev=ev;
	class_add(frag,'calhint');

	var xy, el2, opt={};
	if(el){
		xy={x:calhint_coords.x,y:calhint_coords.y};	
	}else{
		xy={x:ClientWidth()/2-150,y:100};
	}

	if(edit && el) el2=el.childNodes[0];
	
	Popover.show(frag,{arrow:true,modal:edit,xy:xy, xy_el:el2,scroll_correct:'cal_details_scrolled'});
	Popover.obj.onPopoverClose=cal_showpopover_done;
	Popover.obj.hint_only=!edit;
#	cal_popover_populate(ev,edit);
	popover_el=frag;
#	cal_popover_update(ev)
}


function run_test(type)
{
	sndReq('cmd=test_action&test_type='+type), function(chan){
		x_alert('test '+type+' completed');
	}
}

function url_hash_test()
{
	var h;
	window.location.hash = '#inbox';
	
	window.onhashchange = function (e) {
		alert('someone changed it!!: '+window.location.hash);
		stopEvent(e);
#		setTimeout(function(){
		hash_action(window.location.hash);
#		},100);
	}
	if(window.location.hash){
#		alert('hash from url, lets use it: '+window.location.hash);
		hash_action(window.location.hash);
	}else if(pref.hash){
#		alert('hash from login screen: '+pref.hash);
		h=pref.hash;
		window.location.hash = pref.hash;
#		hash_action(pref.hash);
		pref.hash='';
	}
}

function hash_action(hash)
{
	if(hash=='#compose'){
		do_compose();
	}
}

var hcheck_timer;
function hcheck_trigger()
{
	if(hcheck_timer) return;
	hcheck_timer = setTimeout(hcheck_run,100);
}
function hcheck_run()
{
	hcheck_timer = U;
	var node = sw.active;
	var txt = first_n_emails(fancy_edit_value(node.field_to), 1);	//raw_search
	history_extra(txt,node,'edit');
}
function first_n_emails(emails,n)
{
	var txt ='';
	var count=0;
	for_each(emails,function(o){
		if(count>n-1) return; 
		var c = split_address(o);
		if(c[1]==U || c[1].length==0) return;
		if(txt.length>0) txt+=',';
		txt += c[1];
		count++;
	});
	return txt;
}
function new_wide()
{
	if(pref.newlook_layout=='modern1') return true; 
	
	return pref.preview=='horiz' && !pref.wide_old;
}

function allow_inbox_order()
{
	if(sw.fld_id!='INBOX') return false;
#	if(pref.disabled) return false;
#	other conditions
	return true;
}

function comment_to_text(el)
{
	if(!el.firstChild) return '';
	return el.firstChild.firstChild.firstChild.firstChild.innerHTML
}
function edit_comment(e,src)
{
	var sel=find_sel();
	if(sel.length>1){	
		x_alert('$$st_stat_comment_one$$');
		return;
	}
	if(!(sel.fld_id=='INBOX' || sel.fld_id=='Later')){
		x_alert('$$st_stat_comment_where$$');
		return;
	}
	var txt = '';
	for_each_msg(sel,function(row,mid){
		var el = row_to_comment(row);
		txt = comment_to_text(el);
	});
	var caption='$$st_comment_warn$$ ';
	caption+= '<div class="gray" style="padding-top:6px;font-size:10px;">$$st_comment_warn_hint$$</div>'; 	
	if(src=='kbd') caption+= '<div class="gray" style="padding-top:4px; font-size:10px;">$$st_comment_warn_kbd$$</div>'; 
	x_prompt2(caption,txt,function(val){
		if (val==U) return;
		ajax_comment(sel,val)
	},{'title':'$$st_comment_title$$'});
}

function edit_scomment(e,src)
{
	var sel=find_sel();
	if(sel.length>1){	
		x_alert('$$st_stat_comment_one$$');
		return;
	}
	
	var txt = '';
	for_each_msg(sel,function(row,mid){
		txt = decode_lt_gt(row_to_subject(row).innerHTML);
	});

	var caption='$$st_scomment_warn$$ ';
	caption+= '<div class="gray" style="padding-top:6px;font-size:10px;">$$st_scomment_warn_hint$$</div>'; 	
	x_prompt2(caption,txt,function(val){
		if (val==U) return;
		ajax_scomment(sel,val)
	},{'title':'$$st_scomment_title$$',noselect:true});
}


function history_to_list(o) {return o.childNodes[1];}

var lr_unique=0;

function history_extra(email,node,type,mid)
{
||if(istrue(context_disable))||
	return;
||endif||	
	if(sw.is_popup || pref.hide_widehist) return;
	if(pref.defer_disable) return;
	var within = (type=='edit'?node.compose_extra:node.view_extra);
	class_remove(within,'hidden');
	var w = pref.sizer2w*0.8;
	within.parentNode.style.paddingRight=px(w+1);
	within.style.width=px(w);
	within.childNodes[0].innerHTML= '';	
	var opanel_list=history_to_list(within);
	var panel_prefix = 'lr'+(++lr_unique);
	show_history(email,opanel_list,{msg_wanted:sw.fid+'_'+mid});
#	within.onmousedown=function(e){
#		return false;
#		gs_mousedown(node.rl,e);
#	};
#	within.onmouseup=function(e){
#		return false;
#	};
	within.onclick=function(e){
		var t=target(e);
		var row=gs_find_row(node.rl,t);
		if(!row) return;
		mid=row_to_mid(row);
		if (!mid) return;
		gs_none_fast(node.rl);
		gs_row_select(node.rl,row,false)
		opanel_msg(mid,node);
	};
	within.ondblclick=function(e){
		var t=target(e);
		var row=gs_find_row(node.rl,t);
		var mid=row_to_mid(row);
		if (!mid) return;
		show_msg(mid,e);
	}
	node.rl = lr_init(opanel_list,panel_prefix);
	class_add(within,'opanel_list');
	gs_set_cursor_mid(node.rl,mid);

#	QQLIST
# 	onmousedown="return msg_list_mousedown(event);" onmouseup="return msg_list_mouseup(event);" onclick="return msg_list_click(event);"
}

function lr_init(list,prefix)	// cf lm_init
{
	var gsel=new Object();
	gs_init(gsel,prefix,list);
	gs_callbacks(gsel,msglist_rows,row_to_sel,sel_to_row,sel_to_mid,ml_find_row,rl_show_soon);
	return gsel;
}
function rl_show_soon(mid,nofocus,nostatus)
{
	opanel_msg(mid,sw.active);
}	


// cf show_msg+show_msg_step2_inline 	preview_msg 	allow_images 
function opanel_msg(mid,node)
{
	var jmsg=sw.active.jmsg;
#	if(!compare_folders(jmsg.fld_id,sw.fld_id)) return;
	jmsg_reset(jmsg);
	jmsg.cache_mid=mid;
	jmsg.havehist=true;

	opanel_step2(jmsg,node.instance);
}

function opanel_step2(jmsg,instance)	// cf show_msg_step2_inline
{
	var xid=cache_id(jmsg.ident,jmsg.fid,jmsg.cache_mid);
	var qmsg=cache_find(xid);
	if (!qmsg) {
		if(!jmsg.cb_requested){
			retrieve_msg(jmsg.fld_id,jmsg.cache_mid);
			jmsg.cb_requested=true;
		}
		setTimeout(function(){show_msg_step2_inline(jmsg,instance)},200);
		return;
	}
	
	dge('message'+instance+'_panel').childNodes[1].innerHTML = html_from_qmsg(qmsg,'4 '+xid);
	sw.active.jmsg=jmsg;
	set_tab_text(qmsg.data['subject']);
	do_resize();
	check_rrcpt(qmsg);
}
function opanel_select(mid)
{
	var node=sw.active.node;
	if(!node || !node.rl) return;
	gs_select_bymid(node.rl,mid);
}

function picklist_init(txt)
{
	sw.picklist_raw=txt;
}
function qpick_menu(e,src,ctl)	// cf move_menu
{
	var opt = {};
	opt.nomanage=true;
	if(src!='kbd') opt.nofilter=true;
	do_generic_menu_setup('qpick','qpick_menu',(e&&e.shiftKey),opt)
	if(src=='button'){
		do_qpick_show(e)
	}else if(src=='pick' || src=='more_actions'){
		do_qpick_show(e,ctl,opt);
	}else if(src=='kbd'){
		do_qpick_show(e,dge('mnu_qpick'),opt);
	}
}
function do_qpick_show(e,input,opt)
{
	do_generic_show('qpick_menu', e, input, function(del_menu,id,create_new){
		if(id=='none'){
		}else if(id=='note'){
			do_new_note(e);
		}else if(id=='remind'){
			x_alert('remind id='+id)
		}else if(id=='manage'){
			x_alert('manage id='+id)
		}else{
			do_compose(e,U,[id])
		}
	},opt);
}
function do_qpick_menu(e,el)
{
	if (!e) e = window.event;
	var t = target(e);
	var row=ancestor_by_tag(t,'li');
	var mnu = list_to_menu(row);
	var item=row.getAttribute(mnu.search_attrib)

	menu_hide('qpick_menu',item);
	var o=dge('qpick_menu');
	class_add(o,'hidden');

	if (!item) return;
	if (o.cb) o.cb('ok',item);
}
function qpick_init_test()
{
	return;
# TODO
	class_remove(dge('mnu_qpick'),'hidden');
}

# QQQ REMOVE Deferred notice
// TODO: Fix UNFLAG to callback

function xinfo_recalc()
{
	set_status('Pruning old xinfo (this may take some time)','info');
	sndReq('cmd=xinfo_prune,show&page=~result.js', function(chan){
		var success=actionReqJsStat(chan);
		if(!success){
			set_status(success_string,"warning");
		}else{
			set_status('xinfo was recalculated',"success");
		}
	});	
}

function imgdrop_init()
{
	document.onpaste = function(event){
		var items = (event.clipboardData || event.originalEvent.clipboardData).items;
		console.log(JSON.stringify(items)); // will give you the mime types
		var blob = items[0].getAsFile();
		var reader = new FileReader();
		reader.onload = function(event){
			console.log(event.target.result)
		}; // data url!
		reader.readAsDataURL(blob);
	}
}


function policy_init()
{
	if(pref.set_password){
		x_alert("$$st_set_password$$",function(){
			setTimeout(function(){
				user_cgi_dlg('password');
			},0);
		});
	}

}
function html5_cloud_attach(e)
{
	var files = e.target.files || e.dataTransfer.files;
	debugger
	html5_attach_step2(e, files, 0, true);
	e.target.value = null;
}
function html5_attach(e)  	// SW_CLOUDFILE
{
	var files = e.target.files || e.dataTransfer.files;
	bigfile_dialog(files, {e:e, files:files}, function(data, detach_big){
		html5_attach_step2(data.e, data.files, detach_big);
		e.target.value = null;
	});	
}
	
function html5_attach_step2(e, files, detach_big_expire, detach_all)	
{
	for(var i=0;i<files.length;i++){
		file=files[i];
		file.cloudfile_expire = bigfile_expire(file.size, detach_big_expire, detach_all);
		aq_fdnd_add(file)
	}
	aq_fdnd_upload();
}

function strip_attach(e,src)
{
#	// Use setTimeout to allow menu to hide
	setTimeout(function(){
		x_confirm('$$st_dialog_deleteatt$$',function(n){
			if(!n) return;
			var sel=find_sel();
			ajax_strip_attach(sel,{'title':'$$st_scomment_title$$',noselect:true});
		});
	},100);
}

function notify_test()
{
	var allowed = Notification.permission;
	Notification.requestPermission();
	
	var count = 0;
	setInterval(function(){
		count++;
		var notification = new Notification("Mail"+count+" from Marijn Weehuizen : The quick brown fox jumped over the lazy dogs. Foo bar. And the cow jumped over the moon too.");
	}, 20000);

}

function notify_popup(level1, level2, click_cb) 
{
  if (isIOS) return;
  if (level1==U) level1 = 'Hi there!';
  var options = {
	body: level2,
	icon: '||www_base||shared/img/bell.png?||vz||',
	silent: true
  }

  if (!("Notification" in window)) {
    alert("This browser does not support system notifications");
  }

  else if (Notification.permission === "granted") {    
    var notification = new Notification(level1, options);
	notification.onclick = function(event) { 
		window.focus(); 
		parent.focus(); 
		if(click_cb){
			click_cb();
		}
		this.close();
	};
  }

  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {
      if (permission === "granted") {
        var notification = new Notification(level1, options);
      }
    });
  }
}

function notify_check_allowed(val)
{
  if (val!='popup') return;
  if (!("Notification" in window)) {
    alert("This browser does not support system notifications");
  } else if (Notification.permission == 'granted' || Notification.permission == 'denied') {
  	// ignore it
  } else {
    Notification.requestPermission(function (permission) {
      if (permission === "granted") {
        var notification = new Notification("Test notification", {body: 'If you see this, desktop notifications work :-)', icon: '||www_base||shared/img/bell.png?||vz||', silent: true});
      }
    });
  }
}

function notify_switch_to_mail(ident)
{
	if(ident>0 && sw.ident!=ident){
		account_sel(ident)
		return;
	}

	if(!class_contains(sw.active, 'fldmsg')){
		app_menu('mail',dge('app_mail'));
	}

	if(sw.fid==0){
		do_select('none');
		set_first_message(first_message);
	} else {
		FolderShow('INBOX',{fld_type:'1'})
	}

}


function cal_notify_by_email(subj, body) 
{
	var full_to = work_out_from(jmsg);
#	var c = split_address(full_to);
#	var full_from = 'Calendar Alert <'+c[1]+'>';
	var full_from = [full_to];
	
	var jmsg=compose_jmsg([full_to]);
	jmsg.from=[full_from];
	jmsg.subject=subj;
	jmsg.msg_html=body;
	jmsg.params="&no_append=true";
	ajax_send_silent(jmsg,function(){
		check_new_mail();
	});
}

function cal_prcc(type, fld, mid)	// cf spam_info
{
	var prcc_fn=(sw.is_popup?sw_win.ajax_send_calprcc:ajax_send_calprcc);		
	var sel=make_sel(fld,mid)
	prcc_fn(sel, type);
}

# Also see set_first_message
function store_sel()
{
	sw.active_sel = find_sel(true);
	sw.active_shift_sel_id = U;
	var o = sw.ml;
	if(o.shift_sel_start){
		sw.active_shift_sel_id = o.row_to_sel(o.shift_sel_start).id;
	}
}
function restore_sel()
{
	if (!sw.active_sel) return;
	setTimeout(function(){
		do_select('none');
		msglist_select(sw.active_sel,U,true);
		if(sw.active_shift_sel_id){
			var o = sw.ml;		
			gs_shift_start_set(o, o.sel_to_row(dge(sw.active_shift_sel_id)));
		}
	}, 100);
}

// Javascript triggered fullscreen is not very useful. Better have user explicitly set the 
// browser to fullscreen instead
function toggle_fullscreen(e)
{
	var is_fullscreen = (
		document.fullscreenElement ||
		document.webkitFullscreenElement ||
		document.mozFullScreenElement ||
		document.msFullscreenElement
	);

	var allow_fullscreen  = (
		document.fullscreenEnabled ||
		document.webkitFullscreenEnabled ||
		document.mozFullScreenEnabled ||
		document.msFullscreenEnabled
	);

    var el = document.body;
    if(!is_fullscreen)
    {
		if (el.requestFullscreen) {
			el.requestFullscreen();
		} else if (el.webkitRequestFullscreen) {
			el.webkitRequestFullscreen();
		} else if (el.mozRequestFullScreen) {
			el.mozRequestFullScreen();
		} else if (el.msRequestFullscreen) {
			el.msRequestFullscreen();
		}
	}else{
		if (document.exitFullscreen) {
			document.exitFullscreen();
		} else if (document.webkitCancelFullscreen) {
			document.webkitCancelFullscreen();
		} else if (document.mozCancelFullScreen) {
			document.mozCancelFullScreen();
		} else if (document.msCancelFullscreen) {
			document.msCancelFullscreen();
		}
	}

}

function filter_hide()	// setMessages
{
	var el = dge('messages_header');
	class_add(el,'hidden');
	el.innerHTML="";
}
function filter_show(state, count)
{
	var spacer = true ? '<br>' :'&nbsp;&nbsp;&nbsp;';
	var msg_state = 'hidden';
	var txt = '<div class="spamfilter_info">';
	if(true)
	{
		txt += '<span style="float:right"><a onclick="filter_analyse()">Analyse</a></span> ';
		txt += 'Show: ';
		if(state=='apply') {
			txt +='<span class="selected">filtered</span>, <a onclick="filter_toggle(\'count\')">all</a>, <a onclick="filter_toggle(\'only\')">hidden</a> ';
			msg_state = 'hidden';
		} else if(state=='count') {
			txt +='<a onclick="filter_toggle(\'apply\')">filtered</a>, <span class="selected">all</span>, <a onclick="filter_toggle(\'only\')">hidden</a> ';
			msg_state = 'visible';
		} else if(state=='only') {
			txt +='<a onclick="filter_toggle(\'apply\')">filtered</a>, <a onclick="filter_toggle(\'count\')">all</a>, <span class="selected">hidden</span> ';
			msg_state = 'visible';
		}
		txt +=	spacer+' <span class="filter_status">'+count+' messages '+msg_state+' <a onclick="filter_analyse()">matching spamfilter</a></span>';
		txt += '</div>';
	}else{
	
		txt += '<span style="float:right"><a onclick="filter_analyse()">Messages</a></span> ';
		txt += 'Analysed by: <a href="">From</a>, <a href="">Subject</a>';	
		txt +=	spacer+' <span class="filter_status">'+count+' messages '+msg_state+' <a onclick="filter_analyse()">matching spamfilter</a></span>';
		txt += '</div>';
	
		txt += '<div class="spamfilter_active" style="background:#bbb	;padding:4px;">Display filter <input type="button" value="Spam"> <input type="button" value="Notspam"></div>';
	}	
	var el = dge('messages_header');
	class_remove(el,'hidden');
	el.innerHTML = txt;
}

function filter_toggle(new_state)
{
	var opt = {};
	opt.filter_state = new_state;
	F(sw.fld_id,sw.fld_type,0,false,true,opt);
}

function filter_update(state, count)
{
	filter_show(state, count);
	return;
	if(count==0){
		filter_hide();
		return;	
	} 
	if(state=='apply' || state=='count' || state=='only')
	{
		filter_show(state, count);
	}else{
		filter_hide();
	}	
}
function do_filter()
{
	var sel=find_sel();
	if (!sel) return;
//	ajax_spam_rating(sel,'spam',function(node){class_remove(node,'foo')})
//	message_done_action(sel);
}
function filter_analyse()
{
	var extra='';
	var title='Spam folder analysis';
	var cmd='cmd=spamfilter&action=analyse&sid='+sid+extra;
	x_custom_dlg2(title,'<iframe id="dlg_iframe" src="'+cgibase+cmd+'" style="width:100%;height:'+px(300)+';background:#ECE9D8;" frameborder="0"></iframe>',
		function(btn){
#			sndReq('cmd=cal_action,show&page=~calendars.htm'+iid(), function(chan){
#				node=actionReqSethtml(chan.responseText,'utility');
#			});		
		}, function(){}, {'width':560,'nopad':true,'nobtns':true});
}


var checkcal_timer;
var checkcal_last_lcl=0;
var checkcal_last_svr=0;
var checkcal_events=[];
var checkcal_count=0;
var checkcal_notified={};

function check_cal_timed(type, duration)
{
	if(!pref.newcal) return;
	if(type!=U){
		if(type=='lcl'){
			checkcal_last_lcl=time();
		}
		if(type=='svr')
			checkcal_last_svr=time();
	}
	if (checkcal_last_lcl==0 && checkcal_last_svr==0) duration=5;
	if (duration==U) duration=17;
	checkcal_timer = setTimeout(check_cal_next, duration*1000);
}

function check_cal_next()	// cf check_new_timed
{
	cal_update_redline(zc);

	checkcal_count++;
//	if (pref.nocheck) return;
//	if (pref.devt_test=='nobg') return;

	dbg('***** check_cal_timed');
	var t=time();
	dbg('cal last_check='+(t-checknew_last) +' untouched='+(t-sw.last_action));

	if(window.swlogin_pending){
		check_cal_timed();
		return;
	}

	// Check with server
	if(t-checkcal_last_svr>10*60){
#		// Refresh calendar
		check_cal_alerts(); 
		return;
	}
	var now=time();
	for(var i=0; i<checkcal_events.length; i++){
		var evt = checkcal_events[i];
#		// Delete old events and ignore future events
		if(evt.alert<now-5*60 || checkcal_notified[evt.alert_id]){
			dbg('event alert UNWANTED name='+evt.desc);
			checkcal_events.splice(i, 1);
			i--;
			continue;
		}
		if(evt.alert>now) {
			dbg('event_soon alert_in='+((evt.alert-now)/60).toFixed(1)+'min event_at='+showtime(evt.t*1000)+' name='+evt.desc+'] ');
			continue;
		}			
#		// Only ever notify one event at a time
		checkcal_notified[evt.alert_id]=true;
		var at_time = showtime(evt.t*1000)
		if(pref.alert_cal=='popup'){
			notify_popup(evt.desc+', at '+at_time);
			if (pref.sounds!='none') {
				play_sound('event');
			}
		} else if(pref.alert_cal=='email'){
#			 now done serverside!			
#			 cal_notify_by_email('Calendar alert '+at_time, 'Event: '+evt.desc+'<br>'+'At: '+at_time+'<br>'+'Notes: '+evt.notes);
		}
		checkcal_events.splice(i, 1);
		check_cal_timed('lcl',2);	
		return;		
	}

#	// Actually notify - via popup or email :-)
	dbg('monitoring ['+checkcal_events.length+' events] #'+checkcal_count);

	check_cal_timed('lcl');	
}

function check_cal_alerts()		// cf  check_new_mail()
{
	// Done serverside now!
	if(pref.alert_cal=='email') return;

	//if(last_check_cal>time()-2 && !first) return;
	queued_req_add( enBG, 'check_cal', function(first){
		var now = mtime();
		var range = '&t1='+ms2dvZ(now)+'&t2='+ms2dvZ(now+2*24*60*60*1000+10*60*1000);	

||iftrue(using_api)||
		apiGet('core/check_cal?v=sw&cals=all'+range+'&bg=true'+iid(), function(chan){
||else||
		sndReq('cmd=check_cal,show&page=~result.js&cals=all'+range+'&bg=true'+iid(), function(chan){
||endif||
			if (chan.status!=200){
				success_string=err_general(chan,1);
				set_status('$$st_newchk_fail$$ '+success_string,'warning');
				check_cal_timed('svr');
				return;
			}
			var success=actionReqJsStat(chan);
			if(!success){
				check_cal_timed('svr');
				return;
			}			
			check_cal_timed('svr',0);
		},ch[enBG]);
	}, 0);
}
function cal_alerts_add(upcoming_events)
{	
	checkcal_events = upcoming_events;
	dbg('alert events fetched from server '+(checkcal_events.length)+' events #'+checkcal_count);
}

var new_mail_count;
var new_mail_uids;
function new_mail_popup(count,uids)
{
	new_mail_count = count;
	new_mail_uids = uids.split(',');

#	// Actual alert, is now done in response to cache messages web request
#	if (count>0){
#		setTimeout(new_mail_popup_step2, 250);
#	}
}
# newmail on selected account
function new_mail_popup_step2()
{
	var level1, level2;
	var done_some = false;
	var main_ident = sw.ident;
	var main_fid = 0;	//sw.fid
	if(new_mail_count==1){
		var qmsg = cache_find(cache_id(main_ident,main_fid,new_mail_uids[0]));
		if(!qmsg) return;
		var full_sender=qmsg.data.from[0];
		var sender = text2contact(full_sender,false);
		level1 = sender.email[0].value;
		level2 = qmsg.data.subject; 
		done_some=true;
	}
	 else if(new_mail_count>1){
		level1 = $('%s new message%s received',new_mail_count,plural(new_mail_count));
		level2 = 'from ';
		for(var id=0; id<new_mail_uids.length; id++){
			var qmsg = cache_find(cache_id(main_ident,main_fid,new_mail_uids[id]));
			if (!qmsg) continue;
			if (done_some) level2+=', ';
			if (id>=3) {
				level2+='...';
				break;
			} 
			var full_sender=qmsg.data.from[0];
			var sender = text2contact(full_sender,false);
			level2 += sender.email[0].value; 
			done_some = true;
		}
	}
	if(done_some){
		notify_popup(level1,level2, function(){
			notify_switch_to_mail();
		});
	}
}
# newmail on non selected account
function new_mail_popup_other(identity_id)
{
	var identity = sw.identities[identity_id];
	var desc = identity.name;
	if (!desc || desc.length==0) desc = identity.email;
	var level1 = 'New mail on account: '+desc;
	var level2 = '';
	notify_popup(level1, level2, function(){
		notify_switch_to_mail(identity_id);
	});
}



var last_scroll_pos = 0;
var prescroll_subject = '';
function prescroll_msg(qmsg)
{
||if_set(newlook_fancy_scrollbar_disable)||
	if(pref.newlook_ui){
		setTimeout(function(){
			do_resize_real()
		},1);
	}
||endif||
	if(!pref.prescroll) return;
# note only valid for altui configs for now, and when to use "to be decided"
	if(qmsg.data.subject.indexOf('prescroll')==-1) return;
	if(!sw.btns_toggle) return;
	var el_hdrs = dge('msg_headers');
	var el_scroll = dge('message_preview');
	var fullmsg_scroll = 44+el_hdrs.clientHeight + 1-22;
	var pos = 0;
	if(sw.btns_toggle==1 || sw.btns_toggle==2){
		pos = fullmsg_scroll;
	}
	el_scroll.scrollTo(0,pos);
	prescroll_subject = qmsg.data.subject;
	prescroll_propagate(pos);
}
function prescroll_reset()
{
	if(!pref.prescroll) return;
# note only valid for altui configs for now
	last_scroll_pos = 0;
	prescroll_propagate(0);
}
function message_scrolled(e)
{
	if(!pref.prescroll) return;
# note only valid for altui configs for now
	var buttons = dge('alt_buttons_top');
	var el = dge('message_preview');
	var scroll_pos = el.scrollTop;
	var scroll_cutoff = dge('msg_headers').offsetHeight+44-3-21;
	var want_buttons = (scroll_pos<scroll_cutoff) || (scroll_pos<last_scroll_pos);
	if(want_buttons){
		//bottons.style.top=px(0);
		class_remove(buttons,'collapsed');
	} else { 
		//bottons.style.top=px(-20);	
		class_add(buttons,'collapsed');
	}
	last_scroll_pos = scroll_pos;
	prescroll_propagate(scroll_pos);
}
function prescroll_propagate(pos)
{
	return;
	var el = dge('alt_buttons_prescroll');
	if(!el) return;
	class_remove(el,'hidden');
	if(pos<10){
		el.innerHTML='';	
	}else{
		el.innerHTML=prescroll_subject;
	}
}

function close_windows()
{
	var el = dge('utility_alt2');
	if(el) el = el.parentNode;
	if(el) class_add(el,'hidden');
	tab_close('tab1');
}

function contact_lcol_update(el) 	// cf swcal_lcol_update(el)
{
	alt_clear_both('lpanel_contacts');
	if(!el) el=dge(append_alt('lpanel_contacts'));
	if(!el) return;
#	remove_children(el);
	new_anchor('div','\
		<div class="lpanel_toplink"><a href="#" onclick="contact_new_group()">$$st_ct_newgroup$$</a></div>\
# 		Float left makes IE offsetLeft calculation work...???!!! still needed??
		<div id="cm_groups" class="cm_panel" onclick="cm_select_group(this,event)" style="left:0px;zoom:1;"></div>\
	',el);
}

var time_ms;
function time_ms_init()
{
    if (typeof performance !== 'undefined' && typeof performance.now === 'function' && isFinite(performance.now())) {
        time_ms = function() {
            return performance.now();
        };
    } else {
        time_ms = function() {
            return Date.now();
        };
    }
}

function dev_test()
{	
	time_ms_init();
	var endTime = time_ms()+5;
}

function el_by_mode(std_id, alt_id)
{
	return sw.altui ? dge(alt_id) : dge(std_id);
}

function show_util2()
{
	altui_show_utility('util');
	return;

	show_if_exists('alt_slideup');
	var el = dge('utility_alt2');
	el.style.width = px(ClientWidth()-200);
}

function set_sw_active(new_active)
{
	if(new_active==U){
#		debugger;
	}else{
#		debugger;
	}

	sw.active = new_active;
}

function set_tab_node_ref(tab, new_ref)
{
	tab.node_ref = new_ref;
}
function message_resize()
{
	if(sw.is_popup){
		popup_resize();
	}else{	
		do_resize_real();
	}
}

var global_scroll_width;
function get_scrollbar_width()
{
	if(!defined(global_scroll_width)){
		var el = document.createElement("div");
		el.className = "scrollbar-measure";
		document.body.appendChild(el);
		global_scroll_width = el.offsetWidth - el.clientWidth;
		document.body.removeChild(el);
	}
	return global_scroll_width;
}



function custom_done()
{
	x_prompt( '$$st_fldmng_done_desc$$',pref.special_done,function(val){
		if(!defined(val)) return;
		ajax_pref_save('pref_Done='+xescape(val));
#		dge('custom_done_txt').innerHTML = val;
		setTimeout(function(){
			x_alert('Log out of surgeweb and login again to use the updated Archive folder');
		},0);
	});
}

function resize_image(image, target_dim)
{
/*
	var result = {img:image.img, height:image.height, width:image.width};
	var last_draw = image.img;
	while (result.height>max_dim.height && result.width>max_dim.width){
		
		var oc = make_image_canvas(result.width/2, result.height/2);
		var octx = oc.getContext('2d');
		octx.drawImage(last_draw, 0, 0, oc.width, oc.height);
		result.canvas = oc;
		result.width = result.width/2;
		result.height = result.height/2;
	}
	return result;
*/
}

# apply fade effect programmetically!							
function apply_surgeweb_fade(canvas)
{
	var context = canvas.getContext('2d');
	var target_width = canvas.width;
	var target_height = canvas.height;
	var imgData = context.getImageData(0, 0, target_width, target_height);
	var pixArray = imgData.data;
	var nPixLen = pixArray.length;
	for (var nPixel = 0; nPixel < nPixLen; nPixel += 4) {
		var pixelY = parseInt(nPixel / (target_width*4));
		var pixelX = parseInt((nPixel % (target_width*4))/4);
		var fade_start = 220;
		var fade_angle = 1.0 * 1.4;
		var fade_startpoint = fade_start-parseInt(pixelY*fade_angle);
		var alpha = 255;
		if(pixelX>fade_startpoint){
			alpha=255-parseInt(255*(pixelX-fade_startpoint)/80);
		}
		pixArray[nPixel + 3] = alpha; //255 - ((nPixel)%(target_width*4*1.0));
	}
	context.putImageData(imgData, 0, 0);
}


#Some inspiration: 
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
# https://stackoverflow.com/questions/17861447/html5-canvas-drawimage-how-to-apply-antialiasing
function create_bg_image(imgDataURL, cb, area)
{
# Finding EXIF info
#	var bin = atob(imgDataURL.split(',')[1]);
#	var exif = EXIF.readFromBinaryFile(new BinaryFile(bin));
#	alert(exif.Orientation);

	var target_height = 52;
	var target_width = 400; 

	var img = new Image;
	img.src = imgDataURL;
	img.onload = function(e){
		
		var src = {img:img, canvas:U, ctx:U, height:img.height, width:img.width}
		
		var canvas = make_image_canvas(target_width, target_height);
		var context = canvas.getContext('2d');

		if(src.width/src.height>2.5){
			context.drawImage( src.img,
					// Source param
					0,0, parseInt(src.width), parseInt(src.height),
					// Dest param
					0,0, target_width, target_height);		
		} else {
			src = reduce_image_raw(src, {width:target_width*1, height:target_height*1});

			var scale = 0.77;
			var dest_height = parseInt(target_height);
			var draw_width = parseInt(target_height*(img.width/img.height));

			context.imageSmoothingEnabled = true;
			context.imageSmoothingQuality = 'high';
			context.drawImage( src.canvas?src.canvas:src.img, 
					// Source param
					0/*img.width/4*/,parseInt(src.height/4) /*img.height/4*/, parseInt(src.width), parseInt(src.height/3),
					// Dest param
					0*parseInt(target_width-draw_width)/2,0, target_width*scale, dest_height);		
		}
		apply_surgeweb_fade(canvas);

# convert backto data url
		var img2 = canvas.toDataURL();	
		cb(img2);
	};
}

function custom_bg_default()
{
	background = '||www_base||shared/img/banner_raw.png?||vz||';
	toDataURL(background, function(dataURL){
		custom_bg_update_step2(dataURL);
	  });
}

function custom_bg_update(background)
{
	var el = dge('modern_title_text');
	if(defined(el)) el.innerHTML='';

	return custom_bg_update_step2(background);
}

function custom_bg_update_step2(background)
{
	create_bg_image(background, function(processed_image){
	
		var el = dge("banner_img");
#		el.style.background = 'url('+processed_image+') no-repeat fixed';
		el.style.background = 'url('+processed_image+') no-repeat';
#		el.style.backgroundPosition = '50% 50%';

#		el.style.backgroundSize = 'contain';
#		el.style.backgroundSize = 'cover';

#  		el.style.backgroundRepeat= 'no-repeat';
		el.style.backgroundSize = 'fixed';
#  		el.style.backgroundOrigin = 'fixed';

#		el.style.transform = 'scale(4)';

#		el.style.height = '100vh';	

	});	
}
function custom_bg_drop_init()
{
||if_set(newlook_login)||
||if_not(newlook_propagate_disable)||
	var el = dge('top_banner');
	el.addEventListener("dragover", function(e){return stopEvent(e);}, false);
	el.addEventListener("dragleave", function(e){return stopEvent(e);}, false);
	el.addEventListener("drop", function(e){ custom_bg_drop(e);return stopEvent(e);}, false);
||endif||
||endif||
}


function history_init()
{
||if_set(newlook_ui)||
	if(pref.history_disable) return;
#	// Confirm init only gets called once!!!
	if(sw.history!=U) return;

	sw.history = {};
	window.addEventListener('popstate', function(event){
		var loc = history_get_location();
		history_apply_change(loc);
	}, false);

	var loc = history_get_location();
	history_apply_first(loc);
	if(loc==U){
		history_set_location('mail','INBOX');
	}
||endif||	
}
function history_set_location(type,subtype)
{
||if_set(newlook_ui)||
	if(pref.history_disable) return;
	var stateObj = { foo: "bar" };
	var location = 'surgeweb';
	if(type!=U || subtype!=U){
		location += '#'+capitalize(type);
	}
	if(subtype!=U){
		location += '/'+subtype;
	}
	history.pushState(stateObj, null, location);
||endif||	
}

function history_get_location()
{
	var page=0;
	var txt = decodeURIComponent(window.location.hash);
	if(!txt || txt.length==0) return U;
	page = txt.substring(1);
	return page;
}
function history_apply_first(loc)
{
	if(loc==U || loc.indexOf('Mail/')!=0) return;
	sw.fld_id = loc.substr(5);
}
function history_apply_change(loc)
{
	if(loc==U) return;
	if(loc.indexOf('Calendar')==0){
		app_menu('calendar',{skip_history:true});
	}
	if(loc.indexOf('Contacts')==0){
		app_menu('contacts',{skip_history:true});
	}
	if(loc.indexOf('Mail/')==0){
		app_menu_mail();
		
#		Full mode, account, folder selection as needed :-)		
		FolderShow(loc.substr(5), { skip_history:true });
	}
}


function message_preview_real_el(el)
{
	if(pref.scrollbar_type!='modern') return el;

||if_set(newlook_ui)||
# line below: messing up the scrolling, don't think this is needed
#||if_not(newlook_custom_photo_disable)||
	if(el!=U && el.firstChild!=U && el.firstChild.nodeType==Node.ELEMENT_NODE && class_contains(el.firstChild,'nano-content')){
		return el.firstChild;
	}
#||endif||	
||endif||

	return el;
}

function ibz_reward(use_ibz)
{
	return false;
	
||if_not(newlook_ui)||
||if_set(inbox_zero_disable)||	
	return false;
||endif||	
||endif||
	if(!use_ibz) return false;
	var stored_bg = localStorage.getItem("background");
	if(!defined(stored_bg)) return false;

	message_preview_real_el(dge('message_preview')).innerHTML = '||html_begin()||\
		<div style="width:100%;height:100%; background: url('+stored_bg+') center center / cover no-repeat, center center rgb(102, 153, 194);">
		  <div style="position:absolute;line-height:70px;text-align:center;font-size:250%; font-weight:bold; color:white; bottom:10%;left:10%;right:10%;text-shadow: 2px 2px 8px #000;">
			Inbox Zero<br>Attained!
		  </div>
		</div>||html_end()||'; 
	
	return true;
}

function ibz_is_inbox()
{
	return (sw.fld_id=="INBOX");
}


function preload_find_next(mid)
{
	sw.preload = U;
	var o = sw.ml;
	var el = dge('sel_'+mid);
	if(!defined(el)) return;
	var r = o.sel_to_row(el);
	var r2 = r.nextSibling;
	if(!defined(r2)) return;
	var el2 = o.row_to_sel(r2);
	if(!defined(el2)) return;
	var mid2 = o.sel_to_mid(el2);
	var xid=cache_id(sw.ident,sw.fid,mid2);	
	var oo = {};
	oo.mid = o.sel_to_mid(el2);
	oo.fld_id = sw.fld_id;
	oo.xid = xid;
	sw.preload = oo;
}
function preload_cache_next()
{
	if(!defined(sw.preload)) return;
	var o=sw.preload;
	sw.preload = U;
	if(sw_cache && cache_find(o.xid)) return
	retrieve_msg(o.fld_id, o.mid, U, U, true);
}



function do_whitelist_address()		// cf usercgi_summary
{
	x_prompt2('Address to friends whitelist (eg. *@wanteddomain.com) ','',function(val){
		if (!val) return;
		whitelist_address(val);
	}, {'nocancel':true});
}

function whitelist_address(val)
{
	queued_req_add( enQ, 'usercgi_summary', function(){
		var url=backend+'cgi/user.cgi?cmd=auto_login%26lcmd=user_friend_add%26show=sw_whitelist.js%26friend='+xencode(val)+'%26surgeweb=true';
		sndReq('cmd=proxy&sid='+sid+'&add_auto_login=true&url='+url, function(chan){
			var success=actionReqJsStat(chan);

			if(val.startsWith('*@')){
				val = 'Domain '+val.substring(2);
			}

			if(success_string.indexOf('Friend already known') != -1){
				set_status(val+' is already whitelisted', 'info');
			}else if(success_string.indexOf('Friend(s) added') != -1){
				set_status(val+' whitelisted', 'success');
			}else{
				set_status(success_string, 'warning');
			}
		},ch[enQ]);
	});

}
function wildcard_domain(email)
{
	var n=email.indexOf('@');
	if(n==-1) return '';
	return '*'+email.substring(n);
}


var big_file_size = 0;
function bigfile_isbig(size)
{
	return size>pref.bigfile_size
}
function bigfile_anybig(files)
{
	var any_big = false
	for(var i=0;i<files.length;i++){
		var file=files[i];
		if(bigfile_isbig(file.size)) {
			any_big = true;
			big_file_size = file.size;
		}
	}	
	return any_big;
}
function bigfile_dialog(files, data, cb)
{
	if(pref.cloudfile_enabled  == false || bigfile_anybig(files) == false){
		cb(data, 0)
		return;
	}
	var caption = 'File is big ('+format_size_basic(big_file_size)+') and may not be able to be sent as an email.  <br><br> Send as Cloud Attachment? <br><br> Expire link in		\
		<select id="bigfile_expire" class="">\
				<option value="1"> 1 day</option>\
				<option value="2"> 2 days</option>\
				<option value="7" selected> 1 week</option>\
				<option value="31"> 1 month</option>\
		</select>';
	x_confirm(caption,function(selected_option){
		debugger
		if(selected_option == 1){
			selected_option = dge("bigfile_expire").value;
		}
		cb(data, selected_option)		
	},false,{'title':'Attention', ok_txt:'Cloud Attachment', cancel_txt:'Email Attachment', });
}

function bigfile_expire(size, big_expire, detach_all)
{
	var ret = U;
	if(big_expire>0 && bigfile_isbig(file.size)){
		ret = big_expire;
	}
	if(detach_all){
		ret = pref.cloudfile_expire;
	}
	return ret;
}	

function unknown_alert(sender_addreess)
{
	x_alert("This is not someone you regularly communicate with. Confirm this is from the person you think it is from: <br> "+xencode(sender_addreess) );
}