var map;

function Location(locationData) {
	this.id = null;
	this.name = null;
	this.street = null;
	this.zip = null;
	this.city = null;
	this.type = null;
	this.locationlink = null;
	this.longitude = null;
	this.latitude = null;
	this.marker = null;

  this.location = function(locationData){
    this.id = locationData.id;
		this.name = locationData.name;
		this.street = locationData.street;
		this.zip = locationData.zip;
		this.city = locationData.city;
		this.type = locationData.type;
    if(locationData.locationlink.match(/http/g)){
      this.locationlink = '<a href="' +locationData.locationlink+ '" target="_blank">Zum Standort</a>';
    } else {
      this.locationlink = '<a href="' +locationData.locationlink+ '">Zum Standort</a>';
    }
		this.longitude = locationData.longitude;
		this.latitude = locationData.latitude;
		this.marker = new Marker(this);
  }
  
	this.getID = function() {
		return(this.id);
	}
	this.getName = function() {
		return(this.name);
	}
	this.getStreet = function() {
		return(this.street);
	}
	this.getZip = function() {
		return(this.zip);
	}
	this.getCity = function() {
		return(this.city);
	}
	this.getType = function() {
		return(this.type);
	}
	this.getLocationlink = function() {
		return(this.locationlink);
	}
	this.getLongitude = function() {
		return(this.longitude);
	}
	this.getLatitude = function() {
		return(this.latitude);
	}
	this.getMarker = function() {
		return(this.marker);
	}
	this.getInfoWindow = function() {
		infoWindow = "<strong>" + this.name + "</strong><br/>" + this.street + "<br/>" + this.zip + " " + this.city;
		return infoWindow;
	}
	this.getTableData = function() {
	  var distance = mapController.getCenterPoint().distanceFrom(this.marker.getGoogleMarker().getLatLng());
	  distance = (distance/1000).toFixed(2);
		tableData = new Array(
		  this.name,
		  this.street,
		  this.zip,
		  this.city,
		  this.id,
		  this.locationlink
		  //distance,
		  //mapController.createRoutingLabel(this.marker.getGoogleMarker().getLatLng())
		);
		return tableData;
	}
	this.location(locationData);
}

Location.findByID = function(locationID) {
  locationFactoryInstance = LocationFactory.getInstance();
  var locations = locationFactoryInstance.getLocations();
  return locations[locationID];
}

Location.createTableData = function() {
  locationFactoryInstance = LocationFactory.getInstance();
  var locations = locationFactoryInstance.getLocations();
  var tableData = new Array();
  for (var x in locations) {
    tableData.push(locations[x].getTableData());
  }
  return tableData;
}

function Marker(location) {
    var id = null;
    var googleMarker = null;
		var infoWindow = null;
		
    this.marker = function(location){
      id = location.getID();
			var point = new GLatLng(location.getLatitude(), location.getLongitude());
			var icon = this.setIcon(location.getType());
			var locationMarker = new GMarker(point, {icon: icon});
			GEvent.addListener(locationMarker,"click", function() {
        locationMarker.openInfoWindowHtml(location.getInfoWindow());
      });
			googleMarker = locationMarker;
			infoWindow = location.getInfoWindow();
    }
    this.setIcon = function(type) {
      var icon = Icon.findByID(type);
  		return(icon);
  	}
  	this.getGoogleMarker = function() {
  		return(googleMarker);
  	}
    this.marker(location);
}

Marker.createMarkerArray = function() {
  locationFactoryInstance = LocationFactory.getInstance();
  var locations = locationFactoryInstance.getLocations();
  var markers = new Array();
  for (var x in locations) {
    markers.push(locations[x].getMarker().getGoogleMarker());
  }
  return markers;
}

function Icon(iconID, iconData) {
  var id = null;
  var googleIcon = null;
	
  this.icon = function(iconID, iconData){
    id = iconID;
    var icon = new GIcon(G_DEFAULT_ICON);
    icon.image = iconData.url;
    icon.iconSize = new GSize(32, 32);
    icon.iconAnchor = new GPoint(16, 32);
    googleIcon = icon;
  }
  
  this.getGoogleIcon = function(){
    return googleIcon;
  }
  
  this.icon(iconID, iconData);
}

Icon.findByID = function(iconID) {
  iconFactoryInstance = IconFactory.getInstance();
  var icons = iconFactoryInstance.getIcons();
  return icons[iconID].getGoogleIcon();
}

var IconFactory = (function() {
  var instance = null;
	
	function PrivateConstructor() {
    	var icons = {};
      
    	this.createIcons = function(markerIcons) {
        for (var id in markerIcons) {
          var icon = new Icon(id, markerIcons[id])
          icons[id] = icon;
        }
    	}

      this.getIcons = function() {
        return icons;
      }
  }
  
  return new function() {
    this.getInstance = function() {
      if (instance == null) {
        instance = new PrivateConstructor();
        instance.constructor = null;
      }
      return instance;
    }
  }
  
})();

var LocationFactory = (function() {
  var instance = null;
	
	function PrivateConstructor() {
    	var locations = {};
      
      this.updateLocationData = function(ajaxURI, north, east, south, west, service, servicetype, canZoomOut) {
        jQuery.ajax({
          url: ajaxURI,
          global: false,
          cache: false,
          type: "POST",
          data: ({action: 'getlocationlist', north : north, east: east, south: south, west: west, searchservice: service, searchservicetype: servicetype}),
          dataType: "json",
          success: function(locationData){
            locations = {};
          	createLocations(locationData.results[0].locationList);
          	var zoomOut = false;
            if(canZoomOut && !locationData.results[0].locationList.length) {
              zoomOut = true;
            }
          	mapController.onDataChange(zoomOut, locationData.results[0].searchText);
          }
        }
        );
    	}

    	var createLocations = function(locationData) {
    		jQuery.each(locationData, function() {
    				var location = new Location(this);
    				locations[location.getID()] = location;    				
    		});
    	}

      this.getLocations = function() {
        return locations;
      }
  }
  
  return new function() {
    this.getInstance = function() {
      if (instance == null) {
        instance = new PrivateConstructor();
        instance.constructor = null;
      }
      return instance;
    }
  }
  
})();
