// $Id: widgetHtmlBuilder.js,v 1.29 2008/10/18 16:05:02 nick Exp $

var gThemeUrl = getPrefInCookie('themeUri','/theme/default');
var gbSmallTheme = false; // 740 width
var gbTinyTheme = false; // 500 width
var gbNoResize = false;

////////////////
////////////////
////////////////
// start mouse over code
function hideMouseOverDay()
{
	el = getEl('mouseOverDiv');
	el.style.visibility='hidden';
}

////////////////

function showMouseOverDay(date, dayBoxId)
{
	hideMouseOverDay();
	aEventIds = gaEvtsByDate[date];
	if (!aEventIds)
		return;
	var html = '';
	var iAdditionalUpdatesCount = 0;
	for (var i=0; i<aEventIds.length; i++)
	{
		eventId = aEventIds[i];
		var thisEvent = gaEvts['e'+eventId];
		if (!thisEvent) // deleted
			continue;
		
		// skip hidden buddies
		if (!shouldShowUserCalendar(thisEvent))
			continue;
		
		if (thisEvent.isWeather())
			continue;
		
		eventTime = 'all day &raquo; ';
		if (!thisEvent.isAllDay())
			eventTime = timeToTimeString(thisEvent.getStart())+' ';

		var extraSymbols = '';

//		if (thisEvent.getImgUrl().length)
//			extraSymbols += "<img src='"+gThemeUrl+"/imageUpdates.gif' /> ";
			
		if (thisEvent.isTaggedImportant() && thisEvent.isOwner())
			extraSymbols += "<img src='"+gThemeUrl+"/starColor.gif' valign='absmiddle'/> ";

		if (thisEvent.getAttachmentHtml().length)
			extraSymbols += "<img src='/img/attach.gif' valign='absmiddle'/> ";

		if (thisEvent.getPrivacy() == 'private')
			extraSymbols += "<img src='"+gThemeUrl+"/lock.gif' valign='absmiddle'/> ";
			
		if (thisEvent.isInvite())
			extraSymbols += "<img src='"+gThemeUrl+"/envelope.gif' valign='absmiddle'/> ";
			
		if ((thisEvent.getRepeat() != 'no')&&(thisEvent.isOwner()))
			extraSymbols += "<img src='"+gThemeUrl+"/repeat.gif' valign='absmiddle'/> ";
		
		// alarms - don't show to buddies		
		if ((thisEvent.getReminder() != -1)&&(!thisEvent.isFeed())&&(thisEvent.isOwner()))
			extraSymbols += "<img src='"+gThemeUrl+"/reminder.gif' valign='absmiddle'/> ";

		var name = '';
		if (!thisEvent.isHoliday())
		{
			if (thisEvent.isInvite())
				name = 'from '+gaUsers['u'+thisEvent.getUserId()].getFirstName()+': ';
			else if (!thisEvent.isOwner())
				name = gaUsers['u'+thisEvent.getUserId()].getFirstName()+': ';
		}
		
		var sClass = 'mouseOverText';
		if (!thisEvent.isOwner() && !thisEvent.isInvite())
			sClass = 'mouseOverTextBuddy';

		if (shouldShowTagHighlight(thisEvent))
			sClass += ' tagHighlightMouseOver';
			
		sBirthdayAge = getBirthdayString(thisEvent, dbDateToJsDate(date));
		sAnniversaryAge = getAnniversaryString(thisEvent, dbDateToJsDate(date));
			
		html += "<div class='"+sClass+" smallest'>"+eventTime + 
			"<span class='bold small'>" +
			extraSymbols + name + thisEvent.getSummary() + sBirthdayAge + sAnniversaryAge + "</span></div>\n";
	}
	
	if (html.length)
	{
		el = getEl('mouseOverDiv');
		el.innerHTML = html;
		
		elDayBox = getEl(dayBoxId);
		coords = getElementPos(elDayBox);
		coords.x += elDayBox.offsetWidth-75;
		coords.y += elDayBox.offsetHeight-20;
		
		coords = keepHoverOnPage(coords, el);
		setElementPos(el, coords);
		el.style.visibility='visible';
	}
}

// end mouse over code
////////////////
////////////////
////////////////

////////////////
////////////////
////////////////
// start calendar view code
function requestMoreData(bFuture, reaction, iUserId)
{
	iNumWeeksToLoad = 16;
	if (bFuture)
	{
		iStart = gDataEnd;
		iEnd = gDataEnd + 60*60*24*7*iNumWeeksToLoad*1000;
		gDataEnd = iEnd;
	}
	else
	{
		iStart = gDataStart - 60*60*24*7*iNumWeeksToLoad*1000;
		iEnd = gDataStart;
		gDataStart = iStart;
	}
	var args = 'showFeeds='+gbShowFeeds+'&showPrivate='+gbShowPrivate+'&tags='+gTagString+'&forceUser='+iUserId+'&start='+iStart/1000+'&end='+iEnd/1000;
	makeXmlHttpRequest('moreData', args, reaction);
}

var gCenteredTime = 0;
var gStartTime = 0;
var gEndTime = 0;
function drawMainCalendar(iCenteredTimeToShow)
{
	gCenteredTime = iCenteredTimeToShow;
	gStartTime = calculateStartTime(gCenteredTime);
	
	var dateObj = new Date(gStartTime);
	
	var html = "<table id='mainCalendar' cellspacing='0' cellpadding='0'>";
	var dateToday = new Date();
	for (var iDayNum=0; iDayNum<7*gNumWeeksToShow; iDayNum++)
	{
		if (iDayNum % 7 == 0)
			html += "<tr>";

		html +=htmlForOneDay(dateObj, iDayNum);

		if (iDayNum % 7 == 6)
			html += "</tr>";
		gEndTime = dateObj.valueOf(); // do this before incrementing
		dateObj.setDate(dateObj.getDate()+1);
	}

	html += "</table>";
	getEl('mainCalendarContainer').innerHTML = html;

	dStart = new Date(gStartTime);
	year = dStart.getFullYear();
	dEnd = new Date(gEndTime);
	if (dEnd.getFullYear() != year)
		year += '-'+dEnd.getFullYear();
	getEl('calendarYearDisplay').innerHTML = year;
	

	// get more data if we need it
	if (gStartTime < gDataStart)
		requestMoreData(false, 'drawMainCalendar(gCenteredTime);',giUserId);
	else if (gEndTime > gDataEnd)
		requestMoreData(true, 'drawMainCalendar(gCenteredTime);',giUserId);
}

////////////////

function formatEventLine(thisEvent, sTextColorClass, dateObj)
{
	var sClass = '';
	var sStyle = '';
	var sPrefix = '';
	var sStyleFontColor = '';
	var sContextMenu = '';
	if (thisEvent.isOwner() || thisEvent.isInvite())
		sClass = sTextColorClass+' small textMyEvent';
	else
		sClass = 'smallest textLight textBuddyEvent';
		
	if (shouldShowTagHighlight(thisEvent))
		sClass += ' tagHighlightCalendarView';

	// THESE 2 NEED TO WORK TOGETHER
	if (hasColoredBgTag(thisEvent))
	{
		tagBgColor = thisEvent.getTagBgColor();
		if (tagBgColor.length)
		{
			if (tagBgColor.indexOf('transparent') < 0)
			{
				tagBgColor = '#'+tagBgColor;
				sStyleFontColor = getContrastColor(tagBgColor);
			}
			sStyle += 'background: '+tagBgColor+' !important; margin:1px !important; ';
		}
	}
	else if (!thisEvent.isOwner())
	{
		var color = gaBuddyColors['u'+thisEvent.getUserId()];
		if (color && color.indexOf('transparent') < 0)
		{
			color = '#'+color;
			sStyleFontColor = getContrastColor(color);			
		}
		if (color)
			sStyle += 'background: '+color+' !important; margin:1px !important; ';
	}
	else if (thisEvent.getFeedId())
	{
		var color = gaWebcalColors['u'+thisEvent.getFeedId()];
		if (color && color.indexOf('transparent') < 0)
		{
			color = '#'+color;
			sStyleFontColor = getContrastColor(color);
		}
		if (color)
			sStyle += 'background: '+color+' !important; margin:1px !important; ';
	}
	
	tagColor = thisEvent.getTagColor();
	if (tagColor.length && thisEvent.isOwner())
		sStyleFontColor = 'color: '+tagColor+' !important; ';
		
	if (thisEvent.isTaggedStrike())
		sStyle += 'text-decoration: line-through; ';

	if ((sStyle.length)||(sStyleFontColor.length))
		sStyle = 'style="'+sStyle+sStyleFontColor+'"';	
		
	if (thisEvent.isTaggedImportant() && thisEvent.isOwner())
		sPrefix += "<img src='"+gThemeUrl+"/starColor.gif' valign='absmiddle'/> ";
	if (thisEvent.getPrivacy() == 'private')
		sPrefix += "<img src='"+gThemeUrl+"/lock.gif' valign='absmiddle'/> ";
//	if (thisEvent.isICalSub())
//		sPrefix += "<img src='/img/subscribe.gif' /> ";
	if (thisEvent.isInvite())
	{
//		sCount = countComments(thisEvent.getNotes());
		sPrefix += "<img src='"+gThemeUrl+"/envelope.gif' valign='absmiddle'/> ";
//		if (sCount > 0)
//			sPrefix += "<span class='indicator'>"+sCount+" </span>";
	}
		
	if (!thisEvent.isHoliday())
	{
		if (thisEvent.isInvite())
			sPrefix += 'from '+gaUsers['u'+thisEvent.getUserId()].getFirstName()+': ';
		else if (!thisEvent.isOwner())
			sPrefix += gaUsers['u'+thisEvent.getUserId()].getFirstName()+': ';
	}

	var sTime = '';
	if (gShowTimeOnCal)
		sTime = thisEvent.isAllDay() ? '' : '<span style="'+sStyleFontColor+'" class="timeOnCal textLightest smallest">'+timeToTimeString(thisEvent.getStart(), 'tiny')+'</span> ';

	return '<div '+sContextMenu+' class="eventEntry '+sClass+'" '+sStyle+' >&nbsp;' + 
		sTime + sPrefix + thisEvent.getSummary() + 
		"</div>";
}

////////////////


function createContextMenu(eventId)
{
	var thisEvent = gaEvts['e'+eventId];
	var eventSummary = thisEvent.getSummary();
	if (dm_ext_getItemParams(0,1,1)[11] == 0) // make sure we have 2 menu items
		dm_ext_changeItemVisibility(0,1,1,1); // last integer sets visibility

	dm_ext_changeItem(0,1,0,["Edit Event","javascript:showEditEvent("+eventId+")","",""]);
	dm_ext_changeItem(0,1,1,["Delete","javascript:delEvent("+eventId+",'')","",""]);
}

function createTodoContextMenu(iTodoId,sTodoEditStr,sTodoTextStr)
{
	var time = timeToStringDate(new Date());
	
	dm_ext_changeItem(1,1,0,["Edit","javascript:editTodo(\'"+iTodoId+"\', \'"+sTodoEditStr+"\')","",""]);
	dm_ext_changeItem(1,1,1,["Get Info","javascript:toggleDisplay('tdDetails"+iTodoId+"')","",""]);
	dm_ext_changeItem(1,1,2,["Delete","javascript:delTodo(\'"+iTodoId+"\')",""]);
	dm_ext_changeItem(1,1,3,["Add to My Calendar","javascript:copyTodo(\'"+iTodoId+"\')","",""]);
	dm_ext_changeItem(1,1,4,["Add to gCal","http://www.google.com/calendar/event?action=TEMPLATE&text="+encodeURI(sTodoTextStr),"","","","_blank"]);
	dm_ext_changeItem(1,1,5,["Add to Y!Cal","http://calendar.yahoo.com/?v=60&VIEW=d&ST="+time+"&TITLE="+encodeURI(sTodoTextStr),"","","","_blank"]);
//	dm_ext_changeItem(0,1,1,["","","","","","_"]); // grays out the delete
//	dm_ext_changeItemVisibility(0,1,1,0); // last integer sets visibility
//	alert(dm_ext_getItemParams(0,1,0));
}

////////////////

function createBuddyContextMenu(userId,firstName)
{
	dm_ext_changeItem(0,1,0,["Hide Buddy","javascript:toggleUserCalendar(\'"+userId+"\','false')","",""]);
	dm_ext_changeItem(0,1,1,["Buddy Page","/user/"+userId,"",""]);
//	dm_ext_changeItem(0,1,1,["","","","","","_"]); // grays out the delete
//	dm_ext_changeItemVisibility(0,1,1,0); // last integer sets visibility
//	alert(dm_ext_getItemParams(0,1,0));
}


////////////////

function imageHtmlForOneDay(aEventIds)
{
	// if we're showing feeds, show an image on the calendar day if possible
	if (gMode == 'user')
		return '';
		
	for (var i=0; aEventIds && i<aEventIds.length; i++)
	{
		eventId = aEventIds[i];
		var thisEvent = gaEvts['e'+eventId];
		url = thisEvent.getImgUrl(1);
		if (url.length)
			return url;
	}
	return '';
}

////////////////

function htmlForOneDay(dateObj, iDayNum)
{
	var sDate = timeToDbDate(dateObj);

	var dateToday = new Date();
	var sTextColorClass = 'textMedium';
	if (dateObj.toDateString() == dateToday.toDateString())
		sTextColorClass = 'textBlack';
	
	var weatherHtml = '';
	var eventHtml = '';
	var iEventsShown = 0;
	var iEventsHidden = 0;
	var bHasFeed = false;
	var bHasImg = false;
	var sTextStyle = '';
	if (dateObj.valueOf() < gDataStart)
		eventHtml = '<div class="smallest center">Gazing into your past<br /><br /><img src="'+
			gThemeUrl+'/wait.gif"  valign="absmiddle"/></div>';
	else if (dateObj.valueOf() > gDataEnd)
		eventHtml = '<div class="smallest center">Peering into your future<br /><br /><img src="'+
			gThemeUrl+'/wait.gif" valign="absmiddle"/></div>';
	else if (gMode == 'user' && !gaEvtsByDate[sDate]) // we could be waiting for a previous load to complete
		eventHtml = '<div class="smallest center">Waiting for more data<br /><br /><img src="'+
			gThemeUrl+'/wait.gif" valign="absmiddle"/></div>';
	else 
	{
		aEventIds = gaEvtsByDate[sDate]; // might not exist if mode == 'feed'
		imgUrl = imageHtmlForOneDay(aEventIds);
		if (imgUrl.length)
		{
			w = (getWinWidth()-20)/7;
			h = 40 + (giMaxEvtsPerDay*20);
				
			if(gbSmallTheme)
			{
				h = 120;
				w = 100;	
			}
			if(gbTinyTheme)
			{
				h = 60;
				w = 68;
			}
			eventHtml = "<img style='position: absolute; top: 0; left: 0; z-index: 30;' src='"+imgUrl+"' width='"+w+"' height='"+h+"' />";
			if (gbNoResize)
				eventHtml = "<div style='position: absolute; top: 0; left: 0; z-index: 30; background-image:url("+imgUrl+"); width:"+w+"; height: 120; background-position: center;' /><img src='/img/clear.gif' width='"+w+"' height='"+h+"' /></div>";
			sTextStyle = 'style="position: relative; font-weight: bold; color: #fff !important; z-index: 40 !important;"';
			bHasImg = true;
		}
		else
		{
			for (var i=0; aEventIds && i<aEventIds.length; i++)
			{
				eventId = aEventIds[i];
				var thisEvent = gaEvts['e'+eventId];
				if (thisEvent.isWeather() && !thisEvent.isOwner()) // hide buddy's weather
					continue;
							
				if (thisEvent.isWeather())
				{
					if (iDayNum==0 || dateObj.getDate() == 1)
						weatherHtml += '<span class="weatherInfo textMedium" style="padding-left: 16px;">' + thisEvent.getSummary() + '</span>';
					else	
						weatherHtml += '<span class="weatherInfo textMedium">' + thisEvent.getSummary() + '</span>';
				}
				else if (iEventsShown < giMaxEvtsPerDay)
				{
					eventHtml += formatEventLine(thisEvent, sTextColorClass);
					iEventsShown++;
				}
				else
					iEventsHidden++;
			}
		}
	}
	
	var bottomHtml = '';
	if (iEventsHidden)
		bottomHtml = "<div class='moreEventsArrow'><img alt='...' src='"+
			gThemeUrl+"/downOffCcc.gif' /></div>";
	
	var sTdClass = (dateObj.getMonth() % 2 == 0) ? 'calBox' : 'calBoxAltColor';
	var sTextColorClass = 'textLight';
	if (dateObj.toDateString() == dateToday.toDateString())
	{
		sTdClass = 'calBoxToday';
		sTextColorClass = 'textBlack';
	}
	
	var dateHtml = "<div class='calBoxDayLabel "+sTextColorClass+" large' "+sTextStyle+">";
	if (iDayNum==0 || dateObj.getDate() == 1)
	{
		src = gThemeUrl+'/month'+dateObj.getMonth()+'.gif';
		var sDisplay = 'inline';
		if(bHasImg)
			sDisplay = 'none';
		dateHtml += '<img align="left" style="display:'+sDisplay+';" src="' + src + '" />';
	}
	if (bHasFeed)
		dateHtml += "<img style='padding-left:2px; float:left' src='"+gThemeUrl+"/updates.gif' alt='' />";
	if (iDayNum < 7)
		dateHtml += timeToDayOfWeekString(dateObj, 3)+' ';
	dateHtml += dateObj.getDate() + '</div>';
	// now we've got the parts, build the html
	iCalBoxHeight = 40 + giMaxEvtsPerDay*20;
	
	if (gbSmallTheme)
		iCalBoxHeight = '100';
		
	if (gbTinyTheme)
		iCalBoxHeight = '60';

	var html = "<td nowrap valign='top' class='"+sTdClass+"' style='height:"+iCalBoxHeight+"px !important'> \
		<div class='calBoxOutline "+sTdClass+"' id='calBox"+sDate+"'\
		onmouseover=delayCode('showMouseOverDay(\""+sDate+"\",\"calBox"+sDate+"\")',50) \
		onmouseout=delayCode('hideMouseOverDay()',50) \
		onclick=showDayView("+dateObj.valueOf()+"); \
		style='height:"+iCalBoxHeight+"px !important; background-image: url();' \
		>";
	html += dateHtml + eventHtml + weatherHtml + bottomHtml;
	html += "</div></td>";	
	return html;
}

////////////////
////////////////

function shouldShowUserCalendar(thisEvent)
{
	if ((gbShowFeeds == 0)&&(thisEvent.isFeed()))
		return 0;

	return 1;
}

function shouldShowTagHighlight(thisEvent)
{
	if (thisEvent.isOwner())
	{
		sEventTags = thisEvent.getTags().toLowerCase();
		for (var sTag in gaTags)
		{
			if (gaTags[sTag])
			{
				if (sEventTags.indexOf(' '+sTag+' ') >= 0)
					return true;
			}
		}
	}
	return false;
}

function hasColoredBgTag(thisEvent)
{
	if (thisEvent.isOwner())
	{
		sEventTags = thisEvent.getTags().toLowerCase();
		for (var sTag in gaTagColors)
		{
			if (gaTagColors[sTag])
			{
				if (sEventTags.indexOf(' '+sTag+' ') >= 0)
					return true;
			}
		}
	}
	return false;
}
////////////////
////////////////


// end calendar view code
////////////////
////////////////
////////////////


////////////////
////////////////
////////////////
// start day view code
function getEventEndTimeHtml(thisEvent)
{
	var endTimeHtml = '';
	if (thisEvent.getStart() != thisEvent.getEnd())
	{
		dStart = new Date(thisEvent.getStart());
		dEnd = new Date(thisEvent.getEnd());
		endTimeHtml = '&nbsp;<span class="smallest bold textLight">until ';
		if (dStart.getDate() != dEnd.getDate() || dStart.getMonth() != dEnd.getMonth() || dStart.getYear() != dEnd.getYear())
			endTimeHtml += timeToDateString(dEnd, true, 0, true);
		else
			endTimeHtml += timeToTimeString(dEnd);
		endTimeHtml += '</span>';
	}
	return endTimeHtml;
}

gaMyResponsesToOtherInvite = {'unknown':'Undecided', 'yes':'Accepted', 'no':'Declined'};
function getMyResponseToOtherInvite(thisEvent)
{
	var changeUrl = "/index.php?action=invitePickup&amp;id="+thisEvent.getInviteId()+
		"&amp;code="+thisEvent.getInviteCode()+"&amp;decision=";
		
	var html = '<div class="smallest textLight" style="margin-bottom: 2px;"><img src="'+gThemeUrl+'/'+thisEvent.getInviteResponse()+'.gif" /><span class="bold">' +
		gaMyResponsesToOtherInvite[thisEvent.getInviteResponse()] +
		'.</span> &nbsp;<a href="'+changeUrl+'yes">Accept</a> | '+
		'<a href="'+changeUrl+'no">Decline</a> | '+
		'<a href="'+changeUrl+'unknown">Undecided</a>' +
		'</div>';
	
	return html;
}

gaOtherResponsesToMyInvite = {'unknown':'has not responded/decided', 'yes':'will join you', 'no':'cannot make it'};
function getResponsesToMyInvites(thisEvent)
{
	if (thisEvent.isFeed()||thisEvent.isICalSub()) // no responses on feeds or web cals
		return '';

	html = '';
	aInvites = thisEvent.getInvites();
	if (aInvites)
	{
		html = '<p class="dayViewHighlightBox smallest textLight">';
		for (var key in aInvites)
		{
			thisInvite = aInvites[key];
			if(thisInvite.getUserId())
			{
			user = gaUsers['u'+thisInvite.getUserId()];
			html += user.getFirstName()+' '+gaOtherResponsesToMyInvite[thisInvite.getResponse()]+'<br />';
			}

		}
		html += '</p>';
	}
	return html;
}

function hideDayView()
{
	el = getEl('dayViewPopup');
	el.style.visibility = 'hidden';
	hideFocus();
}

// set event handler
document.onkeypress = escHandler;
function escHandler(e)
{
	var evtobj=window.event? event : e;
	var unicode=evtobj.charCode? evtobj.charCode : evtobj.keyCode;

	//if escape is pressed	
	if (unicode == 27)
	{
		hideDayView();
		showWindowShade('indexWindowShade','none');
		oneBoxPopupDone(false, 'input');
		oneBoxPopupDone(false, 'todoInput');
		oneBoxPopupDone(false, 'editEventInvites');
		oneBoxPopupDone(false, 'dayViewInput');
		oneBoxPopupDone(false, '');
		return (false);
	}
}

var gDayViewTime=0;
function showDayView(iTime)
{
	if (!iTime)
	{
		d = new Date();
		iTime = d.valueOf();
	}
	gDayViewTime=iTime;
	// may have to fetch data if we scrolled out of range!
	// get more data if we need it
	var weatherHtml = '';
	var photoHtml = '';
	var eventsHtml = '';
	var d = new Date(iTime);
	var sDate = timeToDbDate(d);
	showWindowShade('indexWindowShade','block');
	
	var dateHtml = '<span class="smallest dayMonth">'+timeToDayOfWeekString(d)+' '+timeToDateString(d, true)+'</span><br />' +
		'<span class="dayViewHeaderArrows">' +
		'<a href="javascript:showDayView('+(iTime-60*60*24*1000)+');"><img border="0" alt="&laquo;" src="'+gThemeUrl+'/leftArrow.gif" /></a>' +
		'<a href="javascript:showDayView('+(iTime+60*60*24*1000)+');"><img border="0" alt="&raquo;" src="'+gThemeUrl+'/rightArrow.gif" /></a>' +
		'</span>' +
		'<span class="dayViewHeaderNumeral">'+d.getDate()+'</span>';
	getEl('dayViewDate').innerHTML = dateHtml;

	if (iTime < gDataStart || iTime > gDataEnd)
	{
		eventsHtml = '<br /><br /><div class="smallest center">Loading more data - just a sec<br /><br /><img src="'+
			gThemeUrl+'/wait.gif" valign="absmiddle"/></div>';
		requestMoreData(iTime > gDataEnd, 'showDayView('+iTime+');',giUserId);
	}
	else
	{
		var aEventIds = Array();
		if (gaEvtsByDate[sDate])
			aEventIds = gaEvtsByDate[sDate];
		var myEvents = '';
		var buddyEvents = '';
		var inviteEvents = '';
		var iPhotoCount = 0;
		var iBuddyEventCount = 0;
		var iBuddyFeedCount = 0;
		for (var i=0; i<aEventIds.length; i++)
		{
			eventId = aEventIds[i];
			var thisEvent = gaEvts['e'+eventId];
			if (!thisEvent) // deleted
				continue;
			if (!shouldShowUserCalendar(thisEvent))
				continue;
	
			var summary = thisEvent.getSummary() + getBirthdayString(thisEvent, d);
			if (thisEvent.getLink().length)
				summary = "<a target='_top' class='external textLight' target='_blank' href='"+thisEvent.getLink()+"'>"+summary+"</a>";
			
			if (thisEvent.isWeather())
			{
				if(gUserId == thisEvent.getUserId())
					weatherHtml = '<p class="smallest"><a class="hoverLink textLight" href="'+thisEvent.getLink()+'" target="_blank">'+thisEvent.getSummary() +'</a></p>';
				continue;
			}
			
			var sStyle='';
			if (thisEvent.getFeedId())
			{
				var color = gaWebcalColors['u'+thisEvent.getFeedId()];
				if (color && color.indexOf('transparent') < 0)
					color = '#'+color;
				if (color)
					sStyle += 'background: '+color+' !important; margin:1px !important; ';
			}
			
			attachmentHtml = thisEvent.getAttachmentHtml();
			var notesHtml = '';
			var notes = thisEvent.getNotes();
			if (notes.length || thisEvent.isInvite() || attachmentHtml.length)
			{
				notes = stripEscapedTags(notes);
				if (thisEvent.isOutsideCalendarFeed())
				{
					notes = notes.substr(0,100)+'...';
				}
				notes = bracketsToMap(linkUrls(notes),eventId);
				notesHtml = '<p class="dayViewHighlightBox smallest textLight">'
				if (notes.length)
				{
					notesHtml += notes+"<br />";
				}
				if (attachmentHtml.length)
					notesHtml += attachmentHtml;
				notesHtml += '</p>';
			}
	
			var iMaxPhotoCount = 5;
			if(gbSmallTheme)
				iMaxPhotoCount = 4;
			if(gbTinyTheme)
				iMaxPhotoCount = 3;
			if ((thisEvent.getImgUrl().length)&&(iPhotoCount < iMaxPhotoCount)) // limit because it looks bad with too many
			{
				photoHtml += '<div class="dayViewImage"><a href="'+thisEvent.getLink()+'" target="_blank">'+
					'<img border="0" height="60" src="' + thisEvent.getImgUrl() + '" /></a></div>';
				iPhotoCount++;
			}
		
			var iconHtml = '';
			if (thisEvent.isTaggedImportant() && thisEvent.isOwner())
				iconHtml += "<img src='"+gThemeUrl+"/starColor.gif' valign='absmiddle'/> ";
			if (thisEvent.getPrivacy() == 'private')
				iconHtml += "<img src='"+gThemeUrl+"/lock.gif' valign='absmiddle'/> ";
			if ((thisEvent.getRepeat() != 'no')&&(thisEvent.isOwner()))
				iconHtml += "<img src='"+gThemeUrl+"/repeat.gif' valign='absmiddle'/> ";	
			if ((thisEvent.getReminder() != -1)&&(!thisEvent.isFeed())&&(thisEvent.isOwner()))
				iconHtml += "<img src='"+gThemeUrl+"/reminder.gif' valign='absmiddle'/> ";
			if (thisEvent.isICalSub())
				iconHtml += "<img src='/img/subscribe.gif' /> ";
				
			dStart = new Date(thisEvent.getStart());
			var startTimeHtml = thisEvent.isAllDay() ? 'today &raquo;' : timeToTimeString(dStart);
			summary += getEventEndTimeHtml(thisEvent);
			var timeTdAttbributes = 'width="55" valign="top" align="right" class="smallest bold textLight"';
			sTitle = '';
			if (thisEvent.isOwner() || thisEvent.isHoliday())
			{
				inviteResponseHtml = getResponsesToMyInvites(thisEvent);
				myEvents += '<tr><td valign="top" width="45" align="left"><img src="'+gThemeUrl+'/clear.gif" border="0" width="45" height="1" />';
				padding='8';
				sClass='large';
				if (thisEvent.getLink())
				{
					padding='5';
					sClass='small';
				}
				if (shouldShowTagHighlight(thisEvent))
					sClass += ' tagHighlightDayView';
				myEvents += '</td><td '+timeTdAttbributes+' style="padding-top:'+padding+'px;"><img src="'+gThemeUrl+'/clear.gif" border="0" width="55" height="1" /><br />'+startTimeHtml+'</td>' +
					'<td align="left" valign="top" width="282" style="'+sStyle+'"><span '+sTitle+ 'class="'+sClass+' bold textMedium">' +
					iconHtml + summary+'</span>'+notesHtml+inviteResponseHtml+'</td></tr>';
			}
			else
			{
				var sHideLink = '';
				var sHideMouseOver = '';
				iBuddyEventCount++;
				buddyEvents += '<tr'+sHideMouseOver+'><td width="45" class="smallest" valign="top"><img src="'+gThemeUrl+'/clear.gif" width="45" height="1" /><br />'+sHideLink+'</td><td '+timeTdAttbributes+' style="padding-top: 5px;">';
				buddyEvents += startTimeHtml;
				buddyEvents += '</td><td width="282" align="left" valign="top" style="'+sStyle+'">'+iconHtml;
				var name='';
				if (!thisEvent.isHoliday())
					name = '<a href="/user/'+thisEvent.getUserId()+'">'+gaUsers['u'+thisEvent.getUserId()].getFirstName()+'</a>: ';
				buddyEvents += '<span class="small textLight">'+name+summary+'</span>'+notesHtml+'</td></tr>';
			}
		}
	
		// right column
		if (photoHtml.length)
			photoHtml = "<div class='dayViewImages'><p class='smallest textMedium' style='margin-bottom: 4px;"+
				" margin-top: 2px;'>Photos:</p>"+photoHtml+'</div>';
		// window height hack
		var imgHeight = '434';
		if (gbTinyTheme)
			imgHeight = '260';
			
		var heightTable = '<table style="float: left;" cellpadding="0" cellspacing="0" border="0"><tr><td height="'+imgHeight+'"><img src="'+gThemeUrl+'/clear.gif" width="10" height="'+imgHeight+'" /></td><td valign="top">';
		// events
		var headerStart = '<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr>'+
			'<td colspan="3"  width="400" align="left" class="dayViewEventHeader textLight small">';
		if (!myEvents.length)
			myEvents = '<tr><td width="45"><img src="'+gThemeUrl+'/clear.gif" width="45" height="1" /></td><td width="55" valign="top" align="right" '+
				'class="smallest bold textLight" style="padding-top:5px;"><img src="'+gThemeUrl+'/clear.gif" width="55" height="1" /><br />'+
				'today &raquo;</td><td width="282" align="left" valign="top" class="small textLight"><img src="'+gThemeUrl+'/clear.gif" width="1" height="1" /><br />nothing scheduled</td></tr>';
		eventsHtml = heightTable + headerStart + 'My Stuff:</td></tr>' + myEvents + '</table>';
		if (inviteEvents.length)
			eventsHtml += headerStart + 'Invitations:</td></tr>' + inviteEvents + '</table>';
		if (buddyEvents.length)
		{
			if ((iBuddyFeedCount > 4)||(iBuddyEventCount > 10)) // hide buddy updates
				eventsHtml += headerStart + 'Buddy Updates: ' + iBuddyEventCount + ' &nbsp;<a href="#" onclick="toggleDisplay(\'buddy'+iTime+'\');return false;">show all?</a></td></tr></table><div id="buddy'+ iTime +'"style="display: none;"><table width="100%" cellpadding="3" cellspacing="0" border="0">' +
					buddyEvents + '</table></div>';
			else
				eventsHtml += headerStart + 'Buddy Updates: ' + iBuddyEventCount + '</td></tr>' + buddyEvents + '</table>';			
		}
	}
	eventsHtml += '</td></tr><tr><td colspan="2" align="right"><div class="closeDayView small"><a id="closeInfoHref" href="#" accesskey="x" onclick="hideDayView(); showWindowShade(\'indexWindowShade\',\'none\'); return false;"><img src="'+gThemeUrl+'/buttonClose.gif" border="0"/></a></div></td></tr></table>';
	getEl('dayViewEvents').innerHTML = eventsHtml;
	getEl('dayViewRightCol').innerHTML = weatherHtml + photoHtml;

	displayCenteredDiv('dayViewPopup');
}

// end day view code
////////////////
////////////////
////////////////

////////////////
////////////////
////////////////
// start popup calendar navigation code
var gCalendarNavStartTime = 0;
function showCalendarNavPopup(iStartTime, iMonths)
{
	gCalendarNavStartTime = iStartTime;
	if (!gCalendarNavStartTime)
		gCalendarNavStartTime = gStartTime;

	el = getEl('calNavPopup');
	el.innerHTML = drawCalendarNavPopup(iMonths);
}

function drawCalendarNavPopup(iMonths)
{	
	dToday = new Date();
	dLast = new Date(gCalendarNavStartTime);
	dLast.setMonth(dLast.getMonth()-1);
	dNext = new Date(gCalendarNavStartTime);
	dNext.setMonth(dNext.getMonth()+1);
	var navOptions = '<a href="javascript:showCalendarNavPopup('+dLast.valueOf()+','+iMonths+')"><img border="0" src="'+gThemeUrl+'/calUp.gif"/></a>'+
		'<a href="javascript:showCalendarNavPopup('+dToday.valueOf()+','+iMonths+')"><img border="0" src="'+gThemeUrl+'/calToday.gif"/></a>'+
		'<a href="javascript:showCalendarNavPopup('+dNext.valueOf()+','+iMonths+')"><img border="0" src="'+gThemeUrl+'/calDown.gif"/></a><br />';
	
	var html = navOptions;
	var d = new Date(gCalendarNavStartTime);
	d.setDate(1);
	for (var month=0; month<iMonths; month++)
	{
		html += drawCalendarNavMonth(d, iMonths);
		d.setMonth(d.getMonth()+1)
	}
	
	html += navOptions;
	return html;
}

function getCalendarNavWeekTag(d)
{
	iTime = d.valueOf();
	var sClass = 'calNavPopupWeek';
	buffer = 60*60*24*1000;
	if (iTime >= gStartTime-buffer && iTime < gEndTime-buffer)
		sClass = 'calNavPopupWeekVisible';

	html = '<tr class="'+sClass+'">';
		
	return html;
}

function onCalendarNavClicked(iTime, iMonths)
{
	if (typeof(onCalendarNavClickedOverride) == 'function')
		return onCalendarNavClickedOverride(iTime);
	if (iTime < gStartTime || iTime > gEndTime)
	{
		drawMainCalendar(iTime);
		showCalendarNavPopup(gCalendarNavStartTime, iMonths); // redraw popup with same start, new highlighting
	}
	flashHighlightedDate(new Date(iTime));
}

function drawCalendarNavMonth(dStart, iMonths)
{
	var d = new Date(dStart.valueOf());
	var html = '<div class="calNavMonthYear textMedium center">'+timeToDateString(d, true, 0, false, true)+'</div>';
	html += '<table cellpadding=0 cellspacing=0 align="center">'+getCalendarNavWeekTag(d);
	var iPos=0
	for (var i=0; i<(d.getDay()-gStartDay+7)%7; i++)
	{
		iPos++;
		html += "<td></td>";
	}
	
	var dToday = new Date();
	iMonth=d.getMonth();
	while (d.getMonth() == iMonth)
	{
		iPos++;
		var sClass='pl';
		
		aEvts = gaEvtsByDate[timeToDbDate(d)];
		if (aEvts && aEvts.length)
			sClass +=' bold';
		if (dToday.getDate()==d.getDate() && dToday.getMonth()==d.getMonth() && dToday.getYear()==d.getYear())
			sClass += ' calNavTodayHighlight';
		
		html += '<td class="calNavDay"><a href="javascript:onCalendarNavClicked('+d.valueOf()+','+iMonths+')" '+
			'onmouseover="this.className=\'calNavPopupDayHighlight\';" '+	
			'onmouseout="this.className=\'\';">';
		html += '<span class="'+sClass+'">'+d.getDate()+'</span>';
		html += '</a></td>';
		if (iPos == 7)
		{
			iPos = 0;
			html += '</tr>'+getCalendarNavWeekTag(d);
		}
		d.setDate(d.getDate()+1);
	}
	
	for (var i=iPos; i<7; i++)
		html += '<td></td>';
	
	html += "</tr></table>";
	return html;
}

// end popup calendar navigation code
////////////////
////////////////
////////////////

////////////////
////////////////
////////////////
// start calendar motion
function moveCalendarNow()
{
	d = new Date();
	drawMainCalendar(d.valueOf());
}

function moveCalendar(increment)
{
	drawMainCalendar(gCenteredTime + increment);
	return;
	
	// just testing stuff below...
	iLoops = 0;
	delay = 40;
	for (var i=0; i<iLoops; i++)
	{
		offset = (i+1)*(100/iLoops);
		str = 'el=getEl("mainCalendar");';
		if (increment > 0)
			str+='el.style.marginTop="-'+offset+'px"; el.style.paddingBottom="'+offset+'px";';
		else
			str+='el.style.marginTop="'+offset+'px"; el.style.marginBottom="-'+offset+'px";';
	
		setTimeout(str, i*delay);
	}
	
	str = "drawMainCalendar("+(gCenteredTime + increment)+")";
	setTimeout(str, (iLoops+1)*delay);
}

// end calendar motion
////////////////
////////////////
////////////////

////////////////
////////////////
////////////////
// start general stuff

function getBirthdayString(thisEvent, date)
{
	if (thisEvent.getSummary().search(/\b(bday)|(birthday)|(b\-day)/i) < 0)
		return '';

	notes = thisEvent.getNotes();
	iStart = notes.search(/\b\d\d\d\d\b/);
	if (iStart < 0)
		return '';
	iYear = date.getFullYear() - notes.substring(iStart, iStart+4);
	if (iYear > 120)
		return '';
	return ' - ' + iYear + ' years old!';
}

function getAnniversaryString(thisEvent, date)
{
	if (thisEvent.getSummary().search(/\b(anniv)|(anniversary)/i) < 0)
		return '';

	notes = thisEvent.getNotes();
	iStart = notes.search(/\b\d\d\d\d\b/);
	if (iStart < 0)
		return '';
	iYear = notes.substring(iStart, iStart+4);
	sNoun = 'years';
	if ((date.getFullYear() - iYear) < 2)
		sNoun = 'year';
	return ' - ' + (date.getFullYear() - iYear) + ' ' + sNoun + ' and counting!';
}



function showPopupCalendar(inputId, hrefId, defaultInputId)
{
	var initialValue = getEl(inputId).value;
	if (!initialValue.length)
		initialValue = getEl(defaultInputId).value;
		
	format = (gDateInputFormat == 1) ? 'd/M/yyyy': 'M/d/yyyy';
		
	calendar.select(getEl(inputId), hrefId, format, initialValue);
}

function onClickSearchResult(userId, sDate)
{
	showUserCalendar(userId);
	d = new Date(sDate)
	showDayView(d.valueOf());
}

function linkUrls(s)
{
	aResults = s.match(/(https?:)/gi);
	if (aResults)
		s = s.replace(RegExp.$1, " " + RegExp.$1);

	var hlink = /\b(https?):\/\/([^ \:\!\)\(\"\'\<\>\n\r\s])+/g; // don't put in ';' - used in &amp;
    return (s.replace (hlink, function ($0,$1,$2)
    {
    		s = $0; 
			// remove trailing dots, if any
   			while (s.length>0 && s.charAt(s.length-1)=='.') 
				s=s.substring(0,s.length-1);
				// add hlink
 			randomId = (Math.round((Math.random()*100000)+1));
			title = 'more info';
//			makeXmlHttpRequest('getUrlTitle', 'url='+s+'&linkId=linkId'+randomId, "getEl('linkId'+"+randomId+").innerHTML = str;");
			return "<a title='linkId" + randomId + "' id='linkId"+randomId+"' class='external textLight' target='_blank' href='"+s+"'>"+title+"</a>"; 
	}
	));
}

function countComments(s)
{
	// find a string " said:" and count instances
	aResults = s.match(/(.said:)/g);
	if (aResults)
		return aResults.length;
	else
		return 0;
}

function stripEscapedTags(s)
{
	a = s.indexOf("&lt;");
	b = s.indexOf("&gt;");
	len = s.length;
	c = s.substring(0, a);
	if(b == -1)
	b = a;
	d = s.substring((b + 1), len);
	s = c + d;
	tagCheck = s.indexOf("&lt;");
	if(tagCheck != -1)
	s = stripTags(s);
	return s;
}
function stripTags(s)
{
	a = s.indexOf("<");
	b = s.indexOf(">");
	len = s.length;
	c = s.substring(0, a);
	if(b == -1)
	b = a;
	d = s.substring((b + 1), len);
	s = c + d;
	tagCheck = s.indexOf("<");
	if(tagCheck != -1)
	s = stripTags(s);
	return s;
}

function escapeAddress(s)
{
	// address in notes my have '&' in them rewritten as '&amp;'
	return encodeURIComponent(s.replace('&amp;', '&'));
}

function bracketsToMap(s,eventId)
{
	// find a string inside [].  add a map link and weather info if possible
	var bracketRE = /\[(.+?)\]/;
	var mapUrl;
	aResults = bracketRE.exec(s);
	weather = '<span id="weatherConditions'+eventId+'"></span>';
	if (aResults)
	{
		if (aResults[0].indexOf('|') >= 0)
		{
			var aDirectionsArray = new Array();
			aDirectionsArray = aResults[0].split("|");
			var sStartAddr = '';
			if (aDirectionsArray[0].indexOf('home') >= 0)
				sStartAddr = gaUsers['u'+gUserId].getHomeString();
			else if (aDirectionsArray[0].indexOf('work') >= 0)
				sStartAddr = gaUsers['u'+gUserId].getWorkString();
			if (sStartAddr.length) // might not have a home/work set
				mapUrl = 'http://maps.google.com/maps?saddr='+escapeAddress(sStartAddr)+'&daddr='+escapeAddress(aDirectionsArray[1]);
			else		
				mapUrl = 'http://maps.google.com/maps?q='+escapeAddress(aDirectionsArray[1]);
		}
		else
		{
			mapUrl = 'http://maps.google.com/maps?q='+escapeAddress(removeBrackets(aResults[0]));
			var weatherString = aResults[1];
			var queryString = '';
			var zipRE = /(\d\d\d\d\d)/;
			aZipMatch = zipRE.exec(weatherString);
			if (aZipMatch)
				queryString = aZipMatch[0];
			else
			{
				var aLocationArray = new Array()
				aLocationArray = weatherString.split(",");
				if (aLocationArray.length == 2)
					queryString = aLocationArray[0]+','+aLocationArray[1];
				else if (aLocationArray.length == 3)
					queryString = aLocationArray[1]+','+aLocationArray[2];
			}
		}
		if (queryString)
			makeXmlHttpRequest('getWeather', 'q='+queryString, 'getEl("weatherConditions'+eventId+'").innerHTML = str;');
		
		s = s.replace (aResults[0], '<a class="external textLight" target="_blank" href="' +mapUrl+ '">Map - '+aResults[0]+'</a>');
		s = removeBrackets(s);
	}
	else
		weather = '';
	return s+weather;
}

function removeBrackets(s)
{
	s = s.replace (/\[/, '');
	s = s.replace (/\]/, '');
	return s;		
}

function fixStrippedHtml(s) // replace special chars stripped from user input
{
	s=s.replace(/&quot;/g,'"');
	s=s.replace(/&#039;/g,"'");
	s=s.replace(/&lt;/g,'<');
	s=s.replace(/&gt;/g,'>');
	s=s.replace(/&amp;/g,'&');
	s=s.replace(/<br>/g,"\r\n");
	s=s.replace(/<br\/>/g,"\r\n");
	s=s.replace(/<br \/>/g,"\r\n");
	return s;
}

function getContrastColor(s)
{
	var sHexTotal = totalHexValue(s);
	if ((s == '#FFDC91')||(s == '#91FFC5')) // small hack to ensure good looking defaults
		return '';

	
	if (sHexTotal > 620)
		return '';
	else
		return 'color: #fff !important; ';
}

function totalHexValue(s)
{
	var sHex = s;
	iRed = HexToR(s);
	iGreen = HexToG(s);
	iBlue = HexToB(s);
	return iRed+iGreen+iBlue;
}

function HexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function HexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function HexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}


function flashHighlightedDate(dateObj,elementId) 
{
	id = 'calBox'+timeToDbDate(dateObj);
	if (elementId)
		id = elementId;
	var hstr = '#';
	var hdig = "0123456789abcdef";
	var cbeg = '#ffff66'; // starts with a yellow
	var cCoorectEnd = getEl(id).style.backgroundColor; // this correctly gets the color. The fade code is buggy
	var cend = '#ffffff';
	var iter = 20; // cycles
	var time = 80; // ms

	var rbeg = hdig.indexOf(cbeg.substr(1,1))*16 + hdig.indexOf(cbeg.substr(2,1));
	var gbeg = hdig.indexOf(cbeg.substr(3,1))*16 + hdig.indexOf(cbeg.substr(4,1));
	var bbeg = hdig.indexOf(cbeg.substr(5,1))*16 + hdig.indexOf(cbeg.substr(6,1));
	var rend = hdig.indexOf(cend.substr(1,1))*16 + hdig.indexOf(cend.substr(2,1));
	var gend = hdig.indexOf(cend.substr(3,1))*16 + hdig.indexOf(cend.substr(4,1));
	var bend = hdig.indexOf(cend.substr(5,1))*16 + hdig.indexOf(cend.substr(6,1));
	for ( i = 1, r = rbeg, g = gbeg, b = bbeg;
	i <= iter;
	r = Math.round(rbeg + i * ((rend - rbeg) / (iter-1))),
	g = Math.round(gbeg + i * ((gend - gbeg) / (iter-1))),
	b = Math.round(bbeg + i * ((bend - bbeg) / (iter-1))), i++ )
	{
		hstr = '#' + hdig.charAt(Math.floor(r/16)) + hdig.charAt(r%16) +
		hdig.charAt(Math.floor(g/16)) + hdig.charAt(g%16) +
		hdig.charAt(Math.floor(b/16)) + hdig.charAt(b%16);
		setTimeout('var el = getEl("' + id + '"); el.style.backgroundColor = "' + hstr + '";', i * time);
	}
   	setTimeout('var el = getEl("' + id + '"); el.style.backgroundColor = "' + cCoorectEnd + '";', (i+1) * time);
}

function calculateStartTime(iCenteredTime)
{
	// it should be in the previous week
	dCentered = new Date(iCenteredTime);
	dCentered.setHours(12);
	dCentered.setMinutes(0);
	dStart = new Date(dCentered.valueOf() - ((dCentered.getDay() + 7 - gStartDay)%7+7)*60*60*24*1000)
	dStart.setHours(12);
	dStart.setMinutes(0);
	dStart.setSeconds(0);
	dStart.setMilliseconds(0);
	
	// time of day should be noon toaccount for potential daylight savings issues
	return dStart.valueOf();
}

////////////////
////////////////

function timeToJsCalendarDate(dateObj)
{
	month = dateObj.getMonth()+1;
	day = dateObj.getDate();
	year = dateObj.getFullYear();
	if (gDateInputFormat == 1)
		return day+'/'+month+'/'+year;
	else
		return month+'/'+day+'/'+year;
}

function dbDateToJsDate(s)
{
	year = s.substring(0,4);
	month = s.substring(5,7)-1; // zero-based
	day = s.substring(8,10);
	return new Date(year, month, day);
}

////////////////
////////////////
var gMonths = ['January','February','March','April','May','June','July','August','September','October','November','December'];
function timeToDateString(dateObj, showMonth, monthLength, showDate, showYear)
{
	var s ='';
	if (showMonth)
	{
		s += gMonths[dateObj.getMonth()];
		if (monthLength)
			s = s.substring(0, monthLength);
	}
	if (showDate)
	{
		if (showMonth)
			s+= ' ';
		s += dateObj.getDate();
	}
	if (showYear)
	{
		if (showDate)
			s += ',';
		if (showDate || showMonth)
			s+= ' ';
		s += dateObj.getFullYear();
	}
	return s;
}

////////////////
////////////////

var gDaysOfWeek = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
function timeToDayOfWeekString(dateObj, length)
{
	var s = gDaysOfWeek[dateObj.getDay()];
	if (length)
		s = s.substring(0, length);
	return s;
}

////////////////
////////////////


function timeToDbDate(d)
{
	day = d.getDate()+"";
	if (day.length == 1)
		day = "0"+day;

	month = (d.getMonth()+1)+"";
	if (month.length == 1)
		month = "0"+month;

	return d.getFullYear() + '-' + month + '-' + day;
}

////////////////
////////////////

function timeToStringDate(d)
{
	day = d.getDate()+"";
	if (day.length == 1)
		day = "0"+day;

	month = (d.getMonth()+1)+"";
	if (month.length == 1)
		month = "0"+month;

	return d.getFullYear() + month  + day;
}


function timeToTimeString(time) // unix time to a time of day
{
	var mer = '';
	var d = new Date(time);
	var hour = d.getHours();
	
	if (!gUse24HourClock)
	{
		if (hour < 12)
			mer = "am";
		else
			mer = 'pm';
		
		if (hour == 0)
			hour = 12;
		else if (hour > 12)
			hour -= 12;
	}
	
	var minute = ":" + d.getMinutes();
	
	if (minute.length == 2)
		minute = ":0" + d.getMinutes();
	
	if (minute == ':00' && !gUse24HourClock)
		minute = '';
	
	return hour + minute + mer;
}
////////////////
////////////////