
// Note DUP in info.php.
var REGION_MAP = {"Alaska":"AK","Alabama":"AL","Arkansas":"AR","American Samoa":"AS","Arizona":"AZ","California":"CA","Colorado":"CO","Connecticut":"CT","Delaware":"DE","District of Columbia":"DC","Florida":"FL","Federated States of Micronesia":"FM","Georgia":"GA","Guam":"GU","Hawaii":"HI","Iowa":"IA","Idaho":"ID","Illinois":"IL","Indiana":"IN","Kansas":"KS","Kentucky":"KY","Louisiana":"LA","Massachusetts":"MA","Maryland":"MD","Maine":"ME","Marshall Islands":"MH","Michigan":"MI","Minnesota":"MN","Mississippi":"MS","Missouri":"MO","Northern Mariana Islands":"MP","Montana":"MT","North Carolina":"NC","North Dakota":"ND","Nebraska":"NE","New Hampshire":"NH","New Jersey":"NJ","New Mexico":"NM","Nevada":"NV","New York":"NY","Ohio":"OH","Oklahoma":"OK","Oregon":"OR","Pennsylvania":"PA","Puerto Rico":"PR","Palau":"PW","Rhode Island":"RI","South Carolina":"SC","South Dakota":"SD","Tennessee":"TN","Texas":"TX","Utah":"UT","Virginia":"VA","Virgin Islands":"VI","Vermont":"VT","Washington":"WA","Wisconsin":"WI","West Virginia":"WV","Wyoming":"WY"};
var COUNTRY_MAP = {"United States": "US", "United Kingdom": "UK"};

var myIp = getCookie('myIp');
var myLocation = getCookie('myLocation');
var myLat = getQueryParam('lat') || getCookie('myLat');
var myLong = getQueryParam('long') || getCookie('myLong');
var myIpInfo = null;
var myProxies = null;
var pingTimeoutId = null;
var isProxiesRendered = false;
var myKey = null;
var maxProxyBarSpeed;

function nin_onIp(ip) {
  myIp = ip;
  if (myIp) {
    setCookie('myIp', myIp);
  }
}

function nin_onProxies(proxies) {
  myProxies = proxies;
  if (myProxies) {
    for (var i = 0; i < myProxies.length; i++) {
      myProxies[i]['location'] = '(' + getLocation(
          myProxies[i]['country'],
          myProxies[i]['region'],
          myProxies[i]['city']) + ')';
    }
    if (myLat && myLong) {
      computeProxySpeeds();
    }
    // sort them.
    myProxies.sort(function(a, b) {
      if (a['free'] && !b['free']) {
        return -1;
      } else if (!a['free'] && b['free']) {
        return 1;
      } else if (a['e_speed'] && !b['e_speed']) {
        return -1;
      } else if (b['e_speed'] && !a['e_speed']) {
        return 1;
      } else if (!b['e_speed'] && !a['e_speed']) {
        return 0;
      } else {
        return (a['e_speed'] < b['e_speed']) ? -1 : 1;
      }
    });
  }
}

function pingProxies() {
  for (var i = 0; i < myProxies.length; i++) {
    if (!myProxies[i]['pinged'] && !myProxies[i]['speed']) {
      myProxies[i]['pinged'] = true;
      pingProxy(i);
      return;
    }
  }
  for (var i = 0; i < myProxies.length; i++) {
    if (!myProxies[i]['pinged']) {
      myProxies[i]['pinged'] = true;
      pingProxy(i);
      return;
    }
  }
}

function pingProxy(i) {
  myProxies[i]['start'] = new Date().getTime();
  loadScript(myProxies[i]['r_url'] + '?ninping=' + i + '&r=' + Math.random());
  pingTimeoutId = setTimeout(function(){ nin_onPing(i, false); }, 2000);
}

function nin_onPing(i, isFailure) {
  if (!isFailure) {
    clearTimeout(pingTimeoutId);
  }
  if (!myProxies[i]['done'] && !isFailure) {
    myProxies[i]['speed'] = new Date().getTime() - myProxies[i]['start'];
    if (!isProxiesRendered) {
      pingProxies();
    }
  }
}

function renderProxies() {
  isProxiesRendered = true;
  myProxies.sort(function(a, b) {
    if (a['speed'] && !b['speed']) {
      return -1;
    } else if (b['speed'] && !a['speed']) {
      return 1;
    } else if (!b['speed'] && !a['speed']) {
      return 0;
    } else {
      return (a['speed'] < b['speed']) ? -1 : 1;
    }
  });
  for (i = 0; i < Math.min(3, myProxies.length); i++) {
    document.getElementById('proxy-ip-' + i).innerHTML = myProxies[i]['ip'];
    document.getElementById('proxy-loc-' + i).innerHTML = myProxies[i]['location'];
  }
  saveSpeedData();
}

function saveSpeedData() {
  var out = [];
  for (i = 0; i < myProxies.length; i++) {
    if (myProxies[i]['speed']) {
      out.push(myProxies[i]['ip'] + ':' + myProxies[i]['speed']);
    }
  }
  setCookie('nin_spd', out.join('|'));
}

function loadSpeedData() {
  var count = 0;
  var out = getCookie('nin_spd');
  if (out) {
    var parts = out.split('|');
    for (var i = 0; i < parts.length; i++) {
      var ipSpeed = parts[i].split(':');
      if (ipSpeed.length == 2) {
        for (j = 0; j < myProxies.length; j++) {
          if (myProxies[j]['ip'] == ipSpeed[0]) {
            var speed = parseInt(ipSpeed[1], 10);
            myProxies[j]['speed'] = speed;
            count++;
          }
        }
      }
    }
  }
  return count;
}

// based on distance from host, regression constants, and normalized host speed
function computeProxySpeeds() {
  myLat = parseFloat(myLat);
  myLong = parseFloat(myLong);
  var minEstSpeed = 2000;
  for (i = 0; i < myProxies.length; i++) {
    var proxLat = parseFloat(myProxies[i]['lat']);
    var proxLong = parseFloat(myProxies[i]['long']);
    if (!myLat || !myLong || !proxLat || !proxLong) {
      myProxies[i]['e_speed'] = 2000;
      continue;
    }
    var dist = getLatLongDist(myLat, myLong, proxLat, proxLong);
    var reg_B = parseFloat(myProxies[i]['b']);
    var reg_M = parseFloat(myProxies[i]['m']);
    var estSpeed = Math.round(reg_B + reg_M * dist);
    var normSpeed = parseFloat(myProxies[i]['norm_speed']);
    if (normSpeed) {
      estSpeed += normSpeed;
    }
    estSpeed = Math.round(estSpeed);
    if (estSpeed > 2000) {
      estSpeed = 2000;
    }
    myProxies[i]['e_speed'] = estSpeed;
    if (estSpeed < minEstSpeed) {
      minEstSpeed = estSpeed;
    }
  }
  if (minEstSpeed < 100) {  // correction required
    for (i = 0; i < myProxies.length; i++) {
      myProxies[i]['e_speed'] += 100 - minEstSpeed;
    }
  }
  computeMaxProxyBarSpeed();
}

function computeMaxProxyBarSpeed() {
  var speeds = [];
  for (i = 0; i < myProxies.length; i++) {
    if (myProxies[i]['e_speed']) {
      speeds.push(myProxies[i]['e_speed']);
    }
  }
  speeds.sort(function(a,b){return a-b;});
  var median = speeds[Math.round(speeds.length/2)];
  var thres = 0;
  while (thres < median) {
    thres += 100;
  }
  maxProxyBarSpeed = Math.round(Math.max(thres * 3, speeds[speeds.length - 1] * 1.2));
}

function nin_onIpLoc(info) {
  myIpInfo = info;
  if (info) {
    myLocation = getLocation(info['CountryName'] || info['CountryCode'],
        info['RegionName'], info['City']);
    myLat = info['Latitude'];
    myLong = info['Longitude'];
    setCookie('myLocation', myLocation);
    setCookie('myLat', myLat);
    setCookie('myLong', myLong);
  }
}

function nin_onKey(key) {
  myKey = key;
  var keyElem = document.getElementById('my-key');
  if (keyElem) {
    keyElem.value = key;
  }
}

function getLocation(country, region, city) {
  var loc = 'unknown';
  loc = country;
  if (region && country) {
    loc = region + ', ' + (COUNTRY_MAP[country] || country);
  }
  if ((country == 'US' || country == 'United States') && REGION_MAP[region] && city) {
    loc = city + ', ' + REGION_MAP[region];
  }
  return loc;
}

/****/

function loadScript(src) {
  var script = document.createElement('script');
  script.src = src;
  var head = document.getElementsByTagName('head')[0];
  head.appendChild(script);
}

function setCookie(name, value, days) {
  days = days || 31;
  if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = '; expires='+date.toGMTString();
	}
	else var expires = '';
  var domain = document.location.href.toLowerCase().indexOf('newipnow.com') >= 0 ? 'domain=newipnow.com;' : '';
	document.cookie = name+"="+escape(value)+expires+"; " + domain + " path=/";
}

function getCookie(cookieName) {
  var results = document.cookie.match('(^|;) ?' + cookieName + '=([^;]*)(;|$)');
  if (results) return unescape(results[2]);
  else return null;
}

function getQueryParam(param) {
  var index = location.search.indexOf(param + '=');
  if (index >= 0 && location.search.length >= param.length + 1) {
    var val = location.search.substring(index + param.length + 1);
    index = val.indexOf('&');
    return (index >= 0) ? val.substring(0, index) : val;
  }
  return null;
}

/****/

function getLatLongDist(lat1, lon1, lat2, lon2) {
	var radlat1 = Math.PI * lat1/180;
	var radlat2 = Math.PI * lat2/180;
	var radlon1 = Math.PI * lon1/180;
	var radlon2 = Math.PI * lon2/180;
	var theta = lon1-lon2;
	var radtheta = Math.PI * theta/180;
	var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
	dist = Math.acos(dist);
	dist = dist * 180/Math.PI;
	dist = dist * 60 * 1.1515;
	return dist; // miles
}                                            

