
#surgeweb new calendaring implementation

# *** New Calendar configuration page :-))
function swcal_url(o)
{
	var l=window.location;
	txt = l.protocol+'//'+l.host+'/cal/calendars/'+(dge('username_display').innerHTML)+'/'+ancestor_by_tag(o,'tr').getAttribute('cal_id');;
	x_prompt2('Copy as normal from here (eg. "'+(isMac?'Cmd':'Ctl')+'+C, Enter") or using context menu',txt,function(val){
		if (!val) return;
	}, {'nocancel':true});
}
function swcal_sharing(o)
{
	var extra='';
	if(o) extra='&cal_sel='+ancestor_by_tag(o,'tr').getAttribute('cal_id');
	var title='Calendar Sharing'
	var cmd='cmd=cal_action,show&page=hdialogs.htm&dlg_type=config_cal&dlg_seq=&dlg_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){
			sndReq('cmd=cal_action,show&page=~calendars.htm'+iid(), function(chan){
				node=actionReqSethtml(chan.responseText,'utility');
			});		
		}, function(){}, {'width':560,'nopad':true,'nobtns':true});
}
function swcal_delete(o)
{
	x_confirm('This will delete this calendar and all events it may contain! Are you sure?',function(n){
		if (!n)return;
		var extra='&cal_sel='+ancestor_by_tag(o,'tr').getAttribute('cal_id');
		sndReq('cmd=cal_action,show&cal_action=delete&page=~calendars.htm'+extra+iid(), function(chan){
			node=actionReqSethtml(chan.responseText,'utility');
		});		
	});
}

# *** Primary and secondary new calendar display object 
var zc=cal_new();
#zc.noevents=true;

# *** Actually show / init of new calendar display

function swcal_show_newcal()	// cf contacts_mgt_sw	<<< from app_menu (step1)
{
	sndReqCached('cmd=show&page=~calendar.htm'+'&if=ajax&static=||web_ref_path||&||vz||', function(chan){
		if (chan.status!=200){
			success_string=err_general(chan,5);
			set_status(success_string,'warning');
			return false;
		}
		node=actionReqSethtml(chan.responseText,'utility');
		zc.output_cal=true;
		swcal_setbtn(zc.cur_view);
		swcal_switch(zc.cur_view)
	},ch[enFG]);
}	
# cb for init from swcal_show_newcal
function swcal_init()	
{
}

# left column clear when selecting app_menu
function swcal_lcol_update(el)		// <<< possible race condition??
{
	if(!el) el=dge('lpanel_calendar');
	if(!el) return;
	remove_children(el);
	new_anchor('div','<div id="cal_lpane" style="padding:0px">'+swcal_lpane_html()+'</div>',el);
}

# actual left column html for old or new calendar display
function swcal_lpane_html()
{	
	var txt;
	if(pref.newcal) {
		txt='\
			<div class="nav_mini_outer"><div id="cal_nav" style="width:100%;" onclick="swcal_nav(event)"> <div style="height:100px;"></div></div></div>\
				<div style="padding:5px;">\
				<div>\
					<input type="button" value="$$st_cal_config$$" onclick="manage_calendars(event)" class="mnu" style="float:right">\
					<input type="button" value="$$st_cal_all$$" onclick="cal_select_all(event)" class="mnu" style="margin-left:1px;"> \
					<input type="button" value="$$st_cal_none$$" onclick="cal_select_none(event)" class="mnu" style="margin-left:1px;">\
				</div>\
				<div class="hline hidden"></div>\
				<div id="cal_list_html"><div style="height:150px;"></div></div>';
		if(!pref.no_surgeplus){
			   '<div><br>Older: <ul><li><a href="#" onclick="do_old(\'calendar\')">SurgePlus Calendar</a></li></ul></div>';
		}
		txt+='</div>';
	}else{
		txt='\
			<div style="padding:5px;">\
				<div class="xc pt20">Configure CalDAV mobile and <br>shared mobile calendars</div>\
				<div class="xc pt20"><input type="button" value="Configure" onclick="manage_calendars(event)"></div>\
				<div class="xc pt20" style="color:#777">Note: This is not the calendar displayed on the right!</div>\
			</div>';
	}
	return txt;
}

# resize handling
function swcal_resize(h,w)
{
	if (sw.active.id!='calendar_panel') return;

	cal_calc_col_width(zc,w);
	o=dge('cal_outline').parentNode;
	o.style.height=px(h);
	
	cal_resize(zc,h,zc.table_inset+zc.col_width*zc.columns);
}

# init actual event data
function setEvents(evs)
{
	zc.raw_evs=evs;
}


# *** Util functions 

function swcal_to_color(cal)
{
	switch(cal){
		default:
		case 1: return '#88f';
		case '0E26CF7E-8849-47D9-BF7A-C038948906B0': return '#8f8';
	}
}

function td(d,m) { var d=new Date(2012,m-1,d,0,0,0,0); return Math.round(d.getTime()/1000)*1000; }
function tt(h,m) { var d=new Date(2012,zc.this_month-1,zc.this_day,h,m,0,0); return Math.round(d.getTime()/1000)*1000; }
function ts(txt) { d=new Date(txt.substr(0,4),txt.substr(4,2)-1,txt.substr(6,2),txt.substr(9,2),txt.substr(11,2),txt.substr(13,2),0); return d.getTime();}
function tu(epoch) { return epoch*1000; }
function tut(epoch) { return ms2dv(epoch*1000);}

function cal_sel(o,ticked)
{
	cbox_assign(o,ticked);
}

function cal_scroll(el)
{
	var el=dge('cal_details_scrolled')
	var o=dge('cal_shadow');
	if(el.scrollTop==0 || el.style.overflowY=='hidden'){
		class_add(o,'hidden');
	}else{
		class_remove(o,'hidden');
	}	
}
function cal_prefix_strip(txt)
{
	if(!txt) return '';
	var i=txt.indexOf("_");
	if(i==-1) return txt;
	txt=txt.substring(i+1);
	return txt;
}
# *** Displayed calenders list on left

function cals_set_all(txt)
{
	el=dge('cal_list_html');
	el.innerHTML=txt;
	el.onclick=calendar_click;
}
var creation_cal;
function calendar_click(e)
{
	if(!e) e=window.event;
	var t=target(e);
	var row=ancestor_by_tag(t,'li');
	for_each(siblings(row),function(o){class_remove(o,'selected')});
	creation_cal=U;

	cal_id=row.getAttribute('cal_id');
	if(!cal_id) return;
	var cal=sw.cals[cal_id];
	if(cal.name.indexOf('(R)')!=-1) {
		x_alert(cal.name+' is a read only calendar')
		return;
	}
	if(cal.name.indexOf('Reminders')!=-1) {	// QQTD
		x_alert('Special calendar '+cal.name+' cannot be added to')
//		return;
	}
	class_add(row,'selected');
	set_status('$$st_cal_stat_create1$$ '+cal.name,'info');
	creation_cal=cal_id;
}
function cals_reset()
{
	sw.cals={};
	sw.cals_array=[];
}
function cals_set_one(cal)
{
	var e=window.event;
	if(sw.cals==U) cals_reset();
	sw.cals[cal.id] = cal;
	sw.cals_array.push(cal.id);
	return cbx('cal_'+cal.id,cal.clr,'swcal_cbx',cal.sel);
}
function swcal_cbx(e,el,ticked)
{
	if(!e) e=window.event;
	cal_show(zc,{keep_frame:true});
	stopEvent(e);
}
function cal_to_sel(el)
{
	return el.firstChild;
}
function swcal_creation_cal()
{
	if(creation_cal) {
		var cbox=dge("cal_"+creation_cal);
		if(cbox && class_contains(cbox,'sel')) return creation_cal;
	}
	var el=dge("cal_list_html").firstChild;
	for(var i=0;i<el.childNodes.length;i++){
		var el2=el.childNodes[i];
		if(!el2)continue;
		var cal_id=el2.getAttribute("cal_id");
		if(!cal_id) continue;
		var cbox=cal_to_sel(el2);
		if(!cbox || !class_contains(cbox,'sel')) continue;
		return cal_id;
	}
	for(var i=0;i<el.childNodes.length;i++){
		var el2=el.childNodes[i];
		if(!el2)continue;
		var cal_id=el2.getAttribute("cal_id");
		if(!cal_id) continue;
		return cal_id;
	}
}



# *** Lower priority UI actions

function swcal_new()
{
	calhint_evel=U;
	var xc=zc;
	
	var now=new Date();
	var xx=new Date(xc.cur_year,xc.cur_month-1,xc.cur_day,now.getHours()+1,0,0,0);
	xc.validate_rc=cal_time_to_rc(xc,xx.getTime());
	xc.validate_xy=[0,0];

	el=cal_create_one(xc,xc.validate_rc,xc.validate_xy);
	var ev=el.ev;
	cal_event_t2ts(ev);
	calhint_evel=el;
	cal_showpopover(true,true);
}


# *** Actual entry points for calendar switching and navigation functions

# primary toolbar view switching
function swcal_switch(type,opt)	
{
	swcal_setbtn(type);
	cal_setview(zc,type);
	cal_show(zc,opt);
}
function swcal_refresh(xc)
{
	cal_populate_events(xc,{});
}
# mini navigator
function swcal_nav(e)
{
	var t=target(e);
	var el=ancestor_by_class(t,'nav');
	if(!el) return;
	var xc=zc;
	var tag=xc.cur_view;
	if(tag=='week') tag='day';
	var txt=el.getAttribute(tag);
	if(txt==null || txt.length==0) return
	var type=parseInt(txt);
	if(xc.cur_view=='year'){
		cal_setwhen(xc,type,U,U);
	}else if (xc.cur_view=='month'){
		cal_setwhen(xc,U,type,U);
	}else if (xc.cur_view=='day' || xc.cur_view=='week'){
		var mdelta=el.getAttribute('mdelta');
		if(mdelta.length==0) {
			cal_setwhen(xc,U,U,type);
		}else{
			cal_setwhen(xc,U,xc.cur_month+parseInt(mdelta),type);
		}
	}
	cal_show(zc);
}
function cal_update_xc(e,xc)	// cf swcal_nav
{
	var el=ancestor_by_class(target(e),'nav');
	if(!el) return;
	var txt=el.getAttribute(xc.cur_view);
	if(txt==null || txt.length==0) return
	var type=parseInt(txt);
	var mdelta=el.getAttribute('mdelta');
	if(mdelta.length==0) {
		cal_setwhen(xc,U,U,type);
	}else{
		cal_setwhen(xc,U,xc.cur_month+parseInt(mdelta),type);
	}
}
function swcal_navdate(tm,type)
{
	var d=new Date(tm);
	cal_setwhen(zc,d.getFullYear(),d.getMonth()+1,d.getDate());
	swcal_switch(type);
}

function swcal_other()
{
	// keyboard or other calendar switching... ??
}

function swcal_today()
{
	cal_settoday(zc);
	cal_show(zc);
}

# *** callbacks OUT of the cal display library

function populate_events_cb(xc)
{
	if(xc.noevents) return;
	cal_dom_assign(xc,[],'cal_events_tmp');	// maybe needs different location??
	var param={}, extra='';
	if (xc.output_cal) { 
		extra+='&output_calendars=true'; 
		xc.output_cal=U;
	}
	param_populate_cal(xc,param);
	if(xc.output_cal) {
		sw.cals={};
		sw.cals_array=[];
	}
	ajaxPost('cmd=cal_action,show&page=~events.js&cal_action=load_only'+extra+iid(), param, function(chan){	
		success = actionReqJs(chan);
		cal_spinner_stop();
		if(!success){
			set_status(success_string,'warning');
			return;
		}
		if(dge(xc.region)==U){
#			Took too long user has already navigated away from calendar?!
			return;
		}
		cal_populate_events_cb(xc,xc.raw_evs);
		do_resize_real();			// trigger a full sw resize to apply the correct calendar sizing
	});
}


function event_savetimes_cb(xc,ev)
{
	return save_edited_event(xc,ev);
}

function param_populate_event(xc,param,ev)
{
	ajax_param(param,'cur_view',xc.cur_view);
	ajax_param(param,'cal_id',ev.cal_id);
	ajax_param(param,'cal_id_orig',ev.cal_id_orig);
	ajax_param(param,'evt_id',cal_prefix_strip(ev.uid));
	ajax_param(param,'event_desc',ev.desc);
	ajax_param(param,'event_t1',ev.t1s);
	ajax_param(param,'event_t2',ev.t2s);
	ajax_param(param,'event_alert1',ev.alert1);
	ajax_param(param,'event_alert2',ev.alert2);
	ajax_param(param,'event_repeat',ev.repeat);
	ajax_param(param,'event_location',ev.location);
	ajax_param(param,'event_attendees',serialise_object(ev.attendees));
	ajax_param(param,'event_invitees',ev.invitees);
	ajax_param(param,'event_note',ev.note);
	ajax_param(param,'event_rid',ev.rid);	
	ajax_param(param,'event_locked',ev.locked);
	ajax_param(param,'event_mtags',ev.mtags);	
	ajax_param(param,'repeat_orig',ev.repeat_orig);
	ajax_param(param,'repeat_applyto',ev.repeat_applyto);	
}
function param_populate_cal(xc,param,ev)
{
	if(ev && !ev.needs_reload) return;
	ajax_param(param,'cal_reload',true);
	ajax_param(param,'cur_view',xc.cur_view);
	
	var t1=ms2dvZ(xc.col_t1s[0]);
	var t2=ms2dvZ(xc.col_t1s[xc.columns]);
	ajax_param(param,'t1',t1);
	ajax_param(param,'t2',t2);
	ajax_param(param,'time_format','unix');
	
	if(!sw.cals || sw.cals.length==0){
		ajax_param(param,'cals','all');
	}else{
		var a=[], bad=false;
		for(cal in sw.cals){
			var el=dge('cal_'+cal);
			if(!el) { bad=true;break;}
			if(!class_contains(el,'sel')) continue;
			a.push(cal);	
		}
		if(bad){
			ajax_param(param,'cals','all');
		}else{
			ajax_param(param,'cals',a.join(','));
		}
	}	
	cal_spinner_start();
}
function save_edited_event(xc,ev)
{
	var ev_el=dge('evt_'+ev.uid);
	class_add(ev_el,'hatched');
	var xtra='';
	var param={};
	param_populate_event(xc,param,ev);
	param_populate_cal(xc,param,ev);
	ev.cal_id_orig = ev.cal_id;
	queued_req_add( enQ, 'event update', function(ev){
		ajaxPost('cmd=cal_action,show&page=~events.js&cal_action=evt_save'+xtra+iid(), param, function(chan){
			success = actionReqJs(chan);
			cal_spinner_stop();
			if(!success){
				set_status(success_string,'warning');
			}else{
				set_status("Event saved",'success');
				class_remove(ev_el,'hatched');
				if(ev.uid.indexOf('keep')!=-1){
					cal_update_ids(ev,ev_el,stored_uid);
					// probably need get all param from server??
					ev.repeat=false;
					ev.subday=true;
					ev.combi=false;
					ev.readonly=false;
				}
				cal_reload_if_needed(xc,ev,true);	// <<< not sure if we always have data!!
			}
		},ch[enQ]);
	},ev);
}

function save_edited_todo(xc,ev,fn)
{
	var xtra='&is_todo=true';
	var param={};
	param_populate_event(xc,param,ev);
	param_populate_cal(xc,param,ev);
	ev.cal_id_orig = ev.cal_id;
	queued_req_add( enQ, 'event update', function(ev){
		ajaxPost('cmd=cal_action,show&page=~events.js&cal_action=evt_save'+xtra+iid(), param, function(chan){
			success = actionReqJs(chan);
			if(!success){
				set_status(success_string,'warning');
			}else{
				set_status("To Do item saved",'success');
				fn();
			}
		},ch[enQ]);
	},ev);
}

var stored_uid;
function store_new_uid(uid)
{
	stored_uid=uid;
}

function event_delete_cb(xc,ev)
{
	var param={};
	param_populate_event(xc,param,ev);
	param_populate_cal(xc,param,ev);
	queued_req_add( enQ, 'event delete', function(ev){
		ajaxPost('cmd=cal_action,show&page=~events.js&cal_action=evt_delete'+iid(), param, function(chan){
			if(!success){
				set_status(success_string,'warning');			
				return;
			}
			cal_reload_if_needed(xc,ev);	// << Could cut out one web request for repeat events!
		},ch[enQ]);
	},ev);
	
}


# *** // CALHINT START
var calhint_prevent=false, cal_popover_hide=false;
var calhint_timer;
var calhint_evel;
var calhint_coords={};
var popover_event;
var popover_attendee;
var popover_el;
function calhint_mousemove(e)
{
	var xc = zc;
	t=target(e);
	var el=ancestor_by_class(t,'cal_event');

	if(calhint_timer){
		clearTimeout(calhint_timer);
		calhint_timer=U;
	}

	if(!el) return;

	calhint_coords.y = y_relative_to(e.clientY,document.body/*dge(xc.root)*/);
	calhint_coords.x = x_relative_to(e.clientX,document.body/*dge(xc.root)*/);

	if(calhint_prevent || cal_popover_hide) return;
	if(xc.cur_view!='year') return;
	
	calhint_timer = setTimeout(cal_showhint,100);
	calhint_evel=el;
}
function cal_showhint()
{
	cal_showpopover()
}


function calhint_enable(enable)
{
	calhint_prevent = !enable;
}
# *** // CALHINT END

# *** High level hooks

function cal_mousemove(e)
{
#	dbg('cal mm');
	calhint_mousemove(e);
}
function cal_keydown(e)
{
	var ret=true;
	switch (e.keyCode){

	case vkUpArrow:
			if (any_modifier(e)){
				cal_nav_up(zc,n_mod(e));
				return ret;
			}
			break;
	case vkDownArrow:
			if (any_modifier(e)){
				cal_nav_down(zc,n_mod(e));
				return ret;
			}
			break;
	case vkLeftArrow:
			if (any_modifier(e)){
				cal_nav_left(zc,n_mod(e));
				ret=false;
				return ret;
			}
			break;
	case vkRightArrow:
			if (any_modifier(e)){
				cal_nav_right(zc,n_mod(e));
				ret=false;
				return ret;
			}
			break;
	case vkEsc:
		if(cal_popover_hide){
			cal_popover_hide=!cal_popover_hide;
		}
		break;
			
	}
	return ret;
}

var calclick_timer;
var calclick_time=0;
function cal_click(e)
{
	if (mtime()-calclick_time<1000) return;
	if(any_modifier(e)) return;
	var xc = zc;
	var t=target(e);
	var el=ancestor_by_class(t,'cal_event');
	if(!el || !el.ev) return;
	if(xc.cur_view=='year') return;

	calclick_time=mtime();
	calhint_evel=el;
	calclick_timer=setTimeout(function(){
		cal_showpopover();
		calclick_timer=U;
	},200);
}
function cal_dblclick(e)
{
	if(any_modifier(e)) return;

	var xc = zc;
	t=target(e);
	clearTimeout(calclick_timer);
	calclick_timer=U;
	clearTimeout(calhint_timer);
	calhint_timer=U;
	calclick_time=mtime();
		
	var el=ancestor_by_class(t,'cal_event');
	calhint_evel=el;
	if(el && el.ev){	//QQDLG
		var ev=el.ev;
		if(ev.locked){
			cal_showpopover(false,false);
		}else{
			cal_showpopover(true,true);
		}
	}else {
		var y = y_relative_to(e.clientY,dge(xc.root));
		var x = x_relative_to(e.clientX,dge(xc.root));
		cal_create_validate({xc:xc},x,y);
	
		if(false&&xc.cur_view=='year'){
			xc.cur_month=xc.validate_rc[0]+1;
			xc.cur_day=xc.validate_rc[1];
			swcal_switch('month');
		}else if(false&&xc.cur_view=='month'){
			xc.cur_day=(xc.validate_rc[1]-6)*7;	// approx TODO:calc properly
			swcal_switch('week');
		}else{
			el=cal_create_one(xc,xc.validate_rc,xc.validate_xy);
			var ev=el.ev;
			cal_event_t2ts(ev);
			calhint_evel=el;
			cal_showpopover(true,false);
		}
	}
}
function cal_cxmenu(e)
{
	t=target(e);
	var el=ancestor_by_class(t,'cal_event');
	if(!el) return;
	calhint_evel=el;
	cal_showhint(e);
	stopEvent(e);
}

# *** Cal editing

function swcal_alert_select(id,cur)
{
	return '<select id="'+id+'" style="width:180px;" onchange="cal_popover_update()">\
				<option value="">$$st_cal_dlg_alert_0$$</option>\
				<option value="PT0S">$$st_cal_dlg_alert_t$$</option>\
				<option value="-PT5M">$$st_cal_dlg_alert_5m$$</option>\
				<option value="-PT15M">$$st_cal_dlg_alert_15m$$</option>\
				<option value="-PT30M">$$st_cal_dlg_alert_30m$$</option>\
				<option value="-PT1H">$$st_cal_dlg_alert_1h$$</option>\
				<option value="-PT2H">$$st_cal_dlg_alert_2h$$</option>\
				<option value="-P1D">$$st_cal_dlg_alert_1d$$</option>\
				<option value="-P2D">$$st_cal_dlg_alert_2d$$</option>\
			</select>';
}
function swcal_repeat_select(id,cur,ev)
{
	var txt='';
	if(ev.repeat){
		txt='&nbsp;repeating <span style="color:gray; font-size:10px;">$$st_cal_dlg_rpt_warn$$</span><input class="hidden" id="'+id+'" value="nochange">';
	}else{
		txt= '<select id="'+id+'" style="width:180px;">\
				<option value="">$$st_cal_dlg_rpt_0$$</option>\
				<option value="DAILY">$$st_cal_dlg_rpt_1d$$</option>\
				<option value="WEEKLY">$$st_cal_dlg_rpt_1w$$</option>\
				<option value="WEEKLY;INTERVAL=2">$$st_cal_dlg_rpt_2w$$</option>\
				<option value="MONTHLY">$$st_cal_dlg_rpt_1m$$</option>\
				<option value="YEARLY">$$st_cal_dlg_rpt_1y$$</option>\
			</select>';
	}
	return txt;
}


function swcal_cal_select(id,cur)
{
	var txt='<select id="'+id+'" style="width:180px;">'
	for(var i=0;i<sw.cals_array.length;i++){
		var id=sw.cals_array[i], cal=sw.cals[id];
		if(cal.name.indexOf('(R)')!=-1) continue;
		if(cal.name.indexOf('Reminders')!=-1) continue;
		txt+='<option value="'+id+'">'+encode_lt_gt(cal.name)+'</option>';
	}
	txt+='</select>';
	return txt;
}
function swcal_setbtn(type)
{
	var el=dge('cal_switch_'+type);
	for_each(siblings(el),function(o){class_remove(o,'cal_cur_view')});
	class_add(el, 'cal_cur_view');
}


function cal_new_event(el)
{
	calhint_evel=el;
	cal_showpopover(true);
}

function cal_edit_date(el)
{
	var txt='<div class="hint_date_box">Date Picker'+ \
		'<br>pick items... <br>';
	txt+='</div>';
	var frag=new_anchor('div', txt, document.body);
	frag.id='cal_date_outer';
	var xy={x:calhint_coords.x+40,y:calhint_coords.y+20};
	Popover.show(frag,{modal:true,xy:xy,zindex:2000,no_shadow:true});
}
function cal_edit_details()
{
	Popover.obj.to_details=true;	
	Popover.end();
	cal_showpopover(true,true)
}
function cal_download_raw()	//cf cal_edit_details cloud_download
{
	var id = calhint_evel.id;
	// "evt_0_SW332363-2E20-0733-3934-02C212379393"
	// "/surgeweb?cmd=cld_action&action=download_file&sid=349773630&cld_store=lcal&cld_path=%2Fcal%2Fcalendars%2Fmarijn%40netwinsite.com%2FSW3465E0-4C65-B783-4C5B-14A632076334&sel=&attachment=true"
	debugger
	//"/surgeweb?cmd=cld_action&action=download_file&sid=347304110&cld_store=lcal&cld_path=%2Fcal%2Fcalendars%2Fmarijn%40netwinsite.com%2FSW3465E0-4C65-B783-4C5B-14A632076334&sel=&attachment=true"
	//var url=cgibase+'cmd=cld_action&action=download_file&sid='+sid+cid()+'&sel='+sel+'&attachment=true';
	//dge('an_iframe').src=url;
}

# // ***

function cal_showpopover(edit,detail)
{
	var xc = zc, ev, txt;
	var el=calhint_evel
	if(el) ev=el.ev;

	if(!el){
		alert('new event popup, drag & drop / doubleclick create for now');
		return;
	}	
	if(ev.readonly){
		edit = false;
		detail = false;
	}

	if(edit&&detail){
		txt=cal_popover_large(xc,ev,edit);
	}else{
		txt=cal_popover_small(xc,ev,edit);
	}
	
	var frag=new_anchor('div', txt, document.body);
	if(edit&&detail){
		frag.edit_detail=true;
	}
	frag.id='cal_popover';
	frag.calhint=el;
	frag.style.width=px(330);
	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 cal_popover_populate(ev,edit)
{
	var el=dge('popover_desc');
	if(edit){
		el.value=ev.desc;
		el.select();
	}else{
		el.innerHTML=encode_lt_gt(ev.desc);
	}
	el=dge('cal_popover_allday');
	if(el) el.checked = ev.allday;
	el=dge('cal_popover_locked');
	if(el) el.checked = ev.locked;
	el=dge('cal_popover_alert1');
	if(el && ev.alert1) el.value=ev.alert1;
	el=dge('cal_popover_alert2');
	if(el && ev.alert2) el.value=ev.alert2;
	el=dge('cal_popover_calendar');
	if(el && ev.cal_id) el.value=ev.cal_id;
	el=dge('cal_popover_calendar_orig');
	if(el && ev.cal_id) el.value=ev.cal_id;
	el=dge('cal_popover_location');
	if(el && ev.location) el.value=ev.location;
	el=dge('cal_popover_invitees');
||if(cal_invite_disable)|| \
    if(el && ev.invitees) el.value=ev.invitees;
||else||
	if(el && ev.attendees){
		cal_populate_attendees(el, ev);
	}
||endif||       
	el=dge('cal_popover_note');
	if(el && ev.note) el.value=ev.note;

	var txt=ms2dv(ev.t1);
	el=dge('cal_popover_t1day'); if(el) el.value=text_to_date(txt.substring(0,8));
	el=dge('cal_popover_t1hr'); if(el&&txt.length>8) el.value=text_to_time(txt.substring(9,15));
	var txt=ms2dv(ev.t2);
	el=dge('cal_popover_t2day'); if(el) el.value=text_to_date(txt.substring(0,8));
	el=dge('cal_popover_t2hr'); if(el&&txt.length>8) el.value=text_to_time(txt.substring(9,15));
	
	popover_event=ev;
}
function cal_popover_update(ev,po)
{
	if(!ev) ev=popover_event;
	if(!ev) return;
	if(!po) po=popover_el;
	if(!po.edit_detail) return;

	var allday=dge('cal_popover_allday').checked;
	var el=dge('cal_popover_t1hr');
	if(el) show_hide(el,!allday);
	el=dge('cal_popover_t2hr');
	if(el) show_hide(el,!allday);
	
	el=dge('cal_popover_alert1');
	var el2=ancestor_by_tag(dge('cal_popover_alert2'),'tr');
	if (el.value==''){
		el2.value='';
		class_add(el2,'hidden');
	}else{
		class_remove(el2,'hidden');
	}
	Popover.resize_height(Popover.obj);
}


function cal_popover_title(ev,edit)
{
	if(edit){
		return '<input id="popover_desc" type="text" class="hint_desc_edit" value=""></input>';
	}else{
		return '<span id="popover_desc" class="hint_desc_noedit"></span>';
	}
}
function showday(xc,t,full)
{
	var d=new Date(t);
	var dow=d.getDay(), dom=d.getDate(), mnth=d.getMonth();
	var txt='';
	if(full){
		txt=xc.DofWf[dow]+' '+num_abbrev(dom)+' '+xc.MofYf[mnth];
	}else{
		txt=xc.DofW[dow]+' '+dom+' '+xc.MofY[mnth];
	}
	return txt;
}
function cal_popover_time(ev,edit)
{
	var theday='<span style="color:gray;">on</span> '+showday(zc,ev.t1,true);
	var alerts=cal_alert_string(ev);
	if(edit){
		txt= '<div>'+showtime(ev.t1)+' - '+showtime(ev.t2)+' '+theday;
		txt+='</div>';
	}else{
		if(ev.allday){
			if(ev.t2-ev.t1>24*60*60*1000){
				var d1=showday(zc,ev.t1), d2=showday(zc,ev.t2);
				txt='<div> allday '+d1 +' - '+d2 ;			
			}else{
				txt='<div> allday '+theday;
			}
			
		}else{
			txt='<div>'+showtime(ev.t1)+' - '+showtime(ev.t2)+' '+theday;
		}	
		if(txt.length>0){
			txt+='<br><span style="font-size:10px; color:gray;">'+alerts+'</span>';
		}
		txt+='</div>';
	}
	return txt;
}
function cal_alert_string(ev)
{
	if(!ev.alert1) return '';
	return 'Alert at '+ev.alert1+' '+ev.alert2;
}
function cal_popover_dbg(ev,edit)
{
	if(edit){
		return '';
	}else{
||iftrue(cal_debug)||	
		return '<div class="cal_hint_extra" style="margin:4px 0 4px 0;">UID:'+ev.uid+'<br>\
			repeat='+ev.repeat+' subday='+ev.subday+' combi='+ev.combi+' readonly='+ev.readonly+' lock='+ev.locked+' slot='+ev.slot+' \
			</div>';
||else||
		return '<div style="height:10px;"></div>';
||endif||
	}
}
function cal_popover_alert(ev,edit)
{
	if(edit){
		return '<div style="margin-top:10px;margin-bottom:10px;">Alert '+swcal_alert_select('cal_popover_alert1','')+'</div>';
	}else{
		return '';
	}
}
function cal_popover_attendees(ev,edit)
{
	if(ev.attendees==U) return '';
	var txt_yes='', txt_maybe='', txt_no='', txt_unknown='';	
	for(var i=0;i<ev.attendees.length;i++){
		var attendee = ev.attendees[i];
		if(attendee.status=='yes'){
			if(txt_yes.length>0) txt_yes+=', ';
			txt_yes += attendee.email;
		} else if(attendee.status=='maybe'){
			if(txt_maybe.length>0) txt_maybe+=', ';
			txt_maybe += attendee.email;
		} else if(attendee.status=='no'){
			if(txt_no.length>0) txt_no+=', ';
			txt_no += attendee.email;
		} else {
			if(txt_unknown.length>0) txt_unknown+=', ';
			txt_unknown += attendee.email;
		}
	}
	
	if(txt_yes.length==0 && txt_no.length==0 && txt_maybe.length==0 && txt_unknown.length==0) return '';
	
	var txt='<div>';
	if(txt_yes.length>0){
		txt += 'Accepted: '+txt_yes+'<br>';
	}
	if(txt_maybe.length>0){
		txt += 'Maybe: '+txt_maybe+'<br>';
	}
	if(txt_no.length>0){
		txt += 'Declined: '+txt_no+'<br>';
	}
#	if(txt_unknown.length>0){
#		txt += 'Unknown: '+txt_unknown+'<br>';
#	}
	txt += '</div><div style="height:10px;"></div>';
	return txt;
}
function cal_popover_btns(xc,ev,edit)
{
	var txt='';
	if(edit) {
		txt+=  '<input type="button" value="$$st_cal_btn_del$$" class="popover_btn popover_btn_right" onclick="cal_popover_delete()">\
				<input type="button" value="$$st_cal_btn_save$$" class="popover_btn popover_btn_right" onclick="cal_popover_save()">\
				<a href="#" class="link_blue" onclick="cal_edit_details()">$$st_cal_btn_edit$$</a>';
	}else{
	
		if(ev.readonly){
			txt+='<span style="color:gray;">$$st_cal_btn_readonly$$</span>';
		} else if(ev.locked){
			txt+='<a href="#" class="link_blue" onclick="cal_popover_unlock()">$$st_cal_btn_unlock$$</a>';
		}else{
			txt+='<a href="#" class="link_blue" onclick="cal_popover_delete()">$$st_cal_btn_delete$$</a> | \
				  <a href="#" class="link_blue" onclick="cal_edit_details()">$$st_cal_btn_edit$$</a>';
		}
		if(xc.cur_view!='week')	{ 
			if (txt.length>0) txt+=' | ';
			txt+='<a href="#" class="link_blue" onclick="cal_popover_asweek()">$$st_cal_btn_asweek$$</a>';
		}
		if(false && keys_2horiz(event)){
			if (txt.length>0) txt+=' | ';
			txt+='<a href="#" class="link_blue" onclick="cal_download_raw()">$$st_cal_btn_raw$$</a>';
		}	
	}
	return txt;
}
function cal_popover_btns2(xc,ev,edit)
{
	return '\
	  <div style="padding-top:15px;padding-left:5px;padding-bottom:12px;">\
		<input type="button" value="$$st_cal_dlg_cancel$$" class="popover_btn popover_btn_right" onclick="cal_popover_cancel()">\
		<input type="button" value="$$st_cal_dlg_save$$" class="popover_btn popover_btn_right" onclick="cal_popover_save()"> \
		<input type="button" value="$$st_cal_dlg_delete$$" class="popover_btn" style="width:100px" onclick="cal_popover_delete()">\
	  </div>';
}
function cal_popover_location(ev,edit)
{
	return '\
	  <input id="cal_popover_location" type="text" value="$$st_cal_dlg_location$$" style="width:316px;"><br>';
}
function cal_popover_small(xc,ev,edit)
{
	var txt='';
	txt+='<div class="hint_box">';
	txt+=cal_popover_title(ev,edit);
	txt+=cal_popover_time(ev,edit);
	txt+=cal_popover_alert(ev,edit);
	txt+=cal_popover_dbg(ev,edit);
	txt+=cal_popover_attendees(ev,edit);
	txt+=cal_popover_btns(xc,ev,edit);
	txt+='</div>';
	return txt;
}
function cal_popover_large(xc,ev,edit)
{
	var txt='';
	txt+='<div class="hint_box">';
	txt+=cal_popover_title(ev,edit);
	txt+=cal_popover_location(ev,edit);
	txt+=cal_popover_details(ev,edit);
	txt+=cal_popover_btns2(xc,ev,edit);
	txt+='</div>';
	return txt;
}

# // popovers COMPLETE
function cal_popover_delete()
{
	Popover.obj.delete_close=true;
	Popover.end();
}
function cal_popover_save()
{
	attendee_press_save();
	Popover.obj.save_close=true;
	Popover.end();
}
function cal_popover_cancel()
{
	Popover.end();
}
function cal_popover_asweek()
{
	Popover.obj.as_week=true;
	Popover.end();	
}

function cal_showpopover_done(o)
{
	if(o.hint_only && !o.delete_close && !o.as_week) {
		if(o.keyHit){
			switch (o.keyHit){
				case vkEsc:
					cal_popover_hide=!cal_popover_hide;
					break;
			}
		}
	    return;
	}
	var ev=popover_event;
	var el=dge('evt_'+ev.uid);
	if(o.to_details){
			cal_update_ev(ev);
		    return;
	}
	if(o.as_week){
		swcal_navdate(ev.t1,'week');
	}else if(o.delete_close){
		cal_popover_delclose(ev,el);
	}else if(o.save_close){
		cal_popover_saveclose(ev,el);
	}else if(o.keyHit){
		switch (o.keyHit){
			case vkEsc:
				cal_popover_dfltclose(ev,el);
				break;
			case vkEnter: 
				cal_popover_saveclose(ev,el);
				break;
		}
	}else{
		cal_popover_dfltclose(ev,el);	
	}
}

function cal_popover_dfltclose(ev,el)
{
	if(el.newly_created) {
		cal_update_ev(ev);
		cal_details_persist(ev,el);
	}else{
#		alert('discard changes')
	}
}
function cal_popover_saveclose(ev,el)
{
	cal_update_ev(ev);
	if(el.newly_created && ev.desc=='$$st_cal_new_event$$'){
		x_custom_dlg('Event description was not modified','',
			function(n){
				if (!n){ remove_node(el); return;}
				cal_details_persist(ev,el);
			},
			function(){
				btn_set(dge('dlg_ok'),'Keep Event',U,'');
				btn_set(dge('dlg_cancel'),'Discard Event',U,'');
			}
		
		);
		return;
	}else{
		cal_query_repeat(ev,function(){
			cal_reload_prepare(ev);
			cal_details_persist(ev,el);
		});
	}
}
function cal_popover_delclose(ev,el)
{
	if(el.newly_created) {
		remove_node(el);
	}else{
		cal_query_repeat(ev,function(){
			cal_reload_prepare(ev);
			event_delete_cb(zc,ev);
			event_local_delete(ev,el);
			cal_event_updated(zc,U);
		});
	}
}


function cal_details_persist(ev,el)
{
	var xc=zc;

	// move ev & DOM from temp to primary storage (if newly created)
	cal_temp_keep(xc,ev,el);
	
	// now update our display etc
	cal_event_updated(xc,ev);

	// trigger a save of the fully featured event
	save_edited_event(xc,ev);
}



function cal_update_ev(ev)
{
	// update the ev and decide on significance of change(s)
	ev.needs_refresh=false;
	ev.needs_reload=false;

	ev.desc=dge('popover_desc').value;
	ev.alert1=dge('cal_popover_alert1').value;
	ev.cal_id_orig=ev.cal_id;

	cal_event_checkts(ev);

	// Plain fields: Loc, invitees, note
	cal_update_one(ev,'location','cal_popover_location',U,U,'$$st_cal_dlg_location$$');
	cal_update_one(ev,'invitees','cal_popover_invitees');
	cal_update_one(ev,'note','cal_popover_note');
	
	// allday
	// Repeat
	cal_update_one(ev,'cal_id','cal_popover_calendar',true,true);
	cal_update_one(ev,'alert1','cal_popover_alert1',false);
	cal_update_one(ev,'alert2','cal_popover_alert2',false);
	cal_update_one(ev,'repeat','cal_popover_repeat',true);
	cal_update_cbox(ev,'locked','cal_popover_locked',true,true);
	
	cal_update_date(ev,'t1','cal_popover_t1day','cal_popover_t1hr');
	cal_update_date(ev,'t2','cal_popover_t2day','cal_popover_t2hr');
	cal_event_t2ts(ev);

	if(ev.allday_changed) ev.needs_reload=true;

	cal_update_lists(zc,zc.evs);	// this the right place??
}
function cal_update_one(ev,tx,el_id,refresh,reload,def)
{
	var el=dge(el_id);
	if(!el) return;
	if(el.value==def) return;
	if(el.value==ev[tx]) return;
	ev[tx]=el.value;
	if(reload) ev.needs_reload=true;
	if(refresh) ev.needs_refresh=true;
}
function cal_update_date(ev,tx,day,hr)
{
	var el_day=dge(day), el_hr=dge(hr);
	if(!el_day || !el_hr) return;
	var td=el_day.value, th=el_hr.value;
	
	if(td.length!=10 || td.substr(4,1)!='-' || td.substr(7,1)!='-') return;
	if(th.length!=8 || th.substr(2,1)!=':' || th.substr(5,1)!=':') return;
	
	var d=new Date(td.substr(0,4),td.substr(5,2)-1,td.substr(8,2),
			   th.substr(0,2),th.substr(3,2),th.substr(6,2),0); 
			   
	ev[tx]=d.getTime();	
}
function cal_update_cbox(ev,tx,el_id,refresh,reload,def)
{
	var el=dge(el_id);
	if(!el) return;
	var val=el.checked?true:false;
	if(val==ev[tx]) return;
	ev[tx]=val;
	if(reload) ev.needs_reload=true;
	if(refresh) ev.needs_refresh=true;
}



function event_local_delete(ev,el)
{
	var xc=zc;
	var evs=xc.evs;
	for(var i=0;i<evs.length;i++){
		if(evs[i]!=ev) continue;
		evs.splice(i,1);
		break;
	}
	remove_node(el);
}


function swcal_delta(e,ctl,dy,dm,dd)
{
	cal_curdelta(zc,dy,dm,dd);
	swcal_switch(zc.cur_view);
}

// Dewtails dialog editing

function cal_popover_details(ev,edit)
{
	if(ev.is_todo) return '';
	var allday=ev&&ev.allday
	var txt='\
		<table style="width:320px;">\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_allday$$</td><td><span style="float:right;"><input id="cal_popover_locked" type="checkbox"> $$st_cal_dlg_locked$$</span>\
			<input id="cal_popover_allday" type="checkbox" onclick="cal_popover_allday(this)" '+(allday?'checked':'')+'></td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_from$$</td><td>\
			<input id="cal_popover_t1day" class="cal_day" type="text"> \
			<input id="cal_popover_t1hr" class="cal_time" type="text"> \
#			 <a href="#" onclick="cal_edit_date()">picker</a>\
		</td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_to$$</td><td>\
			<input id="cal_popover_t2day" class="cal_day" type="text"> \
			<input id="cal_popover_t2hr" class="cal_time" type="text"> \
		</td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_repeat$$</td><td>'+swcal_repeat_select('cal_popover_repeat','',ev)+'</td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_alert$$</td><td>'+swcal_alert_select('cal_popover_alert1','')+'</td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_alert2$$</td><td>'+swcal_alert_select('cal_popover_alert2','')+'</td></tr>\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_cal$$</td><td>'+swcal_cal_select('cal_popover_calendar','')+'\
					<input type="hidden" id="cal_popover_calendar_orig"></td></tr>'+\
(pref.cal_invite_disable?'\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_inv$$</td><td><input id="cal_popover_invitees" type="text" style="width:225px;"></td></tr>\
':'\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_attendees$$</td><td><ul id="cal_invitees" class="hidden invitee_ul"></ul>\
			<input id="cal_popover_invitees" type="text" style="width:225px;" value="$$st_cal_dlg_add_attendee$$" \
				onkeydown="attendee_search_keydown(event,this)" onfocus="attendee_search_focus(event,this)"></td></tr>\
')+'\
		<tr><td class="cal_edit_gray">$$st_cal_dlg_note$$</td><td><textarea id="cal_popover_note" onkeydown="stopBubble(event)" style="height:80px;width:225px;"> </textarea></td></tr>\
	  </table>';
	return txt;
}

function cal_popover_allday(ctl)
{
	var el_h1=dge('cal_popover_t1hr');
	var el_h2=dge('cal_popover_t2hr');
	var el_d1=dge('cal_popover_t1day');
	var el_d2=dge('cal_popover_t2day');
	var ev=popover_event;
	ev.allday_changed=true;
	if(ctl.checked){
		el_h1.value=el_h2.value='00:00:00';
		var dummy={}
		cal_update_date(dummy,'tx','cal_popover_t1day','cal_popover_t1hr');
		var txt=ms2dv(dummy.tx+24*60*60*1000);
		el_d2.value=text_to_date(txt.substring(0,8));
	}else{
		el_h1.value='09:00:00';
		var dummy={}
		el_h2.value='17:00:00';
		cal_update_date(dummy,'tx','cal_popover_t2day','cal_popover_t2hr');
		var txt=ms2dv(dummy.tx+-24*60*60*1000);
		el_d2.value=text_to_date(txt.substring(0,8));
		el_h2.value=text_to_time(txt.substring(9,15));	
	}
	cal_popover_update();
}
function cal_select_all(e)
{
	var el=dge('cal_list_html').firstChild;
	for_each(el.childNodes,function(o){
		var txt=o.getAttribute('cal_id');
		if(!txt || txt.length==0)return;
		class_add(o.firstChild.firstChild,'sel');
	});
	cal_show(zc,{keep_frame:true});
}
function cal_select_none(e)
{
	var el=dge('cal_list_html').firstChild;
	for_each(el.childNodes,function(o){
		var txt=o.getAttribute('cal_id');
		if(!txt || txt.length==0)return;
		class_remove(o.firstChild.firstChild,'sel');
	});
	cal_show(zc,{keep_frame:true});
}
function do_calendar_location_save()
{
	var loc=dge("cal_timezone").value;
	var noedit=dge("cal_noedit").value;
	ajax_pref_save('pref_cal_timezone='+xescape(loc)+'&pref_cal_noedit='+noedit);
	pref.cal_noedit = noedit;
	setTimeout(calendars_refresh, 300);
}
function calendars_refresh()
{
	sndReq('cmd=cal_action,show&cal_action=load_only&page=~calendars.htm'+iid(), function(chan){
		node=actionReqSethtml(chan.responseText,'utility');
	});		
}



function cal_query_repeat(ev,fn,all)
{
	if(ev.rid){
		x_custom_dlg('This is a repeat event, apply to?', '',
			function(n){
				ev.repeat_applyto=(n==0?'future':'current');
				ev.needs_reload=true;
				fn();
			},
			function(){
				btn_set(dge('dlg_ok'),'This Event Only','ml2',120);
				btn_set(dge('dlg_cancel'),'This and Future Events','ml2',160);
			}
		);
	}else{
		ev.repeat_applyto=ev.repeat_orig?'future':'';
		fn();
	}	
}
function cal_reload_prepare(ev)
{
	if(ev.repeat_applyto=='future'){
		ev.needs_reload=true;
		return;
	}
	if(ev.repeat && ev.repeat!=ev.repeat_orig){
		ev.needs_reload=true;
		return;
	}
}
function cal_reload_if_needed(xc,ev,withdata)
{
	if(!ev.needs_reload) return;
	
	if(withdata) {
		cal_populate_events_cb(xc,xc.raw_evs);
		do_resize_real();
	}else{	
		swcal_refresh(xc);
	}
}
function arrowclick(e)
{
	alert('foo');
}
function arrowmmove(e)
{
	alert('bar');
	stopEvent(e);
}
var arrow_warned;
function arrow_mousedown(e)
{
	if(zc.cur_view=='year'&&!arrow_warned) {
		x_alert('Press escape to suppress event information hints and drag / resize events.');
		arrow_warned=true;
	}
	stopEvent(e);
}

function cal_popover_unlock()
{
	cal_edit_details();
	dge('cal_popover_locked').checked=false;
}

function events_on_day(xc,t1)
{
	var evs=xc.evs, arr=[];
	var t2=t1+24*60*60*1000;
	for(var i=0;i<evs.length;i++){
		var ev=evs[i];
		if(ev.t1<t1 && ev.t2<t1) continue;
		if(ev.t1>t2 && ev.t2>t2) continue;
		arr.push(ev);
	}
	return arr;
}

function cal_mnth_more(e,t1)
{
	var t=target(e);
//	var frag=new_anchor('div', 'Item1<br>Item2<br>...', document.body);
//	var xy={x:calhint_coords.x,y:calhint_coords.y};	
//	Popover.show(frag,{arrow:true, xy:xy, offset:700, xy_el:t, scroll_correct:'cal_details_scrolled'});
	
	var dummy=showday(zc,t1) +' '+showtime(t1);
	var xc = zc, ev, txt;
	var el=t;
	var el2=ancestor_by_tag(t,'td');

	var evs=events_on_day(zc,t1);
	var arr=[];
	for(var i=0;i<evs.length;i++){
		var ev=evs[i]
		arr.push(showtime(ev.t1)+' '+ev.desc);
	}
	txt=arr.join('<br>');
	
	var frag=new_anchor('div', txt, document.body);
	frag.id='cal_popover';
	frag.calhint=el;
	frag.style.height=px(frag.firstChild.offsetHeight+15);
	frag.ev=ev;
	class_add(frag,'calhint');

	var xy={x:calhint_coords.x,y:calhint_coords.y};	

	Popover.show(frag,{arrow:true,modal:true,xy:xy, xy_el:el2, scroll_correct:'cal_details_scrolled'});
	Popover.obj.onPopoverClose=cal_showpopover_done;
	Popover.obj.hint_only=true;
	popover_el=frag;
}


function cal_resaturate_swatches()
{
	var el=dge('manage_calendars');
	var arr=el.getElementsByTagName('div'); 
	for(var i=0;i<arr.length;i++){
		var div=arr[i];
		if(!class_contains(div,'swatch')) continue;
		var ds=div.style;
		var c=div.getAttribute('base_color');
		if(!c)continue;
		ds.backgroundColor=resaturate(c,80);
		ds.borderColor=resaturate(c,-40);
	}
}
function calendars_color(e,cal_id)
{
	var el=dge('picker_menu');
	el.innerHTML='<table onmouseup="calendar_color_select(event)">'+color_swatches2(4)+'</table>';
	el.cur_item=cal_id;
	do_menu_show('picker_menu',e,undefined,undefined,{cursor:true})
}
function color_swatches2(per_line)
{
	var txt='';
	var cal_cols = cal_colors();
	for(var i=0;i<cal_cols.length;i++){
  		if( i%per_line == 0 )txt += '<tr>'; 	
		txt+='<td class="swatch_hover"><div class="swatch" style="opacity:0.7;background:'+resaturate(cal_cols[i],80)+';border:1px solid '+resaturate(cal_cols[i],-40)+';" pickid="'+i+'"></div>';
	}
	return txt;
}

// labels_color
// manage_calendars
function calendar_color_select(e)
{
	var el=target(e);
	var picked=el.getAttribute('pickid');
	var cal_cols = cal_colors();
	if(!picked) return;
	var el=dge('picker_menu');
	var param={};
	ajax_param(param,'cal_id',el.cur_item);
	ajax_param(param,'cal_color',cal_cols[picked]);
	ajaxPost('cmd=cal_action,show&page=~calendars.htm&cal_action=set_color'+iid(), param, function(chan){	
#	sndReq('cmd=cal_action,show&cal_action=set_color&cal_id='+xescape(el.cur_item)+'&cal_color='+xescape()+'&page=~calendars.htm'+iid(), function(chan){
		node=actionReqSethtml(chan.responseText,'utility');
		if(!success) set_status(success_string,'warning');
	});
		
}

function cal_invitees_field_set()
{
	var el = dge('cal_popover_invitees');
	el.value='';
}


function cal_populate_attendees(el, ev)
{
	var invite_list = el.previousSibling;
	var list = '';
	var items = ev.attendees;
	for(var i=0; i<items.length; i++){
		var attendee = items[i];
		list += '<li class="invitee_li '+(attendee.remove?' hidden':'')+'"><span onmouseup="cal_invitee_menu(event,'+i+')" onclick="return stopEvent(event)" _unselectable="on">'+attendee.email+' <img src="||www_base||shared/img/1pixel.gif" class="dropdown"></span></li>';
	}
	if (list.length==0) return;
	
	invite_list.innerHTML = list;
	class_remove(invite_list,'hidden');
}

function cal_invitee_menu(e,i)
{
	popover_attendee = i;
	do_menu_show('cal_menu_invitee',e,true);
}

function cal_menu_reinvite(el,e)
{
	var attendee = cal_attendee_data(popover_attendee);
	attendee.reinvite = true;
}
function cal_menu_edit(el,e)
{
	alert('cal_menu_edit');
}
function hide_calentry(n)
{
	var el=dge('cal_invitees');
	var row = el.childNodes[n];
	class_add(row,'hidden');
}
function cal_attendee_data(n)
{
	var ev=popover_event;
	return ev.attendees[n];
}

function cal_menu_remove(el,e)
{
	var attendee = cal_attendee_data(popover_attendee);
	attendee.remove = true;
	hide_calentry(popover_attendee);	
	Popover.resize_height(Popover.obj);
}

function do_add_attendee(address)
{
	if(address.length==0) return;
	
	var ev=popover_event;
	var new_attendee = {};
	new_attendee.id='mailto:'+address;
	new_attendee.email=address;
	new_attendee.new = true;
	if(ev.attendees==U) ev.attendees=[];
	ev.attendees.push(new_attendee);

	var attendees_el=dge('cal_popover_invitees');
	cal_populate_attendees(attendees_el, ev);
	
	Popover.resize_height(Popover.obj);
}

function attendee_valid(input)
{
	if(input==U) return false;
	if(input.value=='' || input.value=='$$st_cal_dlg_add_attendee$$') return false;
	return true;
}
function attendee_check_pending(input)
{
	if(attendee_valid(input)){
		var items = split_to_addresses(input.value)
		for(var i=0;i<items.length;i++){
			var txt = clean_whitespace(items[i]);
			if(input.value.indexOf('@')==-1) {
				txt=txt+'@'+domain;
			}
			do_add_attendee(txt); 
		}
		input.value ="";
	}
}
function attendee_search_keydown(ev,input)
{
	if (ev.keyCode==vkTab){
		attendee_check_pending(input); 
	} else if (ev.keyCode==vkEnter){
		attendee_check_pending(input);
		stopBubble(ev);
	}
}
function attendee_search_focus(ev,input) 
{
	if (input.value=='$$st_cal_dlg_add_attendee$$'){
		cal_invitees_field_set('');
	}
}
function attendee_press_save()
{
	attendee_check_pending(dge('cal_popover_invitees'));
}

