var version = '1.00';

// average of UTMs converted to lat/lng
var originLatitude  =  49.278194247788136
var originLongitude = -123.13953261981007

var originAltitude = 1000;

var markerLat = originLatitude;
var markerLng = originLongitude;
var markerAlt = 100;

//var dragCam = DragCamera();

var topPoint;
var sidePoint;7

var topCoords;
var sideCoords;

var map;
var navGE;

var allowedBounds;

var DesignMode = {pyramid: 0, parallel: 1, grid: 2};
var designMode = DesignMode.pyramid;

var homeID;

google.load("jquery", "1");
google.load("maps", "2");
google.load("earth", "1");

function log(data) {
return;

//var lbl = document.getElementById('instruct1');
//lbl.innerHTML = data;

//return;

  if (window.console && window.console.firebug) {
    console.log(data);
  }
}

// reads the query string parameters
/*
function readLanguageAndPriority() {
  var qsParm = new Array();
  var query = window.location.search.substring(1);
  var parms = query.split('&');
  for (var i=0; i<parms.length; i++) {
    var pos = parms[i].indexOf('=');
    if (pos > 0) {
      var key = parms[i].substring(0,pos);
      var val = parms[i].substring(pos+1);
      qsParm[key] = val;
      log(key);
      log(val);
    }
  }
}
*/

function init() {
//  readLanguageAndPriority();
  
  window.onresize = windowResize;

  var navCombo = document.getElementById('navCombo');
  navCombo.selectedIndex = 1; // start at home
  
  var camModeCombo = document.getElementById('camModeCombo');
  camModeCombo.selectedIndex = 0;

  var stylesCombo = document.getElementById('stylesCombo');
  stylesCombo.selectedIndex = 0;
  
  var lightsCombo = document.getElementById('lightsCombo');
  lightsCombo.selectedIndex = 1;  
  
  findUtmOrigin();

//log('UTM N = '+ originUtmN + ' UTM E = ' + originUtmE);  
//testUtmConversions();

  createWalls();
  
  showTopView();
  
  slider.init();
  	
// create the google earth view	
  google.earth.createInstance('navView', initNavViewCB, failNavViewCB);
  windowResize();
}

function windowResize() {
//  log('resize');
  var clientHeight = document.documentElement.clientHeight;
//  var clientWidth = document.documentElement.clientWidth;

  var topView = document.getElementById('topView');
  var navView = document.getElementById('navView');
  var controlBar = document.getElementById('controlBar');

  var topViewY = topView.offsetTop;
  
  var controlH = controlBar.offsetHeight;
  
  var newViewHeight = clientHeight - topViewY - controlH - 20;
  
//  var gap = 10;
//  var viewW = (clientWidth-gap) / 2;
//  var navLeft = (viewW + gap) + 'px';
//  log(navLeft);
  
//  topView.style.width = viewW + 'px';
//  navView.style.width = viewW + 'px';
//  navView.style.left = navLeft;
  
  topView.style.height = newViewHeight + 'px';
  navView.style.height = newViewHeight + 'px';
  
  
  var newY = topViewY + newViewHeight;
  
//log('NewViewH = ' + newViewHeight);
//log('NewY = ' + newY);
  controlBar.style.top = newY + 'px';
}
  
function syncNavBeams(lat,lng,alt) {
//log('a');
  for (var i=0; i < LIGHTS; i++) {
    if (lightSelected[i]) {
   //   log('lat = ' + marker.lat);
         navLight[i].pointAt(lat, lng, alt);
    }  
  }
}

function syncNavBeamsXYZ(x, y, z) {
  for (var i=0; i < LIGHTS; i++) {
    if (lightSelected[i]) {
      navLight[i].syncXYZ(x, y, z);
    }  
  }
}

function setDebugLabel(value) {
  document.getElementById('DebugLabel').innerHTML = value;
}
  
function addLights(ge,light) {
  for (var i = 0; i < LIGHTS; i++) {
    light[i] = new Light();
    light[i].addToGE(ge,i);
  }  
 }
  
function moveHandler(evt) {
  if (!evt) {
    evt = window.event;
  }
  document.getElementById('PixelXYLabel').innerHTML = evt.clientX + ', ' + evt.clientY;
}

function homeNavCamera() {
log('homing');
  navCamera.selectView(1);
}

function syncNavCam(lat,lng,heading) {
  var camera = navGE.getView().copyAsCamera(navGE.ALTITUDE_RELATIVE_TO_GROUND);
 
  camera.setLatitude(lat);
  camera.setLongitude(lng);
  
  camera.setHeading(heading + 90);
  
 // camera.setAltitude(50);
  navGE.getView().setAbstractView(camera);
}

function initNavViewCB(instance) {
  navGE = instance;
  navGE.getWindow().setVisibility(true);

  addLights(navGE,navLight);
  addWallsToGE(navGE);
  
  navCamera.init(navGE);
  
  syncBeams();
  
  setTimeout(enableBuildings, 3000);
  homeID = setTimeout(homeNavCamera, 3000);
  
  homeNavCamera();
  
  var submitBtn = document.getElementById('submit');
  submitBtn.onclick = submitDesignBtnClicked;
}

function enableBuildings() {
//return;
  showBridgeInNavView();

  navGE.getLayerRoot().enableLayerById(navGE.LAYER_BUILDINGS, true);
	
// add the navigation controls
  navGE.getNavigationControl().setVisibility(navGE.VISIBILITY_AUTO);
//  homeNavCamera();
}  

function failNavViewCB(errorCode) {
  log('Nav view failed');
}
  
function findOriginXY() {
  originX = 0;
  originX = longitudeAtLatitudeToXMetres(originLongitude,originLatitude);

  originY = 0;   
  originY = latitudeToYMetres(originLatitude);  
}
  
function showMouseXY(event) {
  var lat = event.getLatitude();
  var long = event.getLongitude();
  
  document.getElementById('longLatAltLabel').innerHTML = long + ' / ' + lat;

  var x = longitudeAtLatitudeToXMetres(long,lat);
  var y = latitudeToYMetres(lat);

  document.getElementById('XYLabel').innerHTML = x.toFixed(2) + ', '+ y.toFixed(2);
}

function finishedNavLoad(object) {
  if (!object) {
		
// wrap alerts in API callbacks and event handlers
// in a setTimeout to prevent deadlock in some browsers
    setTimeout(function() { alert('Bad or null KML.'); }, 0);
    return;
  }
  navGE.getFeatures().appendChild(object);
}
  
function showBridgeInNavView() {
  var url = 'http://www.vectorialvancouver.net/models/bridge/doc.kml';    

  google.earth.fetchKml(navGE, url, finishedNavLoad);
}

function even(num) {
  return !(num % 2);
}

function odd(num) {
  return (num % 2);
}

function lightsComboChange(select) {
  var i;
  
  switch (select.selectedIndex) {
    case 0 :   // custom
      break; 
      
    case 1 :   // all
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = true;
      }  
      break;
      
    case 2 :   // none
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = false;
      }  
      break;      
      
    case 3 :   // invert
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = !lightSelected[i];
      }  
      break;      

    case 4 :   // odd
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = odd(i);
      }
      break;
      
    case 5 :   // even
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = even(i);
      }
      break;
     
    case 6 :   // vanier park
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = (i < 10);
      }
      break;
      
    case 7 :   // sunset beach
      for (i=0; i < LIGHTS; i++) {
        lightSelected[i] = (i > 9);
      }
      break;      
  }
  syncCheckBoxes();  
}

function showLookAt(ge) {

  var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
  
  var long = lookAt.getLongitude(); 
  var lat = lookAt.getLatitude();
  var alt = lookAt.getAltitude();
  
  var label = document.getElementById('longLatAltLabel');
  label.innerHTML = long + ' / ' + lat + ' / ' + alt;
}

function showNavCamera() {

  var camera = navGE.getView().copyAsCamera(navGE.ALTITUDE_RELATIVE_TO_GROUND);
  
  var lng = camera.getLongitude(); 
  var lat = camera.getLatitude();
  var alt = camera.getAltitude();
  
  log('Longitude = ' + lng + ' latitude = ' + lat + ' altitude = ' + alt);
  
  var heading = camera.getHeading();
  var tilt = camera.getTilt();
  var roll = camera.getRoll();
 
  alert('Longitude = ' + lng + ' latitude = ' + lat + ' altitude = ' + alt + ' heading = ' + heading + ' tilt = ' + tilt + ' roll = ' + roll);
}

function fallBtnClicked(sender) {
  navCamera.fall();

// select custom vantage point  
  var navCombo = document.getElementById('navCombo');
  navCombo.selectedIndex = 0;
  
// select stopped  
  var camModeCombo = document.getElementById('camModeCombo');
  camModeCombo.selectedIndex = 0;
}

function stylesComboChange(sender) {

  switch (sender.selectedIndex) {
    case 0 : // pyramid
      designMode = DesignMode.pyramid;
      break;
      
    case 1 : // parallel 
      designMode = DesignMode.parallel;
      break;

    case 2 : // grid
      designMode = DesignMode.grid;
      slider.setZ(120);
      break;
  }
  syncBeams();
} 

function helpBtnClicked(sender) {
  showNavCamera();
}

function navViewComboChange(sender) {
  var navCombo = document.getElementById('navCombo');
  var i = navCombo.selectedIndex;
  
  if (i > 0) {
    navCamera.selectViewFromCombo(i);
    
// set the camera mode combo to stopped    
    var camModeCombo = document.getElementById('camModeCombo');
    camModeCombo.selectedIndex = 0;
  }
}  

function syncBeams() {
  syncNavBeamsXYZ(marker.target.x, marker.target.y, slider.z);
  syncMapBeamsWithLights();
}

function submitDesignBtnClicked(sender) {
  clearTimeout(homeID);
  showSubmitControls();
}

function checkBounds() {
// see if we're ok
  if (allowedBounds.contains(map.getCenter())) {
    return;
  }
  
// out of bounds, go to the closest allowed point
  var ctr = map.getCenter();
  var lat = ctr.lat();
  var lng = ctr.lng(); 

  var minLat = allowedBounds.getSouthWest().lat();
  var maxLat = allowedBounds.getNorthEast().lat();

  var minLng = allowedBounds.getSouthWest().lng();
  var maxLng = allowedBounds.getNorthEast().lng();
  
  if (lat < minLat) lat = minLat
  else if (lat > maxLat) lat = maxLat;
  
  if (lng < minLng) lng = minLng
  else if (lng > maxLng) lng = maxLng;
  
  map.setCenter(new GLatLng(lat, lng));
}

function restrictMapZoomAndPan() {
// set the min and max zoom levels    
  var mt = map.getMapTypes();
  for (var i=0; i < mt.length; i++) {
    mt[i].getMinimumResolution = 
      function() {
        return 15;
      }
    mt[i].getMaximumResolution = 
      function() {
        return 18;
      }
  }
    
// set up a listener for the bounds    
  GEvent.addListener(map, "move", 
    function() {
      checkBounds();
    }
  );
  allowedBounds = new GLatLngBounds(new GLatLng(49.27354, -123.150297), new GLatLng(49.2835, -123.12824));    
}

function showTopView2() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("topView"));
    map.enableScrollWheelZoom();
    map.enableContinuousZoom();

    map.setCenter(new GLatLng(originLatitude,originLongitude), 16);
    
    map.addControl(new GSmallZoomControl3D());
    map.addControl(new GMapTypeControl());

    map.removeMapType(G_HYBRID_MAP);
    map.setMapType(G_NORMAL_MAP);
    
    restrictMapZoomAndPan();
    
    marker.addToGM();
    
    finishAddingMapBeams();    
    addCheckBoxesToMap();
//  dragCamera.addToGM();
  }
}

function showTopView() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("topView"));
    map.enableScrollWheelZoom();
    map.enableContinuousZoom();

    map.setCenter(new GLatLng(originLatitude,originLongitude), 16);
    
    map.addControl(new GSmallZoomControl3D());
    map.addControl(new GMapTypeControl());

    map.removeMapType(G_HYBRID_MAP);
    map.setMapType(G_NORMAL_MAP);
    
    restrictMapZoomAndPan();
    
    marker.addToGM();
    
    createMapBeams();
    addCheckBoxesToMap();
//  dragCamera.addToGM();
  }
}


function orderBtnClicked(sender) {

//log('mode = ' + navCamera.mode + ' wd = ' + navCamera.watchDogSet);
//return; // !!!

//navCamera.setArcStartPt();
//alert('start of arc = x: ' + marker.target.x + ' y: ' + marker.target.y);
//return;

  var delta, mult;
  var minZ;
  
  var xMetres;
  var yMetres;
  var zMetres;
  
  var newX, newY, newZ;
  var i2;
  
  for (var i=0; i<LIGHTS; i++) if (lightSelected[i]) {
    switch (designMode) {
    
      case DesignMode.pyramid :
        xMetres = marker.target.x;
        yMetres = marker.target.y;
        zMetres = slider.z;
        break;
        
      case DesignMode.parallel :
        xMetres = marker.target.x + navLight[i].base.x;
        yMetres = marker.target.y + navLight[i].base.y;
        zMetres = 500;
        break;
        
      case DesignMode.grid :
        i2 = LIGHTS - 1 - i; 
        xMetres = marker.target.x + navLight[i2].base.x;
        yMetres = marker.target.y + navLight[i2].base.y;
        zMetres = minZAtXY(xMetres, yMetres) + (slider.z - MinSliderZ);
        break;
    }
        

// move the light's target X,Y,Z closer towards the ordered values
    mult = 0.25;

// x
    delta = (xMetres - navLight[i].target.x) * mult;
    newX = navLight[i].target.x + delta;

// y
    delta = (yMetres - navLight[i].target.y) * mult;
    newY = navLight[i].target.y + delta;

// z
    delta = (zMetres - navLight[i].target.z) * mult;
    newZ = navLight[i].target.z + delta;
    
    minZ = minZAtXYZ(newX, newY, newZ);
    if (newZ < minZ) newZ = minZ;

// find the new pan/tilt and end point target
    navLight[i].pointAtXYZ(newX, newY, newZ);
    mapBeam[i].sync(newX, newY, newZ);
  }
}

function disorderBtnClicked(sender) {

//navCamera.setArcEndPt();
//alert('end of arc = x: ' + marker.target.x + ' y: ' + marker.target.y);
//return;

  var mult = 50;
  var delta;
  var zMin;
  var newX, newY, newZ;
  
  for (var i = 0; i < LIGHTS; i++) if (lightSelected[i]) {

// randomize the target
    delta = (Math.random() - 0.5) * mult;
    newX = navLight[i].target.x + delta;
    
    delta = (Math.random() - 0.5) * mult;
    newY = navLight[i].target.y + delta;
    
    delta = (Math.random() - 0.5) * mult;
    newZ = navLight[i].target.z + delta;
    
    zMin = minZAtXYZ(newX, newY);
    if (newZ < zMin) newZ = zMin;

// find the new pan/tilt and end point target
    navLight[i].pointAtXYZ(newX, newY, newZ);
    mapBeam[i].sync(newX, newY, newZ);
  }
}

function allLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (!lightSelected[i]) return false;
  }
  return true;
}  

function noLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (lightSelected[i]) return false;
  }
  return true;
}  

function oddLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (odd(i)) {  // odd light - needs to be selected
      if (!lightSelected[i]) return false;
    }
    else {         // even light - needs to be not selected
      if (lightSelected[i]) return false;  
    }  
  }
  return true;
}  

function evenLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (even(i)) {  // even light - needs to be selected
      if (!lightSelected[i]) return false;
    }
    else {         // odd light - needs to be not selected
      if (lightSelected[i]) return false;  
    }  
  }
  return true;
}  

function vanierParkLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (i < 10) { // vanier light - needs to be selected
      if (!lightSelected[i]) return false;
    }
    else {         // sunset light - needs to be not selected
      if (lightSelected[i]) return false;  
    }  
  }
  return true;
}  

function sunsetBeachLightsSelected() {
  for (var i=0; i < LIGHTS; i++) {
    if (i > 9) {   // sunset light - needs to be selected
      if (!lightSelected[i]) return false;
    }
    else {         // vanier light - needs to be not selected
      if (lightSelected[i]) return false;  
    }  
  }
  return true;
}  

function syncLightsCombo() {
  var i; 
  
  var lightsCombo = document.getElementById('lightsCombo');
  
  if (allLightsSelected()) lightsCombo.selectedIndex = 1
  else if (noLightsSelected()) lightsCombo.selectedIndex = 2
  else if (oddLightsSelected()) lightsCombo.selectedIndex = 4
  else if (evenLightsSelected()) lightsCombo.selectedIndex = 5
  else if (vanierParkLightsSelected()) lightsCombo.selectedIndex = 6
  else if (sunsetBeachLightsSelected()) lightsCombo.selectedIndex = 7
  else lightsCombo.selectedIndex = 0; // custom 
}

function camModeComboChange(sender) {
  switch (sender.selectedIndex) {  
  
    case 0: // stop
      navCamera.stop();
      break;
      
    case 1: // rotate
      navCamera.rotate();
      break;
      
    case 2: // orbit
      navCamera.orbit();
      break;
      
    case 3: // arc
      navCamera.arc();
      break;
  }
  
// select custom in the vantage point combo  
  var navCombo = document.getElementById('navCombo');
  navCombo.selectedIndex = 0;
}  

function selectCustomVantagePoint() {
  var navCombo = document.getElementById('navCombo');
//  navCombo.onchange = null;
  navCombo.selectedIndex = 0;
//  nacCombo.onchange = navViewComboChange;
}