//////////////////////////////////////////////////////////////////////
// Global data 
/////////////////////////////////////////////////////////////////////
var map;
var geocoder = new GClientGeocoder();
var baseIcon = new GIcon();

// http request
var xmlhttp;
   
// Data for link
var gmarkers = new Array();
var htmls = new Array();

// XML documentation
var  xmlDoc;

// Month name
var month_name = new Array ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
			    "Aug", "Sep", "Oct", "Nov", "Dec");

var week_name = new Array ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");

var submission_closed_img = "http://labs.google.com/ridefinder/images/mm_20_red.png";
var submission_open_img="http://labs.google.com/ridefinder/images/mm_20_green.png";
 
// Enable table sorting
function enableTableSorting() {
    var st = new SortableTable(getElementById("table-1"),
			["String", "String", "String", "String","String" ]);
    
    // restore the class names
    st.onsort = function () {
	var rows = st.tBody.rows;
	var l = rows.length;
	for (var i = 0; i < l; i++) {
	    removeClassName(rows[i], i % 2 ? "odd" : "even");
	    addClassName(rows[i], i % 2 ? "even" : "odd");
	}
    };
}

//Load XML (data file) and process it
function processXMLFile() {
    // sortable table
    var sortTable = "<table class='sort-table' id='table-1' cellspacing='0'>" +
	"<col></col><col></col>" +
	"<thead><tr><td title='CaseInsensitiveString'>Conf</td>" + 
	"<td>Date</td><td>Location</td><td>Due</td></tr>" +
	"</thead>";
   

    var swConfList = xmlDoc.getElementsByTagName("sw_conf");
    for (i=0; i<swConfList.length; i++) {
	var conf = new swConf(swConfList[i], true);
        // skip conf already closed
        if (conf.closed) {
	    continue;
        }
	// show map information
	showMapInfo(conf, i);
	sortTable += conf.getTableString(i);
    }

    sortTable += "</tbody></table>";
    getElementById("table").innerHTML = sortTable;
    enableTableSorting();
}

// get year
// ff return year - 1900
// IE returns OK
function getYear(date) {
    if (date.getYear()<1900) {
	return date.getYear()+1900;
    }

    return date.getYear();
}


// get year
// ff return year - 1900
// IE returns OK
function getShortYear(date) {
    var shortYear = getYear(date)-2000;
    if (shortYear<10) {
	return "0" + shortYear;
    }
    
    return shortYear;
}

// to Simple date String
function toSimpleDateString(date) {
    // if date is not available
    if (""+date.getMonth()=="NaN") {
	return "N/A";
    }
    return (date.getMonth()+1) + "/" + date.getDate() + "/" + getShortYear(date); 	
}

// to Simple date String
function toDateString(date) {
    // if date is not available
    if (""+date.getMonth()=="NaN") {
	return "N/A";
    }
    return week_name[date.getDay()] + "&nbsp; " +  month_name[date.getMonth()] + " " + date.getDate() + ", " + getYear(date); 	
}

// data structure for a conference 
function swConf (swConfElement, isXML) {
  this.gpoint = null;
   	
  if(isXML) {  
    this.abb = getXMLValue(swConfElement, "abb");
    this.name = getXMLValue(swConfElement, "name");
    this.start_date = getXMLValue(swConfElement, "start_date");
    
    this.end_date = getXMLValue(swConfElement, "end_date");
    this.submission_date = getXMLValue(swConfElement, "submission_date");
    this.notofication_date = getXMLValue(swConfElement, "notification_date");
    this.loc = getXMLValue(swConfElement, "loc");
    this.url = getXMLValue(swConfElement, "url");
    this.img = getXMLValue(swConfElement, "img");
   } else {
     // read it from csv format
     //FASE 2008,Fundamental Approaches to Software Engineering Conference,3/29/2008,4/6/2008,10/12/2007,Budapest/Hungary,http://www.cs.le.ac.uk/events/fase2008/,,
     var splits = swConfElement.split(",");
     if (splits.length < 7) {
        return null;
     }
     this.abb = splits[0];
     this.name = splits[1];
     this.start_date = splits[2];
     this.end_date = splits[3];
     this.submission_date = splits[4];
     this.notification_date = splits[5];	
     this.loc = splits[6].replace("/", ", ").replace("/", ", ");
     this.url = splits[7]; 
     this.img = splits[8]; // sponsor
     // Geo code
     // for example, http://geo.localsearchmaps.com/?city=London&country=UK  
     if (splits.length > 10) {
	this.gpoint = new GPoint(splits[9], splits[10]);
     	//alert("Geo code: " + splits[9] + ":" + splits[10]);
     }
   }

    // date process
    this.parsed_start_date = new Date(this.start_date);
    this.parsed_end_date = new Date(this.end_date);
    this.parsed_submission_date = new Date(this.submission_date);
    this.parsed_notification_date = new Date(this.notification_date);

    var curdate = new Date();
    this.closed = curdate > this.parsed_end_date;
    this.submission_closed = curdate > this.parsed_submission_date;
    this.notification_closed = curdate > this.parsed_notification_date;

    this.date = "";
    
    if (this.parsed_start_date.getYear()==this.parsed_end_date.getYear()) {
	if (this.parsed_start_date.getMonth()==this.parsed_end_date.getMonth()) {
	    this.date += month_name[this.parsed_start_date.getMonth()] + " ";
	    if (this.parsed_start_date.getDate() == this.parsed_end_date.getDate()) {
		this.date += this.parsed_start_date.getDate();
	    } else {
		this.date += this.parsed_start_date.getDate() +
		    "-" + this.parsed_end_date.getDate();
	    }
	} else {
	    this.date += month_name[this.parsed_start_date.getMonth()] + 
		" " + this.parsed_start_date.getDate() + 
		"-" + month_name[this.parsed_end_date.getMonth()] +
		" " + this.parsed_end_date.getDate();
	} 
	
	this.date += ", " + getYear(this.parsed_end_date);
    } else {
	this.date += month_name[this.parsed_start_date.getMonth()] + 
	    " " + this.parsed_start_date.getDate() +
	    " " + getYear(this.parsed_end_date.getYear()) +
	    "-" + month_name[this.parsed_end_date.getMonth()] +
	    " " + this.parsed_end.getDate() +
	    ", " + getYear(this.parsed_end_date.getYear());
    }

    // font color process
    this.submission_date_open_font="";	
    this.submission_date_close_font="";		
    this.notification_date_open_font="";	
    this.notification_date_close_font="";		

    // decide date font color	
    if (this.submission_closed) {
	this.submission_date_open_font = "<font color='red'>";
	this.submission_date_close_font="</font>";
    } 

    if (this.notification_closed) {
	this.notification_date_open_font = "<font color='red'>";
	this.notification_date_close_font = "</font>";
    }
		
    
    // generate table string based on the idx
    this.getTableString = function(idx) {
	var even_odd = "odd";
	if (idx %2==0) {
	    even_odd = "even";
	}
	
	return '<tr class="' + even_odd + '">' 
		+ '<td><a href="javascript:myclick(' + idx + ')">' 
		+ this.abb +'</a></td><td>'
		+ '<div style="display:none;">'
		// this is a hack to make date range sortable	
		+ this.parsed_start_date.getTime()+'</div>' 
		+  this.date 
		+ '</td>' 
		+ '<td><a href="javascript:myclick(' + idx + ')">' 
		+ this.loc +'</a></td><td>'
		+ '<div style="display:none;">'
		// this is a hack to make date range sortable    	
		+ this.parsed_submission_date.getTime() + '</div>'
		+ this.submission_date_open_font  
                + toSimpleDateString(this.parsed_submission_date)
		+ this.submission_date_close_font 	
		+ '</td><td><div style="display:none;">'
		// this is a hack to make date range sortable
	        + this.parsed_notification_date.getTime()+'</div>'
		+ this.notification_date_open_font 
		+ toSimpleDateString(this.parsed_notification_date)
		+ this.notification_date_close_font 
		+ '</td></tr>';
    }

    // return information for MAP
    this.getMapInfo = function() {
	return "<html><head>"
	+ "<META HTTP-EQUIV=\"PRAGMA\" CONTENT=\"NO-CACHE\">"
	+ "<meta http-equiv=\"Content-Type\" content=\"text/html\">"
	+ "</head><body>"
	+ "<a href=\"" + this.url + "\"><b>" + this.name + " (" + this.abb +")</b></A>"
	+ "<ul>" 
	+ "<li> Date: " + this.date + "</li>"
        + "<li> Location: " + this.loc + "</li>"
	+ "<li> Submission Date: "
	+ this.submission_date_open_font 
	+ toDateString(this.parsed_submission_date)
	+ this.submission_date_close_font 	
	+ "</li>"
	+ "<li> Notification Date: "
	+ this.notification_date_open_font
	+ toDateString(this.parsed_notification_date)
	+ this.notification_date_close_font	 
	+ "</li>"
	+ "</ul><p>&nbsp;</p><p>&nbsp;</p><br></body></html>";
    }
}

function loadAndProcessXML(fileName)
{ 
    //load xml file
    // code for IE
    if (window.ActiveXObject) {
	xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
	xmlDoc.async=false;
	xmlDoc.load(fileName);
	processXMLFile();
    }
    // code for Mozilla, Firefox, Opera, etc.
    else if (document.implementation && document.implementation.createDocument)	{
	xmlDoc=document.implementation.createDocument("","",null);
	xmlDoc.load(fileName);
	xmlDoc.onload=processXMLFile;
    }
    else {
	alert('Your browser cannot handle this script');
	return null;
    }

    return xmlDoc;
}

// return text value of given tag
function getXMLValue(element, tag) {
    var innerElements = element.getElementsByTagName(tag);
    if (!innerElements || innerElements.length==0) {
	return null;
    }
    
    var firstNode = innerElements[0].childNodes[0];
    
    if (!firstNode) {
	return null;
    }
    
    return firstNode.nodeValue;
}


function getElementById(id) {
  return document.getElementById(id);
}    

function addClassName(el, sClassName) {
    var s = el.className;
    var p = s.split(" ");
    var l = p.length;
    for (var i = 0; i < l; i++) {
	if (p[i] == sClassName)
	    return;
    }
    p[p.length] = sClassName;
    el.className = p.join(" ");
}

function removeClassName(el, sClassName) {
    var s = el.className;
    var p = s.split(" ");
    var np = [];
    var l = p.length;
    var j = 0;
    for (var i = 0; i < l; i++) {
	if (p[i] != sClassName)
	    np[j++] = p[i];
    }
    el.className = np.join(" ");
}

      
function load() {
    // Create a base icon for all of our markers that specifies the
    // shadow, icon dimensions, etc.				
    baseIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
    baseIcon.iconSize = new GSize(12, 20);
    baseIcon.shadowSize = new GSize(22, 20);
    baseIcon.iconAnchor = new GPoint(6, 20);
    baseIcon.infoWindowAnchor = new GPoint(5, 1);
    baseIcon.infoShadowAnchor = new GPoint(18, 25);
      
    if (GBrowserIsCompatible()){
        map = new GMap2(getElementById("map"));
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        map.addControl(new GOverviewMapControl());   
        // MIT location
        //map.setCenter(new GLatLng(42.374206,-71.1217), 2);
        map.setCenter(new GLatLng(40, -5), 2);
        
        // Load Tao's CSV
	loadHTTPXMLDoc('seconferences.csv');

        // Load XML
        //loadAndProcessXML("sw_conf.xml");               
    }
}  


// Creates a marker at the given point with the given number label
function createMarker(point, conf, idx) {
    
    var icon = new GIcon(baseIcon);
      //var icon = new GIcon();
    if (conf.submission_closed) {
	icon.image = submission_closed_img;
//	icon.shadow = "http://maps.google.com/mapfiles/kml/pal4/icon53s.png";
    } else {
	icon.image = submission_open_img;
//	icon.shadow = "http://maps.google.com/mapfiles/kml/pal2/icon10s.png";
    } 
    
    //var marker = new GMarker(point, {title:toolTip});
    var marker = new GMarker(point, icon);
    var info = conf.getMapInfo();
    
    GEvent.addListener(marker, "mouseover", function() {
	    marker.openInfoWindowHtml(info);
	});
    
    // Save HTML and marker for later
    gmarkers[idx] = marker;
    htmls[idx] = info;
    
    return marker;
}

// This function picks up the click and opens the corresponding info window
function myclick(i) {
    if (gmarkers[i]) {
	gmarkers[i].openInfoWindowHtml(htmls[i]);
    } else {
	alert("Given address is not correct");
    }
}


function addWrongAddress(address) {
    wrongAdddress += address + "<BR>";
}

function showMapInfo(conf, idx) {
    // use given geocode if it is given
    if (conf.gpoint) {
	map.addOverlay(createMarker (conf.gpoint, conf, idx));
	return;
    }

    // get Geocode from Google API	
    geocoder.getLatLng(
	conf.loc,
	function(point) {
	if (!point) {
	     getElementById("wrong_address").innerHTML += 
	       "<br>Check this Location! " + conf.name + ": <font color='red'>" +conf.loc + "</font></br>";
	 } else {
	       // map.setCenter(point, 12);
	       map.addOverlay(createMarker (point, conf, idx));
	 }
       }
   );
}

function loadHTTPXMLDoc(url)
{		
  xmlhttp=null;	
  
  // code for Mozilla, etc.
  if (window.XMLHttpRequest)
  {
  xmlhttp=new XMLHttpRequest();
  }
  // code for IE
  else if (window.ActiveXObject)
  {
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }

  if (xmlhttp!=null)
  {
  xmlhttp.onreadystatechange=state_Change;
  xmlhttp.open("GET",url,true);
  xmlhttp.setRequestHeader('Cache-Control', 'no-cache');
  xmlhttp.send(null);
  }
  else
  {
  alert("Your browser does not support XMLHTTP.");
  }
}

function state_Change()
{
  // if xmlhttp shows "loaded"
  if (xmlhttp.readyState!=4)
     return;


    // if "OK"
    if (xmlhttp.status!=200) {
      alert("Problem retrieving data file: contact Tao Xie");
      return;
    }
  
    var last_update = xmlhttp.getResponseHeader("Last-Modified");
    getElementById("last_updated").innerHTML += '<font size=-1><I>' + last_update + '</I></font>';
   
    // sortable table
    var sortTable = "<table class='sort-table' id='table-1' cellspacing='0'>" +
	"<col></col><col></col>" +
	"<thead><tr><td title='CaseInsensitiveString'>Name</td>" + 
	"<td>Date</td><td>Location</td><td>Submit</td>" +
  	 "<td>Notice</td>" +
        "</tr>" +
	"</thead>";

    var splits = xmlhttp.responseText.split("\n");
    for (i=0; i<splits.length; i++) {
    	if (splits[i].split(",").length < 7 ) {
          continue;
        }
       	var conf = new swConf(splits[i], false);
        // skip conf already closed
        if (conf.closed) {
	    continue;
        }
	// show map information
	showMapInfo(conf, i);
	sortTable += conf.getTableString(i);
    }

    sortTable += "</tbody></table>";
    getElementById("table").innerHTML = sortTable;
    enableTableSorting();
}


