function GAltimetryLayer(a,b,c,d) {
  a = (!a) ? new GCopyrightCollection("Altimetry") : a;
  b = (!b) ? 0 : b;
  c = (!c) ? 5 : b;
  d = (!d) ? {'opacity':0.50} : d;

  var id = 'ccar_'+(new Date()).valueOf();
  var bb = new GLatLngBounds(new GLatLng(72,180),new GLatLng(-62,-180));
  a.addCopyright(new GCopyright(id,bb,0,"(C) Colorado Center for Astrodynamics Research"));

  this.dates = [];
  this.odate = null;
  this.extension = "png";
  GTileLayer.call(this,a,b,c,d);
  this.load();
}
GAltimetryLayer.prototype = new GTileLayer();



// public setDate(date object) -- assigns active date
GAltimetryLayer.prototype.setDate = function(d) { 
  if( typeof(d) != "object" ) { 
    alert("expecting date object, found: "+typeof(d));
    return false;
  }
  if( this.odate != d ) { 
    this.odate = d;
    GEvent.trigger(this,"datechange",d);
  }
  return true;
};

// public getDate() -- returns active date
GAltimetryLayer.prototype.getDate = function() { 
  return this.odate;
};

// private setDates(a) -- assigns internal array of valid dates
GAltimetryLayer.prototype.setDates = function(a) { 
  if( typeof(a) != "object" ) { 
    alert("expecting array of dates");
    return false;
  }
  for(var i in a) { 
    if( typeof(a[i]) != "object" ) { 
      alert("expecting date, found: "+typeof(a[i]));
      return false;
    }
  }
  this.dates = a;
};

// public getDates -- returns list of available dates
GAltimetryLayer.prototype.getDates = function() { 
  return this.dates;
};


// interface isPng()
GAltimetryLayer.prototype.isPng = function() { 
  return (this.extension=="png");
};


// interface getTileUrl()
GAltimetryLayer.prototype.getTileUrl = function(t,z) { 
  var zd = (z<10) ? '0'+z : z;
  var stamp = this.dateToStamp(this.odate);
  return 'http://sandbar.ucsd.edu/tiles/altimetry/'+stamp+'/'+
    zd+'/tz'+z+'x'+t.x+'y'+t.y+'.'+this.extension;
};


// private dateToStamp(d)
GAltimetryLayer.prototype.dateToStamp = function(d) { 
  d = (!d) ? this.odate : d;
  if( typeof(d) == "undefined" ) { 
    return false;
  }
  var yyyy = d.getUTCFullYear();
  var mm   = d.getUTCMonth()+1;
  var dd   = d.getUTCDate();
  mm = (mm<10) ? '0'+mm : mm;
  dd = (dd<10) ? '0'+dd : dd;
  return (yyyy+''+mm+''+dd);
};

// public dateToString(d)
GAltimetryLayer.prototype.dateToString = function(d) { 
  d = (!d) ? this.odate : d;
  if( typeof(d) == "undefined" ) {
    return false;
  } 
  var yyyy = d.getUTCFullYear();
  var mm   = d.getUTCMonth()+1;
  var dd   = d.getUTCDate();
  mm = (mm<10) ? '0'+mm : mm;
  dd = (dd<10) ? '0'+dd : dd;
  return (yyyy+'-'+mm+'-'+dd);
};



// private stampToDate(s)
GAltimetryLayer.prototype.stampToDate = function(s) { 
  if( !s || String(s).length != 8 ) { 
    return false;
  }
  var o = new Date(0);
  o.setUTCFullYear( parseInt(s.substr(0,4),10) );
  o.setUTCMonth( parseInt(s.substr(4,2),10) - 1 );
  o.setUTCDate( parseInt(s.substr(6,2),10) );
  return o;
};



// protected load()
GAltimetryLayer.prototype.load = function() { 
  this.dates = [];
  var alt = this;
  var url = 'query.php?listAltimetry';
  GDownloadUrl(url,function(data,code) {
    if( code != 200 ) {
      GEvent.trigger(alt,"load",data,code);
      alert("listAltimetry failed (Code "+code+")");
      return false;
    }

    var dates = [];
    var dom = GXml.parse(data);
    var stamps = dom.getElementsByTagName("stamp");
    for(var i=0,n=stamps.length;i<n;i++) {
      var stamp = (stamps[i].firstChild.nodeValue).toString();
      dates.push(alt.stampToDate(stamp));
    }

    dates.sort( function(a,b){return (b.getTime()-a.getTime());} );
    
    if( dates.length > 0 ) { 
      alt.setDates(dates);
      alt.setDate(dates[0]);
    }
    GEvent.trigger(alt,"load",data,code);
  });
};
