if (typeof trackel === 'undefined') { var trackel = {}; }

trackel.map = (function($) {

  var ns = trackel, 
      that = {
        videos: {0: {}}
      },
      _markerImages = {},
      _markers = {},
      _$map, //map dom element
      _map, //google map instance
      _infoWindow,
      _shadowShadow,
      _apiUriBase = 'http://trackel10.dev/api/',
      _apiUriVideo = _apiUriBase+'video/',
      _defaultCoords = {lat: 52.453056, lng: 13.290556}, //Berlin
      _defaultLatLng,
      _defaultZoom = 7,
      _defaultMapTypeId = google.maps.MapTypeId.ROADMAP;

  that.setMap = function(map) {
    _map = map;
  };
  that.getMap = function() {
    return _map;
  };
  
  that.setDefaultMapTypeId = function(value) {
    _defaultMapTypeId = value;
  };
  that.setDefaultZoom = function(value) {
    _defaultZoom = value;
  };

  that.setMarkerImages = function(images) {
    for (var key in images) {
      _markerImages[key] = new google.maps.MarkerImage(images[key],
        // This marker is 20 pixels wide by 32 pixels tall.
        new google.maps.Size(25, 31),
        // The origin for this image is 0,0.
        new google.maps.Point(0,0),
        // The anchor for this image is the base of the flagpole at 0,32.
        new google.maps.Point(25, 31)
      );
    }
  };
  
  that.loadVideos = function(options) {
    ns.log('trackel.map.loadVideos');
    if (!ns.initialized) {
      $(document).bind('trackel:init', function() { that.loadVideos(options); });
      return;
    }

    ns.showLoading(_$map);

    if (options.useCurrentLocation) {
      that.getCurrentLocation(function(geoCoords) {     
        options.useCurrentLocation = false;
        options.geoCoords = geoCoords;
        that.loadVideos(options);
      });
      options.geoCoords = _defaultCoords; //proceed with default location while current geolocation is detected   
    }
    
    if (options.geoCoords) {
      options.urlParsed = options.url.replace(/%latitude%/, options.geoCoords.lat);
      options.urlParsed = options.urlParsed.replace(/%longitude%/, options.geoCoords.lng);
      _map.setCenter(new google.maps.LatLng(options.geoCoords.lat, options.geoCoords.lng));
    }
    else {
      options.urlParsed = options.url;
    }
  
    $.ajax({
      url: options.urlParsed,
      dataType: 'json',
      success: function(videos) {
        _$map.removeClass('error');
        that.setVideos(videos);
        if (!options.geoCoords) {
          var randomKey = Math.floor(Math.random() * videos.length); 
          var randomVideo = videos[randomKey];
          _map.setCenter(new google.maps.LatLng(randomVideo['lat'], randomVideo['long']));
          that.showVideo(randomVideo);
        }
        ns.hideLoading(_$map);
      },
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        _$map.addClass('error');
        if (typeof console !== 'undefined' && console.error) {
          console.error(textStatus);
        }
        ns.hideLoading(_$map);
      }
    });
  }

  that.setVideos = function(videos) {
    var length = videos.length;
    for (var i = 0; i < length; i++) {
      that.setVideo(videos[i]);
    }
  };
  
  that.setVideo = function(video) {
    if (that.videos[0][video.id]) {
      ns.log('trackel.map.setVideo: video '+video.id+' already exists');
      return;
    }

    var marker = new google.maps.Marker({
      position: new google.maps.LatLng(video['lat'], video['long']),
      map: _map,
      shadow: _markerShadow,
      icon: _markerImages[video.trackel_location_category_id],
      title: video.titel,
      //zIndex: location[3]
    });

    video._marker = marker;
    
    that.videos[0][video.id] = video;
    if (video.trackel_location_category_id) {
      if (!that.videos[video.trackel_location_category_id]) {
        that.videos[video.trackel_location_category_id] = {};
      }
      that.videos[video.trackel_location_category_id][video.id] = video;
    }
    if (video.trackel_location_category_id2) {
      if (!that.videos[video.trackel_location_category_id2]) {
        that.videos[video.trackel_location_category_id2] = {};
      }
      that.videos[video.trackel_location_category_id2][video.id] = video;
    }
    
    google.maps.event.addListener(marker, 'click', function() {
      that.showVideo(video);
    });

  };
  
  that.showVideo = function(video) {
    _infoWindow.setContent(that.getInfoWindowHtml(video));
    _infoWindow.open(_map, video._marker);
  };
  
  that.getInfoWindowHtml = function(video) {
    var video_url = video.feed_url.replace(/\.mp4$/, '.flv');
    var player_html = "<div id='playerWrapper'>"+
      "<object id='player'"+
          "classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"+
          "codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9.0.115'"+
          "width='238' height='201'>"+
        "<param name=bgcolor value='#FFFFFF'>"+
        "<param name=movie value='/jw/embed/player.swf'>"+
        "<param name=allowfullscreen value='true'>"+
        "<param name=allowscriptaccess value='always'>"+
        "<param name=wmode value='transparent'>"+
        "<param name='flashvars' value='file="+video_url+"&frontcolor=ffffff&lightcolor=ffffff&skin=/jw/embed/skinSmall.swf&controlbar=over&screencolor=ffffff&image="+video.thumb_url+"'>"+

        "<embed name='player' "+
          "type='application/x-shockwave-flash' "+
          "pluginspage='http://www.macromedia.com/go/getflashplayer' "+
          "width='238' height='201' "+
          "bgcolor='#FFFFFF' "+
          "src='/jw/embed/player.swf' "+
          "allowfullscreen='true' "+
          "allowscriptaccess='always' "+
          "wmode='transparent' "+
          "flashvars='file="+video_url+"&frontcolor=ffffff&lightcolor=ffffff&skin=/jw/embed/skinSmall.swf&controlbar=over&screencolor=ffffff&image="+video.thumb_url+"'>"+
        "</embed>"+
      "</object>"+
    "</div>";
    
    var infowindow_html = "<div class='info_window'>";
        infowindow_html += "<h1><a href='" + video.trackel_url +  "'>" + video.titel + "</a></h1>";
        infowindow_html += player_html;
        infowindow_html += "<table><tr>";
        infowindow_html += "<td width='69'>" + video.rating.rating_html + "</td>";
        infowindow_html += "<td>" + video.rating.count_html + "</td>";
        infowindow_html += "<td class='last'>from <a class='blue' href='/myTrackel/show/id/" + video.author_id + "'>" + video.author + "</a></td>";
        infowindow_html += "</tr></table>";
        infowindow_html += "</div>";
    
    return infowindow_html;
  }
  
  

  that.getCurrentLocation = function(callback) {
    ns.log('trackel.map.getCurrentLocation');
    var browserSupportFlag = false;
    
    // Try W3C Geolocation method (Preferred)
    if (navigator.geolocation) {
      browserSupportFlag = true;
      navigator.geolocation.getCurrentPosition(function(position) {
          ns.log('got geolocation from W3C method');
          callback({ lat: position.coords.latitude, lng: position.coords.longitude });
        },
        function() {
          ns.log('did not get geolocation from W3C method');
          callback(_defaultCoords);
        }
      );
    }
    else if (google.gears) {
      // Try Google Gears Geolocation
      browserSupportFlag = true;
      var geo = google.gears.factory.create('beta.geolocation');
      geo.getCurrentPosition(function(position) {
          ns.log('got geolocation from google gears');
          callback({ lat: position.latitude, lng: position.longitude });
        },
        function() {
          ns.log('did not get geolocation from google gears');
          callback(_defaultCoords);
        }
      );
    }
    else {
      // Browser doesn't support Geolocation
      ns.log('could not retrieve geolocation (neither W3C method nor google gears are available)');
      //that.handleNoGeolocation(browserSupportFlag);
    }
  };

  that.toggleFullscreen = function() {
    $('body').toggleClass('fullscreen');
  }
  
  that.addMapControl = function (options) {
    if (!ns.initialized) {
      $(document).bind('trackel:init', function() { that.addMapControl(options); });
      return;
    }

    var $element = $('<div class="UIControl"></div>');
    if (options.className) {
      $element.addClass(options.className);  
    }

    // Set CSS for the control border
    var $inner = $('<div class="inner"></div>');
    if (options.help) {
      $inner.attr('title', options.help);
    }
    $inner.appendTo($element);

    // Set CSS for the control interior
    var $label = $('<div class="label"></div>');
    $label.html(options.label);
    $label.appendTo($inner);

    google.maps.event.addDomListener($inner[0], 'click', options.clickHandler);
    _map.controls[google.maps.ControlPosition.TOP_RIGHT].push($element[0]);
  };

  that.hideAllCategories = function() {
    ns.log('trackel.map.hideAllCategories');
    /*
    $('img', _$map).filter(function() {
        return this.src.match(/cat_.*\.png/);
    }).parent().hide();
    */
    var allVideos = that.videos[0];
    for (var id in allVideos) {
      allVideos[id]._marker.setVisible(false);
    }
  };
  
  that.showCategory = function(categoryId) {
    ns.log('trackel.map.showCategory: '+categoryId);
    /*
    var regexp = new RegExp('cat_'+categoryId);
    $('img', _$map).filter(function() {
      return regexp.test(this.src);
    }).parent().show();
    */
    
    var allVideos = that.videos[categoryId];
    for (var id in allVideos) {
      var video = allVideos[id];
      video._marker.setVisible(true);
      var icon = categoryId == 0 ? _markerImages[video.trackel_location_category_id] : _markerImages[categoryId];
      video._marker.setIcon(icon);
    }
  };
  
  that.categoryLinkOnClick = function(e) {
    ns.log('trackel.map.categoryLinkOnClick');
    e.preventDefault();
    e.stopPropagation();
    var $link = $(this);
    var url = $link.attr('href');
    var categoryId = url.substring(url.lastIndexOf('/')+1);
    if (!parseInt(categoryId)) {
      categoryId = '0'; //all categories
    }
    that.hideAllCategories();
    that.showCategory(categoryId);
  }
  
  that.initCategoryLinks = function() {
    var $categoryLinks = $('#map_categories a', _$map);
    $categoryLinks.click(that.categoryLinkOnClick);
  };
  
  that.init = function() {
    ns.log('trackel.map.init');
    
    _$map = $("#map_canvas");
    if (!_$map || !_$map.length) {
      ns.log('map dom element not found');
      return false;
    }

    _defaultLatLng = new google.maps.LatLng(_defaultCoords.lat, _defaultCoords.lng);
    _infoWindow = new google.maps.InfoWindow({content: 'tpl'});

    var mapOptions = {
      zoom: _defaultZoom,
      center: _defaultLatLng,
      mapTypeId: _defaultMapTypeId
    };
    _$map.addClass('init');
    _map = new google.maps.Map(_$map[0], mapOptions);
    setTimeout(function() {_$map.removeClass('init');}, 500); //we need to initialize map in fullscreen mode in order to make fullscreen toggling work    
    
    var $mapContents = $('#map_contents > *');
    $mapContents.each(function(key, value) {
      $(value).appendTo(_$map);
    });
    
    that.initCategoryLinks();
    
    that.setMarkerImages({
      1: '/images/category_icons/cat_1_s.png',
      2: '/images/category_icons/cat_2_s.png',
      3: '/images/category_icons/cat_3_s.png',
      4: '/images/category_icons/cat_4_s.png',
      5: '/images/category_icons/cat_5_s.png',
      6: '/images/category_icons/cat_6_s.png',
      7: '/images/category_icons/cat_7_s.png',
      8: '/images/category_icons/cat_8_s.png'
    });

    _markerShadow = new google.maps.MarkerImage('/images/category_icons/cat_shadow_s.png',
      // The shadow image is larger in the horizontal dimension
      // while the position and offset are the same as for the main image.
      new google.maps.Size(41, 31),
      new google.maps.Point(0,0),
      new google.maps.Point(25, 31)
    );
    
    that.addMapControl({
      label: 'Fullscreen', 
      help: 'Click to display map in fullscreen mode',
      clickHandler: that.toggleFullscreen,
      className: 'toggleFullscreen'
    });

  };
  
  $(document).bind('trackel:init', that.init);
  
  return that;
  
})(jQuery);

if(window.jfPD){jfPD.controller.loadJavascripts();}
