/* Copyright (c) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Loads the Google data JavaScript client library */
google.load("gdata", "2.x", {packages: ["calendar"]});

function init() {
  // init the Google data JS client library with an error handler
  google.gdata.client.init(handleGDError);
  // load the code.google.com developer calendar
  //loadDeveloperCalendar();
  loadNodeCalendar();
}

/**
 * Loads the Baltimore Node Event Calendar
 */
function loadNodeCalendar() {
  loadCalendarByAddress('baltimorenode.org_5jbobahkshgj11vut3cndhppoo@group.calendar.google.com');
}

/**
 * Adds a leading zero to a single-digit number.  Used for displaying dates.
 * 
 * @param {int} num is the number to add a leading zero, if less than 10
 */
function padNumber(num) {
  if (num <= 9) {
    return "0" + num;
  }
  return num;
}

/**
 * Determines the full calendarUrl based upon the calendarAddress
 * argument and calls loadCalendar with the calendarUrl value.
 *
 * @param {string} calendarAddress is the email-style address for the calendar
 */ 
function loadCalendarByAddress(calendarAddress) {
  var calendarUrl = 'http://www.google.com/calendar/feeds/' +
                    calendarAddress + 
                    '/public/full';
  loadCalendar(calendarUrl);
}

/**
 * Uses Google data JS client library to retrieve a calendar feed from the specified
 * URL.  The feed is controlled by several query parameters and a callback 
 * function is called to process the feed results.
 *
 * @param {string} calendarUrl is the URL for a public calendar feed
 */  
function loadCalendar(calendarUrl) {
  var service = new 
      google.gdata.calendar.CalendarService('gdata-js-client-samples-simple');
  var query = new google.gdata.calendar.CalendarEventQuery(calendarUrl);
  query.setOrderBy('starttime');
  query.setSortOrder('ascending');
  query.setFutureEvents(true);
  query.setSingleEvents(true);
  query.setMaxResults(10);

  //service.getEventsFeed(query, listEvents, handleGDError);
  service.getEventsFeed(query, nextEvent, handleGDError);
}

/**
 * Callback function for the Google data JS client library to call when an error
 * occurs during the retrieval of the feed.  Details available depend partly
 * on the web browser, but this shows a few basic examples. In the case of
 * a privileged environment using ClientLogin authentication, there may also
 * be an e.type attribute in some cases.
 *
 * @param {Error} e is an instance of an Error 
 */
function handleGDError(e) {
  document.getElementById('jsSourceFinal').setAttribute('style', 
      'display:none');
  if (e instanceof Error) {
    /* alert with the error line number, file and message */
    alert('Error at line ' + e.lineNumber +
          ' in ' + e.fileName + '\n' +
          'Message: ' + e.message);
    /* if available, output HTTP error code and status text */
    if (e.cause) {
      var status = e.cause.status;
      var statusText = e.cause.statusText;
      alert('Root cause: HTTP error ' + status + ' with status text of: ' + 
            statusText);
    }
  } else {
    alert(e.toString());
  }
}

/**
 * Callback function for the Google data JS client library to call with a feed 
 * of events retrieved.
 *
 * Creates an unordered list of events in a human-readable form.  This list of
 * events is added into a div called 'events'.  The title for the calendar is
 * placed in a div called 'calendarTitle'
 *
 * @param {json} feedRoot is the root of the feed, containing all entries 
 */ 

function nextEvent(feedRoot) {
	var days = ["Sun.", "Mon.", "Tues.", "Wed.", "Thurs.", "Fri.", "Sat."];
	var months = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."];
	
	var entries = feedRoot.feed.getEntries();
	
	/*
	var eventDiv = document.getElementById('events');
	if (eventDiv.childNodes.length > 0) {
    	eventDiv.removeChild(eventDiv.childNodes[0]);
	}
	*/
	/* create a new unordered list */
	//var ul = document.createElement('ul');
	/* set the calendarTitle div with the name of the calendar */
	//document.getElementById('calendarTitle').innerHTML = feedRoot.feed.title.$t;
	/* loop through each event in the feed */
	//var len = entries.length;
	
	var entry = entries[0];
	var title = entry.getTitle().getText();
	
	
	document.getElementById('event-title').innerHTML = "";
	//EVENT LINK INFO 
	/*
	var entryLinkHref = null;
    if (entry.getHtmlLink() != null) {
      entryLinkHref = entry.getHtmlLink().getHref();
    }
	entryLink = document.createElement('a');
    entryLink.setAttribute('href', entryLinkHref);
    
    entryLink.appendChild(document.createTextNode(title));
    
    document.getElementById('event-title').appendChild(entryLink);
    */
    
    document.getElementById('event-title').appendChild(document.createTextNode(title));
	
	var notes = entry.getContent().getText();
	if( notes.length + title.length * 1.6 > 220 ) {
		var index = 200 - title.length * 1.6;
		while(notes.charAt(index) != ' ') {
			index--;
		}
		notes = notes.substring(0, index);
		notes = notes + " ... ";
	}
	
    var startTime = null;
    var endTime = null;
    var startJSDate = null;
    var times = entry.getTimes();

    if (times.length > 0) {
      startTime = times[0].getStartTime();
      startJSDate = startTime.getDate();
      endTime = times[0].getEndTime();
      endJSDate = endTime.getDate();
    }
    var entryLinkHref = null;
    if (entry.getHtmlLink() != null) {
      entryLinkHref = entry.getHtmlLink().getHref();
    }
    var dateString = days[startJSDate.getDay()] + " " + months[startJSDate.getMonth()] + " " + startJSDate.getDate();
    if (!startTime.isDateOnly()) {
      dateString += " " + startJSDate.getHours() + ":" + 
          padNumber(startJSDate.getMinutes());
    } else {
    	dateString = "Loading... ";
    }
    if(endJSDate != null){
    	 dateString += " to " + (endJSDate.getMonth() + 1) + "/" + endJSDate.getDate();
	}
    
    //Insert into HTML
    document.getElementById('event-time').innerHTML = formatDate(times[0]);
    document.getElementById('event-desc').innerHTML = notes;

    var li = document.createElement('li');

    /* if we have a link to the event, create an 'a' element */
    if (entryLinkHref != null) {
      entryLink = document.createElement('a');
      entryLink.setAttribute('href', entryLinkHref);
      entryLink.appendChild(document.createTextNode(title));
      li.appendChild(entryLink);
      li.appendChild(document.createTextNode(' - ' + dateString));
    } else {
      li.appendChild(document.createTextNode(title + ' - ' + dateString));
    }	    

    /* append the list item onto the unordered list */
    eventDiv.appendChild(li);
	//eventDiv.appendChild(ul);
}

//FUNCTION to OUTPUT the EVENT DATE and TIME
function formatDate(eventTime) {
	var days = ["Sun.", "Mon.", "Tues.", "Wed.", "Thurs.", "Fri.", "Sat."];
	var months = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."];
	
	var startHours = null;
	var startMeridian = "";
	var endHours = null;
	var endMeridian = "";
	var startDateString = "";
	var endDateString = "";
	var startMinutesString = "";
	var endMinutesString = "";
	var startMinutes;
	var endMinutes;
	
	
	var dateString = "";

	var startGDataTime = eventTime.getStartTime();
	var endGDataTime = eventTime.getEndTime();
	var startTime = startGDataTime.getDate();
	var endTime = endGDataTime.getDate();
	
	var today = new Date();
	
	if(startTime.getDate() == endTime.getDate() && startTime.getMonth() == endTime.getMonth()) {
		endDateString = "";
	} else {
		endDateString = days[startTime.getDay()] + " " + months[startTime.getMonth()] + " " + startTime.getDate();
	}
	if(startTime.getFullYear() == today.getFullYear() && startTime.getMonth() == today.getMonth() && startTime.getDate() == today.getDate()) {
		startDateString = "Today";
	} else if (startTime.getFullYear() == today.getFullYear() && startTime.getMonth() == today.getMonth() && startTime.getDate() == today.getDate() + 1) {
		startDateString = "Tomorrow";
	} else {
		startDateString = days[startTime.getDay()] + " " + months[startTime.getMonth()] + " " + startTime.getDate();
	}
	
	
	if (!startGDataTime.isDateOnly()) {
		//Check and see if both start and end time are in the same half of the day 
		var sameMeridian = false;
		if( (startTime.getHours() < 12 && endTime.getHours() < 12) || (startTime.getHours() >= 12 && endTime.getHours() >= 12) ) {
			sameMeridian = true;
		}

		if(startTime.getHours() >= 12) {
			startHours = startTime.getHours();
			if(startHours != 12) {
				startHours = startHours - 12;
			}
			if(!sameMeridian) {
				startMeridian = " p.m. ";
			}
		} else {
			startHours = startTime.getHours();
			if(!sameMeridian) {
				startMeridian = " a.m. ";
			}
		}
		startMinutes = startTime.getMinutes();
		if(startMinutes < 10 && startMinutes > 0) {
			startMinutesString = ":0" + startMinutes;
		} else if ( startMinutes != 0 ) {
			startMinutesString = ":" + startMinutes;
		}
		startTimeString = ", " + startHours + startMinutesString + startMeridian;
		
		if(endTime.getHours() >= 12) {
			if(endTime.getHours() != 12) {
				endHours = endTime.getHours() - 12;	
			}
			endMeridian = " p.m. ";
		} else {
			endHours = endTime.getHours();
			endMeridian = " a.m. ";
		}
		
		endMinutes = startTime.getMinutes();
		if(endMinutes < 10 && endMinutes > 0) {
			endMinutesString = ":0" + endMinutes;
		} else if ( endMinutes != 0 ) {
			endMinutesString = ":" + endMinutes;
		}
		endTimeString = " " + endHours + endMinutesString + endMeridian;

		dateString = startDateString + startTimeString + " &ndash " + endDateString + endTimeString;
	} else {
		dateString = startDateString;
	}
	return dateString;
	
}

google.setOnLoadCallback(init);