/* Copyright (C) 2007 Michael Kosowsky  All rights reserved. */


			///////////// UTILS /////////////////

var is_msie = navigator.userAgent.toLowerCase().indexOf('msie') != -1;

function WTBrowserCompatible() {
  var s = navigator.userAgent.toLowerCase();
  if (s.match(/(firefox|iceweasel)\/(2|1\.5)/i))
    return 1;
  return 1;
}


	// Possibly the right way to do inheritance cf. http://www.kevlindev.com/tutorials/javascript/inheritance/
function derive(newclass, base) {
  function xxx() {}
  xxx.prototype      = base.prototype;
  newclass.prototype = new xxx();
}

Array.prototype._foreach = function(f) { for (var __i = 0; __i < this.length; __i++) f(this[__i]); };



function read_cookie(c) {
  var s = document.cookie.match(new RegExp(c + '=([^;]*)'));
  return s && s[1]? s[1] : null;  
}

function set_cookie(c, v) {
  document.cookie = c + '=' + v + ';expires=' + new Date((new Date()).getTime() + 365 * 24 * 60 * 60 * 100).toGMTString();
}


function round0(x) {
  return Math.round(x);
}

function round1(x) {
  return Math.round(x * 10)/10;
}

function round2(x) {
  return Math.round(x * 100)/100;
}

function round4(x) {
  return Math.round(x * 10000)/10000;
}

function round6(x) {
  return Math.round(x * 1000000)/1000000;
}


function radio_clear(r) {
  for (var i = 0; i < r.length; i++)
    r[i].checked = 0;
}

function radio_set(r, v) {
  for (var i = 0; i < r.length; i++)
    if (r[i].value == v) {
      r[i].checked = 1;
      return 1;
    }
  return 0;
}

function radio_get(r) {
  for (var i = 0; i < r.length; i++)
    if (r[i].checked)
      return r[i].value;
  return null;
}

function encodeURI_more(s) {
  s = encodeURI(s);
  s = s.replace(/\&/g, '%26');
  s = s.replace(/\=/g, '%3D');
  s = s.replace(/\+/g, '%2B');
  return s;
}

function exec_or_value(f, o) {
  if (typeof f != 'function')
    return f;
		// arguments.slice(2) doesn't work
  var a = [];
  for (var i = 2; i < arguments.length; i++)
    a.push(arguments[i]);
  return f.apply(o, a);
}

function word_param(k) {
  var a = location.search.match('(?:\\?|&)' + k + '=(\\w+)');
  return a && a[1];
}

function words_param(k) {
  var a = location.search.match('(?:\\?|&)' + k + '=([\\+\\w]+)');
  return a && a[1]? a[1].split('+') : [];
}

function twodigits(x) {
  return x < 10? '0' + x : x;
}

function default_timezone() {
  var d = new Date;
  var m = d.getTimezoneOffset();
  var s = (m > 0? '-' : '+');
  m = Math.abs(m);
  return s + twodigits(Math.floor(m / 60)) + twodigits(m - 60 * Math.floor(m / 60));
}


			///////////// ANGLES /////////////////

function read_angle(s) {
    // leading spaces and + or -
    var a = s.match(/^\s*([\+\-]?)(.*)/);
    s = a[2];
    var sign = a[1] == '-'? -1 : 1;
    
    // then the rest all digits or spaces or decimal point
    if (s.search(/[^\d\.\s]/) != -1)
        return null;

    // only one decimal point, and it must be on last element
    if (s.search(/\..*(\s|\.)/) != -1)
        return null;

    var dms = s.split(/\s+/);

    if (dms.length >= 3)
	return sign * ((dms[0] - 0) + ((dms[1] - 0) + (dms[2] - 0) / 60) / 60);
    else if (dms.length == 2)
	return sign * ((dms[0] - 0) + (dms[1] - 0) / 60);

    var l = s.indexOf('.');
    var frac;
    if (l < 0) {
      frac = 0;
      l = s.length;
    } else {
      frac = s.substring(l) - 0;
      s = s.substring(0, l);
    }

    if (l < 4)				// 44 or 108.  NOTE: 108 is 108 deg, not 1 deg 8'
	return sign * (s - 0 + frac);
    else if (l < 6)			// 4423 10804
	return sign * ((s.substring(0, l-2) - 0) + ((s.substring(l-2, l) - 0) + frac) / 60);
    else
	return sign * ((s.substring(0, l-4) - 0) + ((s.substring(l-4, l-2) - 0) + ((s.substring(l-2, l) - 0) + frac) / 60) / 60);
}

// HACK: mode is number of parts - 1, e.g. 0 for DD, 1 for 'DDMM', 2 for 'DDMMSS'
function format_angle(x, mode, pos_char, neg_char, is_html) {
  var a = expand_angle(Math.abs(x), mode);
  var s = '';
  var symbols = [is_html? '&deg;' : '', "'", '"'];
  for (var i = 0; i <= mode; i++)
    s += a[i] + symbols[i] + ' ';
  if (x < 0)
    if (neg_char)
      s += neg_char;
    else
      s = '-' + s;
  else if (pos_char)
   s += pos_char;

  return s;
}

function expand_angle(x, mode) {
  if (mode == 0)
    return [round6(x)];
  var d = Math.floor(x);
  x = 60 * (x - d);
  if (mode == 1)
    return [d, round4(x)];
  var m = Math.floor(x);
  x = 60 * (x - m);
  return [d, m, round2(x)];
}

function format_lat(x, mode, is_html) {
    return format_angle(x, mode, 'N', 'S', is_html);
}

function format_lon(x, mode, is_html) {
    return format_angle(x, mode, 'E', 'W', is_html);
}

function format_latlon(lat, lon, mode, is_html) {
  return    format_lat(lat, mode, is_html)
          + (is_html? '&nbsp;&nbsp;' : '  ')
          + format_lon(lon, mode, is_html);
}


			///////////// REQUESTS /////////////////

			//////////////////////////////////////// WT SPECIFIC

function signup() {
  var email = prompt("Give us an email address and\nwe'll send you news about the site", '');
  if (email)
    wt_async_request('/bin/subscribe.cgi?email=' + encodeURI_more(email), 'SUBSCRIBE',
						function(s) { alert(s.replace(/\n/g,'') + ' subscribed.  Thanks.') });
}

function results_file(id, filename) {
  return '/results/' + id + '/' + filename;
}

// DATA format: status lat lon elev elev-above-ground queued_time start_time end_time is_public declination name
var DATA_PUBLIC_INDEX = 8;
var DATA_NAME_INDEX = 11;

			//////////////////////////////////////// REQUESTS

// BUG: make all requests asynchronous, so browser doesn't get hung up if server hangs
//      To do so we could implement something like a list of requests, followed by a
//	function to call once they're all complete, and maybe a sempahore and a cancel routine


function _wt_request(url, error_label) {
  alert('1-'+url);
  var request  = GXmlHttp.create();
  request.open("GET", url, 0);
  request.send(null);
  alert('ici');
  alert(request.responseText);
  var o = parse_response(request);
  if (!o.ok && error_label)
    alert(error_label + ': ' +
		(  o.status_message?     o.status_message
		 : o.app_status_message? o.app_status_message
                 : 'request error'));
  return o;
}



function _wt_async_request_v2jg(url, error_label, callback) {
  alert('2-'+url);
  //var request  = GXmlHttp.create();
  var request = null; 
  if (window.XMLHttpRequest) // Firefox 
    request = new XMLHttpRequest(); 
  else if (window.ActiveXObject) // Internet Explorer 
    request = new ActiveXObject("Microsoft.XMLHTTP"); 
  else { // XMLHttpRequest non supporté par le navigateur 
    alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest..."); 
    return; 
  }
  url=location.href;
  alert(url);
  request.open("GET", url,  true);
  request.onreadystatechange = function() {
    if (request.readyState != 4)
      return;
    var o = parse_response(request);
    if (!o.ok && error_label)
      alert(error_label + ': ' +
		(  o.status_message?     o.status_message
		 : o.app_status_message? o.app_status_message
                 : 'request error'));
    callback(o);
  }
  request.send(null);
}


function _wt_async_request(url, error_label, callback) {
  //alert('2-'+url);
  //var testurl = ""
  //testurl = prompt("url",url)
  var request  = GXmlHttp.create();
  request.open("GET", url,  true);
  request.onreadystatechange = function() {
    if (request.readyState != 4)
      return;
    var o = parse_response(request);
    if (!o.ok && error_label)
      alert(error_label + ': ' +
		(  o.status_message?     o.status_message
		 : o.app_status_message? o.app_status_message
                 : 'request error'));
    callback(o);
  }
  request.send(null);
}

function wt_request(url, error_label) {
  alert('3-'+url);
  var o = _wt_request(url, error_label);
  return o.response;
}


function wt_async_request(url, error_label, callback) {
  //alert('4-'+url);
  _wt_async_request(url, error_label, function(o) { if (o.ok && o.response) callback(o.response); });
}
  

function wt_request_array(url, error_label, test) {
  alert('5-'+url);
  var o = _wt_request(url, error_label);
  if (!o.ok)
    return null;

		// get rid of final NL so we don't have extra field
  o.response_array = o.response.replace(/\n$/, '').replace(/\n/g, ' ').split(' ');
  if (test && !test(o.response_array)) {
    if (error_label)
      alert(error_label + ': invalid response');
    return null;
  }

  return o.response_array;
}

function wt_async_request_array(url, error_label, test, callback) {
  alert('6-'+url);
  _wt_async_request(url, error_label, function(o) {
    if (!o.ok)
      return;
		// get rid of final NL so we don't have extra field
    o.response_array = o.response.replace(/\n$/, '').replace(/\n/g, ' ').split(' ');
    if (test && !test(o.response_array)) {
      if (error_label)
        alert(error_label + ': invalid response');
      return;
    }
    if (o.response_array)
      callback(o.response_array)
  });
}

function wt_request_array_of_lines(url, name) {
  alert('7-'+url);
  var s = wt_request(url, name);
  if (s == null)
    return null;
	// pop off last element, which will be blank (if response ends with \n)
  var a = s.split('\n');
  a.pop();
  return a;
}

function wt_async_request_array_of_lines(url, name, callback) {
  //alert('8-'+url);
	// pop off last element, which will be blank (if response ends with \n)
  wt_async_request(url, name, function(s) { var a = s.split('\n'); a.pop(); callback(a); });
}

function parse_response(request) {
  alert(request.responseText);
  var o = {ok: 0,
	   response: null,
	   http_status_code: null,
	   http_status_message: null,
	   app_status_code: null,
	   app_status_message: null};

  o.http_status_code    = request.status;
  o.http_status_message = request.statusText;
  if (request.status != 200)
    return o;

  var s;
  var a;
  try { s = request.getResponseHeader('X-App-Status'); } catch(e) {}
  if (s && (a = s.match(/^(\d\d\d)\s+(.+)/))) {
    o.app_status_code    = a[1];
    o.app_status_message = a[2];
    if (a[0] != 200)
      return o;
  }

  o.ok             = 1;
  o.response       = request.responseText;
  alert(o.response);
  
  return o;
}

