function ICastCustomMarker(map, latlng, opts) {
  google.maps.OverlayView.call(this);
  this.latlng_ = latlng;
  this.setMap(map);
  this.map_ = map;
  this.height_ = opts.icon.height || 32;
  this.width_  = opts.icon.width || 32;
  this.image_ = opts.icon.image;
  this.anchor_ = {};
  this.anchor_.x = opts.icon.anchor.x || 0;
  this.anchor_.y = opts.icon.anchor.y || 0;
  this.div_ = $('<div></div>');
  this.content_ = opts.content || '';
  this.has_info_window_ = opts.has_info_window || false;
}

ICastCustomMarker.prototype = new google.maps.OverlayView();

ICastCustomMarker.prototype.onAdd = function() {
  var that = this;
  this.div_.css({
    'position': 'absolute',
    'overflow': 'hidden',
    'padding-left': '0px'
  });
  
  
  this.div_.append(
    $('<img src="'+ this.image_ +'" width="'+ this.width_ +'" height="'+ this.height_ +'" />')
  );
  
  google.maps.event.addDomListener(this.div_, 'click', function(e) {
    google.maps.event.trigger(that, 'click', e);
  });
  
  var panes = this.getPanes();
  $(panes['overlayImage']).append(this.div_);
  
  if (this.content_ != '' && this.has_info_window_) {
    this.div_.css({ 'cursor': 'pointer' });
    this.div_.qtip({
      content: {
        text: this.content_,
        title: {
          text: 'blub',
          button: true
        }
      },
      show: {
        event: false,
        ready: true
      },
      hide: false,
      position: {
        my: 'bottom center',
        at: 'top center',
        container: $(panes['overlayImage'])
      },
      style: {
        classes: 'ui-tooltip-tipsy-white ui-tooltip-shadow'
      }
    });
    
    this.div_.click(function() {
      $(this).qtip('toggle');
    });
  }
  
};

ICastCustomMarker.prototype.onRemove = function() {
  if (!this.div_) return false;
  this.div_.parentNode.removeChild(this.div_);
};

ICastCustomMarker.prototype.draw = function() {
  var divPixel = this.getProjection().fromLatLngToDivPixel(this.latlng_);
  this.div_.css({
    'width': this.width_ + 'px',
    'height': this.height_ + 'px',
    'top': divPixel.y - this.anchor_.y + 'px',
    'left': divPixel.x - this.anchor_.x + 'px'
  });
  $(this.div_).qtip('reposition');
};

ICastCustomMarker.prototype.getDiv = function() {
  return this.div_;
};

(function($) {
  
  var ICastGMap = function(element, options) {
    
    var that = this;
    
    var settings = $.extend({}, $.fn.icastGMap.defaults, options);
    
    var mapdiv = $(element);
    
    this.map = new google.maps.Map(element, settings);
    
    if (settings.directions.enabled) {
      this.currentDirections = null;
      this.oldDirections = [];
      this.directionsBounds = new google.maps.LatLngBounds;
      this.directionsService = new google.maps.DirectionsService();
      this.directionsDisplay = new google.maps.DirectionsRenderer({
        'map': this.map,
        'preserveViewport': true,
        'draggable': settings.directions.draggable
      });
      if (settings.directions.panelId != '') {
        this.directionsDisplay.setPanel(document.getElementById(settings.directions.panelId));
      }
      if (settings.directions.draggable) {
        google.maps.event.addListener(this.directionsDisplay, 'directions_changed', function() {
          if (that.currentDirections) {
            that.oldDirections.push(that.currentDirections);
          }
          that.currentDirections = that.directionsDisplay.getDirections();
        });
      }
      mapdiv.append(
        $('<div id="direction_origin_ui">Route berechnen</div>').hover(function() {
          $(this).css('border', '1px solid #678AC7');
        }, function() {
          $(this).css('border', '1px solid #A9BBDF');
        }).click(function() {
          if (!$(this).hasClass('active')) {
            $(this)
              .addClass('active')
              .css('cursor', 'default')
              .append('<p>')
              .append(
                $('<form id="route_form"><label for="origin">Von </label><input id="origin" type="text" /><input type="submit" value="Go"/></form>')
                  .submit(function() {
                    $('.ui-tooltip-tip').qtip('hide');
                    that.calcRoute($('#origin').val());
                    if ($('#'+settings.directions.panelId).css('display') != 'block') {
                      mapdiv.animate({ width: '-='+$('#'+settings.directions.panelId).outerWidth() }, function() {
                        $('#'+settings.directions.panelId).fadeIn();
                        that.map.fitBounds(that.directionsBounds);
                      });
                    }
                    return false;
                  })
              )
              .append('</p>')
          }
        })
      );
    }
    
    if (settings.marker.enabled) {
      this.marker = new ICastCustomMarker(this.map, new google.maps.LatLng(settings.marker.lat, settings.marker.lng), settings.marker);
      if (settings.marker.content != '') {
        var div = this.marker.getDiv();
        var panes = this.marker.getPanes();
        
      }
    }
    
    this.calcRoute = function(origin) {
      var request = {
        origin: origin,
        destination: settings.directions.destination,
        travelMode: google.maps.DirectionsTravelMode.DRIVING
      }
      that.directionsService.route(request, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          that.directionsDisplay.setDirections(response);
          that.directionsBounds = response.routes[0].bounds;
        }
      });
    }
    
    return this;
  }
  
  $.fn.icastGMap = function(options) {
    return this.each(function(key, value){
      if ($(this).data('icastGMap')) return $(this).data('icastGMap');
      $(this).data('icastGMap', new ICastGMap(this, options));
    });
  };
  
  //Default settings
  $.fn.icastGMap.defaults = {
    zoom: 16,
    center: new google.maps.LatLng(50.1612778885697, 8.656392395496368),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    mapTypeControl: true,
    mapTypeControlOptions: {
      mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.TERRAIN],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    },
    zoomControl: true,
    zoomControlOptions: {
      style: google.maps.ZoomControlStyle.SMALL
    },
    directions: {
      enabled: false,
      origin: '',
      destination: '',
      draggable: false,
      panelId: ''
    },
    marker: {
      enabled: false,
      lat: 50.1612778885697,
      lng: 8.656392395496368,
      has_info_window: false,
      content: '',
      icon: {
        image: '',
        width: 32,
        height: 32,
        anchor: {
          x: 0,
          y: 0
        }
      }
    }
  };
  
})(jQuery);

