// Copyright(c)2007 Daniel Pupius - http://pupius.co.uk/
// This is hacked code, it is ugly!

function $(el) { return document.getElementById(el); }

var gt = new function() {
  var _this = this;
  var _results = [];
  var _markers = [];
  var _interval = null;
  var _xhr = new XMLHttpHandler();
  _xhr.onrecieve = function(e) {
    _this.onrecieve(e);
  };
  

  // Handle the XHR response
  this.onrecieve = function(e) {
    window.clearInterval(_interval);
    $('input').disabled = false;
    $('button').disabled = false;
    $('button').innerHTML = 'Run Trace';
    this.processTrace(e.content);
    this.displayTrace();
    this.displayMap();
  };

  // Process the response text into a useful array
  this.processTrace = function(content) {
    _results.length = 0;
    var rows = content.split('\n');
    for (var i = 0; i < rows.length; i++) {
      var parts = rows[i].split('||');
      _results.push({
        ip: parts[0],
        lat: parts[1],
        lon: parts[2],
        host: parts[3],
        city: parts[4],
        country: parts[5]
      });
    }
    while (!_results[_results.length - 1].ip && _results.length > 0) {
      _results.pop();
    }
  };

  // Show the IP trace rows
  this.displayTrace = function() {
    var tr = $('trace');
    for (var i = 0; i < _results.length; i++) {
      var displayString = _results[i].ip == '' ? '*' : _results[i].ip;
      if (_results[i].lat && _results[i].lon) {
        displayString += ' (' + _results[i].lat + ', ' + _results[i].lon + ')';
        var li = document.createElement('li');
        var span = document.createElement('span');
        span.gtid = i;
        span.onclick = this.showResult;
        span.appendChild(document.createTextNode(displayString));
        li.appendChild(span);
      } else {
        if (displayString != '*') displayString += ' (no geo data)';
        var li = document.createElement('li');
        li.appendChild(document.createTextNode(displayString));
      }
      tr.appendChild(li);
    }
  };

  // Show the points on the map
  this.displayMap = function() {
    _markers.length = 0;
    var points = [];
    for (var i = 0; i < _results.length; i++) {
      if (_results[i].lat && _results[i].lon) {
        var marker = new GMarker(new GLatLng(_results[i].lat, _results[i].lon));
        marker.gtid = i;
        _map.addOverlay(marker);
        _markers[i] = marker;
        points.push(new GLatLng(_results[i].lat, _results[i].lon));
      }
    }
    var polyline = new GPolyline(points, '#FF0000', 8);
    _map.addOverlay(polyline);
  };

  // Show an info window about a particular data point
  this.showInfoWindow = function(id) {
    var data = _results[id];
    var marker = _markers[id];
    if (marker) {
      var html = '<p style="font-size:11px"><b>' + data.city + '</b><br>\n' +
                 data.country + '<br>\n' +
                 data.lat + 'N  ' + data.lon + 'E<br>\n' + 
                 data.host + '<br>' + data.ip + '</p>';
  
      _map.panTo(new GLatLng(data.lat, data.lon));
      marker.openInfoWindowHtml(html);
    }
  };

  // Event handler for the individual results
  this.showResult = function(e) {
    e = e || window.event;
    var id = e.target ? e.target.gtid : e.srcElement.gtid;
    _this.showInfoWindow(id);
  };

  // Provide feedback that we're still waiting and not hanging
  var _throb = 0;
  this.intervalThrob = function() {
    var str = 'Tracing' 
    if (_throb > 5) _throb = 0;
    str += new Array(_throb).join('.');
    $('button').innerHTML = str;
    _throb++;
  };
  
  // Command to initiate the trace
  this.runTrace = function() {
    if (_xhr.isBusy()) {
      alert('Busy with another trace');
      return;
    }
    var ip = $('input').value;
    _xhr.send('./traceroute.php?ip=' + ip);
    $('input').disabled = true;
    $('button').disabled = true;
    $('button').innerHTML = 'Tracing';
    _interval = window.setInterval(this.intervalThrob, 250);

    var tr = $('trace');
    while (tr.firstChild) { tr.removeChild(tr.firstChild); }
    
    _map.setCenter(new GLatLng(34.8859309, 5.625), 1);
    _map.clearOverlays();
  };

  
  $('button').disabled = false;
  $('input').disabled = false;

  _map = new GMap2(document.getElementById('map'));
  _map.enableDoubleClickZoom();
  _map.enableContinuousZoom();
  _map.addControl(new GLargeMapControl());
  _map.setCenter(new GLatLng(34.8859309, 5.625), 1);

  GEvent.addListener(_map, 'click', function(marker, point) {
    if (marker) {
      _this.showInfoWindow(marker.gtid);
    }
  });

};


