var KMLTour = new Class({
  is_loaded: false,
  
  current_hole: 0,
  current_object: null,

  _current_dest: null,
  _wait: -1,
  
  initialize: function(container, options) {
    var self = this;
    
    var url = options['url'];
    self.wait = options['wait'] || 10000;
    
    google.load('earth', '1', {other_params: 'sensor=false'});
    
    window.addEvent('domready', function() {
      google.earth.createInstance(container, function(instance) {
        self.ge = instance;
        
        self.ge.getWindow().setVisibility(true);
        self.ge.getOptions().setFlyToSpeed(0.15);
        self.ge.getNavigationControl().setVisibility(self.ge.VISIBILITY_AUTO);
        
        self.is_loaded = true;
        
        self.render(url);
      }, function(error) {
        console.log("Error (" + error + ")");
      });
    });
  },
  
  render: function(url) {
    var self = this;
    
    google.earth.fetchKml(self.ge, url, function(kml) {
      if (!kml) {
        window.setTimeout(function() {
          alert('Error.');
          console.log('Could not load KML.');
        }, 0); // necessary hack
      }
      
      self.kml = kml;
      self.course = new Course(kml);
      
      self.ge.getFeatures().appendChild(kml);
      
      self.zoom_to(kml);
      window.setTimeout(function() {
        self.play();
      }, 15000);
    });
  },
  
  play: function() {
    var self = this;
    
    self.show_hole(1, 'tee');
    
    self.countdown = window.setInterval(function() {
      if (!self.is_playing()) {
        if (self._wait < 0) {
          self._wait = self.wait;
        } else {
          if (self._wait != 0) {
            self._wait -= 1000;
          } else {
            self._wait = -1;
            self.next();
          }
        }
      }
    }, 1000);
  },
  
  next: function() {
    var self = this;
    
    var next_hole;
    var next_object;
    
    if (self.current_object == null) {
      next_hole = 1;
      next_object = 'tee';
    } else if (self.current_object == 'tee') {
      next_hole = self.current_hole;
      next_object = 'pin';
    } else if (self.current_object == 'pin') {
      next_hole = self.current_hole + 1;
      next_object = 'tee';
    }
    
    self.show_hole(next_hole, next_object);
  },
  
  previous: function() {
    var self = this;
    
    var prev_hole;
    var prev_object;
    
    if (self.current_object == null) {
      prev_hole = 18;
      prev_object = 'pin';
    } else if (self.current_object == 'tee') {
      prev_hole = self.current_hole - 1;
      prev_object = 'pin';
    } else if (self.current_object == 'pin') {
      prev_hole = self.current_hole;
      prev_object = 'tee';
    }
    
    self.show_hole(prev_hole, prev_object);
  },
  
  show_hole: function(num, object) {
    var self = this;
    
    if (num < 1) {
      num = self.course.holes.getLength();
    } else if (num > self.course.holes.getLength()) {
      console.log(num - self.course.holes.getLength());
      num = 1;
    }
    
    self.zoom_to(self.course.get_hole(num, object));
    self.current_hole = num;
    self.current_object = object;
  },
  
  zoom_to: function(element) {
    var self = this;
    self._current_dest = element.getAbstractView();
    self.ge.getView().setAbstractView(element.getAbstractView());
  },
  
  is_playing: function() {
    var self = this;
    if (!self._current_dest) {
      return false;
    }
    
    var here = self.ge.getView().copyAsLookAt(
      self.ge.ALTITUDE_RELATIVE_TO_GROUND);
    var there = self._current_dest;
    // alert(Math.abs(here.getLongitude() - there.getLongitude()));
    if ((Math.abs(here.getLatitude() - there.getLatitude()) > 0.007)
     && (Math.abs(here.getLongitude() - there.getLongitude()) > 0.007)) {
      return true
    } else {
      return false;
    }
  }
});

KMLTourController = new Class({
  initialize: function(kml_tour, options) {
    var play = $(options['play']);
    var previous = $(options['previous']);
    var next = $(options['next']);
    
    play.addEvent('click', function() {
      kml_tour.play();
    });
    
    next.addEvent('click', function() {
      kml_tour._wait = -1;
      kml_tour.next();
    });
    
    previous.addEvent('click', function() {
      kml_tour._wait = -1;
      kml_tour.previous();
    });
  }
});

var Course = new Class({
  initialize: function(kml) {
    this.kml = kml;
    this.holes = this.kml.getFeatures().getChildNodes();
  },
  
  get_hole: function(num, object) {
    var hole =  new Hole(num, this.holes.item(num - 1));
    
    if (!object) {
      return hole.kml;
    } else if (object == 'tee') {
      return hole.tee;
    } else if (object == 'pin') {
      return hole.pin;
    }
  }
});

var Hole = new Class({
  initialize: function(num, kml) {
    this.num = num;
    this.kml = kml;
    this.items = this.kml.getFeatures().getChildNodes();
    this.tee = this.items.item(0);
    this.pin = this.items.item(1);
  }
});
