﻿// Copyright 2009 Google Inc.  All Rights Reserved.

/**
 * @fileoverview Module to control Earth API behavior on
 * Google Earth pages.
 * @author Michal Drewniak
 */

/**
 * Create earth namespace.
 */
var earth = earth || {};

/**
 * Google Earth API class. Initializes Earth API object.
 * @constructor
 */
earth.EarthAPI = function() {
  google.earth.createInstance('earthapimap', this.initPlugin, this.failureCB);
  this.showInstallMsg();
};

/**
 * Initializes plugin options.
 * @param {Object} object Earth plugin object.
 */
earth.EarthAPI.prototype.initPlugin = function(object) {
  earth.EarthAPI.ge = object;
  earth.EarthAPI.ge.getWindow().setVisibility(true);
  earth.EarthAPI.ge.getLayerRoot().enableLayerById(
      earth.EarthAPI.ge.LAYER_BUILDINGS, true);
  earth.EarthAPI.ge.getOptions().setFlyToSpeed(.50);
  earth.EarthAPI.ge.getOptions().setStatusBarVisibility(true);
  earth.EarthAPI.ge.getNavigationControl().setVisibility(
      earth.EarthAPI.ge.VISIBILITY_SHOW);
  if (!earth.globals.apibuildings) {
    earth.EarthAPI.ge.getLayerRoot().enableLayerById(
        earth.EarthAPI.ge.LAYER_BUILDINGS, false);
  }
  if (earth.globals.defaultKml) {
    earth.earthapi.loadKML(earth.globals.defaultKml,
                           earth.globals.defaultKmlType);
  }
};

/**
 * Displays image associated with selected KML (instead of the KML itself).
 * @param {string} kmlId Order number associated with the kml.
 */
earth.EarthAPI.prototype.showImage = function(kmlId) {
  urchinTracker('/earth/earthapi_' + kmlId);
  this.hideInstallMsg();

  var earthapimap = document.getElementById('earthapimap');
  earthapimap.style.height = '0';
  var imgSrc = document.getElementById('kmlurl_' + kmlId).name;
  var earthapiimage = document.getElementById('earthapiimage');

  earthapiimage.innerHTML = '<img src="' + imgSrc + '" />';
  earthapiimage.className = '';
};

/**
 * Shows media located in the landing-media container.
 * @param {number} mediaId Number identifying media to show.
 */
earth.EarthAPI.prototype.showMedia = function(mediaId) {
  var mediaContainer = document.getElementById('landing-media')
  var media = mediaContainer.getElementsByTagName('div');

  // Hide earth api
  var earthapimap = document.getElementById('earthapimap');
  earthapimap.style.height = '0';

  for (var i = 0, s = media.length; i < s; i++) {
    media[i].className = 'hidden';
  }
  if (earth.EarthAPI.ge && document.getElementById('kmlurl_' + mediaId)) {
    this.showKML(mediaId);
  } else {
    media[mediaId].className = '';
    mediaContainer.className = '';
  }
};

/**
 * Displays KML file selected via filmstrip's thumbnail.
 * @param {string} kmlId Id of the kml to be displayed.
 * @param {string} type Type of the kml (earth, sky).
 */
earth.EarthAPI.prototype.showKML = function(kmlId, type) {
  urchinTracker('/earth/earthapi_' + kmlId);
  this.hideInstallMsg();

  var earthapiimage = document.getElementById('earthapiimage');
  var landingMedia = document.getElementById('landing-media');
  document.getElementById('earthapimap').style.height = '100%';

  if (earthapiimage) {
    earthapiimage.className = 'hidden';
  }
  if (landingMedia) {
    landingMedia.className = 'hidden';
  }

  if (earth.EarthAPI.ge) {
    var kmlUrl = document.getElementById('kmlurl_' + kmlId).href;
    this.loadKML(kmlUrl, type);
  } else {
    document.getElementById('earthapimap').innerHTML = '';
    if (document.getElementById('earthapiimage')) {
      document.getElementById('earthapiimage').innerHTML = '';
    }
    google.earth.createInstance('earthapimap', this.initPlugin, this.failureCB);
  }
};


/**
 * Replaces currently shown kml.
 * @param {string} kmlUrl Id of the kml to be displayed.
 * @param {string} type Type of the kml (earth, sky).
 */
earth.EarthAPI.prototype.loadKML = function(kmlUrl, type) {
  if (kmlUrl) {
    earth.globals.defaultKml = kmlUrl;
  }
  if (earth.EarthAPI.ge && kmlUrl) {
    var arrKmlUrl = kmlUrl.split('.');
    var ext = arrKmlUrl[arrKmlUrl.length - 1];

    earth.EarthAPI.ge.getWindow().setVisibility(true);
    this.removeKML();

    if (type == 'sky') {
      earth.EarthAPI.ge.getOptions().setMapType(
          earth.EarthAPI.ge.MAP_TYPE_SKY);
    } else if (type == 'ocean') {
      var lookAt = earth.EarthAPI.ge.createLookAt('');
      lookAt.setAltitudeMode(earth.EarthAPI.ge.ALTITUDE_RELATIVE_TO_SEA_FLOOR);
      lookAt.setTilt(70);
      lookAt.setRange(1500);
      earth.EarthAPI.ge.getView().setAbstractView(lookAt);
    } else {
      earth.EarthAPI.ge.getOptions().setMapType(
          earth.EarthAPI.ge.MAP_TYPE_EARTH);
    }

    if (ext == 'kml') {
      var networkLink = earth.EarthAPI.ge.createNetworkLink('');
      networkLink.setFlyToView(true);

      var link = earth.EarthAPI.ge.createLink('');
      link.setHref(kmlUrl);
      networkLink.setLink(link);
      earth.EarthAPI.currentNetLink = networkLink;
      earth.EarthAPI.ge.getFeatures().appendChild(networkLink);
    } else {
      google.earth.fetchKml(earth.EarthAPI.ge, kmlUrl, function(object){
        finished(object);
      });
    }
    this.addOverlay();

  } else {
    document.getElementById('earthapimap').innerHTML = '';
    google.earth.createInstance('earthapimap',
        this.initPlugin, this.failureCB);
  }
};

/**
 * Adds overlay to the plugin instance.
 */
 earth.EarthAPI.prototype.addOverlay = function() {
  if (!earth.globals.apioverlay) return;
  var screenOverlay = earth.EarthAPI.ge.createScreenOverlay('');
  screenOverlay.setIcon(earth.EarthAPI.ge.createIcon(''));
  screenOverlay.getIcon().setHref(earth.globals.apioverlay);

  // Set screen position in fractions.
  screenOverlay.getOverlayXY().setXUnits(earth.EarthAPI.ge.UNITS_FRACTION);
  screenOverlay.getOverlayXY().setYUnits(earth.EarthAPI.ge.UNITS_FRACTION);
  screenOverlay.getOverlayXY().setX(.5);
  screenOverlay.getOverlayXY().setY(.175);

  earth.EarthAPI.ge.getFeatures().appendChild(screenOverlay);
};

/**
 * Removes previously loaded KML.
 */
earth.EarthAPI.prototype.removeKML = function() {
  earth.EarthAPI.ge.getTourPlayer().setTour(null);
  earth.earthapi.tour = null

  if (earth.EarthAPI.currentKMZ) {
    earth.EarthAPI.ge.getFeatures().removeChild(earth.EarthAPI.currentKMZ);
  }
  if (earth.EarthAPI.currentNetLink) {
    earth.EarthAPI.ge.getFeatures().removeChild(earth.EarthAPI.currentNetLink);
  }
};

/**
 * Attaches new kml to the plugin.
 * @param {Object} object Earth Plugin object.
 */
function finished(object) {
  if (!object) {
    setTimeout(function() {
      alert('Bad or null KML.');
    }, 0);
    return;
  }

  earth.EarthAPI.ge.getFeatures().appendChild(object);
  earth.EarthAPI.currentKMZ = object;

  // Walk the DOM looking for a KmlTour
  walkKmlDom(object, function() {
    if (this.getType() == 'KmlTour') {
      earth.earthapi.tour = this;
      return false; // stop the DOM walk here.
    }
  });

  if (earth.earthapi.tour) {
    earth.EarthAPI.ge.getTourPlayer().setTour(earth.earthapi.tour);
    earth.EarthAPI.ge.getTourPlayer().play();
  }

}

/**
 * Silently fails.
 * @param {Object} object Earth Plugin object.
 */
earth.EarthAPI.prototype.failureCB = function(object) {
  // do nothing
};

/**
 * Displays "install plugin" message if plugin not installed.
 */
earth.EarthAPI.prototype.showInstallMsg = function() {
  if (!google.earth.isInstalled()) {
    var msg = document.getElementById('installPluginMsg');
    if (msg) {
      msg.className = 'info-grey';
    }
  }
};

/**
 * Hides "install plugin" message
 */
earth.EarthAPI.prototype.hideInstallMsg = function() {
  var msg = document.getElementById('installPluginMsg');
  if (msg) {
    msg.className = 'hidden';
  }
};
