

var CalendarDemo2 = {};

CalendarDemo2.initialize = function () {

  CalendarDemo2.sparql = new SPARQL.Service("http://sparql.org/sparql");
  CalendarDemo2.sparql.setPrefix("foaf", "http://xmlns.com/foaf/0.1/");
  CalendarDemo2.sparql.setPrefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  CalendarDemo2.sparql.setPrefix("dc", "http://purl.org/dc/elements/1.1/");
  CalendarDemo2.sparql.setPrefix("ical", "http://www.w3.org/2002/12/cal/icaltzd#");
  CalendarDemo2.sparql.setPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");

  CalendarDemo2.dsmgr = SPARQL.UI.DataSetManager(document.getElementById("calendars"));

  CalendarDemo2.dsmgr.addNamedGraph("http://torrez.us/elias/school.ics", "Elias' School");

}

SPARQL.UI = {};

SPARQL.UI.DataSetManager = function(o) {

  var table = o;
  var st = null;

  const NAMED_GRAPH = "named";
  const DEFAULT_GRAPH = "default";

  function _init() {
    var headers = document.createElement('tr');
    var vars = ["","Name","URL","Status"];
    var types = [];
    for(i = 0; i < vars.length; i++) {
      var header = document.createElement('td');
      header.appendChild(document.createTextNode(vars[i]));
      headers.appendChild(header);
      types.push("String");
    }
    if(!table.tHead) table.createTHead();
    if(table.tBodies.length == 0) table.appendChild(document.createElement('tbody'));
    table.tHead.appendChild(headers);

    st = new SortableTable(table,types);
  };

  function _findRow(nameOrIndexOrUrl) {
    return table.rows[nameOrIndexOrUrl];
  };

  function _enableGraph(nameOrIndexOrUrl, enable) {
    var row = _findRow(nameOrIndexOrUrl);
    if(!row) return;
    _addClassName(row, enable ? "odd" : "even");
    _removeClassName(row, enable ? "even" : "odd");
    row.cells[0].firstChild.disabled = !enable;
    row.cells[0].firstChild.checked = enable;
    row.graphEnabled = enable;
  };

  function _setURL(nameOrIndexOrUrl, url) {
    var row = _findRow(nameOrIndexOrUrl);
    row.graphURL = url;
    row.cells[2].innerHTML = url;
  }

  function _setRealURL(nameOrIndexOrUrl, url) {
    var row = _findRow(nameOrIndexOrUrl);
    row.graphRealURL = url;
  }

  function _appendStatus(nameOrIndexOrUrl, msg) {
    var row = _findRow(nameOrIndexOrUrl);
    row.cells[3].innerHTML += "<div>" + msg +"</div>";
  }

  function _setStatus(nameOrIndexOrUrl, msg) {
    var row = _findRow(nameOrIndexOrUrl);
    row.cells[3].innerHTML = "<div>" + msg +"</div>";
  }

  function _trim(str) { 
    return str.replace(/^\s+|\s+$/, ''); 
  };

  function _validateGraph(row) {
    var handleSuccess = function(o) {

      var supportedTypes = { "rdf"  : [ "application/rdf+xml", "text/html" ],
	"ical" : [ "text/calendar" ],
	"html" : [ ],
	"xml"  : [ "text/xml" ] };

      var types = {};
      var contentType = o.allResponseHeaders.split("\n").filter(function(i) { return i.indexOf("Content-Type") > -1; });
      contentType[0].split(":")[1].split(";").map(function(i) { if(i.indexOf('=') == -1)types[_trim(i)] = i });

      var mode = null;

      for(s in supportedTypes) {
	if(supportedTypes[s].some(function(c) {return types[c];})) {
	  mode = s;
	  break;
	}
      }

      switch(mode) {
	case "html":
	  _appendStatus(row.rowIndex, "Found HTML. GRDDL Parser coming soon. Sorry.");
	  break;
	case "ical":
	  _enableGraph(row.rowIndex, true);
	  _setRealURL(row.rowIndex, "http://torrez.us/services/ics2rdf/" + row.graphURL);
	  _appendStatus(row.rowIndex, "Found iCal. Using http://torrez.us/ics2rdf service.");
	  break;
	case "rdf":
	  _enableGraph(row.rowIndex, true);
	  _appendStatus(row.rowIndex, "Found RDF contents.");
	  break;
	case "xml":
	  _enableGraph(row.rowIndex, true);
	  _appendStatus(row.rowIndex, "Found XML contents. Treating it as RDF.");
	  break;
      };
    };

    var handleFailure = function(o) {
       _setStatus(row.rowIndex, "Error: " + o.status + " " + o.statusText);
    };

    var callback =
    {
      success: handleSuccess ,
      failure: handleFailure,
      argument: row,
      scope: this
    }

    YAHOO.util.Connect.asyncRequest('HEAD',row.graphRealURL, callback,null);
  };

  function _getSelectedGraphs() {
    var urls = [];
    for(var i = 1; i < table.rows.length; i++) {
      var row = table.rows[i];
      if(!row.graphEnabled) continue;
      if(row.cells.length == 0) continue;
      if(!row.cells[0].hasChildNodes()) continue;
      if(!row.cells[0].firstChild.checked) continue;
      urls.push(row);
    }
    return urls;
  };

  function _addGraph(type, url, name) {
    var row = document.createElement('tr');

    row.graphName = name || "no name";
    row.graphURL = url;
    row.graphRealURL = url;
    row.graphType = type;
    row.graphEnabled = false;
    
    var checkBox = document.createElement('td');
    var nameCell = document.createElement('td');
    var urlCell = document.createElement('td');
    var statusCell = document.createElement('td');
    var cb = document.createElement('input');
    cb.type = "checkbox";
    checkBox.appendChild(cb);
    nameCell.appendChild(document.createTextNode(name || "no name"));
    urlCell.appendChild(document.createTextNode(url));
    statusCell.appendChild(document.createTextNode(""));
    row.appendChild(checkBox);
    row.appendChild(nameCell);
    row.appendChild(urlCell);
    row.appendChild(statusCell);
    table.tBodies[0].appendChild(row);

    // disable for now
    _enableGraph(row.rowIndex, false);
    _validateGraph(row)
  };

  this.addNamedGraph = function(url, name) { _addGraph(NAMED_GRAPH, url, name); };

  function _buildDataSet(q) {
    var urls = _getSelectedGraphs();
    for(var i = 0; i < urls.length; i++) {
      if(urls[i].graphType == NAMED_GRAPH)
      q.addNamedGraph(urls[i].graphRealURL);
      if(urls[i].graphType == DEFAULT_GRAPH)
      q.addDefaultGraph(urls[i].graphRealURL);
    }
  }
  
  this.buildDataSet = _buildDataSet;

  // helpers

  function _addClassName(el, class) {
    var classes = el.className.split(" ");
    if(classes.some(function(c) { return c == class; }))
      return;
    classes.push(class);
    el.className = classes.join(" ");
  };

  function _removeClassName(el, class) {
    el.className = el.className.split(" ").filter(
      function(c) { return c != class; }).join(" ");
  };

  _init();

  return this;
};
