/**
 * kst map code
 */

(function($) {

// MapManager
MapManager = function(map, options) {
  // defaults
  this.zoom = 9;
  this.markerZoom = 16;
  this.markerImage = 'http://maps.google.com/mapfiles/ms/icons/blue.png';
  this.markerSize = [32, 32];
  this.shadowImage = 'http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png';
  this.shadowSize = [59, 32];

  $.extend(this, options);

  // extend callback with this if callback is available
  if (this.markeradded) {
    $.extend(this.markeradded, this);
  }
  if (this.zoomchanged) {
    $.extend(this.zoomchanged, this);
  }
  if (this.initialized) {
    $.extend(this.initialized, this);
  }
  if (this.willmove) {
    $.extend(this.willmove, this);
  }
  if (this.moved) {
    $.extend(this.moved, this);
  }
  
  // create the map
  this.map = new google.maps.Map2(document.getElementById(map));
  
  var $this = this;
  // hook initialized event
  google.maps.Event.addListener(this.map, 'load', function() {
    $this.initialized();
  });
};

// MapManager class
$.extend(MapManager.prototype, {

  initialize: function() {
    this.places = {}
    this.map.addControl(new google.maps.LargeMapControl3D());
    this.map.addControl(new google.maps.HierarchicalMapTypeControl());

// To enable overview map uncomment this
//    var overview = new google.maps.OverviewMapControl();
//    this.map.addControl(overview);


    // set centre
    this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude), this.zoom);
    this.map.enableContinuousZoom();
    // this.map.enableScrollWheelZoom();
    // set minimum and maximum zoom
    G_NORMAL_MAP.getMaximumResolution = function() { return 17; }
    G_SATELLITE_MAP.getMaximumResolution = function() { return 17 }
    G_HYBRID_MAP.getMaximumResolution = function() { return 17; }
    G_NORMAL_MAP.getMinimumResolution = function() { return 9; }
    G_SATELLITE_MAP.getMinimumResolution = function() { return 9; }
    G_HYBRID_MAP.getMinimumResolution = function() { return 9; }
    /* load overlay */
    if (this.startOverlay) {
      this.loadGroundOverlay(this.startOverlay, this.startOverlayBounds);
    }
    this.manager = new MarkerManager(this.map);
    this.loadGeoRSS();
    
  },

  // load overlay
  loadGroundOverlay: function(overlay, box) {
    var k = this;
    var bounds = new google.maps.LatLngBounds(
      new google.maps.LatLng(box[1], box[3]),
      new google.maps.LatLng(box[0], box[2])
    );
    // var ov = new google.maps.GroundOverlay(overlay, bounds);
    var tile = new google.maps.TileLayer(google.maps.CopyrightCollection(''), this.zoom, this.zoom);
    var mercator = new google.maps.MercatorProjection(this.zoom+1);
    tile.getTileUrl = function(p, zoom) {
      if (zoom != k.zoom) {
        return 'http://www.maptiler.org/img/none.png';
      }
      var ymax = 1 << zoom;
      var y = ymax - p.y -1;
      var tileBounds = new google.maps.LatLngBounds(
        mercator.fromPixelToLatLng( new google.maps.Point( (p.x)*256, (p.y+1)*256 ) , zoom ),
        mercator.fromPixelToLatLng( new google.maps.Point( (p.x+1)*256, (p.y)*256 ) , zoom )
      );
      if (bounds.intersects(tileBounds)) {
        return overlay + '/' + zoom + '/' + p.x + '/' + y + '.png';
      }
      else {
        return 'http://www.maptiler.org/img/none.png';
      }
    }
    tile.isPng = function() { return true; }
    tile.getOpacity = function() { return 1.0; }

    var ov = new google.maps.TileLayerOverlay(tile);
    var hybrid = new google.maps.TileLayerOverlay(G_HYBRID_MAP.getTileLayers()[1]);

    this.map.addOverlay(ov);
    // this.map.addOverlay(hybrid);
    
    // remove the overlays if the zoom level is not initial zoom level
    google.maps.Event.addListener(this.map, 'zoomend', function(oldLevel, newLevel) {
      if (newLevel == k.zoom) {
        this.addOverlay(ov);
        // this.addOverlay(hybrid);
      }
      else {
        // this.removeOverlay(hybrid);
        this.removeOverlay(ov);
      }
      // trigger zoomchange event
      k.zoomchanged(oldLevel, newLevel);
    });
    // restrict the map area
    google.maps.Event.addListener(this.map, 'drag', function() {
      if (bounds.contains(this.getCenter())) {
        return;
      }

      var C = this.getCenter();
      var X = C.lng();
      var Y = C.lat();

      var maxX = bounds.getNorthEast().lng();
      var maxY = bounds.getNorthEast().lat();
      var minX = bounds.getSouthWest().lng();
      var minY = bounds.getSouthWest().lat();

      if (X < minX) { X = minX; }
      if (X > maxX) { X = maxX; }
      if (Y < minY) { Y = minY; }
      if (Y > maxY) { Y = maxY; }
      
      this.setCenter(new google.maps.LatLng(Y, X));
    });
  },

  // load the geo rss
  loadGeoRSS: function() {
    var k = this;
    var icon = new google.maps.Icon(G_DEFAULT_ICON);
    icon.image = this.markerImage;
    icon.iconSize = new google.maps.Size(this.markerSize[0], this.markerSize[1]);
    icon.shadow = this.shadowImage;
    icon.shadowSize = new google.maps.Size(this.shadowSize[0], this.shadowSize[1]);

    $.ajax({
      type: 'GET',
      dataType: 'xml',
      url: this.endpoint,
      success: function(data, status) {

        // iterate entries and add markers
        $(data).find('feed entry').each(function(index) {
          var e = $(this);
          var title = e.find('title').text();
          var desc = e.find('summary').text();

          // add marker to map
          var point = '[nodeName=georss:point]';
          var ovimage = '[nodeName=kst:overlay]';
          var ovbox = '[nodeName=kst:overlay-box]';

          // add overlay
          var overlayImage = e.find(ovimage).text();
          var num = e.find(ovbox).text().split(/\s+/);
          var box = new google.maps.LatLngBounds(
            new google.maps.LatLng(num[1], num[3]),
            new google.maps.LatLng(num[0], num[2])
          );
          if (overlayImage) {
            var overlay = new google.maps.GroundOverlay(overlayImage, box);
            k.map.addOverlay(overlay);
          }

          // add marker
          var id = e.find('id').text();
          var num = e.find(point).text().split(/\s+/);
          var pos = new google.maps.LatLng(num[0], num[1]);
          var marker = new google.maps.Marker(pos, {icon:icon});

          // google.maps.Event.addListener(k.map, 'extinfowindowopen', function() {
          //   this.setCenter(pos, k.markerZoom);
          // });

          var node = $(desc);
          // add tabs
          var tabs = $('<ul>');
          tabs.addClass('tabs');
          node.find('.tab:first').addClass('active');
          node.find('.tab').each(function() {
            var e = $(this);
            var label = e.attr('title');
            tabs.append(
              $('<li>')
                .addClass('tab')
                .html(
                  $('<a>')
                    .attr('href', '#' + e.attr('id'))
                    .text(label)
                )
            );

          });
          tabs.find('li.tab:first').addClass('active');
          // prepend tabs to nodes
          node.prepend(tabs);

          // bind click event to marker
          var html = node.html();

          google.maps.Event.bind(marker, 'click', k, function() {

            // add flash content
            marker.openExtInfoWindow(k.map, 'dia', html,
              {
                beakOffset: 8,
                paddingX: 70,
                paddingY: 35
              }
            );
            
            // precaculate context
            var context = $('#dia');
            // add tab events

            $('li.tab a:not(.processed)', context).click(function() {
              var target = $(this).attr('href');
              if (target) {
                // IE7 compatibility
                target = target.substring(target.indexOf('#'));
                $(this).addClass('processed');
                $(this).parent().addClass('active').siblings().removeClass('active');
                $(target, context).addClass('active').siblings().removeClass('active');
              }
              return false;
            });
            
            // initiate panorama flash file
            $('.panorama:not(.processed)', context).each(function() {
              var e = $(this);
              e.addClass('processed');
              e.flash({
                swf: e.attr('flash-file'),
                expressInstall: true,
                flashvars: { xml_file: e.attr('xml-file') },
                params: { allowFullScreen: true, allowScriptAccess: 'sameDomain', wmode: 'transparent' },
                width: 580,
                height: 277
              });
            });
            // initiate jwplayer flash file
            $('.gallery:not(.processed)', context).each(function() {
               var e = $(this);
               e.addClass('processed');
               e.flash({
                 swf: e.attr('flash-file'),
                 expressInstall: true,
								 flashvars: { file: e.attr('xml-file'), backcolor: 'f2f2f2', frontcolor: 'cccccc', lightcolor: 'c2c7ca', skin: e.attr('skin-file'), playlist: 'right', autostart: 'false', icons: 'false', playlistsize: '152', controlbar: 'bottom', screencolor: 'f2f2f2', stretching: 'fill'},
                 params: { allowFullScreen: true, allowScriptAccess: 'always', wmode: 'transparent' },
                 width: 577,
                 height: 277
               });
             });
            // initiate jwplayer image rotator
            $('.rotator:not(.processed)', context).each(function() {
               var e = $(this);
               e.addClass('processed');
               e.flash({
                 swf: e.attr('flash-file'),
                 expressInstall: true,
								 flashvars: { file: e.attr('xml-file'), width: '340', height: '256', backcolor: '0xFFFFFF', frontcolor: '0xFFFFFF', overstretch: 'fit', screencolor: '0xFFFFFF', shownavigation: 'false', transition: 'slowfade', rotatetime: '3', shuffle: 'false'},
                 params: { allowFullScreen: true, allowScriptAccess: 'always'},
                 width: 340,
                 height: 256
               });
             });
             
            // initiate swf player
            $('.3drotator:not(.processed)', context).each(function() {
               var e = $(this);
               e.addClass('processed');
               e.flash({
                 swf: e.attr('flash-file'),
                 expressInstall: true,
                 flashvars: { backcolor: '0xFFFFFF'},
                 params: { allowFullScreen: true, allowScriptAccess: 'always'},
                 width: 340,
                 height: 256
               });
             });
            
            // set the map center and zoom to the marker location
            // and to marker zoom
            k.map.setCenter(pos, k.markerZoom);
            
            if (k.moved) k.moved(this);
             
          });

          k.manager.addMarker(marker, k.zoom);
          k.places[id] = {
            latlng: pos,
            zoom: k.markerZoom,
            marker: marker
          };
          if (k.markeradded) {
            k.markeradded({id: id, title: title});
          }
        });
      }
    });
  },

  reset: function() {
    this.map.closeExtInfoWindow();
    this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude), this.zoom);
  },

  moveTo: function(name) {
    var $this = this;
    this.map.closeExtInfoWindow();
    if (this.willmove)
      this.willmove(name);
    setTimeout(function() {
    if ($this.places[name]) {
      var p = $this.places[name];
      google.maps.Event.trigger(p.marker, 'click');
    }
    }, 500);
  }
});

$.extend(window, {
  kst: {
    MapManager: MapManager
  }
});

})(jQuery);
