function calCallbackDbResult(res, cal) {
	cal.schedule = res;
	cal.dbDone = true;
	if(cal.dbDone && cal.cellsDone)
		calFillCalWithSchedule(cal);
}

function calFillCalWithSchedule(calTbl) {
	var today = new Date();
	var numberOfDaysWithEvents = calTbl.schedule.length;

	if(typeof(calTbl.divContainer.eventList) != "undefined")
		var evList = calTbl.divContainer.eventList;
	if(evList) {
		evList = document.getElementById(evList);
		if(evList)
			evList.innerHTML = "";
	}


		var days_with_events = calTbl.schedule;
		for(var i = 0; i < numberOfDaysWithEvents; i++)
			days_with_events[i].datum = calDecodeDate(days_with_events[i].datum);

		var start_day_index = 0;			//erster tag ist evtl ausserhalb des angezeigten kalenders, deswegen vllt nicht bei 0 anfangen...
		var all_days_have_been_set = true;	//flag wird gebraucht um die loop nicht abbrechen zu müssen wenn alle tage gesetzt wurden
		if(days_with_events.length > 0){		//ansonsten würde der aktuelle tag evtl nicht markiert werden, da vorher abgebrochen wurde
			while((days_with_events[start_day_index].datum.month < calTbl.divContainer.month) &&
					(days_with_events[start_day_index].datum.day < calTbl.cCells[0].day))
			{
				start_day_index++;
				if(days_with_events[start_day_index] == undefined)
				{
				  start_day_index--;
				  break;
				}
			}
			all_days_have_been_set = false;
		}

		var i_currentDayIndex = start_day_index;

		for(var i_currentCellIndex = 0; i_currentCellIndex < 42; i_currentCellIndex++) {
			var cell = calTbl.cCells[i_currentCellIndex];
			var isEventDay = false;
			calTbl.divContainer.curDay = cell.day;
			calTbl.divContainer.curMonth = cell.month;
			calTbl.divContainer.curYear = cell.year;
			
			if(all_days_have_been_set == false)
			//############################ Event Clicks ######################################
			if((parseInt(cell.day) == days_with_events[i_currentDayIndex].datum.day) && (parseInt(cell.month) == days_with_events[i_currentDayIndex].datum.month) && (parseInt(cell.year) == days_with_events[i_currentDayIndex].datum.year)) {
				isEventDay = true;
				//++++++++++++++++++++++++++++ overlay container +++++++++++++++++++++++++++++++++
					var overlay_div = calGetOverlayEventContainer(calTbl.divContainer);
				//++++++++++++++++++++++++++++ loop through events ++++++++++++++++++++++++++++++++
					var class_collection = new Array();
					var overlay_collection = new Array();
					for(var i_eventIndex = 0; i_eventIndex < days_with_events[i_currentDayIndex].events.length; i_eventIndex++){
						var thisEventColor = "#000000";	//startwert
						var thisType = "";
						var typeFlag = days_with_events[i_currentDayIndex].events[i_eventIndex].flags & 3;
						var siblingstring = "";
						if(typeFlag == 0) {
							cell.obj.className += " cSingleDayEvent";
							class_collection.push(String(".cSingleDayEvent"));
							thisEventColor = calGetBackground(".cSingleDayEvent");
							days_with_events[i_currentDayIndex].events[i_eventIndex].typestring = "einmalig";
						} else if(typeFlag == 1) {
							cell.obj.className += " cFloatingEvent";
							class_collection.push(String(".cFloatingEvent"));
							thisEventColor = calGetBackground(".cFloatingEvent");
							days_with_events[i_currentDayIndex].events[i_eventIndex].typestring = "fortlaufend";
							siblingstring = calCreateSiblingDurationString(days_with_events[i_currentDayIndex].events[i_eventIndex].siblings);
						} else if(typeFlag >= 2) {
							cell.obj.className += " cRepeatingEvent";
							class_collection.push(String(".cRepeatingEvent"));
							thisEventColor = calGetBackground(".cRepeatingEvent");
							days_with_events[i_currentDayIndex].events[i_eventIndex].typestring = "mehrmalig";
							siblingstring = calCreateSiblingListString(days_with_events[i_currentDayIndex].events[i_eventIndex].siblings);
						}
							if(siblingstring != "")
								days_with_events[i_currentDayIndex].events[i_eventIndex].siblingstring = siblingstring;

							days_with_events[i_currentDayIndex].events[i_eventIndex].eventcolor = thisEventColor;

						if(!cell.obj.className.match("cUnimportant")){
							var singleEventOverlay = calGetOverlayEventTemplate(calTbl.divContainer);
							//alert(dump(days_with_events[i_currentDayIndex].events[i_eventIndex]));
							for (var keyword in days_with_events[i_currentDayIndex].events[i_eventIndex]) {
								var foundAt = singleEventOverlay.search("%%"+keyword+"%%");
								var i_foundAtOffset = 0;
								if(singleEventOverlay.substr(foundAt-2, 2) == "}}"){
									singleEventOverlay = singleEventOverlay.substring(0,foundAt-2)+singleEventOverlay.substring(foundAt);
									while((i_foundAtOffset >= 0) && (singleEventOverlay.substr(foundAt-i_foundAtOffset, 2) != "{{"))
										i_foundAtOffset++;
									if(i_foundAtOffset > 0)
									singleEventOverlay = singleEventOverlay.substring(0,foundAt-i_foundAtOffset)+singleEventOverlay.substring(foundAt-i_foundAtOffset+2);
								}
								if(singleEventOverlay.substr(foundAt+keyword.length, 2) == "{{"){
									i_foundAtOffset = 0;
									singleEventOverlay = singleEventOverlay.substring(0,foundAt+keyword.length)+singleEventOverlay.substring(foundAt+keyword.length+2);
									while((i_foundAtOffset <= singleEventOverlay.length) && (singleEventOverlay.substr(foundAt+i_foundAtOffset, 2) != "}}"))
										i_foundAtOffset++;
									singleEventOverlay = singleEventOverlay.substring(0,foundAt+i_foundAtOffset)+singleEventOverlay.substring(foundAt+i_foundAtOffset+2);
								}

								singleEventOverlay = singleEventOverlay.replace(new RegExp("%%"+keyword+"%%", 'g'), days_with_events[i_currentDayIndex].events[i_eventIndex][keyword]);
							}

							singleEventOverlay = singleEventOverlay.replace(/%%[^%]*%%/g, "");
							singleEventOverlay = singleEventOverlay.replace(/{{[^{^}]*}}/g, "");
							overlay_collection.push(singleEventOverlay);
						}
					}
				//++++++++++++++++++++++++++ create overlay from collection ++++++++++++++++++++++++++++++
					var alldivs = overlay_div.getElementsByTagName("td");
					var containerev = null;
					for(var i = 0; i < alldivs.length; i++){
						if(alldivs[i].getAttribute("class") == "coOverlayContainerEvents"){
							containerev = alldivs[i];
							break;
						}
					}
					if(containerev != null){
						containerev.innerHTML = overlay_collection.join("");
						if(calTbl.divContainer.admin){
							containerev.onDelete = calTbl.divContainer.onDelete;
							containerev.onEdit = calTbl.divContainer.onEdit;
						}
					}
					var containerdate = null;
					for(var i = 0; i < alldivs.length; i++){
						if(alldivs[i].getAttribute("class") == "coOverlayContainerDate"){
							containerdate = alldivs[i];
							break;
						}
					}
					if(containerdate != null) containerdate.innerHTML = cell.day + "." + cell.month + "." + cell.year;
				//++++++++++++++++++++++++++++++++++++ cell color ++++++++++++++++++++++++++++++++++++++++
					var mixed_background_color = calMixBackground(class_collection);
					//alert(mixed_background_color);
					cell.obj.style.background = mixed_background_color;
					if(cell.obj.className.match("cUnimportant")){	//tage die schon zum nach- bzw noch zum vormonat gehören
						var blurColor = calGetCssRule(".cEventBlur").style.backgroundColor.toUpperCase();
						if(blurColor.match("RGB")) {
							var arrayColor = blurColor.slice(4).replace(")","").replace(/ /g, "").split(",");
							blurColor = "#";
							for(var r = 0; r < arrayColor.length; r++)
								blurColor += myIntToHex(arrayColor[r]);
							/*blurColor = blurColor.replace(")","");
							blurColor = blurColor.replace(/ /g, "");
							blurColor = blurColor.split(",");
							blurColor = "#"+blurColor.join("");*/
						}
						cell.obj.style.background = calMixColors(mixed_background_color, blurColor, blurColor);
					}
					else {
				//+++++++++++++++++++++++++++++++++++ cell events ++++++++++++++++++++++++++++++++++++++++
						cell.obj.overlayContent = overlay_div;
						cell.obj.onmouseover = function(e){Overlay({event:e, content:this.overlayContent, followMouse: true, closeOthers: true,
									left:20, top:20, vertical_align: calTbl.divContainer.overlayVerticalAlign,
									horizontal_align: calTbl.divContainer.overlayHorizontalAlign, overlay_delay: calTbl.divContainer.overlayDelay,
									overlay_fade: calTbl.divContainer.overlayFade, overlay_fade_speed: calTbl.divContainer.overlayFadeSpeed, isDom:true});};
						cell.obj.onmouseout = function(){Overlay_CloseAll();};
				//+++++++++++++++++++++++++++++++++++ cell onclick? ++++++++++++++++++++++++++++++++++++++
						if(typeof(calTbl.divContainer.onEventClick) == "undefined")
							calTbl.divContainer.onEventClick = "none";
						//++++++++++++++++++++++++++++++ static overlay ++++++++++++++++++++++++++++++++++
						else if(calTbl.divContainer.onEventClick == "static") {
							cell.obj.onclick = function(e){
												var outBak = this.onmouseout;
												this.onmouseout = null;
												var cell = this;
												var o = Overlay(
													{
														event:e, content:this.overlayContent,
														followMouse: false,
														mousePos: true,
														closeOthers: true,
														left:-20, top:-20,
														//vertical_align: calTbl.divContainer.overlayVerticalAlign,
														//horizontal_align: calTbl.divContainer.overlayHorizontalAlign,
														vertical_align: calTbl.divContainer.onEventClickStaticVerticalAlign,
														horizontal_align: calTbl.divContainer.onEventClickStaticHorizontalAlign,
														overlay_delay: calTbl.divContainer.overlayDelay,
														overlay_fade: calTbl.divContainer.overlayFade,
														overlay_fade_speed: calTbl.divContainer.overlayFadeSpeed,
														overlay_close_onclick: true,
														overlay_close_timeout: 2000,
														overlay_close_callback: function(olay){olay.cell.onmouseout = olay.outBak;},
														isDom: true
													});
												o.cell = cell;
												o.outBak = outBak;
												//o.onclick = function(e){ Overlay_CloseAll(); cell.onmouseout = outBak;};
											};
						}
						//++++++++++++++++++++++++++++ nothing happens +++++++++++++++++++++++++++++++++
						else if(calTbl.divContainer.onEventClick == "none")
							cell.obj.onclick = null;
						//++++++++++++++++++++++++++++ fire a function +++++++++++++++++++++++++++++++++
						else if(typeof(calTbl.divContainer.onEventClick) == "function")
								cell.obj.onclick = calTbl.divContainer.onEventClick;
						//++++++++++++++++++++++++++++++++ do post +++++++++++++++++++++++++++++++++++++
						else {	//calTbl.divContainer.onEventClick ist die url
							var form = document.createElement("form");
							form.action = calTbl.divContainer.onEventClick;
							form.style.display = "none";
							form.method = "post";
							if(typeof(calTbl.divContainer.onEventClickNewWindow) == "undefined")
								calTbl.divContainer.onEventClickNewWindow = false;
							if(calTbl.divContainer.onEventClickNewWindow == false)
								form.target = "_self";
							else if(calTbl.divContainer.onEventClickNewWindow == true)
								form.target = "_blank";

							if(calTbl.divContainer.onEventClickPostEnable){
								if(calTbl.divContainer.onEventClickPostYear != "none"){
									var forminp = document.createElement("input");
									forminp.setAttribute("type", "text");
									forminp.name = calTbl.divContainer.onEventClickPostYear;
									forminp.value = cell.year;
									form.appendChild(forminp);null
								}
								if(calTbl.divContainer.onEventClickPostMonth != "none"){
									var forminp = document.createElement("input");
									forminp.setAttribute("type", "text");
									forminp.name = calTbl.divContainer.onEventClickPostMonth;
									forminp.value = cell.month;
									form.appendChild(forminp);
								}
								if(calTbl.divContainer.onEventClickPostDay != "none"){
									var forminp = document.createElement("input");
									forminp.setAttribute("type", "text");
									forminp.name = calTbl.divContainer.onEventClickPostDay;
									forminp.value = cell.day;
									form.appendChild(forminp);
								}
							}
							cell.obj.onclick = function(){document.body.appendChild(form); form.submit();};
						}
				//+++++++++++++++++++++++++++++++++++ fill event list ++++++++++++++++++++++++++++++++++++++
						if(evList){
							//evList.innerHTML += "<div class='clDayContainer'><div class='clDayRuler'>"+cell.day + "." + cell.month + 
							//"." + cell.year+"</div>"+overlay_collection.join("<div class='clEventRuler'></div>")+"</div>";
							var divCont = document.createElement("div");
							divCont.setAttribute("class", "clDayContainer");
							divCont.innerHTML = "<div class='clDayRuler'>"+cell.day + "." + cell.month + 
								"." + cell.year+"</div>"+overlay_collection.join("<div class='clEventRuler'></div>");
							if(calTbl.divContainer.admin){
								divCont.onDelete = calTbl.divContainer.onDelete;
								divCont.onEdit = calTbl.divContainer.onEdit;
							}
							evList.appendChild(divCont);
						}
						}
				i_currentDayIndex ++;
				//+++++++++++++++++++++++ done or are there days with events left? +++++++++++++++++++++++++
				if(typeof(days_with_events[i_currentDayIndex]) == "undefined")
					all_days_have_been_set = true;
			}
			//############################ Day Clicks ########################################
			if(!isEventDay){ //Tag hat keine Termine
				//++++++++++++++++++++++++++++ overlay container +++++++++++++++++++++++++++++++++
				var overlay_div = calGetOverlayEventContainer(calTbl.divContainer);
				var alldivs = overlay_div.getElementsByTagName("td");
				var containerev = null;
				for(var i = 0; i < alldivs.length; i++){
					if(alldivs[i].getAttribute("class") == "coOverlayContainerEvents"){
						containerev = alldivs[i];
						break;
					}
				}
				if(containerev != null)	containerev.innerHTML = "Für diesen Tag sind noch keine Termine eingetragen.";
				var containerdate = null;
				for(var i = 0; i < alldivs.length; i++){
					if(alldivs[i].getAttribute("class") == "coOverlayContainerDate"){
						containerdate = alldivs[i];
						break;
					}
				}
				if(containerdate != null) containerdate.innerHTML = cell.day + "." + cell.month + "." + cell.year;
				cell.obj.overlayContent = overlay_div;
				//++++++++++++++++++++++++++++ fire a function +++++++++++++++++++++++++++++++++
				if(calTbl.divContainer.onDayClick == "none")
					cell.obj.onclick = null;
				//++++++++++++++++++++++++++++ static overlay ++++++++++++++++++++++++++++++++++
				else if(calTbl.divContainer.onDayClick == "static") {
					cell.obj.onclick = function(e){
										var outBak = this.onmouseout;
										this.onmouseout = null;
										var cell = this;
										var o = Overlay(
											{
												event:e, 
												content:this.overlayContent,
												followMouse: false,
												mousePos: true,
												closeOthers: true,
												left:-20, top:-20,
												//vertical_align: calTbl.divContainer.overlayVerticalAlign,
												//horizontal_align: calTbl.divContainer.overlayHorizontalAlign,
												vertical_align: calTbl.divContainer.onEventClickStaticVerticalAlign,
												horizontal_align: calTbl.divContainer.onEventClickStaticHorizontalAlign,
												overlay_delay: calTbl.divContainer.overlayDelay,
												overlay_fade: calTbl.divContainer.overlayFade,
												overlay_fade_speed: calTbl.divContainer.overlayFadeSpeed,
												overlay_close_onclick: true,
												overlay_close_timeout: 2000,
												overlay_close_callback: function(olay){olay.cell.onmouseout = olay.outBak;},
												isDom:true
											});
										o.cell = cell;
										o.outBak = outBak;
										//o.onclick = function(e){ Overlay_CloseAll(); cell.onmouseout = outBak;};
									};
				}
				//++++++++++++++++++++++++++++ do dayClick Fkts ++++++++++++++++++++++++++++++++
				else if(typeof(calTbl.divContainer.onDayClick) == "function") {
						cell.obj.onclick = calTbl.divContainer.onDayClick;
				}
			}
			//++++++++++++++++++++++++++++++++++ is that today's cell? +++++++++++++++++++++++++++++++++++++
			if((cell.obj.className.match("cMarkedToday") == null) && (parseInt(cell.day) == today.getDate()) 
				&& (parseInt(cell.month) == today.getMonth()+1) && (parseInt(cell.year) == today.getFullYear()))
					cell.obj.className += " cMarkedToday";
		}
}

function calCreateSiblingListString(siblings){
	if((typeof(siblings) != "object") || (typeof(siblings.length) == "undefined"))
		return "";

	var str = "";
	var length = siblings.length;
	for(var i = 0; i<length; i++){
		var sib = siblings[i];

		var dt = calDecodeDate(sib.datum);
		if(str != "")
			str += ", ";
		str += dt.day + ". " + calGetNameOfMonth(dt.month) + " " + dt.year;
	}

	return str;
}

function calCreateSiblingDurationString(siblings){
	if((typeof(siblings) != "object") || (typeof(siblings.length) == "undefined"))
		return "";

	var str = "";
	var length = siblings.length;

	if(siblings.length > 0) {
		var sib = siblings[0];
		var sdt = calDecodeDate(sib.startdatum);
		var edt = calDecodeDate(sib.enddatum);
		str = sdt.day + ". " + calGetNameOfMonth(sdt.month) + " " + sdt.year + " - " + edt.day + ". " + calGetNameOfMonth(edt.month) + " " + edt.year;
		return str;
	}
	else
		return "";
}

function calGetOverlayEventTemplate(div){
	var str = "<table width=100%>"+
			"<tr>"+
				"<td rowspan=8 width='10px' bgcolor='%%eventcolor%%'>";
	if(div.admin)
		str += "<input type='button' value='X' onclick='calOnDelete(this, %%ID%%, %%flags%%, \"%%titel%%\")'><br><input type='button' value='E' name='edit' onclick='calOnEdit(this, %%ID%%, %%flags%%, \"%%titel%%\")'>";
				
	str += "</td>"+
				"<td class='coTime'>%%timestring%%&nbsp;</td>"+
			"</tr><tr>"+
				"<td class='coTitle'><b>%%titel%%</b></td>"+
			"</tr><tr>"+
				"<td class='coLocation'>{{Veranstaltungsort: <b>}}%%ort%%{{</b>}}</td>"+
			"</tr><tr>"+
				"<td class='coContent'>%%beschreibung%%</td>"+
			"</tr><tr>"+
				"<td class='coHost'>{{Veranstalter: }}%%veranstalter%%</td>"+
			"</tr><tr>"+
			"</tr><tr>"+
				"<td class='coHost'>{{Homepage: <a href='}}%%href%%{{'>}}%%href%%{{</a>}}</td>"+
			"</tr><tr>"+
				"<td class='coSibling'>{{Nachfolgende Termine: }}%%siblingstring%%</td>"+
			"</tr><tr>"+
				"<td class='coType'>%%typestring%%</td>"+
			"</tr>"+
		"</table>";
	return str;
}

function calGetOverlayEventContainer(div){
	var d = document.createElement("div");
	d.setAttribute("class", "coOverlayContainer");
	var tab = document.createElement("table");
	var tbo = document.createElement("tbody");
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	td.setAttribute("class", "coOverlayContainerDate");
	var input = document.createElement("input");
	input.setAttribute("type", "button");
	input.setAttribute("value", "neuen Termin erstellen");
	input.day = div.curDay;
	input.month = div.curMonth;
	input.year = div.curYear;
	input.onclick = function(){div.onNew(this.day, this.month, this.year);};
	
	d.appendChild(tab);
	tab.appendChild(tbo);
	tbo.appendChild(tr);
	tr.appendChild(td);
	
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	td.setAttribute("class", "coOverlayContainerEvents");
	
	tbo.appendChild(tr);
	tr.appendChild(td);
	
	var tr = document.createElement("tr");
	var td = document.createElement("td");
	if(div.admin) {
		tbo.appendChild(tr);
		tr.appendChild(td);
		td.appendChild(input);
	}
	return d;
}

function calOnDelete(me, id, flags, title){
	var div = me.parentNode.parentNode.parentNode.parentNode.parentNode;
	if(typeof(div.onDelete) != "function")
		return;
	if(flags == 0 || flags == 2){
		var shure = confirm(title + " wirklich löschen?");
		if(shure)
			div.onDelete(id);
	}
	else if(flags == 1){
		var shure = confirm("Bei " + title + " handelt es sich um ein Blockevent.\nAlle Vorkommen werden somit gelöscht!\n"+ title + " wirklich löschen?");
		if(shure)
			div.onDelete(id);
	}

}

function calOnEdit(me, id, flags, title){
	var div = me.parentNode.parentNode.parentNode.parentNode.parentNode;
	if(typeof(div.onEdit) != "function")
		return;
	div.onEdit(id);
}

function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;
	
	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";
	
	if(typeof(arr) == 'object') { //Array/Hashes/Objects 
		for(var item in arr) {
			var value = arr[item];
			
			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}

