// constructor
function Root() {
  this.root = new Array();
  this.id = 0;
}

// static class variables...
Root.units = "english";

// instance variables...
Root.prototype.root;
Root.prototype.id;

/**
 * set_units(unit)
 * @arg unit = {"english"|"metric"}
 */
Root.set_units = function(unit) {
  Root.units = unit;
}

Root.calculate_distance = function(a, b) {
  // using the haversine formula, credit goes to...
  // http://www.movable-type.co.uk/scripts/latlong.html
  var R = (Root.units == "english") ? 3958.7558 : 6371; 

  var dLat = (a.lat - b.lat) * Math.PI / 180;
  var dLon = (a.lng - b.lng) * Math.PI / 180;
  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
          Math.cos(a.lat * Math.PI / 180) * Math.cos(b.lat * Math.PI / 180) * 
          Math.sin(dLon / 2) * Math.sin(dLon / 2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
  return R * c;
}

/**
 * Returns the distance of this route
 * units argument is optional, if omitted, get_distance() will use
 *  the default units for the route
 */
Root.prototype.get_distance = function(units) {
  var distance = 0;
  var last_point = false;
  var old_units = Root.units;

  if (units) { Root.set_units(units); }
  for (var x = 0; x < this.root.length; x++) {
    if (!last_point) {
      last_point = this.root[x];
    } else {
      distance += Root.calculate_distance(this.root[x], last_point);
      last_point = this.root[x];
    }
  }

  if (units) { Root.set_units(old_units); }
  return distance;
}

Root.prototype.is_new = function() { return this.id == 0; }

// all arguments and returns are of class LatLng
Root.prototype.push_point = function(p) { this.root.push(p); }
Root.prototype.pop_point = function() { return this.root.pop(); }
Root.prototype.get_points = function() { return this.root; }

Root.prototype.unpack_points = function(root) { this.root = eval(root); }
Root.prototype.pack_points = function() { 
  var packed = new Array();
  for (var i = 0; i < this.root.length; i++) {
    packed.push({lng : this.root[i].lng, lat : this.root[i].lat});
  }

  return Json.encode(packed); 
}

Root.prototype.load_root = function(id) {
  this.id = id;
  var url = RR.get_url("/root/get", {"id" : id});
  var result = RR.get_ajax().getSyncHttpRequest(url);

  if (result != "") {
    this.unpack_points(result.points);
    this.name = result.name;
    // any more info...
    return true;
  }

  return false;
}

Root.prototype.insert_root = function() {
  if (!this.is_new()) { return false; }

  var params = {"root" : Json.encode(this.root)};
  var url = RR.get_url("/root/insert");
  return RR.get_ajax().postSyncHttpRequest(url, params);
}

Root.prototype.save_root = function() {
  if (this.is_new()) { return this.insert_root(); }

  var params = {"id" : id, "root" : Json.encode(this.root)}
  var url = RR.get_url("/root/save", params);
  return RR.get_ajax().postSyncHttpRequest(url, params);
}

