/*
* Copyright (c) 2009-2010 ATMAIL. All rights reserved
* See http://atmail.com/license.php for license agreement
*/

// setup our namespace
if(!com) var com={};
if(!com.atmail) com.atmail={};

com.atmail.calendar = {
	name: 'calendar',
	loadingSpriteSettings: {fps: 8, no_of_frames: 8, width: 24, height: 24},
	owner: undefined,		// account name of owner
	colors: [ "00bf02", "bf0000", "FF8300", "00bfbf", "bf00bd", "4d4d4d", "0002bf", "64DF64", "ff8080", "FFA240", "38DFDF", "ff80fe", "8081ff", "A6A6A6"],
	colorUsage: [],
	sourceUrls: [],
	currentSelectedCalendar: null,
	baseUrl: ''
}

com.atmail.calendar.ACTION = {
	ADD: 1,
	REMOVE: 2,
	COLOR: 4,
	OPTIONS: 8,
	ALL: 1 | 2 | 4 | 8
};

function utcDate(inputDate)
{
	current_local_offset = new Date();
	current_local_offset = current_local_offset.getTimezoneOffset();
	dateUTC = new Date(+inputDate - (current_local_offset * 60 * 1000));
	return dateUTC;
}

function escapeExpression(str) {
    str = str.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "_");
    return str.replace('@', '');
}

function xmlEntitiesDecode(s)
{
	return s.replace(/&apos;/g, "'")
		.replace(/&quot;/g, '"')
		.replace(/&gt;/g, '>')
		.replace(/&lt;/g, '<')
		.replace(/&amp;/g, '&');
}

function generateCalendarHTML(obj)
{
    var calendar_owner = $(obj).attr('calendar_owner');
	var id = $(obj).attr("id");
	var relative_href = $(obj).attr("relative_href");
	var etag = $(obj).attr("etag");
	var name = htmlentities(xmlEntitiesDecode($(obj).attr("name").replace(/\+/g,  " ")));
	var color = $(obj).attr("color");
	var is_selected = ((com.atmail.calendar.currentSelectedCalendar == id) ? " newcalendar_selected\"" : "\"");
	var HTML = 	"<div calendar_owner=\"" + calendar_owner + "\" id=\"" + id + "\" etag=\"" + etag + "\" class=\"calendarListItem " + is_selected + ">" +
					"<span class=\"calendarListItemLabel\" title=\"" + name + ($(obj).attr('mode') == 'read' ? ' ( ' + jsTranslate('Read Only') + ' )' : '') + "\"></span>" +
					'<span class="folder-options" title="Calendar Options">Calendar Options</span>' +
					'<span class="folder-color" title="Calendar Color">Calendar Color</span>' +

					"<div class=\"checkboxHolder\" style=\"left: 10px; top: -10px;\">" + 
						"<div class=\"checkboxBackground\" style=\"background-color: " + color + ";\"></div>" + 
						"<div class=\"checkboxFrame\"></div>" +
						"<div class=\"checkboxTick newcalendar_tick\" checked=\"1\" title=\"" + jsTranslate("Hide Calendar") + "\"></div>" + 
					"</div>" + 
					"<div id=\"totalCountBox\">" + 
						"<table cellpadding=0 cellspacing=0 border=0>" + 
							"<tr>" + 
								"<td id=\"totalCountLeft\">&nbsp;</td>" + 
								"<td id=\"totalCountMiddle\">" + Math.ceil(Math.random() * 200) + "</td>" + 
								"<td id=\"totalCountRight\">&nbsp;</td>" + 
							"</tr>" + 
						"</table>" + 
					"</div>" + 
				
				"</div>";
	
	return HTML;
}

function generateColorID(color)
{
	return color.replace('#', '').toLowerCase();
}

function trackCalendarColorUsage(color, inc)
{
	if(inc == undefined) inc = 1;
	color = generateColorID(color);
	if(com.atmail.calendar.colorUsage[color] == undefined)
	{
		com.atmail.calendar.colorUsage[color] = 0;
	}
	com.atmail.calendar.colorUsage[color] += inc;
}

function generateNewColor()
{
	var NewColor = "ff0000";
	var leastUsedColor = 0;
	var leastUsedColorUsage = undefined;

	for (var x in com.atmail.calendar.colors)
	{
		var usage = com.atmail.calendar.colorUsage[generateColorID(com.atmail.calendar.colors[x])];

		if(usage == undefined)
		{
			usage = 0;
		}
		
		if(leastUsedColorUsage == undefined || usage < leastUsedColorUsage)
		{
			leastUsedColor = x;
			leastUsedColorUsage = usage;
		}
	}
	
	NewColor = com.atmail.calendar.colors[leastUsedColor];
	trackCalendarColorUsage(NewColor);
	
	return NewColor;
}

function setCalendarColor(target_calendar, newCalendarColour)
{
	var relativeHref = null;
	for (var i in calendarCache.cache)
	{
		if (calendarCache.cache[i].id == target_calendar)
		{
			trackCalendarColorUsage(calendarCache.cache[i].color, -1);
			calendarCache.cache[i].color = newCalendarColour;
			trackCalendarColorUsage(newCalendarColour);
			relativeHref = calendarCache.cache[i].relative_href;
			break;
		}
	}

	$("#" + target_calendar, '#Calendar').children(".checkboxHolder").children(".checkboxBackground").css("background-color", newCalendarColour);
	$("#eventList", '#Calendar').children(".eventListItem").each(function()
	{
		if ($(this).data("relative_href") == relativeHref) 
		{
			$(this).children(".checkboxHolder").children(".checkboxBackground").css("background-color", newCalendarColour);
		}
	});
	
	$.ajax(
	{
		async: false,
		type: "POST",
		cache: false,
		url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
		data: {
				'etag' : target_calendar,
				'func' : 'updatecalcolor',
				'relative_href' : relativeHref,
				'color' : newCalendarColour.replace('#', '')
		},
		dataType: "json"
	});	
}

function unbindAction(action_to_disable)
{
	switch( action_to_disable )
	{
		case undefined:
		case 'all':
		{
			unbindAction('today');
			unbindAction('day');
			unbindAction('week');
			unbindAction('month');
			unbindAction('refresh');
			unbindAction('sync');			
		}
		break;
		case 'today':
		{
			$('#action_view_today', '#Calendar').unbind();
		}
		break;
		case 'day':
		{
			$('#action_view_day', '#Calendar').unbind();
		}
		break;
		case 'week':
		{
			$('#action_view_week', '#Calendar').unbind();
		}
		break;
		case 'month':
		{
			$('#action_view_month',  '#Calendar').unbind();
		}
		break;
		case 'refresh':
		{
			$('#action_refresh', '#Calendar').unbind();
		}
		break;
		case 'sync':
		{
			$('#action_view_sync', '#Calendar').unbind();
		}
		break;
	}
}

function updateDefaultView(viewType)
{
	$.php(com.atmail.calendar.baseUrl + "/index.php/mail/settings/calendarsave?fields[CalDavView]=" + viewType + "&save=1");
}

function bindAction(action_to_enable)
{
	switch( action_to_enable )
	{
		case undefined:
		case 'all':
		{
			bindAction('today');
			bindAction('day');
			bindAction('week');
			bindAction('month');
			bindAction('refresh');
			bindAction('sync');
		}
		break;
		case 'today':
		{
			$('#action_view_today', '#Calendar' ).bind('click', function() {return setTodaysDate(todaysDate);} );			
		}
		break;
		case 'day':
		case 'week':
		case 'month':
		{
			$('#action_view_' + action_to_enable, '#Calendar').bind('click', function() {updateDefaultView(action_to_enable);return switchView(action_to_enable);} );
		}
		break;
		case 'refresh':
		{
			$('#action_refresh', '#Calendar').bind('click', function () {refreshCalendars();$("#eventsListBox", '#Calendar').data('quickview').refresh();$("#calendarInside").fullCalendar("refetchEvents");});
		}
		break;
		case 'sync':
		{
			$("#action_view_sync", '#Calendar').bind('click', function(e) {
				e.preventDefault();
				e.stopPropagation();
				openHelp('calendar');
			});
		}
		break;
	}
}

function enableAction( action_to_enable, force, skip_bind )
{
	if(force == undefined)
	{
		force = false;
	}

	if(skip_bind == undefined)
	{
		skip_bind = false;
	}

	if(action_to_enable == undefined)
	{
		action_to_enable = 'all';
	}

	switch( action_to_enable )
	{
		case undefined:
		case 'all':
		{
			enableAction('today');
			enableAction('day');
			enableAction('week');
			enableAction('month');
			enableAction('refresh');
			enableAction('sync');
		}
		break;
		case 'today':
		{
			$('#action_view_today', '#Calendar').enable( function() {} );
		}
		break;
		case 'day':
		{
			$('#action_view_day', '#Calendar').enable( function() {} );
		}
		break;
		case 'week':
		{
			$('#action_view_week', '#Calendar').enable( function() {} );
		}
		break;
		case 'month':
		{
			$('#action_view_month', '#Calendar').enable( function() {} );
		}
		break;
		case 'refresh':
		{
			$('#action_refresh', '#Calendar').enable( function() {} );
		}
		break;
		case 'sync':
		{
			$('#action_view_sync', '#Calendar').enable( function() {} );
		}
		break;
	}

	if(action_to_enable != 'all' && !skip_bind)
	{
		unbindAction( action_to_enable );
		bindAction( action_to_enable );
	}
}

function disableAction ( action_to_disable )
{
	if(action_to_disable == undefined)
	{
		action_to_disable = 'all';
	}

	if(action_to_disable != 'all')
	{
		unbindAction(action_to_disable);
	}

	switch( action_to_disable )
	{
		case undefined:
		case 'all':
		{
			disableAction('today');
			disableAction('day');
			disableAction('week');
			disableAction('month');
			disableAction('refresh');
			disableAction('sync');
		}
		break;
		case 'today':
		{
			$('#action_view_today', '#Calendar').disable();
		}
		break;
		case 'day':
		{
			$('#action_view_day', '#Calendar').disable();
		}
		break;
		case 'week':
		{
			$('#action_view_week', '#Calendar').disable();
		}
		break;
		case 'month':
		{
			$('#action_view_month', '#Calendar').disable();
		}
		break;
		case 'refresh':
		{
			$('#action_refresh', '#Calendar').disable();
		}
		break;
		case 'sync':
		{
			$('#action_view_sync', '#Calendar').disable();
		}
		break;
	}
}

function toggleFolderActions(actions, toggle)
{
	if(actions & com.atmail.calendar.ACTION.ADD)
	{
		if(toggle)
		{
			if($('#folder_add:disabled', '#Calendar'))
			{
				$('#folder_add', '#Calendar').enable(function() {}).unbind().bind('click', function() {newCalendar();});
			}
		}
		else
		{
			$('#folder_add', '#Calendar').disable();			
		}
	}

	if(actions & com.atmail.calendar.ACTION.REMOVE)
	{
		if(toggle)
		{
			if($('#folder_remove:disabled', '#Calendar'))
			{
				$('#folder_remove', '#Calendar').enable(function() {}).unbind().bind('click', function()
				{
					if(!$(this).find("a").is(".disabled") && confirm(jsTranslate("Are you sure you want to delete the calendar?")) )
					{
						removeCalendar();
						$("#eventsListBox", '#Calendar').data('quickview').refresh({refreshAll: true, 'calendarHrefs': calendarCache.getActiveCalendars()});
					}
				});
			}
		}
		else
		{
			$('#folder_remove', '#Calendar').disable();
		}
	}

	if(actions & com.atmail.calendar.ACTION.COLOR)
	{
		if(toggle)
		{
			if($('.folder-color:disabled', '#Calendar'))
			{
				$('.folder-color', '#Calendar').enable(function() {}).unbind().bind('click', function(e) {
					e.stopPropagation();
					return colorCalendar();
				});
			}
		}
		else
		{
			$('.folder-color', '#Calendar').disable();
		}
	}			

	if(actions & com.atmail.calendar.ACTION.OPTIONS)
	{
		if(toggle)
		{
			if($('.folder-options:disabled', '#Calendar'))
			{
				$('.folder-options', '#Calendar').enable(function() {}).unbind().bind('click', function() {return editCalendar();});
			}
		}
		else
		{
			$('.folder-options', '#Calendar').disable();
		}
	}
}

function generateCalendarUUID(xml)
{
	return (unescape(xml.attr("principal_url")) + unescape(xml.attr("relative_href"))).replace(/[^a-z0-9]/gi,'');
}

function generateOwnerUUID(owner)
{
	return unescape(owner).replace(/@/g, '').replace(/\./g, '');
}

function sortCalendars(a,b)
{
	var extraA = '';
	var extraB = '';
	if($(a).attr('calendar_owner') == com.atmail.calendar.owner)
	{
		extraA = '                                                   ';
	}
	if($(a).attr('home'))
	{
		extraA += '                                                   ';
	}
	if($(b).attr('calendar_owner') == com.atmail.calendar.owner)
	{
		extraB = '                                                   ';
	}
	if($(b).attr('home'))
	{
		extraB += '                                                   ';
	}	
	a = extraA + $.trim($(a).attr('calendar_owner') + $(a).attr('name')).toLowerCase();
	b = extraB + $.trim($(b).attr('calendar_owner') + $(b).attr('name')).toLowerCase();
    return ((a == b) ? 0:((a > b) ? 1:-1));  
}

function generateCalendarColor(xml)
{
	var currentCalendarColor = xml.attr('color').replace(/#/g, '');
	var newCalendarColor = currentCalendarColor == '' ? generateNewColor() : currentCalendarColor;

	if(newCalendarColor != currentCalendarColor)
	{
		$.ajax(
		{
			async: true,
			type: "POST",
			cache: false,
			url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
			data: {
				'etag' : xml.attr('etag'),
				'func' : 'updatecalcolor',
				'relative_href' : xml.attr("relative_href"),
				'color' : newCalendarColor
			},
			dataType: "xml"
		});
	}

	return '#' + newCalendarColor;
}

function refreshCalendars(ownerCalendar)
{
	if(ownerCalendar != undefined)
	{
		com.atmail.calendar.owner = ownerCalendar;
	}
	
	$("#primary_content", '#Calendar').attr('blocked', false);	
	
	$.ajax(
	{
		async: false,
		type: "POST",
		url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
		data: {'func' : 'calname'},
		dataType: "xml",
		success: function(xml)
		{
			var currentOwner = '';
			var ownerCount = 1;
			var calendarRefreshResult = calendarCache.refresh($(xml));
			var deletedIds = calendarRefreshResult.deleted;
			var updatedIds = calendarRefreshResult.updated;
			for(var deletedId in deletedIds)
			{
				$('#' + deletedIds[deletedId], '#Calendar').remove();
			}

			var calendars = $(xml).find("CalName").sort(sortCalendars);
			var newOwner = '';
			var clickFirstCalendar = false;
			calendars.each(function()
			{
				var updated = false;
				var attr_id = $(this).attr('id');

				for(var updatedId in updatedIds)
				{
					if(updatedIds[updatedId] == attr_id)
					{
						updated = true;
						break;
					}
				}
				$(this).attr("id", generateCalendarUUID($(this)));
				$(this).attr('color', generateCalendarColor($(this)));

				if(calendarCache.add($(this)) || updated)
				{
					if (!com.atmail.calendar.currentSelectedCalendar)
					{
						com.atmail.calendar.currentSelectedCalendar = $(this).attr("id");
						clickFirstCalendar = true;
					}
					
					newOwner = $(this).attr("calendar_owner");
					var isHome = $(this).attr("home");

					if(currentOwner != newOwner)
					{
						currentOwner = newOwner;
						currentOwnerId = generateOwnerUUID(currentOwner);

						if(!$('#' + currentOwnerId, "#calendarList", '#Calendar').length)
						{
							if(isHome) {
								$("#calendarList", '#Calendar').append("<div class=\"calendarOwnerItem\" style=\"display:none\" id=\"" + currentOwnerId + "\">" + 
										"<span class=\"calendarOwnerItemLabel\">MY CALENDARS</span>" + 
										'<span id="folder_remove" title="Delete current calendar">Delete Current Calendar</span>' +
										'<span id="folder_add" title="Add new calendar">Add New Calendar</span>' +
								"</div>");								
							}
							else {
								$("#calendarList", '#Calendar').append("<div class=\"calendarOwnerItem\" style=\"display:none\" id=\"" + currentOwnerId + "\">" + 
										"<span class=\"calendarOwnerItemLabel\">" + 'SHARED - ' + htmlentities(currentOwner) + "</span>" + 
								"</div>");								
							}


							ownerCount++;
						}
					}
					calendarSelector = displayCalendarFromXML($(this), currentOwnerId);
					if(!updated)
					{
						trackCalendarColorUsage($(this).attr('color'));
						com.atmail.calendar.sourceUrls.push(com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + $(this).attr("relative_href"));
						if(clickFirstCalendar)
						{
							clickFirstCalendar = false;
							calendarSelector.trigger('click');
						}
					}
				}
			});

			if(ownerCount > 1)
			{
				$('.calendarOwnerItem', "#calendarList").show();
			}
			
			if(!com.atmail.calendar.sourceUrls.length)
			{ 
				$("#secondary", '#Calendar').block({message: null, overlayCSS: {backgroundColor: '#000', opacity: .2}});
				$("#actions", '#Calendar').block({message: null, overlayCSS: {backgroundColor: '#000', opacity: .2}});
				$("#primary_content", '#Calendar').block({message: "<div style='position:relative;'>" + jsTranslate("Error while connecting to calendar system.<br>Please reload to try again.") + "</div>", overlayCSS: {backgroundColor: '#000', opacity: .2},
					centerX: true,
					centerY: true,
					css: { 
		            border: 'none', 
		            padding: '15px', 
		            backgroundColor: '#000', 
		            '-webkit-border-radius': '10px', 
		            '-moz-border-radius': '10px', 
		            opacity: .5, 
		            color: '#fff' 
		        }});
				$("#primary_content", '#Calendar').attr('blocked', true);
				disableAction();
			}
			else
			{
				enableAction();	
			}
		}
	});
}

function newCalendar()
{
	var RandomID = new Date();

	var NewColor = generateNewColor();
	
	$.ajax(
	{
		async: false,
		type: "POST",
		cache: false,
		url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
		data: {'calendar_owner': '',
				'color' : "#" + NewColor,
				'description' : '',
				'etag' : RandomID.getTime(),
				'func' : 'mkcal',
				'name' : jsTranslate('Untitled'),
				'order' : ''
		},
		dataType: "xml",
		success: function(xml)
		{
			$(xml).find("calName").each(function()
			{
				$(this).attr("id", generateCalendarUUID($(this)));
				$(this).attr('color', generateCalendarColor($(this)));

				calendarCache.add($(this));
				
				$("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').removeClass('newcalendar_selected');
				$("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').css("background-color", "");

				eventSelector = displayCalendarFromXML($(this), generateOwnerUUID($(this).attr('account')));

				$("#calendarList", '#Calendar').scrollTo(eventSelector);
				$("#calendarInside", '#Calendar').fullCalendar("addEventSource", com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + $(this).attr("relative_href"));
				$("#eventsListBox", '#Calendar').data('quickview').refresh({refreshAll: false, 'calendarHrefs': calendarCache.getActiveCalendars()});

				eventSelector.trigger('click');
				eventSelector.trigger('dblclick');

			});
		}
	});
}

function removeCalendar()
{
	if ($("#calendarList .calendarListItem").length == 1)
	{
		alert(jsTranslate("You must have at least one calendar."));
		return false;
	}

	$("#calendarInside", '#Calendar').fullCalendar("removeEventSource", com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + $("#" + com.atmail.calendar.currentSelectedCalendar).data("relative_href"));

    if($("#" + com.atmail.calendar.currentSelectedCalendar).attr('calendar_owner') != com.atmail.calendar.owner)
    {
        $.ajax(
            {
                async: false,
                type: "POST",
                cache: false,
                url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
                data: {
                    'func' : 'deluser',
                    'mode' : 'write',
                    'username' : $("#" + com.atmail.calendar.currentSelectedCalendar).attr('calendar_owner'),
                    'proxy_username' : com.atmail.calendar.owner,
                    'calendar_url' : $("#" + com.atmail.calendar.currentSelectedCalendar).data("relative_href")
                },
                dataType: "xml"
            });
    }
    else
    {
        $.ajax(
        {
            async: false,
            type: "POST",
            cache: false,
            url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
            data: {
                'etag' : $("#" + com.atmail.calendar.currentSelectedCalendar).attr("id"),
                'func' : 'delcal',
                'relative_href' : $("#" + com.atmail.calendar.currentSelectedCalendar).data("relative_href")
            },
            dataType: "xml"
        });
    }
	trackCalendarColorUsage($("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').data('xml').attr('color'), -1);
	$("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').remove();
	$("#calendarList", '#Calendar').children(".calendarListItem:first").trigger('click');

	return true;
}


function colorCalendar()
{
	if ($("#calendarList", '#Calendar').children().length < 1)
	{
		return false;
	}

	var $button = $('#calendarList>.newcalendar_selected>.folder-color')
	var offset = $button.offset();
	var top = offset.top - 95;

	$("#colourPickerBG", '#Calendar').animate({opacity: "show", top: top}, "fast");

	return true;
}

function editCalendar()
{
	selector = $("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar');
	editCalendarClicked(com.atmail.calendar.baseUrl + "/index.php/mail/calendar/modifypermissions", com.atmail.calendar.currentSelectedCalendar,
		{
			owner: selector.data('owner'),
			principal_path: selector.data('principal_url'),
			server: selector.data('server'),
			relative_href: selector.data('relative_href'),
			calendar_path: selector.data('relative_href'),
			calendar_name: selector.data('name'),
			etag: selector.data('etag'), random:(new Date()).getTime()
		}
	);
}

function setTodaysDate(inputDate)
{
	setDisplayDate(inputDate);
	$("#miniCalendar", '#Calendar').monthCal("setSelectedDate", inputDate);
	$("#monthSelectorBox", '#Calendar').monthSelector("selectMonth", inputDate.getMonth(), true);
	$("#monthSelectorBox", '#Calendar').monthSelector("selectYear", inputDate.getFullYear(), true);
	$("#calendarInside", '#Calendar').fullCalendar("gotoDate", inputDate);
}

function switchView(type)
{
	
	$("#miniCalendar", '#Calendar').monthCal('refresh');

	switch(type)
	{
	case 'day':
	case 'Day':
	{
		$("#datePicker", '#Calendar').removeClass("datePickerWeekView").removeClass("datePickerMonthView").addClass("datePickerDayView");
		$(".mainLayoutLeft", '#Calendar').removeClass("mainLayoutLeftWeekView").removeClass("mainLayoutLeftMonthView").addClass("mainLayoutLeftDayView");
		$(".mainLayoutRight", '#Calendar').removeClass("mainLayoutRightWeekView").removeClass("mainLayoutRightMonthView").addClass("mainLayoutRightDayView");
		$("#calendarPicker", '#Calendar').removeClass("calendarPickerWeekView").removeClass("calendarPickerMonthView").addClass("calendarPickerDayView");
		$(".offset_toolbar", '#Calendar').removeClass("ToolbarMonth").removeClass("ToolbarWeek").addClass("ToolbarDay");

		$("#monthSelectorBox", '#Calendar').monthSelector("makeBig");
		$("#miniCalendar", '#Calendar').monthCal('makeBig');

		$("#displayDate", '#Calendar').show();
		$("#eventsListBox", '#Calendar').show();
		$("#calendarInside", '#Calendar').fullCalendar("changeView", "agendaDay");

		// update the toolbar
		$('#action_view_day', '#Calendar').addClass('enabled');
		$('#action_view_week', '#Calendar').removeClass('enabled');
		$('#action_view_month', '#Calendar').removeClass('enabled');

		$("#eventsListBox", '#Calendar').data('quickview').refresh();

	}break;

	default:
	case 'week':
	case 'Week':
	{
		$("#datePicker", '#Calendar').removeClass("datePickerDayView").removeClass("datePickerMonthView").addClass("datePickerWeekView");
		$(".mainLayoutLeft", '#Calendar').removeClass("mainLayoutLeftDayView").removeClass("mainLayoutLeftMonthView").addClass("mainLayoutLeftWeekView");
		$(".mainLayoutRight", '#Calendar').removeClass("mainLayoutRightDayView").removeClass("mainLayoutRightMonthView").addClass("mainLayoutRightWeekView");
		$("#calendarPicker", '#Calendar').removeClass("calendarPickerDayView").removeClass("calendarPickerMonthView").addClass("calendarPickerWeekView");
		$(".offset_toolbar", '#Calendar').removeClass("ToolbarDay").removeClass("ToolbarMonth").addClass("ToolbarWeek");

		$("#monthSelectorBox", '#Calendar').monthSelector("makeSmall");
		$("#miniCalendar", '#Calendar').monthCal('makeSmall');

		$("#displayDate", '#Calendar').hide();
		$("#eventsListBox", '#Calendar').hide();
		$("#calendarInside", '#Calendar').fullCalendar("changeView", "agendaWeek");

		// update the toolbar
		$('#action_view_day', '#Calendar').removeClass('enabled');
		$('#action_view_week', '#Calendar').addClass('enabled');
		$('#action_view_month', '#Calendar').removeClass('enabled');				
	}break;

	case 'month':
	case 'Month':
	{
		$("#datePicker", '#Calendar').removeClass("datePickerDayView").removeClass("datePickerWeekView").addClass("datePickerMonthView");
		$(".mainLayoutLeft", '#Calendar').removeClass("mainLayoutLeftDayView").removeClass("mainLayoutLeftWeekView").addClass("mainLayoutLeftMonthView");
		$(".mainLayoutRight", '#Calendar').removeClass("mainLayoutRightDayView").removeClass("mainLayoutRightWeekView").addClass("mainLayoutRightMonthView");
		$("#calendarPicker", '#Calendar').removeClass("calendarPickerDayView").removeClass("calendarPickerWeekView").addClass("calendarPickerMonthView");
		$(".offset_toolbar", '#Calendar').removeClass("ToolbarWeek").removeClass("ToolbarDay").addClass("ToolbarMonth");

		$("#monthSelectorBox", '#Calendar').monthSelector("makeBig");
		$("#miniCalendar", '#Calendar').monthCal('makeBig');

		$("#displayDate", '#Calendar').show();
		$("#eventsListBox", '#Calendar').show();
		$("#calendarInside", '#Calendar').fullCalendar("changeView", "month");

		// update the toolbar
		$('#action_view_day', '#Calendar').removeClass('enabled');
		$('#action_view_week', '#Calendar').removeClass('enabled');
		$('#action_view_month', '#Calendar').addClass('enabled');
		$("#eventsListBox", '#Calendar').data('quickview').refresh();
	}break;
	}
}

function myescape(text)
{
	if(encodeURIComponent)
	{
		return encodeURIComponent(text);
	}
	else
	{
		return escape(text);
	}
}


function searchCalendar()
{
	lastTabNumber++
	tabLabel = "Calendar Search";

	var searchOffset 	= $("#search_anything").offset();
	var lastTabOffset 	= $('ul#navMessages li:last').offset();
	var lastTabWidth 	= $('ul#navMessages li:last').width();
	
	// TODO: browser style non-fitting tabs dropdown, currently oldest tab is
	// dropped/removed
	if( (searchOffset.left - lastTabOffset.left - lastTabWidth) < 190 )
		$('div#navMessages').tabs('remove', 1);
	
	$('div#navMessages').tabs('add','#searchResultsTab' + lastTabNumber, tabLabel);
	$('#searchResultsTab' + lastTabNumber).index = 4;
	$('#searchResultsTab' + lastTabNumber).addClass('viewmessageTab');
	$('#searchResultsTab' + lastTabNumber).bind('tabSelected', function() 
	{
		enableMailActions();
	});
	
	$('#searchResultsTab' + lastTabNumber).trigger('tabSelected');
	$('#searchResultsTab' + lastTabNumber).html('<div id="primary_header" class="loading"><h1>' + jsTranslate('Searching...') + '</h1></div>');
	$('#searchResultsTab' + lastTabNumber).load(moduleBaseUrl + '/search/search?searchType=calendar', $('#searchForm').serializeArray(), function() 
	{
		$('#primary_header').each( function()
		{ 	
			$(this).removeClass('loading');
		}); 
	});
	
	return false;
}

var alarmsSet = [];
var qtipdragging = false;

function setAlarm(urlstr, datestr, timestr, daystr, description, timeout, id, href)
{
	// timeout input is in seconds
	// its required to be ms
	timeout = timeout * 1000;
	resetAlarm = false;
	
	if(typeof(alarmsSet) != 'undefined' && typeof(alarmsSet[id]) != 'undefined')
	{
		// reset the alarm if its not displayed
		if(!alarmsSet[id].displayed)
		{
			clearTimeout(alarmsSet[id].timeoutHandle);
			alarmsSet[id].timeoutHandle = 0;
			delete alarmsSet[id];
			resetAlarm = true;
		}
	}
	else
	{
		resetAlarm = true;
	}

	if(!resetAlarm)
	{
		return;
	}

	alarmsSet[id] = {
		displayed: false, 
		timeoutHandle : setTimeout( 
		function()
		{ 
			alarmsSet[id].displayed = true;
			$('#alarmholder').qtip(
			{
				content:
				{
					title:
					{
						text: jsTranslate('Reminder'),
						button: ''
					},
					text: jsTranslate('Loading...'),
					url: urlstr,
					data:
					{
						url: urlstr, 
						description : description,
						time: timestr,
						date: datestr,
						day: daystr,
						overdue: timeout,
						id: id,
						href: href
					}
				},
				show: {ready: true},
				hide: false,
				position:
				{
					target: $(document.body),
					corner: 'center'
				},
				style:
				{
					width: "100%",
					background: "transparent"
				},
				api:
				{
					beforePositionUpdate: function()
					{
						return (qtipdragging == true ? false : true);
					},
					onRender: function()
					{
						$(this).find('.grey-back').css({height: "215px"});
				         // this.elements.tooltip.<span class="highlight"
							// style="padding-left: 0px; padding-right:
							// 0px;">draggable</span>();
						this.elements.tooltip.draggable({
							start: function(){
								qtipdragging = true;
								}
							}
						);
					},
					onHide : function()
					{
						alarmsSet[id].displayed = false;
						this.destroy();
					}
				}
			})
		}, timeout)
	};
}

function ToggleAdvancedRecurrence()
{
	// RepeatAdvancedView

}

function calculateFits(container, element, rect)
{
	var elementOffset = element.offset();
	var elementHeight = element.height();
    var headerHeight = $('div#header').height();
    var elementMiddle = elementOffset.top - headerHeight + (elementHeight / 2);
    elementOffset.top -= headerHeight;

	var qtip_top_offset = 36;

    fits = {
        top : ((elementMiddle - (rect.height / 2)) > 0),
        //topFull : ((elementOffset.top - rect.height) > 0),
        left : ((elementOffset.left - rect.width) > 0),
        right : ((elementOffset.left + rect.width + element.width()) < container.width),
        bottom : ((elementMiddle + (rect.height / 2) - qtip_top_offset ) < container.height),
        //bottomFull : ((elementOffset.top + rect.height - qtip_top_offset) < container.height),
        offset: {x: 0, y: 0}
    };

	if( !fits.left && !fits.right )
	{
		fits.offset.x = rect.width - elementOffset.left;
		fits.left = true;
	}

	if (container.height < rect.height)
	{
		// The popup is larger than the container
        fits.top = false;
        fits.bottom = false;
        //The popup will fit on the screen if header area is used as well
        //fits.offset.y = ((((container.height + headerHeight) / 2) - (elementMiddle + (elementHeight / 2))) - qtip_top_offset);
        fits.offset.y = ((((container.height + headerHeight) / 2) - (elementMiddle)) - qtip_top_offset);
	}
    else if(!fits.bottom && fits.top)
    {
        // Figures out if offset needed, if so what offset
        if ((container.height - elementMiddle) < 40 )
        {
            //If the element runs off the bottom of the screen
            if(fits.left && !fits.right)
            {
                fits.offset.y = container.height - 40 - elementMiddle - 21;
            }
            else
            {
                fits.offset.y = container.height - 40 - elementMiddle - 20;
            }
        }
    }

	return fits;
}


com.atmail.popup = {
	destroy: function()
	{
		if($('#Calendar').data("qtip"))
		{
			$('#Calendar').qtip("destroy");
			// here qtip incorrectly clears the interfaces array and causes js error
			// and then requests interaces.length == undefined which !== 0
			// so, redefine interfaces length to 0
			$.fn.qtip.interfaces = {};
		}
	}
};

function displayPopup(id, relative_href, newtab, domobj)
{
 	com.atmail.popup.destroy();

    var notooltip = false;
	
	var popupSize = {width : 324, height : 462};

	if(newtab == undefined)
	{
		newtab = false;
	}
	
	if(id.indexOf('_') != -1)
	{
		id = id.substring(0, id.indexOf('_'))
	}
	if(domobj.parent().parent().is('.fc-event'))
	{
		domobj = domobj.parent().parent();
	}

	var containerSize = {width: $(window).width(), height: ($(window).height() - $('div#header').height())};
	fits = calculateFits(containerSize, domobj, popupSize);

	var tooltip_position = "rightMiddle";
	var target_position = "leftMiddle";

    if(fits.left && !fits.right)
{
    if(fits.bottom && fits.top)
    {
        //Displayed in middle of screen
        tooltip_position = "rightMiddle";
        target_position = "leftMiddle";
        fits.offset.y += 14;
    }
    else if(!fits.bottom && fits.top)
    {
        //Displayed at bottom of screen
        tooltip_position = "rightBottom";
        target_position = "leftMiddle";
        fits.offset.y += 21;
    }
    else if(fits.bottom && !fits.top)
    {
        //Displayed at top of screen
        tooltip_position = "rightTop";
        target_position = "leftMiddle";
        fits.offset.y -= 11;
    }
    else
    {
        //Doesn't fit on screen, display in middle
        notooltip = true;
        tooltip_position = "rightMiddle";
        target_position = "leftMiddle";
    }
}
    else
    {
        if(fits.bottom && fits.top)
        {
            //Displayed in middle of screen
            tooltip_position = "leftMiddle";
            target_position = "rightMiddle";
            fits.offset.y += 26;
        }
        else if(!fits.bottom && fits.top)
        {
            //Displayed at bottom of screen
            tooltip_position = "leftBottom";
            target_position = "rightMiddle";
            fits.offset.y += 52;
        }
        else if(fits.bottom && !fits.top)
        {
            //Displayed at top of screen
            tooltip_position = "leftTop";
            target_position = "rightMiddle";
            fits.offset.y -= 9;
        }
        else
        {
            //Doesn't fit on screen, display in middle
            notooltip = true;
            tooltip_position = "leftMiddle";
            target_position = "rightMiddle";
        }
    }

	$('#Calendar').qtip(
	{
		content:
		{
			title: false,
			method: "post",
			text: "<div id='loading-text' style='left:43% !important; top:48% !important;'></div>",
			url: moduleBaseUrl + '/calendar/popup/',
			data: {'contextId' : '#calpop', 'id' : id, 'relative_href' : relative_href, 'popup' : true}
		},
		position:
		{
			target: domobj, // Position it via the document body...
			corner:
			{
				tooltip: tooltip_position, // Use the corner...
				target: target_position // ...and opposite corner
			},
			adjust:
			{
				x: fits.offset.x,
				y: fits.offset.y,
				screen: false,
				scroll: false,
				resize: false,
				mouse: false
			}
		},
		show:
		{
			ready: true // Show it
		},
		hide:
		{
			when:
			{
				target: $(document.body).children('header, #Calendar').not( $(self) ).not( $('#ui-datepicker-div') ).not('script'),
				event: 'mousedown scroll mousewheel'
			}
		},
		api:
		{
			onHide: com.atmail.popup.destroy,
			beforeContentLoad: function()
			{
				var elem = this.elements.tooltip.find("#loading-text");
				if(elem.length) elem.sprite(com.atmail.calendar.loadingSpriteSettings);
			},
			onContentLoad: function()
			{
				var elem = this.elements.tooltip.find("#loading-text");
				if(elem.length) elem.destroy().remove();
                if (notooltip)
                {
                    this.elements.tooltip.addClass('notooltip');
                }
			}
		},
		style:
		{
			width: popupSize.width,
			name: 'light',
			tip: true // Give it a speech bubble tip with automatic corner detection
		}
	});
}

function editCalendarClicked(in_url, id, in_data)
{
	messageId = id;

	var i = 1;
	var tabMatch = 0;

	// select message if already opened, else open message in new tab
	$('#navMessages li').each(function(i, e) {

		if ($(this).data('messageId') == messageId) {
			tabMatch = 1;
			$('#navMessages').tabs( 'select', $(this).attr('name') )
			return;
		}
		i++;
	});

	// Need to catch return again, return above only breaks out of the .each
	if (tabMatch == 1) return;

	lastTabNumber = $('div#navMessages').data('lastTabNumber') + 1;
	if(lastTabNumber == undefined)
		lastTabNumber = 0;
	tabLabel = 'Permissions';

	// TODO: maxTabsPossibleInWindow must be determined from the browser width (
	// or emulate FF tabs with the < > to cycle)
	var searchOffset = $("#search_anything").offset();
	var lastTabOffset = $('ul#navMessages li:last').offset();
	var lastTabWidth =  $('ul#navMessages li:last').width();

	// TODO: browser style non-fitting tabs dropdown, currently oldest tab is
	// dropped/removed
// if( (searchOffset.left - lastTabOffset.left - lastTabWidth) < 190 )
// $('div#navMessages').tabs('remove', 1);

	$('div#navMessages').tabs('add','#calendarTab' + lastTabNumber, tabLabel);
	$('#calendarTab' + lastTabNumber).addClass('viewmessageTab');
// $('#calendarTab' + lastTabNumber).html('<div id="primary"
// class="loading"><div class="editEventToolBar" id="toolBar"><h1>Loading ' +
// tabLabel +'...</h1></div></div>');

    // add messageId as data to new tab for checking for duplicates to
	$('li[name=#calendarTab' + lastTabNumber + ']').data('messageId', messageId);
	$('li[name=#calendarTab' + lastTabNumber + ']').data('calendarTab', true);

	$('#calendarTab' + lastTabNumber).load(in_url, in_data);
	$('div#navMessages').data('lastTabNumber', lastTabNumber);
}

var selectedDate = new Date(todaysDate);
var dateExts = [[jsTranslate("Sun"), jsTranslate("Sunday")], [jsTranslate("Mon"), jsTranslate("Monday")], [jsTranslate("Tue"), jsTranslate("Tuesday")], [jsTranslate("Wed"), jsTranslate("Wednesday")], [jsTranslate("Thu"), jsTranslate("Thursday")], [jsTranslate("Fri"), jsTranslate("Friday")], [jsTranslate("Sat"), jsTranslate("Saturday")]];
var monthExts = [[jsTranslate("Jan"), jsTranslate("January")], [jsTranslate("Feb"), jsTranslate("February")], [jsTranslate("Mar"), jsTranslate("March")], [jsTranslate("Apr"), jsTranslate("April")], [jsTranslate("May"), jsTranslate("May")], [jsTranslate("Jun"), jsTranslate("June")], [jsTranslate("Jul"), jsTranslate("July")], [jsTranslate("Aug"), jsTranslate("August")], [jsTranslate("Sep"), jsTranslate("September")], [jsTranslate("Oct"), jsTranslate("October")], [jsTranslate("Nov"), jsTranslate("November")], [jsTranslate("Dec"), jsTranslate("December")]];

Date.prototype.getDayExt = function(Full) {
	return dateExts[this.getDay()][(Full) ? 1 : 0];
};
Date.prototype.getMonthExt = function(Full) {
	return monthExts[this.getMonth()][(Full) ? 1 : 0];
};

Date.prototype.getDaysInMonth = function() {
	var lastDayInMonth = 0;
	var testDate = new Date(this);
	while (this.getMonth() == testDate.getMonth()) {
		lastDayInMonth = testDate.getDate();
		testDate.setDate(testDate.getDate() + 1);
	}
	return lastDayInMonth;
};

Date.prototype.getOrdinalSuffix = function() {
	return (this.getDate() == 1 || this.getDate() == 21 || this.getDate() == 31) ? "st" : ((this.getDate() == 2 || this.getDate() == 22) ? "nd" : ((this.getDate() == 3 || this.getDate() == 23) ? "rd" : "th"));
};

Date.prototype.getLongDate = function() {
	return this.getDayExt(true) + " " + this.getDate() + this.getOrdinalSuffix() + " " + this.getMonthExt(true) + " " + this.getFullYear();
};

function setDisplayDate(date) {
	for (var i = 1; i <= 31; i ++) $("#displayDateImg" , '#Calendar').removeClass("displayDateImg" + i);
	selectedDate = date;
	$("#displayDateImg", '#Calendar').text(date.getDate());
	$("#displayDateText", '#Calendar').empty().append(date.getDayExt(true) + ",&nbsp;" + date.getDate() + "&nbsp;" + date.getMonthExt() + "<br>" + date.getFullYear());
}

function getCalendarData(Field) {
	for (var i in calendarCache.cache) {
		if (calendarCache.cache[i]["id"] == com.atmail.calendar.currentSelectedCalendar)
		{
			return calendarCache.cache[i][Field];
		}
	}
	return false;
}

(function($){
	$.fn.fitText = function( )
	{
		var dom = $(this);
		var currentText = dom.attr('title');
		var domWidth = dom.text(currentText).width();
		var domOffsetLeft = dom.offset().left;
		var domParentWidth = dom.parent().width();
		var domActualWidth = domWidth + domOffsetLeft;

		if( domActualWidth > domParentWidth )
		{
			// we dont fit
			// lets try and calc how many characters actually fit
			var avgPxPerCharacter = domActualWidth / (currentText.length ? currentText.length : 1);
			var totalCharactersAllowed = (domParentWidth - domOffsetLeft) / avgPxPerCharacter;
			dom.text(currentText.slice(0, totalCharactersAllowed) + '...')
		}
		else
		{
			// it fits
			// clear the help text
			dom.attr('title', '');
		}
	}
})(jQuery);

function showColorOptionButton(parent, bShow)
{
	if(bShow) {
		parent.addClass('newcalendar_selected');
	}
	else {
		parent.removeClass('newcalendar_selected');
	}
}

function editCalendarName(jqObj, xml)
{
	showColorOptionButton(jqObj, false);

	var label = jqObj.children(".calendarListItemLabel");
	var OrgLabel = jqObj.children(".calendarListItemLabel").text();
	jqObj.children(":first").replaceWith("<span class=\"calendarListItemLabel\"><input type=\"text\" value=\"" + OrgLabel + "\" style=\"width: 130px; overflow: hidden; border: 1px solid #97a9b6;\"></span>");
	jqObj.children(":first").children(":first").select();
	jqObj.children(":first").children(":first").focus();

	var totalCountNum = jqObj.children(":nth-child(3)").children(":first").children(":first").children(":first").children(":nth-child(2)").text();
	jqObj.children(":nth-child(3)").children(":first").children(":first").children(":first").children(":nth-child(2)").empty();
	jqObj.children(":nth-child(3)").children(":first").children(":first").children(":first").children(":nth-child(2)").append("Apply");

	jqObj.children(":first").children(":first").keypress(function(e) {
		if (e.keyCode == 27) {
			// Esc
			showColorOptionButton(jqObj, true);
			$(this).blur();
		} else if (e.keyCode == 13) {
			// Enter
			showColorOptionButton(jqObj, true);
			$(this).parent().parent().children(":nth-child(3)").click();
		}
	});

	jqObj.children(":first").children(":first").blur(function() 
	{
		$(this).parent().parent().children(":nth-child(3)").click();
	});

	jqObj.children(":nth-child(3)").click(function() {
		$(this).unbind("click");

		var NewLabel = $(this).parent().children(":first").children(":first").attr("value");
		$(this).parent().children(":first").replaceWith("<span class=\"calendarListItemLabel\" title=\"" + htmlentities(NewLabel) + ($(this).attr('mode') == 'read' ? ' ( ' + jsTranslate('Read Only') + ' )' : '') + "\"></span>");
		$(this).parent().children("span:first").fitText();
		$.ajax({
			async: false,
			type: "POST",
			cache: false,
			url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
			data: { 
				'etag' : xml.attr("etag"),
				'func' : 'updatecalname',
				'relative_href' : xml.attr("relative_href"),
				'title' : NewLabel
			},
			dataType: "xml"
		});
	});
	
}

function timezoneDone( result )
{
	if(result == 0)
	{
		$('a', '#nav_set').attr('scrollTZ', true);
		$('a', '#nav_set').trigger('click');
	}
}

function timezoneIncorrectDisplay(current_tz, new_tz)
{
	var html = '<span>' + jsTranslate('Your current timezone does not match your webmail timezone.<br>Would you like to go to your timezone settings?') + '</span>';
	$.simpleFlash(html, "notice", true, new Array('Yes', 'No'), "timezoneDone");	
}

function eventResizeDrop(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view)
{	
	startDateUTC = utcDate(event.start);
	endDateUTC = (event.end ? utcDate(event.end) : null);

	var postData = 
	{ 	
		func 		: 'updatecal',		
		id 			: event.id,
		json		: 1,
		ajax		: 1,
		relative_href : event.relative_href,
		DateStart	: Math.round(startDateUTC.getTime() / 1000),
		DateEnd		: (event.end ? Math.round(endDateUTC.getTime() / 1000) : null)
	};

	if(postData['DateEnd'] == null)
	{
		delete postData['DateEnd'];
	}

	$.ajax(
	{
		async: false,
		cache: false,
		type: "POST",
		url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
		dataType: "json",
		data: postData,
		success: function(json)
		{
			$("#calendarInside", '#Calendar').fullCalendar("refetchEvents");
		}
	});
}

var current_Tz = 0;

function displayCalendarFromXML(xml, owner)
{
	var html = generateCalendarHTML(xml);
	var calendarList = $("#calendarList", '#Calendar');
	calendars = calendarList.find('.calendarOwnerItem, .calendarListItem');
	calendarsTotal = calendars.length;
	ownerCalendarIndex = calendars.index(calendarList.find('#' + owner));
	currentCalendarSelector = calendarList.find("#" + xml.attr('id'));
	if(!currentCalendarSelector.length)
	{
		insertPosition = ownerCalendarIndex;
		for(a=ownerCalendarIndex+1;a<calendarsTotal;a++)
		{
			testCalendar = calendars.eq(a);
			if(testCalendar != undefined)
			{
				if(testCalendar.hasClass('calendarOwnerItem'))
				{
					break;
				}
				else
				{
					insertPosition = a;
				}
			}
		}
		calendars.eq(insertPosition).after(html);
	}
	else
	{
		// calendar already populated, so lets replaceWith
		currentCalendarSelector.replaceWith(html);
	}

	var newCalendarSelector = $("#" + xml.attr("id"), "#calendarList", '#Calendar');
	// adjust naming
	newCalendarSelector.find('span:first').fitText();
	newCalendarSelector.data("xml", xml);
	newCalendarSelector.data("mode", xml.attr('mode'));
	newCalendarSelector.data("name", xml.attr("name"));
	newCalendarSelector.data("principal_url", xml.attr("principal_url"));
	newCalendarSelector.data("relative_href", xml.attr("relative_href"));
	newCalendarSelector.data("server",  xml.attr("server"));
	newCalendarSelector.data("home",  xml.attr("home"));
	newCalendarSelector.data("owner", xml.attr('calendar_owner'));
	if(xml.attr('mode') != 'read')
	{
		newCalendarSelector.mouseover(function()
		{
			if ($(this).attr("id") != com.atmail.calendar.currentSelectedCalendar)
			{
				$(this).css("background-color", "#ced6e0");
			}
		});
		newCalendarSelector.mouseout(function()
		{
			if ($(this).attr("id") != com.atmail.calendar.currentSelectedCalendar)
			{
				$(this).css("background-color", "");
			}
		});
	
		newCalendarSelector.click(function()
		{
			if($(this).attr("id") != com.atmail.calendar.currentSelectedCalendar)
			{
				$("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').removeClass('newcalendar_selected');
				$("#" + com.atmail.calendar.currentSelectedCalendar, '#Calendar').css("background-color", "");
				$(this).addClass('newcalendar_selected');
				com.atmail.calendar.currentSelectedCalendar = $(this).attr("id");
			}
			
			if($(this).data('home'))
			{
				toggleFolderActions(com.atmail.calendar.ACTION.REMOVE, false);
				toggleFolderActions(com.atmail.calendar.ACTION.ADD | com.atmail.calendar.ACTION.OPTIONS | com.atmail.calendar.ACTION.COLOR, true);
			}
			else
			{
				toggleFolderActions(com.atmail.calendar.ACTION.ALL, true);
			}
		});

		newCalendarSelector.dblclick(function()
		{
			var xmldata = $(this).data('xml');
			editCalendarName($(this), xmldata);
		});
	}
	else
	{
		newCalendarSelector.css("cursor", "default");
		newCalendarSelector.children('.calendarListItemLabel').css("cursor", "default");
		newCalendarSelector.children('.checkboxFrame').css("cursor", "pointer");
	}

	newCalendarSelector.children(".checkboxHolder").children(".checkboxTick").click(function() {
		relative_href = $(this).parent().parent().data("relative_href");
		if ($(this).attr("checked") == 1)
		{
			calendarCache.toggle($(this).parent().parent().attr('id'), false);
			$("#calendarInside", '#Calendar').fullCalendar("removeEventSource", com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + relative_href);
			$(this).removeClass('newcalendar_tick');
			$(this).attr("checked", 0);
			$(this).attr("title", "Show Calendar");
			$("#eventsListBox", '#Calendar').data('quickview').remove({'relativeHref': relative_href});
		}
		else
		{
			calendarCache.toggle($(this).parent().parent().attr('id'), true);
			$("#calendarInside", '#Calendar').fullCalendar("addEventSource", com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + relative_href);
			$(this).addClass('newcalendar_tick');
			$(this).attr("checked", 1);
			$(this).attr("title", "Hide Calendar");
			$("#eventsListBox", '#Calendar').data('quickview').refresh({'refreshAll':true, 'calendarHrefs': calendarCache.getActiveCalendars()});
		}
	});
	
	return newCalendarSelector;
}

function startCalendar(in_url, default_view, defTZ, ownerUsername) {
	com.atmail.calendar.baseUrl = in_url;
	current_Tz = defTZ;
	
    if(com.atmail.calendar.baseUrl[com.atmail.calendar.baseUrl.length - 1] == '/')
    {
            com.atmail.calendar.baseUrl = com.atmail.calendar.baseUrl.substr(0, com.atmail.calendar.baseUrl.length - 1);
    }


	setDisplayDate(todaysDate);
	var smallRequired = (default_view == 'Week' ? true : false);
	$("#monthSelectorBox", '#Calendar').monthSelector({
		small: smallRequired,
		calendarSelector: function(year, month, day) {
			$("#miniCalendar", '#Calendar').monthCal("changeDate", year, month, day);
		}
	});
	
	refreshCalendars(ownerUsername);		
	$("#eventsListBox", '#Calendar').quickview({'calendarHrefs': calendarCache.getActiveCalendars(), 'timezone': current_Tz});

	$("#colourPickerBG", '#Calendar').click(function() {
		$(this).animate({opacity: "hide", bottom: "20px"}, "fast");
	});

	$("#colourPickerItem", "#colourPickerBG", '#Calendar').each(function() {
		$(this).hover(function() {
			$(this).css("background-image", "url(../images/calendar/colour_picker_item_bg.png)");
		}, function() {
			$(this).css("background-image", "");
		});

		$(this).click(function() {
			setCalendarColor(com.atmail.calendar.currentSelectedCalendar, $(this).attr('color'));
			$("#calendarInside", '#Calendar').fullCalendar("refetchEvents");
		});
	});

	var miniCalOverviewData = {};
	$("#miniCalendar", '#Calendar').monthCal({
		showDate: new Date(todaysDate),
		size: (smallRequired ? 210 : 285),
		small: smallRequired,
		smallText: smallRequired,
		select: function(date) {
			setDisplayDate(date);
			$("#monthSelectorBox", '#Calendar').monthSelector("selectMonth", date.getMonth(), true);
			$("#monthSelectorBox", '#Calendar').monthSelector("selectYear", date.getFullYear(), true);
			$("#datePicker", '#Calendar').css("border-left", "1px dashed #97a9b6");
			$("#calendarInside", '#Calendar').fullCalendar("gotoDate", date);
		},
		monthRender: function(date) {
			var calendarHrefs = [];
			for (var i in calendarCache.cache) calendarHrefs.push(calendarCache.cache[i].relative_href);

			var startDate = new Date(date);
			startDate.setDate(1);
			startDate.setMonth(startDate.getMonth() - 1);
			utcStartDate = utcDate(startDate);

			var endDate = new Date(date);
			endDate.setDate(endDate.getDaysInMonth());
			endDate.setMonth(endDate.getMonth() + 1);
			utcEndDate = utcDate(endDate);

			$.ajax({
				async: true,
				type: "POST",
				url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
				data:
				{
					'ajax' : 1,
					'func' : 'overview',
					'json' : 1,
					'calendarhref' : calendarHrefs.join(),
					'start' : Math.round(utcStartDate.getTime() / 1000),
					'end' : Math.round(utcEndDate.getTime() / 1000)
				},
				dataType: "json",
				success: function(json) {
					$("#miniCalendar").monthCal("clearEventHints");
					for (var i in json) $("#miniCalendar").monthCal("setEventHint", new Date(i.split("-")[2], parseFloat(i.split("-")[1]) - 1, i.split("-")[0]), parseFloat(json[i]));
					$("#miniCalendar", '#Calendar').monthCal("renderEventHints");
				}
			});
		}
	});

	var calFirstLoad = false;
	
	var userDefaultView = "agendaWeek";

	if(default_view == 'Day')
	{
		userDefaultView = "agendaDay";
	}
	else if (default_view == 'Week')
	{
		userDefaultView = "agendaWeek";
	}
	else if (default_view == 'Month')
	{
		userDefaultView = "month";
	}
	
	$("#calendarInside", '#Calendar').fullCalendar({
		header: false,
		editable: true,
		allDayDefault: false,
		ignoreTimezone: false,
		defaultTimezone: defTZ,
		year: todaysDate.getFullYear(),
		month: todaysDate.getMonth(),
		date: todaysDate.getDate(),
		defaultView: userDefaultView,
		eventSources: com.atmail.calendar.sourceUrls,
		selectable: true,
		selectHelper: function(startDate, endDate) {
			if(getCalendarData('mode') == 'read') return true;
			return $("<div style=\"background-color: " + getCalendarData("color") + "; opacity: .2; filter: alpha(opacity=20);\">&nbsp;</div>");
		},
        contentHeight: document.body.clientHeight - 94,
		unselectAuto: true,
		select: function(startDate, endDate, allDay, view)
		{
			if(getCalendarData('mode') == 'read') return true;
			// convert dates to utc first
			// on new event we dont honour deafult timezone atm, fix me
			current_local_offset = new Date();
			current_local_offset = current_local_offset.getTimezoneOffset();
			startDateUTC = new Date(+startDate - (current_local_offset * 60 * 1000));
			endDateUTC = new Date(+endDate - (current_local_offset * 60 * 1000));
			$.ajax({
				async: false,
				type: "POST",
				url: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue",
				dataType: "json",
				data:
				{
					'func' : 'add',
					'json' : 1,
					'ajax' : 1,
					'relative_href' : getCalendarData("relative_href"),
					'Location' : '',
					'Msg_Text' : '',
					'Msg_Title' : jsTranslate('New Event'),
					'Msg_Type' : jsTranslate('General'), 
					'appmode' : jsTranslate('Private'),
					'startDate' : Math.round(startDateUTC.getTime() / 1000),
					'endDate' : Math.round(endDateUTC.getTime() / 1000),
					'AllDayEvent' : ((allDay) ? 1 : "")
				},
				success: function(json)
				{
					if(json.status != 201)
					{
						$("#calendarInside", '#Calendar').fullCalendar("unselect");
						$.simpleFlash(jsTranslate("An error occured creating the event."), 'error');
						return;
					}

					$("#miniCalendar", '#Calendar').monthCal("addEventHint", startDateUTC, 1);
					$("#miniCalendar", '#Calendar').monthCal("renderEventHints");
					$("#calendarInside", '#Calendar').fullCalendar("unselect");
					$("#calendarInside", '#Calendar').fullCalendar("renderEvent",
					{
						id: json["id"],
						title: jsTranslate("New Event"),
						start: Math.round(startDate.getTime() / 1000),
						end: Math.round(endDate.getTime() / 1000),
						"allDay": allDay,
						color: getCalendarData("color"),
						relative_href: getCalendarData("relative_href"),
						source: com.atmail.calendar.baseUrl + "/index.php/mail/calendar/caldavglue?ajax=1&func=ajaxcal&json=1&calendarhref=" + getCalendarData("relative_href")
					});
					$("#eventsListBox", '#Calendar').data('quickview').refresh({refreshAll: true});
				}
			});
			return false;
		},
		eventClick: function(calEvent, jsEvent, view) {
			var jqTarget = jQuery(jsEvent.target);
			if($('.fc-agenda-body', "#calendarInside", '#Calendar').length)
			{
				$('.fc-agenda-body', "#calendarInside", '#Calendar').scrollTo(
					jqTarget, 
					{
						duration : 300,
						offset : 
						{ 
							left: 0, 
							top: (-1 * (($('.fc-view').height() / 2.0) - (jqTarget.height() / 2.0)))
						}, 
						onAfter : function()
						{
							try
							{
								displayPopup(calEvent.id, calEvent.relative_href, false, jqTarget);
							}
							catch(err)
							{
							}
						}
					}
				);
			}
			else
			{
				displayPopup(calEvent.id, calEvent.relative_href, false, jqTarget);
			}
		},
		eventRender: function(event, element) {
			$(element).children("a").children(".fc-event-time").hide();
		},
		eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view)
		{
			result = eventResizeDrop(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view);
			if(event.id.indexOf("_") != 1)
			{
				$("#eventsListBox", '#Calendar').data('quickview').refresh({refreshAll: true, fetchTotal: true});
			}
			return result;
		},
		eventResize: function(event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view)
		{
			return eventResizeDrop(event, dayDelta, minuteDelta, null, revertFunc, jsEvent, ui, view);
		},
		loading: function(bool) {
			$("#loading-text", "#calendarInside", '#Calendar').destroy();
			$("#loading-text", "#calendarInside", '#Calendar').remove();
			if (bool) {
					if(!$("#primary_content", '#Calendar').attr('blocked'))
					{
						$("#calendarInside", '#Calendar').block({message: "<div id='loading-text'><span class='loading'></span></div>", overlayCSS: {backgroundColor: 'transparent', opacity: 0.4}, css: {backgroundColor: 'transparent',color: '#575757',border: '0'}});
					}
					$('#loading-text', "#calendarInside", '#Calendar').sprite(com.atmail.calendar.loadingSpriteSettings);
			}
			else
			{
					if(!$("#primary_content", '#Calendar').attr('blocked'))
					{
						$("#calendarInside", '#Calendar').unblock();
						if (!calFirstLoad)
						{
							$(".fc-agenda-body", "#calendarInside", '#Calendar').scrollTo($("tr:eq(18)", ".fc-agenda-body", "#calendarInside"), {duration: 'normal'});
							calFirstLoad = true;
						}
					}

			}
		},
	    windowResize: function(view)
	    {
				com.atmail.popup.destroy();
				$("#calendar").fullCalendar("option", "contentHeight", document.body.clientHeight - 72);
				$("#calendarInside").children(":first").children(":first").children(":nth-child(2)").css("height", (document.body.clientHeight - 123) + "px");
	    }
	});
	switchView(default_view);
}


function parseDate(s, ignoreTimezone, defaultTimezone)
{
	// ignoreTimezone defaults to true
	if (typeof s == 'object')
	{ 
		// already a Date object
		return s;
	}
	if (typeof s == 'number')
	{
		// a UNIX timestamp
		return new Date(s * 1000);
	}
	if (typeof s == 'string')
	{
		if (s.match(/^\d+$/))
		{
			// a UNIX timestamp
			return new Date(parseInt(s) * 1000);
		}
		if (ignoreTimezone === undefined)
		{
			ignoreTimezone = true;
		}

		return parseISO8601(s, ignoreTimezone, defaultTimezone) || (s ? new Date(s) : null);
	}
	// TODO: never return invalid dates (like from new Date(<string>)), return
	// null instead
	return null;
}


function parseISO8601(s, ignoreTimezone, defaultTimezone) { // ignoreTimezone
															// defaults to false
	// derived from http://delete.me.uk/2005/03/iso8601.html
	// TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html
	var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/);

	if (!m) {
		return null;
	}

	if(parseInt(defaultTimezone) >= 0)
	{
		sign = '+';
		defaultTimezoneStr = defaultTimezone;
	}
	else
	{
		sign = '-';
		defaultTimezoneStr = parseInt(defaultTimezone) * -1;
		defaultTimezoneStr = defaultTimezoneStr.toString();
	}
	if(defaultTimezoneStr.indexOf('.') != -1)
	{
		var temp = defaultTimezoneStr.split('.');
		temp[1] = Math.round(parseInt(temp[1]) * 60.0);
		defaultTimezoneStr = (temp[0].length == 1 ? ('0' + temp[0]) : temp[0]) + ":" + (temp[1].length == 1 ? ('0' + temp[1]) : temp[1]);
	}
	else
	{
		defaultTimezoneStr = (defaultTimezoneStr.length == 1 ? ('0' + defaultTimezoneStr) : defaultTimezoneStr) + ":00";
	}

	if (ignoreTimezone || !m[14]) {
		s += sign + defaultTimezoneStr;
		m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/);
		if (!m) {
			return null;
		}
	}

	var date = new Date(m[1], 0, 1);
	if (ignoreTimezone || !m[14]) {
		var check = new Date(m[1], 0, 1, 9, 0);
		if (m[3]) {
			date.setUTCMonth(m[3] - 1);
			check.setUTCMonth(m[3] - 1);
		}
		if (m[5]) {
			date.setUTCDate(m[5]);
			check.setUTCDate(m[5]);
		}
		fixDate(date, check);
		if (m[7]) {
			date.setUTCHours(m[7]);
		}
		if (m[8]) {
			date.setUTCMinutes(m[8]);
		}
		if (m[10]) {
			date.setUTCSeconds(m[10]);
		}
		if (m[12]) {
			date.setUTCMilliseconds(Number("0." + m[12]) * 1000);
		}
		fixDate(date, check);
	}else{
		date.setUTCFullYear(
			m[1],
			m[3] ? m[3] - 1 : 0,
			m[5] || 1
		);
		date.setUTCHours(
			m[7] || 0,
			m[8] || 0,
			m[10] || 0,
			m[12] ? Number("0." + m[12]) * 1000 : 0
		);
		var offset = Number(m[16]) * 60 + Number(m[17]);
		offset *= m[15] == '-' ? 1 : -1;
		current_local_offset = new Date();
		current_local_offset = current_local_offset.getTimezoneOffset();
		date = new Date(+date + ((offset + (current_local_offset + (parseInt(defaultTimezone) * 60)))* 60 * 1000));
	}
	return date;
}
