﻿// Copyright 2008 Google Inc.
// All Rights Reserved.
/**
  * @fileoverview Some function for Sky Maps
  * 
  * @author  ( )
  */

function deleteKml() {
  if (kmlOverlay !== null) {
    map.removeOverlay(kmlOverlay);
    var loadedKml = document.getElementById('loadedKml');
    loadedKml.innerHTML = "";
  }
}

/*
  changeCenter: change center to default center

  @param {Mixed} obj GGeoXml Object
  @return {void}
*/
function changeCenter(obj, opt_customZoom) {
  var center = obj.getDefaultCenter();
  var zoom = opt_customZoom || 7;
  map.setCenter(new GLatLng(center.lat(), center.lng()), zoom);
}

/*
  updateKml: loads kml

  @param {String} opt_kml KML|Z URL
  @param {Boolean} opt_justChangeCenter Just change the center to default position
  @return {void}
*/
function updateKml(kml, opt_justChangeCenter, opt_displayName, opt_isPlanet, opt_customZoomPlanet) {
  if (opt_justChangeCenter) {
    var temporalKml = new GGeoXml(kml, function() {
      try {
        var center = temporalKml.getDefaultCenter();
        map.setCenter(new GLatLng(center.lat(), INVERT_CENTER_SEARCH * center.lng()), 10);
      } catch(ex) {
      }
    });
  } else {
    if (opt_isPlanet) {
      if (planetKmlOverlay !== null)
        map.removeOverlay(planetKmlOverlay);
      planetKmlOverlay = new GGeoXml(kml, function() {
        if (planetKmlOverlay.loadedCorrectly()) {
          changeCenter(planetKmlOverlay, opt_customZoomPlanet);
          map.addOverlay(planetKmlOverlay);
        }
      });
      return;
    }
    if (kmlOverlay !== null) 
      map.removeOverlay(kmlOverlay);
    kmlOverlay = new GGeoXml(kml, function() {
      if (kmlOverlay.loadedCorrectly()) {
        try {
          changeCenter(kmlOverlay);
          try {
            var loadedKml = document.getElementById('loadedKml');
            var qtbWidths = getPosition(document.getElementById('qtbIRAS')).width + 
                            getPosition(document.getElementById('qtbWMAP')).width + 
                            getPosition(document.getElementById('qtbCassini')).width;
            if (opt_displayName) {
              var kmlName = opt_displayName;
            } else {
              var kmlName = kml.match(/\/([^\/]+\.km[l|z])/);
              kmlName = kmlName[1];
            }
            loadedKml.innerHTML = kmlName + ' <img src="' + iconFolder + 'close.gif" style="cursor:pointer;" onClick="deleteKml();">';
            var myWidth = getPosition(loadedKml).width;
            loadedKml.style.left = px(qtbWidths - myWidth);
          } catch (ex) {
            // reduced versions won't have close
          }
          map.addOverlay(kmlOverlay);
        } catch(ex) {
        }
      } else {
        alert('Error loading Kml');
      }
    });
  }
}

/*
  doSearch: if searching kml / kmz just add it!

  TODO (): do now parse with search if there is only one result
  @param {String} The id of the HTMLTextElement which value we are searching
  @return {void}
*/
function clickSearch(textToSearch) {
  doSearch(null, textToSearch);
}
function doSearch(searchText, opt_query) {
  try {
    var query = document.getElementById(searchText).value;
  } catch(ex) {
    var query = opt_query || '';
  }
  if (/^(-?\d+:\d+:[\d\.]+)\s*,\s*(-?\d+:\d+:[\d\.]+)$/.exec(query)) {
    var matches = query.match(/^(-?\d+:\d+:[\d\.]+)\s*,\s*(-?\d+:\d+:[\d\.]+)$/);
    var lng = - raToLng(matches[1]);
    var lat = decToLat(matches[2]);
    query = lat + "," + lng;
  }
  function encodeHtml(html) {
    var encoded = document.createElement('div');
    var textNode = document.createTextNode(html);
    encoded.appendChild(textNode);
    return encoded.innerHTML.replace(/\"/g, '&quot;').replace(/\'/g, '&#039;');
  }
  function fakeLink(oneMatch) {
    var match = /<Placemark><name>([^>]+)<\/name>/i.exec(oneMatch);
    var rname = match[1];
    var urlName = encodeURIComponent(rname);
    var htmlName = encodeHtml(rname);
    var searchUrl = baseSearchUrl + urlName;
    return '<tr><td>' + 
           '<a href="#" style="color:black;font-size:11px;" onClick="javascript:updateKml(\'' + searchUrl + '\', true);">' + rname + '</a></td></tr>';
  }

  var resultStart = '<table width="100%" cellspacing="0" cellpadding="0">';
  var results = '';
  var noMatches = '<tr><td style="font-size:11px"><font color=\'#000\'>No results</font></td></tr>';
  var resultEnd = '</table>';

  if (/\.km[l|z]$/.test(query)) {
    updateKml(query);
  } else {
    var floatingBox;
    GDownloadUrl(downSearchUrl + encodeURIComponent(query) + '&hl=en', function(html, resp) {
      if (parseInt(resp) == 200) {
        var didyoumean = html.match(/<Folder>/gi);
        var matches = html.match(/<Placemark><name>([^>]+)<\/name>/gi);
        if (matches === null) {
          var ntmatch = /<NetworkLink><name>([^>]+)<\/name>.*?<href>([^<]+)/gi.exec(html);
          if (ntmatch === null) {
            results = noMatches;
          } else {
            results = '<tr><td style="font-size:11px">- 1 Results for <b>' + encodeHtml(query) + '</b> -</td></tr>';
            results += '<tr><td style="font-size:11px"><font color=\'#000\'>' + ntmatch[1] + '</font></td></tr>';
            updateKml(ntmatch[2], false, ntmatch[1]);
          }
        } else {
          results = '<tr><td style="font-size:11px">- ' + matches.length.toString() + ' Results for <b>' + encodeHtml(query) + '</b> -</td></tr>';
          for (var i = 0; i < matches.length; i++) 
            results += fakeLink(matches[i]);
          if (matches.length == 1 && didyoumean === null) {
            // only load if there is one match and it's not a suggestion
            var match = /<Placemark><name>([^>]+)<\/name>/i.exec(matches[0]);
            updateKml(baseSearchUrl + encodeURIComponent(query), true);
          }
        }
        floatingBox = resultStart + results + resultEnd;
        var floatingDiv = document.getElementById('searchResults');
        var closeSearch = document.getElementById('closeSearch');
        var searchBox = document.getElementById('searchtext');
        var positionBox = getPosition(searchBox);
	floatingDiv.innerHTML = floatingBox;
        floatingDiv.style.width = px(positionBox.width);
	floatingDiv.style.left = px(positionBox.left);
        floatingDiv.style.top = px(positionBox.top + positionBox.height);
        closeSearch.style.top = px(0);
        closeSearch.style.left = px((('left'=='left')?positionBox.width:12) - 12);
        closeSearch.style.display = floatingDiv.style.display = 'block';
	closeSearch.style.visibility = floatingDiv.style.visibility = 'visible';
        floatingDiv.appendChild(closeSearch);
      }
      else {
        alert('Search is not responding, sorry...');
      }
    });
  }
}

/*
  eraseInfo: delete information when out of map

  @return {void}
*/
function eraseInfo() {
  displayInfo(map.getCenter(), false, ' ');
}

/*
  latToDec: latitude to declination

  @param {Number} latitude
  @return {Number} declination for this latitude
*/
function latToDec(latitude) {
  if (latitude < 0) return '-' + latToDec(- latitude);
  var DEC = Math.floor(latitude).toString() + '° ';
  latitude = (latitude - Math.floor(latitude)) * 60;
  DEC += Math.floor(latitude).toString() + '\' ';
  latitude = (latitude - Math.floor(latitude)) * 60;
  DEC += latitude.toFixed(1) + '"';
  return DEC;
}

/*
  decToLat: declination to latitude

  @param {Number} dec
  @return {Number} latitude for this declination
*/
function decToLat(dec) {
  if (dec[0] == '-') return '-' + decToLat(dec.substring(1));
  var decSplit = dec.split(':');
  var latitude = parseFloat(decSplit[0]) + 
                 parseFloat(decSplit[1]) / 60.0 + 
                 parseFloat(decSplit[2]) / 3600.0;
  return latitude;
}

/*
  lngToRa: longitude to right ascension

  @param {Number} longitude
  @return {Number} right ascension
*/
function lngToRa(longitude) {
  longitude = (- longitude + 180) / 15;
  var RA = Math.floor(longitude).toString() + 'h ';  
  longitude = (longitude - Math.floor(longitude)) * 60;
  RA += Math.floor(longitude).toString() + 'm ';
  longitude = (longitude - Math.floor(longitude)) * 60;
  RA += Math.floor(longitude).toFixed(1) + 's';
  return RA;
}

/*
  raToLng: right ascension to longitude

  @param {Number} right ascension
  @return {Number} longitude
*/
function raToLng(ra) {
  var raSplit = ra.split(':');
  var longitude = parseFloat(raSplit[0]) + 
                  parseFloat(raSplit[1]) / 60.0 + 
                  parseFloat(raSplit[2]) / 3600.0;
  return - (longitude * 15 - 180);
}

/*
  displayInfo: display information of the mouse pointer point

  @param {GLatLnt} point The GLatLng the mouse pointer in on
  @return {void}
*/
function displayInfo(point) {
//  var skydec = document.getElementById('skydec');
//  var skyra = document.getElementById('skyra');
//  skydec.value = latToDec(point.lat());
//  skyra.value = lngToRa(point.lng());
}

/*
  getSkyTileLayer: create a GTileLayer that will show the sky images

  @return {GTileLayer}
*/
function getSkyTileLayer() {
  var skyTileLayer = new GTileLayer(SkyCopyright, 0, SkyZoomLevels - 1);
  skyTileLayer.getTileUrl = function(point, zoom) {
    var base = jpegBaseURL;
    var url = base + point.x + '_' + point.y + '_' + zoom + '.jpg';
    return url;
  };
  skyTileLayer.getOpacity = function() {
    return 1.0;
  };
  skyTileLayer.isPng = function() {
    return false;
  };
  return skyTileLayer;
}

/*
  generateSkyMap: delete all maps and add a new skymap

  @param {GMap2} map The map to change to sky
  @param {GTileLayer} skyTileLayer The tilelayer object for the map
  @return {void}
*/
function generateSkyMap(map, skyTileLayer) {
  var skyMapType = new GMapType([skyTileLayer],
                                new GMercatorProjection(SkyZoomLevels), 
                                'Sky', {errorMessage: 'No data'});
  skyMapType.getTextColor = function() { return 'white'; }
  skyMapType.getLinkColor = function() { return '#aaaaee'; }
  skyMapType.getErrorMessage = function() { return 'No imagery available at this zoom level. Try <a href="javascript:gotoInit();">zooming out</a>.'; }
  map.addMapType(skyMapType);
  map.setMapType(skyMapType);
  map.removeMapType(G_NORMAL_MAP);
  map.removeMapType(G_SATELLITE_MAP);
  map.removeMapType(G_HYBRID_MAP);
  //map.enableScrollWheelZoom();
}

// Resize the UI components because something's been opened or closed
// Based on Google's Moon resizeMap
function resizeMap() {
  var map = document.getElementById("map");
  var slider = document.getElementById("slider");
  var infoTab = document.getElementById("infoTab");

  /* compute our expected state */
  var mapheight = getWindowHeight() - getPosition(map).top;
  var mapwidth = getWindowWidth();
  var mapleft = 0;

  /* try setting everything's size: */
  map.style.height = px(450);  //px(mapheight - (slider.style.display == "none" ? 0 : 89));
  map.style.width = px(940);
  map.style.left = px(mapleft);
  infoTab.style.left = px(mapleft);
  slider.style.left = px(mapleft + parseInt(getPosition(infoTab).width));
  slider.style.width = 940; //px(mapwidth - parseInt(getPosition(infoTab).width));
  checkMapSize();
}

// Following function were copied from some Google Moon files
// See google moon for more information

// Gets the position of a html element
function getPosition(elem) {
  var offset = 0;
  var x = 0; y = 0;
  var w = elem.offsetWidth;
  var h = elem.offsetHeight;
  while (elem != null) {
    y += elem.offsetTop;
    x += elem.offsetLeft;
    elem = elem.offsetParent;
  }
  var out = { top: y, left: x, width: w, height: h};
  return(out);
}

// Returns number + "px"
function px(numPixels) { return Math.round(numPixels) + "px"; }

// Gets page size as a GSize
function getPageSize() {
  return new GSize(
      window.innerWidth ||
          (document.documentElement && document.documentElement.clientWidth) ||
          document.body.clientWidth,
      window.innerHeight ||
          (document.documentElement && document.documentElement.clientHeight) ||
          document.body.clientHeight);
}

// Gets page height
function getWindowHeight() {
	return(getPageSize().height);
}

// Gets page width
function getWindowWidth() {
	return(getPageSize().width);
}

function hideResults() {
  var sr = document.getElementById('searchResults');
  var cs = document.getElementById('closeSearch');
  sr.style.display = cs.style.display = 'none';
  sr.style.visibility = cs.style.visibility = 'hidden';
}

