/*
    Preview Samba Team events in a sidebar column.
    Deryck Hodge <deryck@samba.org>
*/

var ua = navigator.userAgent.toLowerCase();
var is_opera = ua.indexOf('opera') > -1;
var is_ie = ua.indexOf('msie') > -1 && !is_opera;
var is_ie5 = is_ie && ua.indexOf('msie 5') > -1;

function E(e)
{
	if (typeof e == 'undefined') {
		e = window.event;
	}
	if (typeof e.target == 'undefined') {
		e.target = e.srcElement;
	}

	return e;
}


/* 
   Convert a string to DOM.
   Taken from (with some modifications) Google's AJAXSLT
   by Steffen Meschkat, which was released under a BSD license.
*/
function stringSplit(s, c) {
  var a = s.indexOf(c);
  if (a == -1) {
    return [ s ];
  }
  
  var parts = [];
  parts.push(s.substr(0,a));
  while (a != -1) {
    var a1 = s.indexOf(c, a + 1);
    if (a1 != -1) {
      parts.push(s.substr(a + 1, a1 - a - 1));
    } else {
      parts.push(s.substr(a + 1));
    } 
    a = a1;
  }

  return parts;
}

function xmlResolveEntities(s) {

  var parts = stringSplit(s, '&');

  var ret = parts[0];
  for (var i = 1; i < parts.length; ++i) {
    var rp = stringSplit(parts[i], ';');
    if (rp.length == 1) {
      // no entity reference: just a & but no ;
      ret += parts[i];
      continue;
    }
    
    var ch;
    switch (rp[0]) {
      case 'lt': 
        ch = '<';
        break;
      case 'gt': 
        ch = '>';
        break;
      case 'amp': 
        ch = '&';
        break;
      case 'quot': 
        ch = '"';
        break;
      case 'apos': 
        ch = '\'';
        break;
      case 'nbsp': 
        ch = String.fromCharCode(160);
        break;
      default:
        // Cool trick: let the DOM do the entity decoding. We assign
        // the entity text through non-W3C DOM properties and read it
        // through the W3C DOM. W3C DOM access is specified to resolve
        // entities. 
        var span = window.document.createElement('span');
        span.innerHTML = '&' + rp[0] + '; ';
        ch = span.childNodes[0].nodeValue.charAt(0);
    }
    ret += ch + rp[1];
  }

  return ret;
}

function parseToDOM(str) {
  var regex_empty = /\/$/;

  var regex_tagname = /^([\w:-]*)/;
  var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;

  var root = document.createElement('div');

  var stack = [];

  var parent = root;
  stack.push(parent);

  var x = stringSplit(str, '<');
  for (var i = 1; i < x.length; ++i) {
    var xx = stringSplit(x[i], '>');
    var tag = xx[0];
    var text = xmlResolveEntities(xx[1] || '');

    if (tag.charAt(0) == '/') {
      stack.pop();
      parent = stack[stack.length-1];

    } else if (tag.charAt(0) == '?') {
      // Ignore XML declaration and processing instructions
    } else if (tag.charAt(0) == '!') {
      // Ignore notation and comments
    } else {
      var empty = tag.match(regex_empty);
      var tagname = regex_tagname.exec(tag)[1];
      var node = document.createElement(tagname);

      var att;
      while (att = regex_attribute.exec(tag)) {
        var val = xmlResolveEntities(att[3] || att[4] || '');
        node.setAttribute(att[1], val);
      }
      
      if (empty) {
        parent.appendChild(node);
      } else {
        parent.appendChild(node);
        parent = node;
        stack.push(node);
      }
    }

    if (text && parent != root) {
      parent.appendChild(document.createTextNode(text));
    }
  }

  return root;
}


/* 
    XMLHttp handling.
*/
function initRequest()
{
	var request = null;

	if (is_ie) {
		var objVer = is_ie5 ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP";

		try {
			request= new ActiveXObject(objVer);
		}
		catch (err) {
			// Pass for now, but eventually handle the error
		}
		
	} else {
		try {
			request = new XMLHttpRequest();
		}
		catch (err) {
			// Pass for now, but eventually handle the error
		}
	}

	return request;
}

function handleHttpRequest(request, url, handler, data)
{
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			if (request.status == 200) {
				if (handler) {
					handler(request, url);
				}
			}
		}
	};

	if (data == null) {
		method = 'GET';
	} else {
		method = 'POST';
	}

	request.open(method, url, true);
	request.send(data);
}

function httpRequest(url, handler, data)
{
	var request = initRequest();
	handleHttpRequest(request, url, handler, data);
}

function previewEvent(path)
{
	path = path + 'json/'
	httpRequest(path, displayEvents, null);	
}

function displayEvents(request)
{
	eventList = eval(request.responseText);
	var eventSidebar = document.getElementById('events');
	if (eventSidebar.childNodes.length > 0) {
		var i;
		var len = eventSidebar.childNodes.length;
		for (i=len-1; i>-1; i--) {
			eventSidebar.removeChild(eventSidebar.childNodes[i]);
		}
	}
	var j;
	for (j=0; j<eventList.length; j++) {
		var title = document.createElement('h3');
		title.className = 'pretitle';
		title.appendChild(document.createTextNode(eventList[j].fields['title']));
		var description = parseToDOM(eventList[j].fields['description']);
		description.className = 'predescription';
		var link = document.createElement('a');
		link.href = '/calendar/' + eventList[j].fields['slug'] + '/';
		link.className = 'moreinfo';
		link.appendChild(document.createTextNode('Complete Event Info'));
		eventSidebar.appendChild(title);
		eventSidebar.appendChild(description);
		eventSidebar.appendChild(link);
	}
}

window.onclick = function(e)
{
	e = E(e);

	if (e.target.className == 'event') {
		previewEvent(e.target.href);
		return false;
	} 
}
