// Main script for GoogleSatTrack var 3.6
// Copyright:: Copyright (C) 2009 Isana Kashiwai<isana at lizard-tail.com>
// License::  GPL
// Update:: 20.01.21

/*
history
development release for 3.6.0 (20091101): 
- always full screen
- movable data window
development release for 3.6.0 (20091102): 
- IE support
development release for 3.6.0 (20091202): 
-periodical retrieving of default settings & satellites list
-changed or added functions
  *delete "Defaults"
  *delete "Satellite"
  *change "long_updator"
  *change "set_defaults"
  *add "SatelliteListLoader"
3.6.0 (20091221): 
  first release ver 3.6.0
3.6.1 (20091223): 
- "glued" cursor problem 
  *change "onMouseMove"
3.6.2 (20100103)
- fixed a bug that the satellte dose not appear on the ground track.
 *change Clock.prototype.GMST on "sgp4.js"
3.6.3 (20100121)
- "mile" to "sm" 
- "ml/s" to "mph"
- "km/s" to "km/h"
---
versioning schemes  
  "major.minor.revision (update)"
  The major number is increased when there are significant jumps in functionality, 
  the minor number is incremented when only minor features or significant fixes have been added, 
  and the revision number is incremented when minor bugs are fixed.
*/


function Pref(){}

function now_sec(){
  var d = new Date();
  var year=d.getUTCFullYear();
  var month=d.getUTCMonth();
  var day=d.getUTCDate();
  var hours=d.getUTCHours();
  var minutes=d.getUTCMinutes();
  var seconds=d.getUTCSeconds();
  var now_sec=Date.UTC(year, month-1, day, hours, minutes, seconds);
  return now_sec;
}

function createXMLhttpObject(){
  XMLhttpObject = false;
  if(window.XMLHttpRequest) {
    XMLhttpObject = new XMLHttpRequest();
  }else if(window.ActiveXObject) {
    try {
      XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
    }catch(e){
      XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return XMLhttpObject;
}

function DataLoader(callback,data,resp,async) {
  XMLhttpObject=createXMLhttpObject();
  if (!XMLhttpObject){return;}
  XMLhttpObject.open("GET", data, async);
  XMLhttpObject.send(null);
  if(async==false){
    try{
      if(resp == "xml"){
      var data = XMLhttpObject.responseXML;
      }else{
      var data = XMLhttpObject.responseText;
      }
      callback(data);
    }catch(e){
      var pref = new Pref();
      if(pref.status == "startup"){
        var str = '<div style="line-height:1.5em;font-size:x-large;margin-top:5em;text-align:center"><strong>GoogleSatTrack is temporary unavailable due to heavy traffic.<br>Please try again later.</strong><br><br><img src="image/iss.png"></div>';
        document.getElementById("map").innerHTML = str;
      }else{
        return;
      }
    }
  }else{
    try{
      XMLhttpObject.onreadystatechange = function() {
        if(XMLhttpObject.readyState == 4){
          if(XMLhttpObject.status == 200){
            if(resp == "xml"){
            var data = XMLhttpObject.responseXML;
            }else{
            var data = XMLhttpObject.responseText;
            }
            callback(data);
          }
        }else{
          return;
        }
      }
    }catch(e){
      var pref = new Pref();
      if(pref.status == "startup"){
        var str = '<div style="line-height:1.5em;font-size:x-large;margin-top:5em;text-align:center"><strong>GoogleSatTrack is temporarily unavailable due to heavy traffic.<br>Please try again later.</strong><br><br><img src="image/iss.png"></div>';
        document.getElementById("map").innerHTML = str;
      }else{
        return;
      }
    }
  }
}

//callback methods for DataLoader
XMLLoader = function(xmlData){
  var data_type = xmlData.getElementsByTagName('data_type')[0].childNodes[0].nodeValue;
  if (data_type == "TLE"){
  var sat_name = xmlData.getElementsByTagName('sat_name')[0].childNodes[0].nodeValue;
  var first_line = xmlData.getElementsByTagName('first_line')[0].childNodes[0].nodeValue;
  var second_line = xmlData.getElementsByTagName('second_line')[0].childNodes[0].nodeValue;
  Pref.prototype.tmp_first_line=first_line;
  Pref.prototype.tmp_second_line=second_line;
      }
}

DefaultSettingLoader = function(jsonData){
  Default = eval("("+jsonData+")");
  return;
}

SatelliteListLoader = function(jsonData){
  Satellite = eval("("+jsonData+")");
  return;
}

GroundTrackLoader=function(jsonData){
  Pref.prototype.gt = eval("("+jsonData+")");
  return;
}

function setStaticData(){
  var pref = new Pref();
  if(pref.msg){
  document.getElementById("message").style.display="block";
  document.getElementById('message').innerHTML = pref.msg;
  }
  if(!pref.sat2_name){
  document.title = "GoogleSatTrack - " + pref.sat1_name;
  }else{
  document.title = "GoogleSatTrack - " + pref.sat1_name + " & " + pref.sat2_name;
  }
  delete pref;
}

//initialization of the map
var map;
function InitMap(){
  var pref = new Pref();
  var date = new Date();
  var position = pref.sat1_orbit.calc(date);  
  var default_position = position.latlng();
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map"));
    map.disableDragging();
    map.addControl(new GSmallZoomControl());
    map.addControl(new GMapTypeControl());
    map.addControl(new GOverviewMapControl());
    map.addControl(new GScaleControl());
    
    InitMask();
    showMask();

    GEvent.addListener(map, "zoomend", function(oldLevel,newLevel){
      map_zoomed(oldLevel,newLevel);
    })
    if(pref.zoom<=pref.minimum_zoom){
      map.setCenter(new GLatLng(0,0),pref.zoom,G_SATELLITE_MAP);
      Pref.prototype.move_mode = "static";  
    }else{
      map.setCenter(new GLatLng(default_position.latitude,default_position.longitude), pref.zoom,G_SATELLITE_MAP);
      Pref.prototype.move_mode = "dynamic";  
    }
  }
  delete pref;
}

function map_zoomed(oldLevel,newLevel){
  var pref = new Pref();
  if(pref.status!="startup"){
    setMoveMode(false)
  }
  delete pref;
};

function setMoveMode(recenter){
  var zoom = map.getZoom();
  var pref = new Pref
  var prev_move_mode = pref.move_mode;
  var move_mode = pref.move_mode;
  if(zoom<=pref.minimum_zoom){
    move_mode = "static";
    if(prev_move_mode=="dynamic"||recenter==true){
      map.setCenter(new GLatLng(0,0),zoom,map.getCurrentMapType());
    }
  }else{
    move_mode = "dynamic";  
    if(prev_move_mode=="static"||recenter==true){
      map.setCenter(new GLatLng(pref.sat_lat,pref.sat_lng),zoom,map.getCurrentMapType());
   }
  }
  Pref.prototype.move_mode = move_mode;
  setIndicator()
delete pref;
}

RightMask = function (image,width,height) {
  this.image_ = image;
  this.width_ = width;
  this.height_ = height;
 
}
RightMask.prototype = new GControl()

RightMask.prototype.initialize = function(map) {
  var container = document.createElement("div");
  container.style.zIndex = 1;  
  var RightMaskDiv = document.createElement("div");
  RightMaskDiv.setAttribute('id','right_mask');
  RightMaskDiv.width = this.width_ + "px";
  RightMaskDiv.height = this.height_ + "px";
  RightMaskDiv.innerHTML="<img src='./image/gray.png' width='"+this.width_+"' height='"+this.height_+"'>";
  container.appendChild(RightMaskDiv);
  map.getContainer().appendChild(container);
  return container;
}
RightMask.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, 0));
}


LeftMask = function (image,width,height) {
  this.image_ = image;
  this.width_ = width;
  this.height_ = height;
}

LeftMask.prototype = new GControl()

LeftMask.prototype.initialize = function(map) {
  var container = document.createElement("div");
  container.style.zIndex = 1;  
  
  var LeftMaskDiv = document.createElement("div");
  LeftMaskDiv.setAttribute('id','left_mask');
  LeftMaskDiv.width = this.width_ + "px";
  LeftMaskDiv.height = this.height_ + "px";
  LeftMaskDiv.innerHTML="<img src='./image/gray.png' width='"+this.width_+"' height='"+this.height_+"'>";
  container.appendChild(LeftMaskDiv);
  map.getContainer().appendChild(container);
  return container;
}
LeftMask.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(0, 0));
}

function InitMask(){
  var map_area = document.getElementById("map");
  if (map_area.hasChildNodes()) {
    var children = map_area.childNodes;
    var zindex=0
    for (var i = 0; i < children.length; i++){
      var prev_zindex = zindex;
      if(children[i].style.zIndex){
        zindex = children[i].style.zIndex;
      }else{
        zindex = 0;
      }
      children[i].style.zIndex = zindex+2;
      if(prev_zindex>=zindex){
        var smallest_zindex=zindex;
      }
    }
  }
  var map_pane = map.getPane(G_MAP_FLOAT_PANE).parentNode.parentNode;
  map_pane.style.zIndex="0";

  return
}

function removeMask(){
  if(left_mask){
    map.removeControl(left_mask)
  }
  if(right_mask){
    map.removeControl(right_mask)
  }
}

function showMask(){
  var pref = new Pref();
  var area = map.getSize();
  var zoom = map.getZoom();
  if(zoom<=pref.minimum_zoom){
    switch(zoom){
      case 0:
      var width = Math.floor((area.width-256)/2);
      break;
      case 1:
      var width = Math.floor((area.width-512)/2);
      break;
      case 2:
      var width = Math.floor((area.width-1024)/2);
      break;
      case 3:
      var width = Math.floor((area.width-2048)/2);
      break;
      case 4:
      var width = Math.floor((area.width-4096)/2);
      break;
      default:
      var width = "0";
    }
  }else{
    switch(zoom){
      case 0:
      var width = area.width - (256-13);
      break;
      case 1:
      var width = area.width - (512-25);
      break;
      case 2:
      var width = area.width - (1024-50);
      break;
      case 3:
      var width = area.width - (2048-100);
      break;
      case 4:
      var width = area.width - (4096-200);
      break;
      default:
      var width = "0";
    }
  }
  if(width<0){width = 0}
    left_mask = new LeftMask("./image/gray.png",width+1,area.height)
    right_mask = new RightMask("./image/gray.png",width,area.height)
    
    map.addControl(left_mask);
    map.addControl(right_mask);
   return;
}


createMarker = function(point,icon_image,icon_shadow,icon_size) {
  var sat_icon = new GIcon();
  sat_icon.image = icon_image;
  sat_icon.shadow = icon_shadow;
  sat_icon.iconSize = new GSize(icon_size, icon_size);
  sat_icon.shadowSize = new GSize(icon_size, icon_size);
  sat_icon.iconAnchor = new GPoint(icon_size/2, icon_size/2);
  this.create = new GMarker(point, sat_icon);
}

PostionString = function(latitude,longitude,altitude,velocity){
  var lat_integer = Math.floor(latitude);
  var long_integer = Math.floor(longitude);
  if (lat_integer>0){
    var lat_decimal = Math.floor((latitude-lat_integer)*60*100)/100;
    var lat = Math.abs(lat_integer)+"&deg;&nbsp;" + Math.abs(lat_decimal) + "&prime;&nbsp;N"
  }else{
    var lat_decimal = Math.floor(6000-(latitude-lat_integer)*60*100)/100;
    var lat = Math.abs(lat_integer+1)+"&deg;&nbsp;" + Math.abs(lat_decimal) + "&prime;&nbsp;S"
  }
  if (long_integer>0){
    var long_decimal = Math.floor((longitude-long_integer)*60*100)/100;
    var long = Math.abs(long_integer)+"&deg;&nbsp;" + Math.abs(long_decimal) + "&prime;&nbsp;E"
  }else{
    var long_decimal = Math.floor(6000-(longitude-long_integer)*60*100)/100;
    var long = Math.abs(long_integer+1)+"&deg;&nbsp;" + Math.abs(long_decimal) + "&prime;&nbsp;W"
  }
  var pref = new Pref();

  if(pref.unit=="mile"){
    var v_unit = "mph";
    var d_unit = "sm";
    var u = 0.621371192;
  }else{
    var v_unit = "km/h";
    var d_unit = "km";
    var u = 1;
  }
  
  var alt = Math.floor(Number(altitude)*u*1000)/1000 + " " + d_unit;
  var v = Math.floor(Number(velocity)*u*1000*3600)/1000 + " " + v_unit;;
  
  delete pref;
  
  this.latitude = lat;
  this.longitude = long;
  this.altitude = alt;
  this.velocity = v;
  return this;
}

CalcSat = function(){
  var pref = new Pref();
  var zoom = map.getZoom();
  var mode = pref.mode;
  var move_mode = pref.move_mode;
  var date = new Date();

  var sat1_icon_image = pref.sat1_icon_image;
  var sat1_icon_shadow = pref.sat1_icon_shadow;
  var sat1_icon_size = pref.sat1_icon_size;

  var position = pref.sat1_orbit.calc(date);
  var sat1_position = position.latlng();
  Pref.prototype.sat_lat = sat1_position.latitude;
  Pref.prototype.sat_lng = sat1_position.longitude;

  var marker1 = new createMarker(new GLatLng(Number(sat1_position.latitude),Number(sat1_position.longitude)),sat1_icon_image,sat1_icon_shadow);

  map.removeOverlay(sat_marker1);
  var m1 = new createMarker(new GLatLng(Number(sat1_position.latitude),Number(sat1_position.longitude)),sat1_icon_image,sat1_icon_shadow,sat1_icon_size);
  sat_marker1 = m1.create;
  map.addOverlay(sat_marker1);
  if(move_mode == "dynamic"){
    map.panTo(new GLatLng(Number(sat1_position.latitude), Number(sat1_position.longitude)), zoom);
  }
  var position_str1 = new PostionString(sat1_position.latitude,sat1_position.longitude,sat1_position.altitude,sat1_position.velocity);
  var doc = document;
  doc.getElementById("sat1_name").innerHTML = pref.sat1_name; 
  doc.getElementById("sat1_lat").innerHTML = position_str1.latitude;
  doc.getElementById("sat1_long").innerHTML = position_str1.longitude;
  doc.getElementById("sat1_alt").innerHTML = position_str1.altitude;
  doc.getElementById("sat1_v").innerHTML = position_str1.velocity;

  if(mode == "double" || mode == "triple"){
    var sat2_icon_image = pref.sat2_icon_image;
    var sat2_icon_shadow = pref.sat2_icon_shadow;
    var sat2_icon_size = pref.sat2_icon_size;
    var position = pref.sat2_orbit.calc(date);
    var sat2_position = position.latlng();
    var marker2 = new createMarker(new GLatLng(Number(sat2_position.latitude),Number(sat2_position.longitude)),sat2_icon_image,sat2_icon_shadow);
    map.removeOverlay(sat_marker2);
    var m2 = new createMarker(new GLatLng(Number(sat2_position.latitude),Number(sat2_position.longitude)),sat2_icon_image,sat2_icon_shadow,sat2_icon_size);
    sat_marker2 = m2.create;
    map.addOverlay(sat_marker2);

    var position_str2 = new PostionString(sat2_position.latitude,sat2_position.longitude,sat2_position.altitude,sat2_position.velocity);
    var doc = document;
    doc.getElementById("sat2_name").innerHTML = pref.sat2_name; 
    doc.getElementById("sat2_lat").innerHTML = position_str2.latitude;
    doc.getElementById("sat2_long").innerHTML = position_str2.longitude;
    doc.getElementById("sat2_alt").innerHTML = position_str2.altitude;
    doc.getElementById("sat2_v").innerHTML = position_str2.velocity;
   }
   
  if(mode == "double"){
    if(pref.unit=="mile"){
      var d_unit = "sm";
      var u = 0.621371192;
    }else{
      var d_unit = "km";
      var u = 1;
    }

    var distance = Math.sqrt((sat1_position.x-sat2_position.x)*(sat1_position.x-sat2_position.x)+(sat1_position.y-sat2_position.y)*(sat1_position.y-sat2_position.y)+(sat1_position.z-sat2_position.z)*(sat1_position.z-sat2_position.z))
    if (distance<50){
      distance = "less than 50";
    }else{
      distance = Math.floor(distance*u*100)/100;
    }

    doc.getElementById("distance").innerHTML = "Distance  : " + distance + " " + d_unit; 

  }
  if(mode=="triple"){
    var sat3_icon_image = pref.sat3_icon_image;
    var sat3_icon_shadow = pref.sat3_icon_shadow;
    var sat3_icon_size = pref.sat3_icon_size;
    var position = pref.sat3_orbit.calc(date);
    var sat3_position = position.latlng();
    var marker3 = new createMarker(new GLatLng(Number(sat3_position.latitude),Number(sat3_position.longitude)),sat3_icon_image,sat3_icon_shadow);
    map.removeOverlay(sat_marker3);
    var m3 = new createMarker(new GLatLng(Number(sat3_position.latitude),Number(sat3_position.longitude)),sat3_icon_image,sat3_icon_shadow,sat3_icon_size);
    sat_marker3 = m3.create;
    map.addOverlay(sat_marker3);  
  }

  delete pref;
    window.setTimeout("CalcSat();",1000);
}


function GTStaticMode(){
  var pref = new Pref();
  if(pref.gt){
    var gt = pref.gt.data;
    var data_length = gt.length-1;
    var orbit = 0;
    var start_lng = gt[0].lng;
    if(start_lng>0){
      var prev_sign="+";
    }else{
      var prev_sign="-";
    }
    var gt_array = []
  
    for(i=0; i<data_length; i++){  
      if(gt[i].lng<0){
        var sign = "-";
      }else if(gt[i].lng>0){
        var sign = "+";
      }
      if(prev_sign != sign && prev_sign != "-"){
        orbit++
      }
      if(!gt_array[orbit]){
        gt_array[orbit]=[]
      }
      gt_array[orbit].push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      var prev_sign = sign;
    }
    var gt_array_length = gt_array.length;
    for (i=0;i<gt_array_length;i++){
        var gt_polyline = new GPolyline(gt_array[i].reverse(),"#ff0000",1,1)
        map.addOverlay(gt_polyline);
    }
  }else{
    alert("Ground track is temporarily unsavailable.\n Sorry for any inconvenient.");
    document.forms[0].elements[0].checked=false
    Pref.prototype.ground_track_flag=false;
  }
  delete pref;
  return;
}

function GTDynamicMode(){
  var pref = new Pref();
  if(pref.gt){
    var gt = pref.gt.data;
    var data_length = gt.length-1;
    var gt_array1=[],gt_array2=[],gt_array3=[],gt_array4=[],gt_array5=[],gt_array6=[];
    for(i=0; i<data_length; i++){
      if(i<=60){
        gt_array1.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
      if(i>=60&&i<=120){
        gt_array2.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
      if(i>=90&&i<=150){
        gt_array3.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
      if(i>=150&&i<=210){
        gt_array4.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
      if(i>=180&&i<=240){
        gt_array5.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
      if(i>=240){
        gt_array6.push(new GLatLng(Number(gt[i].lat),Number(gt[i].lng)));
      }
    }
    gt_polyline1 = new GPolyline(gt_array1,"#ff0000",1,1);
    gt_polyline2 = new GPolyline(gt_array2.reverse(),"#ff0000",1,1);
    gt_polyline3 = new GPolyline(gt_array3,"#ff0000",1,1);
    gt_polyline4 = new GPolyline(gt_array4.reverse(),"#ff0000",1,1);
    gt_polyline5 = new GPolyline(gt_array5,"#ff0000",1,1);
    gt_polyline6 = new GPolyline(gt_array6.reverse(),"#ff0000",1,1);
    
    map.addOverlay(gt_polyline1);
    map.addOverlay(gt_polyline2);
    map.addOverlay(gt_polyline3);
    map.addOverlay(gt_polyline4);
    map.addOverlay(gt_polyline5);
    map.addOverlay(gt_polyline6);  
  }else{
    alert("Ground track is temporary unsavailable.\n Sorry for any inconvenient.");
    document.forms[0].elements[0].checked=false
    Pref.prototype.ground_track_flag=false;
  }
  delete pref;
  return;

}

function showGroundTrack(){
  var pref = new Pref();
  if(pref.move_mode=="static"){
    GTStaticMode();
  }else{
    GTDynamicMode();  
  }
  delete pref;
}




function showLatLngLines(){
  for (i = 0; i < 12; i++) {
    var lat = (i-9)*30;
    var center= map.getCenter();
    var center_lng = center.lng() 
    if(center_lng>0){
      lng_polyline1 = new GPolyline([new GLatLng(lat,0),new GLatLng(lat,-179)],"#777777",1,0.5);
      lng_polyline2 = new GPolyline([new GLatLng(lat,center_lng),new GLatLng(lat,0)],"#777777",1,0.5);
      lng_polyline3 = new GPolyline([new GLatLng(lat,center_lng),new GLatLng(lat,179)],"#777777",1,0.5);
      lng_polyline4 = new GPolyline([new GLatLng(lat,-179),new GLatLng(lat,-30)],"#777777",1,0.5);
    }else{
      lng_polyline1 = new GPolyline([new GLatLng(lat,180),new GLatLng(lat,30)],"#777777",1,0.5);
      lng_polyline2 = new GPolyline([new GLatLng(lat,center_lng),new GLatLng(lat,-179)],"#777777",1,0.5);
      lng_polyline3 = new GPolyline([new GLatLng(lat,center_lng),new GLatLng(lat,0)],"#777777",1,0.5);
      lng_polyline4 = new GPolyline([new GLatLng(lat,0),new GLatLng(lat,179)],"#777777",1,0.5);
    }
      map.addOverlay(lng_polyline1);
      map.addOverlay(lng_polyline2);
      map.addOverlay(lng_polyline3);
      map.addOverlay(lng_polyline4);
  }
  for (i = 0; i < 12; i++) {
    var lng = i*30;
    lat_polyline = new GPolyline([new GLatLng(-85,lng),new GLatLng(85,lng)],"#777777",1,0.5);
    map.addOverlay(lat_polyline);
  }
}


function short_updator(){
  var pref = new Pref();
  if(pref.status != "startup"){
    setIndicator()
  }
  delete pref;
  window.setTimeout("short_updator();",300000);
}

function mid_updator(){
  var pref = new Pref();
  if(pref.status != "startup"){
    if(pref.ground_track_flag){
      DataLoader(GroundTrackLoader,pref.gt_query1,"text",false);
       var now = now_sec();
       Pref.prototype.gt_loaded = now;
   }
  }
    delete pref;
    window.setTimeout("mid_updator();",1200000);
}

function long_updator(){
  var pref = new Pref();
  if(pref.status != "startup"){
    var nocache = "?nocache=" +(new Date()).getTime();
    DataLoader(DefaultSettingLoader,"./default.json"+nocache,"text",false);
    DataLoader(SatelliteListLoader,"./satellites.json"+nocache,"text",false);
    sat_loader(pref.target);
    setIndicator()
  }
    delete pref;
    window.setTimeout("long_updator();",3600000);
}

function setIndicator(){
  var pref = new Pref();
  map.clearOverlays();
  removeMask()
  if(pref.latlngline_flag == true){
    showLatLngLines();
  }
  if((pref.night_shade_flag == true) || (pref.terminator_flag == true)){
    if(pref.night_shade_flag == true){
      night_shade = true;
    }else{
      night_shade = false    
    }
    if(pref.terminator_flag == true){
      boundary = true;
    }else{
      boundary = false;
    }
  var date = new Date();
  var terminator = new Terminator(date);
  terminator.show(map,boundary,night_shade);
  }
  if(pref.ground_track_flag == true){
    var ground_track = showGroundTrack();
  }
  showMask()
  delete pref;
}

function scanIndicator(){
  var pref = new Pref();
  if (document.forms[0].elements[0].checked){
      var now = now_sec();
      var e = now - pref.gt_loaded; 
 if(pref.ground_track_flag == true && e > 600000){
      DataLoader(GroundTrackLoader,pref.gt_query1,"text",false);
      Pref.prototype.gt_loaded = now;
    }
    Pref.prototype.ground_track_flag=true;
  }else{
    Pref.prototype.ground_track_flag=false;
  }
  if (document.forms[0].elements[1].checked){
    Pref.prototype.latlngline_flag=true;
  }else{
    Pref.prototype.latlngline_flag=false;
  }
  if (document.forms[0].elements[2].checked){
    if(document.forms[0].elements[3].options[0].selected){
      Pref.prototype.night_shade_flag=true;
      Pref.prototype.terminator_flag=false;
    }else if(document.forms[0].elements[3].options[1].selected){
      Pref.prototype.night_shade_flag=false;
      Pref.prototype.terminator_flag=true;
    }
  }else{
     Pref.prototype.night_shade_flag=false;
     Pref.prototype.terminator_flag=false;
  }
  if(document.forms[0].elements[4].options[0].selected){
    Pref.prototype.unit="km";
  }else if(document.forms[0].elements[4].options[1].selected){
    Pref.prototype.unit="mile";
  }
  setIndicator()
}

function showConfig(){
  var pref = new Pref();

  if (pref.config_window==false){
var element = document.createElement('div'); 
element.setAttribute('id', "config_panel_bk");

  var estyle = element.style;
  estyle.cssText  = 'filter: alpha(opacity=60); -moz-opacity:0.60; opacity:0.60;';
  estyle.backgroundColor = 'black';
  estyle.width = '768px';
  estyle.height = '512px';
  estyle.position = 'absolute';
  estyle.zIndex = '100';

  var element2 = document.createElement('div'); 
  element2.setAttribute('id', "config_panel");
  
  var estyle2 = element2.style;
  estyle2.cssText  = 'filter: alpha(opacity=100); -moz-opacity:1.0; opacity:1.0;';
  estyle2.width = '768px';
  estyle2.height = '512px';
  estyle2.position = 'absolute';
  estyle2.zIndex = '101';


  var satnum = Satellite.sat_list.length;
  var cp_str = "";
  cp_str += '<div style="text-align:center;">';
  cp_str += '<div style="width:600px;margin:1em auto auto auto;color:#ffffff;line-height:1.2em;text-align:left;">';
  cp_str += '<p style="margin:0 0 0 0;border-bottom:1px solid #fff;color:#ffffff;"><strong>select satellite from pre-set list</strong></p>';
  cp_str += '<form name="sat_selector" style="margin:0 0 0 0">';
  cp_str += '<span id="caption">preset satellites : </span><br>';
  cp_str += '<select name="sat_list" >';
  for(i=0; i<satnum; i++){
    var id = Satellite.sat_list[i];
    if(Satellite[id].label){
      var label = Satellite[id].label;
    }else{
      var label = Satellite[id].name;    
    }
    if(id == pref.default_target){
      cp_str += '<option value="index.html">' + label + " (default)</option>";
    }else{
      cp_str += '<option value="index.html?&target=' + Satellite[id].id +'">' + label + '</option>';
    }
  }
  cp_str += '</select>&nbsp;&nbsp;&nbsp;&nbsp;';
  cp_str += '<input type="button" value="apply selection" onclick="setPreset()">';
  cp_str += '</form>';
  cp_str += '<p style="margin:2em 0 0 0;border-bottom:1px solid #fff;color:#ffffff;"><strong>define satellite by name & two line elements</strong></p>';
  cp_str += '<form name="user_defined" style="margin:0 0 0 0" onSubmit="setUserDefined();return false;">';
  cp_str += '<span id="caption">satellite name : </span><br>';
  cp_str += '<input type ="text" name="sat_name" style="width:600px;" value="' + pref.sat1_label + '"/><br>';
  cp_str += '<span id="caption">two line elements : <span><br>';
  cp_str += '<textarea name="tle" style="width:600px; height:50px" cols = "2">'+pref.sat1_first_line+"\n"+pref.sat1_second_line+'</textarea>';  
  cp_str += '<div style="margin:1em auto auto auto;text-align:center;"><input type="button" value="apply definition" onclick="setUserDefined()"></div>';
  cp_str += ' </form>';
  cp_str += '<p style="font-size:small;">Due to the limitation of algorithms, the high altitude satellites whose orbital period is longer than 225 minutes (altitude higher than 5800km in circular orbit) may not show proper position yet.</p>';
  cp_str += ' </div></div>';
  element2.innerHTML = cp_str;

      var map_area = document.getElementById("map");
      map_area.appendChild(element);
      map_area.appendChild(element2);
      if(pref.data_window==true){
        showData();
      }
      document.forms["config"].elements[5].checked = true;          
      Pref.prototype.config_window = true;
  }else{
      var map_area = document.getElementById("map"); 
      map_area.removeChild(document.getElementById("config_panel_bk"));
      map_area.removeChild(document.getElementById("config_panel"));
      document.forms["config"].elements[5].checked = false;          
      Pref.prototype.config_window = false;
  }
  delete pref;

}
function setPreset(){
   var url = document.forms["sat_selector"].elements["sat_list"].value
  location.href=url;

}
function setUserDefined(){
   var sat_name = document.forms["user_defined"].elements["sat_name"].value
   var tle = document.forms["user_defined"].elements["tle"].value
   var tle_array = tle.split("\n");
   var first_line = tle_array[0];
   var second_line = tle_array[1];   
  location.href="index.html?&target=custom&sat_name=" + sat_name + "&1st=" + first_line + "&2nd=" + second_line;

}
QueryDecoder = function(){
  var query=[];
  var q = location.search.replace(/^\?/, '&').split("&");
  var l = q.length;
  for(i=0; i<l;i++){
   var tmp_array = q[i].split("=");
      var name = tmp_array[0];
      var value = tmp_array[1];
      query[name] = value;
  }
  return query;
}

function escapeHTML(str) {
  return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); //"
}


function sat_loader (target){
  var pref = new Pref();
  var sat = Satellite[target];
  Pref.prototype.mode = sat.mode;
  Pref.prototype.target = target;
  Pref.prototype.sat1_name = sat.name;
  if(sat.label){
    Pref.prototype.sat1_label = sat.label;
  }else{
    Pref.prototype.sat1_label = sat.name;
  }
  if(sat.target=="custom"){
    Pref.prototype.sat1_first_line = sat.first_line;
    Pref.prototype.sat1_second_line = sat.second_line;
    var tle = new TLE();
    var orbital_elements1 = tle.decode(sat.first_line,sat.second_line);
    var gt_query = "gstserver.rb?mode=gt&target=custom&1st="+ sat.first_line + "&2nd=" + sat.second_line;
    Pref.prototype.gt_query1 = gt_query;
    DataLoader(GroundTrackLoader,gt_query,"text",false);
  }else{

    var tle_data = './gstserver.rb?mode=tle&target=' + sat.target;
    DataLoader(XMLLoader,tle_data,"xml",false);
    Pref.prototype.sat1_first_line = pref.tmp_first_line;
    Pref.prototype.sat1_second_line = pref.tmp_second_line;

    var tle = new TLE();
    var orbital_elements1 = tle.decode(pref.tmp_first_line,pref.tmp_second_line);

    delete pref;
    delete Pref.prototype.tmp_first_line;
    delete Pref.prototype.tmp_second_line;

    var gt_query = 'gstserver.rb?mode=gt&target=' + sat.target;
    Pref.prototype.gt_query1 = gt_query;
    DataLoader(GroundTrackLoader,gt_query,"text",false);
  }
  Pref.prototype.sat1_orbit = new SGP4(orbital_elements1);
  Pref.prototype.sat1_icon_image = sat.icon_image;
  Pref.prototype.sat1_icon_shadow = sat.icon_shadow;
  Pref.prototype.sat1_icon_size = sat.icon_size;

  if(sat.mode == "double" || sat.mode == "triple"){
    var sat2 = Satellite[sat.second_target];
    Pref.prototype.sat2_name = sat2.name;
  if(sat2.target=="custom"){
    Pref.prototype.sat2_first_line = sat2.first_line;
    Pref.prototype.sat2_second_line = sat2.second_line;
    var tle = new TLE();
    var orbital_elements2 = tle.decode(sat2.first_line,sat2.second_line);
   }else{
    var tle_data2 = './gstserver.rb?mode=tle&target=' + sat2.target;
    DataLoader(XMLLoader,tle_data2,"xml",false);
    var pref = new Pref();
    Pref.prototype.sat2_first_line = pref.tmp_first_line;
    Pref.prototype.sat2_second_line = pref.tmp_second_line;
    var tle = new TLE();
    var orbital_elements2 = tle.decode(pref.tmp_first_line,pref.tmp_second_line);
    delete Pref.prototype.tmp_first_line;
    delete Pref.prototype.tmp_second_line;
    }
    delete pref;

    Pref.prototype.sat2_orbit = new SGP4(orbital_elements2);
    Pref.prototype.sat2_icon_image = sat2.icon_image;
    Pref.prototype.sat2_icon_shadow = sat2.icon_shadow;
    Pref.prototype.sat2_icon_size = sat2.icon_size;
  }

  if(sat.mode == "triple"){
    var sat3 = Satellite[sat.theard_target];
    Pref.prototype.sat3_name = sat3.name;
    var tle_data3 = './gstserver.rb?mode=tle&target=' + sat3.target;
    DataLoader(XMLLoader,tle_data3,"xml",false);
    var pref = new Pref();
    Pref.prototype.sat3_first_line = pref.tmp_first_line;
    Pref.prototype.sat3_second_line = pref.tmp_second_line;
    var tle = new TLE();
    var orbital_elements3 = tle.decode(pref.tmp_first_line,pref.tmp_second_line);
    delete pref;
    delete Pref.prototype.tmp_first_line;
    delete Pref.prototype.tmp_second_line;

    Pref.prototype.sat3_orbit = new SGP4(orbital_elements3);
    Pref.prototype.sat3_icon_image = sat3.icon_image;
    Pref.prototype.sat3_icon_shadow = sat3.icon_shadow;
    Pref.prototype.sat3_icon_size = sat3.icon_size;

  }
  delete pref;
  var now = now_sec();
  Pref.prototype.gt_loaded = now;
}

function custom_sat_loader(sat_name,first_line,second_line){
    Pref.prototype.mode = "single"
    Pref.prototype.target = "custom";
    Pref.prototype.gt_query1 = "gstserver.rb?mode=gt&target=custom&1st="+ first_line + "&2nd=" + second_line;
    Pref.prototype.sat1_name = sat_name;
    var tle = new TLE();
    Pref.prototype.orbital_elements1 = tle.decode(first_line,second_line);
    var pref = new Pref();
    DataLoader(GroundTrackLoader,pref.gt_query1,"text",false);
    Pref.prototype.sat1_orbit = new SGP4(pref.orbital_elements1);
    
    delete pref;
    Pref.prototype.sat1_icon_image = "image/sat1.png";
    Pref.prototype.sat1_icon_shadow = "image/shadow.png";  
    Pref.prototype.sat1_icon_size = 45;  
    var now = now_sec();
    Pref.prototype.gt_loaded = now;
}

function setCookie(){
  var expire = new Date();
  expire.setTime(expire.getTime()+(14*24*60*60*1000));
  var pref = new Pref();
  document.cookie = "gst_ground_track=" + pref.ground_track_flag + "; expires=" + expire.toGMTString();  //for debug
  document.cookie = "gst_latlngline=" + pref.latlngline_flag + "; expires=" + expire.toGMTString();  //for debug
  document.cookie = "gst_night_shade=" + pref.night_shade_flag + "; expires=" + expire.toGMTString();  //for debug
  document.cookie = "gst_terminator=" + pref.terminator_flag + "; expires=" + expire.toGMTString(); //for debug
  document.cookie = "gst_unit=" + pref.unit + "; expires=" + expire.toGMTString(); //for debug
  document.cookie = "gst_zoom=" + map.getZoom() + "; expires=" + expire.toGMTString(); //for debug
}

function getCookie(){
  var cookie_str=document.cookie;
  if(cookie_str){
    var cookie_array = cookie_str.split(";");
    var cookie_length = cookie_array.length;
    var cookie_hash = []
    for (i=0; i<cookie_length; i++){
      var temp_array = cookie_array[i].split("=");
      if(temp_array[1]=="true"){
        var flag=true;
      }else if(temp_array[1]=="false"){
        var flag=false;
      }
      if(temp_array[0].match(/gst_ground_track/)){ //for debug
        Pref.prototype.ground_track_flag=flag;
      }else if(temp_array[0].match(/gst_latlngline/)){  //for debug
        Pref.prototype.latlngline_flag=flag;
      }else if(temp_array[0].match(/gst_night_shade/)){  //for debug
        Pref.prototype.night_shade_flag=flag;
      }else if(temp_array[0].match(/gst_terminator/)){  //for debug
        Pref.prototype.terminator_flag=flag;
      }else if(temp_array[0].match(/gst_unit/)){  //for debug
        Pref.prototype.unit=temp_array[1];
      }else if(temp_array[0].match(/gst_zoom/)){  //for debug
        Pref.prototype.zoom=Number(temp_array[1]);
      }
    }    
  }
}

function  set_defaults(){
  sat_marker1 ="";
  sat_marker2 ="";
  sat_marker3 ="";
  var nocache = "?nocache=" +(new Date()).getTime();
  DataLoader(DefaultSettingLoader,"./default.json"+nocache,"text",false);
  DataLoader(SatelliteListLoader,"./satellites.json"+nocache,"text",false);
  Pref.prototype.zoom=Number(Default["zoom"]);
  Pref.prototype.maximum_zoom=Number(Default["maximum_zoom"]);
  Pref.prototype.minimum_zoom=Number(Default["minimum_zoom"]);
  Pref.prototype.default_target=Default["target"];
  Pref.prototype.msg=Default["message"];
  Pref.prototype.unit = Default["unit"];
  Pref.prototype.ground_track_flag=false;
  Pref.prototype.latlngline_flag=false;
  Pref.prototype.night_shade_flag=true
  Pref.prototype.terminator_flag=false;
  Pref.prototype.fullwindow_flag = false;
  Pref.prototype.data_window = false;
  Pref.prototype.config_window = false;
  getCookie();
  var pref = new Pref();
  if(pref.ground_track_flag == true){
    document.forms[0].elements[0].checked = true;
  }
  if(pref.latlngline_flag == true){
    document.forms[0].elements[1].checked = true;
  }

  if(pref.night_shade_flag == true || pref.terminator_flag == true){
    if(pref.night_shade_flag == true){
      document.forms[0].elements[2].checked = true;
      document.forms[0].elements[3].options[0].selected = true
    }else if(pref.terminator_flag == true){
      document.forms[0].elements[2].checked = true;
      document.forms[0].elements[3].options[1].selected = true;
    }
  }else{
    document.forms[0].elements[2].checked = false;
  }
  if(pref.unit == "km"){
    document.forms[0].elements[4].options[0].selected = true
    Pref.prototype.unit_factor = 1;        
  }else if(pref.unit == "mile"){
    document.forms[0].elements[4].options[1].selected = true
    Pref.prototype.unit_factor = 0.621371192;
  }

  delete pref;
}

getScreenSize = function() {
  if ( window.innerWidth ) {
    var width = window.innerWidth;
  }
  else if ( document.documentElement && document.documentElement.clientWidth != 0 ) {
    var width =  document.documentElement.clientWidth;
  }
  else if ( document.body ) {
    var width = document.body.clientWidth;
  }
  if ( window.innerHeight ) {
    var height = window.innerHeight;
  }
  else if ( document.documentElement && document.documentElement.clientHeight != 0 ) {
    var height =  document.documentElement.clientHeight;
  }
  else if ( document.body ) {
    var height =  document.body.clientHeight;
  }
  this.width = width;
  this.height = height;
  return this;
}

function FitToWindow(){
  var pref=new Pref();
  var screen = getScreenSize();
  var prev_width = screen.width;
  var prev_height = screen.height;
  var new_width  = prev_width;
  var new_height  = prev_height-20;
  Pref.prototype.map_width=new_width;
  Pref.prototype.map_height=new_height;
  var d = document.getElementById("map").style;
  var d2 = document.getElementById("indicator").style;
  d.width  = new_width;  
  d.height  = new_height;
  d2.width  = new_width;
  
  if(new_width>=4096){
    Pref.prototype.minimum_zoom=4;
  }else if(new_width>=2048){
    Pref.prototype.minimum_zoom=3;
  }else if(new_width>=1024){
    Pref.prototype.minimum_zoom=2;
  }else if(new_width>=512){
    Pref.prototype.minimum_zoom=1;
  }else if(new_width>=256){
    Pref.prototype.minimum_zoom=0;  
  }
  if(pref.status=="running"){
    map.checkResize();
    setMoveMode(true);
  }
  clearTimeout(WindowResizeTimer);
  WindowResizeTimer = false
}

function showData(){
  var pref = new Pref();
    if(pref.data_window==false){
        document.getElementById("data").style.display="block";
        document.forms["config"].elements[6].checked = true;    
        if(document.addEventListener){
        document.getElementById("data").addEventListener("mousedown",onMouseDown,false);
        document.getElementById("data").addEventListener("mouseup",onMouseUp,false);
        }else{
        document.getElementById("data").attachEvent("onmousedown",onMouseDown);
        document.getElementById("data").attachEvent("onmouseup",onMouseUp);
        }
      if(pref.config_window==true){
        showConfig();
      }
        Pref.prototype.data_window=true;
    }else{
        if(document.removeEventListener){
        document.getElementById("data").removeEventListener("mousedown",onMouseDown,false);
        document.getElementById("data").removeEventListener("mouseup",onMouseUp,false);
        document.getElementById("data").style.display="none";
        }else{
        document.getElementById("data").detachEvent("onmousedown",onMouseDown);
        document.getElementById("data").detachEvent("onmouseup",onMouseUp);
        }
        document.getElementById("data").style.display="none";
        document.forms["config"].elements[6].checked = false;
        Pref.prototype.data_window=false;  
    }

}
function StartUp(){
  if(window.top !== window.self){
    FitToWindow();
    var str = '<div style="line-height:1.5em;font-size:x-large;margin-top:5em;text-align:center"><strong>GoogleSatTrack is not designed to work in frames. <br> Please visit the original site <a href="http://www.lizard-tail.com/isana/tracking/" target="_top">http://www.lizard-tail.com/isana/tracking/</a> directly for satellite tracker.</strong><br><br><img src="image/iss.png"></div>';
    document.getElementById("map").innerHTML = str;
  }else{
    Pref.prototype.status = "startup"
    set_defaults()
    var pref = new Pref();
    var target = pref.default_target;
    delete pref;
    
    var q = new QueryDecoder();
    if(q["target"]){
      target = q["target"];
    }
    if(target=="custom"){
      var sat_name = escapeHTML(decodeURI(q["sat_name"]));
      var first_line = decodeURI(q["1st"]);
      var second_line = decodeURI(q["2nd"]);
      Pref.prototype.sat1_name=sat_name;
      Pref.prototype.sat1_first_line=first_line
      Pref.prototype.sat1_second_line=second_line
      custom_sat_loader(sat_name,first_line, second_line);
    }else{
      sat_loader(target);
    }

    FitToWindow();
    InitMap();
    long_updator();
    mid_updator();
    short_updator();
    setStaticData();
    map.checkResize();
    //setMoveMode(true);
    var pref = new Pref();
    if(pref.mode=="double"){
      document.getElementById("indicator").style.display="block";
      document.getElementById("sat1_data").style.display = "block"; 
      document.getElementById("sat2_data").style.display = "block"; 
      document.getElementById("distance_data").style.display = "block"; 
    }else{
      document.getElementById("indicator").style.display="block";
      document.getElementById("sat1_data").style.display = "block"; 
    }
    CalcSat();
    setIndicator();
    Pref.prototype.status = "running"
  }
  return;
}


function Unload(){
  setCookie();
  GUnload();
  return;
}

window.onload = function(){StartUp()}
window.onunload = function(){Unload()}
WindowResizeTimer = false;
window.onresize = function(){
  if(!WindowResizeTimer){
    window.setTimeout("FitToWindow()", 1000) 
    WindowResizeTimer = true;
  }
  return;
}

Pref.prototype.data_window_left=50;
Pref.prototype.data_window_top=5;

function onMouseDown(event){
  if(!event) {event = window.event}
  var pref = new Pref();
    if(document.addEventListener){
      document.addEventListener("mousemove",onMouseMove,false);
    }else{
      document.body.attachEvent("onmousemove",onMouseMove);
    }

  Pref.prototype.cursor_offset_x = event.clientX - pref.data_window_left;
  Pref.prototype.cursor_offset_y = event.clientY - pref.data_window_top;

  return;
  }

function onMouseUp(event){
  if(document.addEventListener){
    document.removeEventListener("mousemove",onMouseMove,false);
  }else{
    document.body.detachEvent("onmousemove",onMouseMove);
  }
  return;
}

function onMouseMove(event){
  if(!event) {event = window.event}
  var pref = new Pref();
  var top = Number(event.clientY-pref.cursor_offset_y);
  var left = Number(event.clientX-pref.cursor_offset_x);
  document.getElementById("data").style.top = top;
  document.getElementById("data").style.left =left;
  if(event.clientY>pref.map_height+5 || event.clientX>pref.map_width-5 || event.clientY<5 || event.clientX<5){
      if(document.addEventListener){
        document.removeEventListener("mousemove",onMouseMove,false);
      }else{
        document.body.detachEvent("onmousemove",onMouseMove);
      }
      return;  
  }

  Pref.prototype.data_window_left=left;
  Pref.prototype.data_window_top=top;
  return;
}
