var eventDates;
var eventLabels;
function loadCalendar()
{	
	$(document).ready(function()
	{  
    $.get('calendar.xml', function(d)
    {  
    	// IE workaround
			if (typeof d == "string") 
			{
				xml = new ActiveXObject("Microsoft.XMLDOM");
				xml.async = false;
				xml.loadXML(d);
		  } 
		  else 
		  {
		  	xml = d;
		  }		   
		  
		  eventDates = new Object();
		  $(xml).find('event').each(function()
	    {	
				var etitle = $(this).attr("title");  
				var ecolor = $(this).attr("color");
				var ename;
				var eroom;
				var estreet;
				var ecity;
				
				$(this).find('location').each(function()
	    	{	
	    		ename = $(this).attr("name");
	    		eroom = $(this).attr("room");
	    		estreet = $(this).attr("street");
	    		ecity = $(this).attr("city");
	    		eplz = $(this).attr("plz");
	    	});
				
				$(this).find('date').each(function()
	    	{	
					var edate = $(this).attr("date");  
					var etime = $(this).attr("time");
				
					var eventObj = new Object();
					eventObj["date"] = edate;
					eventObj["title"] = etitle;
					eventObj["color"] = ecolor;
					eventObj["time"] = etime;
					eventObj["name"] = ename;
					eventObj["room"] = eroom;
					eventObj["street"] = estreet;
					eventObj["city"] = ecity;
					eventObj["plz"] = eplz;					
				
					if ( eventDates[edate] == null )
					{
						eventDates[edate] = new Array();												
					}
					eventDates[edate].push(eventObj);
	    	});
	    }); 
	    
	    // [color][labels]
	    eventLabels = new Object();
	    for (var edate in eventDates)
	    {
	    	var color = null;
	    	var labels = new Array();
	    	for (var idx = 0; idx < eventDates[edate].length; idx ++)
	    	{
	    		eventObj = eventDates[edate][idx];
	    		if ( color != null )
	    		{
	    			color = addColors(color, eventObj["color"]);
	    		}
	    		else
	    		{
	    			color = eventObj["color"];
	    		}		
	    		labels.push(eventObj["title"]);
	    	}
	    	
	    	if ( eventLabels[color] == null )
	    	{	    		
	    		eventLabels[color] = new Array();
	    	}
	    	
	    	// unique labels
	    	for ( var idx = 0; idx < labels.length; idx++ )
	    	{
	    		var newLabel = labels[idx];
	    		var exist = false;
	    		
	    		for ( var jdx = 0; jdx < eventLabels[color].length; jdx++ )
	    		{
	    			if ( eventLabels[color][jdx] == newLabel )
	    			{
	    				exist = true;
	    				break;
	    			}
	    		}
	    		if ( !exist )
	    		{
	    			eventLabels[color].push(newLabel);	    	
	    		}
	    	}
	    }
	     
	    setToday(true);
		});  
	}); 
}

function addColors(color1, color2)
{
	if ( color1 && color1.length > 0 && color2 && color2.length > 0 )
	{
		var newR = (hexToR(color1) + hexToR(color2)) / 2;
		var newG = (hexToG(color1) + hexToG(color2)) / 2;
		var newB = (hexToB(color1) + hexToB(color2)) / 2;
		return "#" + rgbToHex(newR, newG, newB);
	}
	else 
	{
		if (color1 && color1.length > 0)
		{
			return color1;
		}
		else
		{
			return color2;
		}
	}
}

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 rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);}
function toHex(n) {
 n = parseInt(n,10);
 if (isNaN(n)) return "00";
 n = Math.max(0,Math.min(n,255));
 return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
}

function addCalendarTooltip(node, eventDatas)
{
	var color;
	
	for ( var i=0; i<eventDatas.length; i++ )
	{
		color = addColors(color, eventDatas[i]["color"]);
	}
	
	node.setAttribute('style','background-color:' + color + ';');
	
	var aref = document.createElement("a");
	aref.setAttribute("class", "tooltip");
	aref.setAttribute("href","#");
	
	var nodeChildren = node.childNodes;
	for( var i=0; i<nodeChildren.length; i++ )
	{
		aref.appendChild(nodeChildren[i]);
	}
	/* //TODO: remove code
	for( var i=0; i<nodeChildren.length; i++ )
	{
		aref.removeChild(nodeChildren[i]);
	}
	*/
	
	var tooltip = document.createElement("div");	
	tooltip.setAttribute("class", "default");	
	tooltip.setAttribute("style", "border: 1px solid " + color + ";");	
	
	var spacerLine = document.createElement("hr");
	spacerLine.setAttribute("height","1px");
	var lineBreak = document.createElement("br");
	
	for ( var i=0; i<eventDatas.length; i++ )
	{
		var eventData = eventDatas[i];
		var btitle = document.createElement("b");
		btitle.appendChild( document.createTextNode(eventData["title"]) );
		tooltip.appendChild(btitle);
		tooltip.appendChild(lineBreak.cloneNode(true));
		tooltip.appendChild(lineBreak.cloneNode(true));
		tooltip.appendChild(document.createTextNode('Am ' + eventData["date"] + ' ab '+ eventData["time"] + 'Uhr.'));
		tooltip.appendChild(lineBreak.cloneNode(true));
		tooltip.appendChild(lineBreak.cloneNode(true));		
		tooltip.appendChild(document.createTextNode(eventData["name"] +', ' + eventData["room"]));
		tooltip.appendChild(lineBreak.cloneNode(true));
		tooltip.appendChild(document.createTextNode(eventData["street"]));
		tooltip.appendChild(lineBreak.cloneNode(true));
		tooltip.appendChild(document.createTextNode(eventData["plz"] + ', ' + eventData["city"]));
		if ( i < eventDatas.length - 1 )
		{
			tooltip.appendChild(spacerLine.cloneNode(true));
		}
	}
	
	aref.appendChild(tooltip);
	node.appendChild(aref);	
}

function getTodayYear()
{
  var now   = new Date();
  var nowYear  = now.getYear();
  if (nowYear < 2000)    
    nowYear = nowYear + 1900; 
  return nowYear;
}

function getTodayMonth()
{
  var now   = new Date();	
  return now.getMonth();
}

function getTodayDay()
{
  var now   = new Date();
  return now.getDate();
}

function initializeGUI()
{
	var months = new Array("Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember");
  	var guiCont = document.getElementById("calendar");
  	// append cal month & year buttons
  	var cntrlForm = document.createElement("form");
  	cntrlForm.setAttribute("name", "calControl");
  	cntrlForm.setAttribute("onSubmit", "return false;");
  	var cntrlDiv = document.createElement("div");
  	var cntrlSel = document.createElement("select");
  	cntrlSel.setAttribute("name","month");
  	cntrlSel.setAttribute("onChange","selectDate();");
  	for ( var i = 0; i < months.length; i++ )
  	{
  		var cntrlOption = document.createElement("option");
  		var cntrlMonth = document.createTextNode(months[i]);
  		cntrlOption.appendChild(cntrlMonth);
  		cntrlSel.appendChild(cntrlOption);
  	}  	
  	cntrlDiv.appendChild(cntrlSel);
  	var cntrlYear = document.createElement("input");
  	cntrlYear.setAttribute("name", "year");
  	cntrlYear.setAttribute("type", "text");
  	cntrlYear.setAttribute("size", "4");
  	cntrlYear.setAttribute("maxlength", "4");
  	cntrlYear.setAttribute("onChange", "selectDate();");
  	cntrlDiv.appendChild(cntrlYear);  	
  	cntrlForm.appendChild(cntrlDiv);
  	guiCont.appendChild(cntrlForm);
  	
  	// append calendar
  	var calPage = document.createElement("div");
  	calPage.setAttribute("id","calPage");
  	calPage.setAttribute("style", "height:160px;");
  	guiCont.appendChild(calPage);
  	
		// append cal buttons
		var btnForm = document.createElement("form");
		btnForm.setAttribute("name", "calButtons");
		var btnDiv = document.createElement("div");
		
		var btnPY = document.createElement("input");
		btnPY.setAttribute("type", "button");
		btnPY.setAttribute("name", "previousYear");
		btnPY.setAttribute("value", "<<");
		btnPY.setAttribute("onclick", "setPreviousYear();");
		btnPY.setAttribute("style", "padding:0px;text-align:center;width:26px;");
		var btnPM = document.createElement("input");
		btnPM.setAttribute("type", "button");
		btnPM.setAttribute("name", "previousMonth");
		btnPM.setAttribute("value", "<");
		btnPM.setAttribute("onclick", "setPreviousMonth();");
		btnPM.setAttribute("style", "padding:0px;text-align:center;width:26px;");
		var btnTD = document.createElement("input");
		btnTD.setAttribute("type", "button");
		btnTD.setAttribute("name", "today");
		btnTD.setAttribute("value", "Heute");
		btnTD.setAttribute("onclick", "setToday();");
		btnTD.setAttribute("style", "padding:0px;text-align:center;width:50px;");
		var btnNM = document.createElement("input");
		btnNM.setAttribute("type", "button");
		btnNM.setAttribute("name", "nextMonth");
		btnNM.setAttribute("value", ">");
		btnNM.setAttribute("onclick", "setNextMonth();");
		btnNM.setAttribute("style", "padding:0px;text-align:center;width:26px;");
		var btnNY = document.createElement("input");
		btnNY.setAttribute("type", "button");
		btnNY.setAttribute("name", "nextYear");
		btnNY.setAttribute("value", ">>");
		btnNY.setAttribute("onclick", "setNextYear();");
		btnNY.setAttribute("style", "padding:0px;text-align:center;width:26px;");
		
		btnDiv.appendChild(btnPY);
		btnDiv.appendChild(btnPM);
		btnDiv.appendChild(btnTD);
		btnDiv.appendChild(btnNM);
		btnDiv.appendChild(btnNY);
		
		btnForm.appendChild(btnDiv);
		guiCont.appendChild(btnForm);
		
		// TODO: append legend
		guiCont.appendChild( document.createElement("br") );
		for (var color in eventLabels)
	  {
	  	var legendDiv = document.createElement("div");
	  	var legendColor = document.createElement("div");
	  	legendColor.setAttribute("style", "width:10px;height:10px;margin-right:5px;display:inline-block;background-color:" + color + ";");
	  	var legendLabel = document.createElement("span");
	  	legendLabel.setAttribute("style","font-size:0.75em;");
	  	legendLabel.appendChild( document.createTextNode( eventLabels[color] ) );
	  	
	  	legendDiv.appendChild(legendColor);
	  	legendDiv.appendChild(legendLabel);
	  	guiCont.appendChild(legendDiv);
	  }
	  
		//alert(eventDates["17.09.2011"].length);		
}

function setToday()
{
	setToday(false);
}
function setToday(initGUI) 
{
  var nowDay = getTodayDay();
  var nowMonth = getTodayMonth();
  var nowYear = getTodayYear();
  this.focusDay = nowDay;
  
  if ( initGUI )
  {
  	initializeGUI();
  }  
  document.calControl.month.selectedIndex = nowMonth;
  document.calControl.year.value = nowYear;
  displayCalendar(nowMonth, nowYear);
}

function isFourDigitYear(year) 
{
  if (year.length != 4) 
  {
    alert ("Sorry, the year must be four-digits in length.");
    document.calControl.year.select();
    document.calControl.year.focus();
  } 
  else 
  { 
    return true; 
  }
}

function selectDate()
{
  var year  = document.calControl.year.value;
  if (isFourDigitYear(year)) 
  {
    var day   = 0;
    var month = document.calControl.month.selectedIndex;
    displayCalendar(month, year);
  }
}

function setPreviousYear() 
{
  var year  = document.calControl.year.value;
  if (isFourDigitYear(year)) 
  {
    var day   = 0;
    var month = document.calControl.month.selectedIndex;
    year--;
    document.calControl.year.value = year;
    displayCalendar(month, year);
  }
}

function setPreviousMonth() 
{
  var year  = document.calControl.year.value;
  if (isFourDigitYear(year)) 
  {
    var day   = 0;
    var month = document.calControl.month.selectedIndex;
    if (month == 0) 
    {
      month = 11;
      if (year > 1000) 
      {
        year--;
        document.calControl.year.value = year;
      }
    }
    else 
    { 
      month--;
    }
    document.calControl.month.selectedIndex = month;
    displayCalendar(month, year);
  }
}

function setNextMonth() 
{
  var year  = document.calControl.year.value;
  if (isFourDigitYear(year)) 
  {
    var day   = 0;
    var month = document.calControl.month.selectedIndex;
    if (month == 11) 
    {
      month = 0;
      year++;
      document.calControl.year.value = year;
    } 
    else 
    { 
      month++; 
    }
    document.calControl.month.selectedIndex = month;
    displayCalendar(month, year);
  }
}

function setNextYear() 
{
  var year = document.calControl.year.value;
  if (isFourDigitYear(year)) 
  {
    var day = 0;
    var month = document.calControl.month.selectedIndex;
    year++;
    document.calControl.year.value = year;
    displayCalendar(month, year);
  }
}

function getDisplayDate(day, month, year)
{
  if ( day < 10 ) 
  {
    day = "0" + day;
  }
  month += 1;
  if ( month < 10 ) 
  {
    month = "0" + month;
  }
  return day + "." + month + "." + year
}

function setEventMarker(node, day, month, year)
{
  var today = -1;
  // mark today
  if ( month == getTodayMonth() && year == getTodayYear() )
  {
    today = getTodayDay();
    if ( today == day )
    {
      node.setAttribute("style","border-style:solid;border-width:1px;border-color:#DD0000;");
    }
  }

  var dispDate = getDisplayDate(day, month, year); 
  
  if ( eventDates[dispDate] != null && eventDates[dispDate].length > 0 )
  {
  	addCalendarTooltip(node, eventDates[dispDate]);
  }
}

function displayCalendar(month, year) 
{       
  month = parseInt(month);
  year = parseInt(year);
  var i = 0;
  var days = getDaysInMonth(month+1,year);
  var firstOfMonth = new Date (year, month, 1);
  var startingPos = firstOfMonth.getDay();
  days += startingPos;

  // cleanup
  var children = document.getElementById("calPage").childNodes;
  for ( var i = 0; i < children.length; i++)
  {
    document.getElementById("calPage").removeChild(children[i]);
  }

  // create calendar table
  var dayOfWeek = new Array("So","Mo","Di","Mi","Do","Fr","Sa");
  var newTable = document.createElement("table");
  newTable.setAttribute("style","font-family:'Tahoma';font-size:0.8em;");
  newTable.setAttribute("cellpadding","3");
  newTable.setAttribute("cellspacing","0");
  newTable.setAttribute("border","0");

  var newHeader = document.createElement("thead");
  var headerTr = document.createElement("tr");
  
  for ( var i = 0; i < dayOfWeek.length; i++ )
  {
    var headerTd = document.createElement("td");
    headerTd.setAttribute("style","font-weight:bold;");
    var txt = document.createTextNode(dayOfWeek[i]);
    headerTd.appendChild(txt);
    headerTr.appendChild( headerTd );
  }

  newHeader.appendChild(headerTr);

  var newBody = document.createElement("tbody");

  var tableTr = document.createElement("tr");
  newBody.appendChild(tableTr);

  for (i = 0; i < startingPos; i++) 
  {
    if ( i%7 == 0 ) 
    {
      tableTr = document.createElement("tr");
      newBody.appendChild(tableTr);
    }
    var tableTd = document.createElement("td");	
    tableTr.appendChild( tableTd );
  }

  for (i = startingPos; i < days; i++) 
  {
    if ( i%7 == 0 ) 
    {
      tableTr = document.createElement("tr");
      newBody.appendChild(tableTr);
    }
    var value = "";
    if (i-startingPos+1 < 10)
    {
      value += "0";
    }
    value += i-startingPos+1;
    var tableTd = document.createElement("td");
    var txt = document.createTextNode(value);
    tableTd.appendChild(txt);
    setEventMarker(tableTd, i - startingPos + 1, month, year);
    tableTr.appendChild( tableTd );
  }
  for (i=days; i<42; i++)  
  {
    if ( i%7 == 0 ) 
    {
      tableTr = document.createElement("tr");
      newBody.appendChild(tableTr);
    }
    var tableTd = document.createElement("td");	
    tableTr.appendChild( tableTd );
  }

  newTable.appendChild(newHeader);
  newTable.appendChild(newBody);
  document.getElementById("calPage").appendChild(newTable);
}

function getDaysInMonth(month,year)
{
  if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
  {
    return 31;
  }
  else if (month==4 || month==6 || month==9 || month==11)
  {
    return 30;
  }
  else if (month==2)  
  {
    if (isLeapYear(year))
    { 
      return 29; 
    }
    else 
    { 
      return 28; 
    }
  }
  return null;
}

function isLeapYear (Year) 
{
  return (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)); 
}

loadCalendar();
