var VDB = VDB || {};

VDB.marker = new Class({
	initialize: function (options, isNew, vdbMap) {

		this._id             = options.id || 0;
		this._type           = options.type;
		this._category       = options.category || '';
		this._status         = options.status || '';
		this._statusName     = options.status_description || '';
		this._detailUrl      = options.detailUrl || '';
		this._title          = options.title || '';
		this._street	     = options.street || '';
		this._url            = options.detailUrl || '';
		this._votes          = options.votes || 0;
		this._votesThreshold = options.voteThreshold || 0;
		this._markerClusterArray = new Array();

		this._vdbMap = vdbMap;
		this._isNew  = isNew ? true : false;

		//when it is a new marker make it draggable
		var markerOptions = {
			draggable: this._isNew,
			bounce: this._isNew
		}
		
		markerOptions.title = options.title;

		//determine what icon to use
		if (options.status == 'closed') {
			markerOptions.icon = VDB.utils.icons.resolved;
		} else if (options.status == 'nosolution') {
			markerOptions.icon = VDB.utils.icons.noResponse;
		} else if (options.type == 'problem') {
			markerOptions.icon = this._isNew ? VDB.utils.icons.newProblem : VDB.utils.icons.problem;
		} else if (options.type == 'idea') {
			markerOptions.icon = this._isNew ? VDB.utils.icons.newIdea : VDB.utils.icons.idea;
		}

		//create the marker
		this._marker = new GMarker(new GLatLng(options.latitude,options.longitude), markerOptions);

		GEvent.addListener(this._marker, 'click', (function () {
			VDB.map.markerOpen = this._marker;
			this._vdbMap._map.setCenter(this._marker.getLatLng());
			if ($('panel-welcome')) {
				$('panel-welcome').destroy();
				$$('#widget-address', '#widget-addbtns', '#widget-categories').setStyle('display', 'block');
			}
		}).bind(this));

		//if it is a new issue start with an open infowindow
		if (isNew) {
			
			this._vdbMap.trackEvent(this._vdbMap._typesDescr[options.type],'Plaatsen')
			
			GEvent.addListener(this._marker, 'dragend', this.getReadableAddress.bind(this));
			
			GEvent.addListener(this._marker, 'dragstart', (function () {
				this._lastPosition = this._marker.getLatLng();
			}).bind(this));

		//if it is a existing issue bind the HTML to the marker
		} else {
			var wrapper  = new Element('div', {'class': 'infowindow', 'id': 'infowindow'});
			var location = new Element('p', {'html': this._street});
			var votes    = null; //alleen ideeen hebben stemmen in tooltip
			var title    = new Element('h2', {'text': this._title});

			if (this._type == 'problem') {
				var viewDetails = new Element('span', {'text': 'Meer over dit probleem', 'class': 'describe'});
				var status      = new Element('p', {'html': this._statusName + ' probleem'});
			} else if (this._type == 'idea') {
				var viewDetails = new Element('span', {'text': 'Meer over dit idee', 'class': 'describe'});
				var votes       = new Element('p', {'class': 'votes', 'html': '<span>' + this._votes + '</span> ' + (this._votes == 1 ? 'stem' : 'stemmen')})
				var status      = new Element('p', {'html': this._statusName + ' idee'});
			}

			viewDetails.addEvent('click', this.showDetails.bind(this));

			wrapper.adopt(title, votes, status, location, viewDetails);

			this._marker.bindInfoWindow(wrapper);
		}
	},

	/**
	 * Get an readable address from the marker location and bind that as infowindow HTML 
	 */
	getReadableAddress: function () {
		var geoCoder = new GClientGeocoder(VDB.utils.cache);
		geoCoder.getLocations(this._marker.getLatLng(), this.bindAddressHtml.bind(this));
	},


	/**
	 * Callback function for VDB.marker.getReadableAddress
	 * @param {Object} Object literal with the address data
	 */
	bindAddressHtml: function (response) {
		//no data could be found for the location
		if (!response.Placemark) {
			this._vdbMap._application.setMessage('Geen geldige locatie', 'Voor deze locatie konden geen gegevens gevonden worden', true);

			if (this._lastPosition == '') {
				this._vdbMap._map.removeOverlay(this._marker);
			} else {
				this._marker.setLatLng(this._lastPosition);
			}

			return;

		//the location is not in the Netherlands
		} else if (response.Placemark[0].AddressDetails.Country.CountryNameCode != 'NL') {
			this._vdbMap._application.setMessage('Geen geldige locatie', 'U kunt alleen ideeën en problemen aandragen binnen Nederland', true);

			if (this._lastPosition == '') {
				this._vdbMap._map.removeOverlay(this._marker);
			} else {
				this._marker.setLatLng(this._lastPosition);
			}

			return;

		//The location can be used 
		} else {
			this._lastPosition = '';
			this._vdbMap._application.hideMessage();
		}

		//see if there is streetname data
		if (response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.DependentLocality) {
			var addressData = response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.DependentLocality;
			var street = addressData.Thoroughfare.ThoroughfareName;
			var city   = addressData.DependentLocalityName;

		} else {
			var street = 'Onbekende locatie';
			var city   = response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
		}

		var wrapper, html, actions, insertDetails, remove, title;

		if (this._isNew) {
			wrapper = new Element('div', {'class': 'infowindow'});

			if (this._type == 'idea') {
				this._vdbMap.trackEvent('Idee', 'Verplaatst', street + ', ' + city )			
				title = new Element('h2', {'text': 'Nieuw idee'});
				insertDetails = new Element('span', {'text': 'Beschrijf dit idee', 'class': 'describe'});
			} else if (this._type == 'problem') {
				this._vdbMap.trackEvent('Probleem', 'Verplaatst', street + ', ' + city )	
				title = new Element('h2', {'text': 'Nieuw probleem'});
				insertDetails = new Element('span', {'text': 'Beschrijf dit probleem', 'class': 'describe'});
			}

			html = new Element('p');
			html.grab(title);
			html.grab(new Element('br'));
			html.grab(new Element('span', {'class': 'address', 'text': street + ', ' + city}));

			remove = new Element('span', {'text': 'Verwijderen', 'class': 'remove'});

			
			
			insertDetails.addEvent('click', this.insertDetails.bind(this));
			remove.addEvent('click', this.removeFromMap.bind(this));

			wrapper.adopt(html, insertDetails, remove);
		}

		this._vdbMap._map.setCenter(this._marker.getLatLng());
		this._marker.bindInfoWindow(wrapper);
		GEvent.trigger(this._marker, 'click');
	},


	/**
	 * Shows the details of the issue
	 */
	showDetails: function () {
		var lat = this._marker.getLatLng().lat();
		var lng = this._marker.getLatLng().lng();

		this._vdbMap.showMode('info', {'type': 'iframe', 'url': this._url, 'issue': this._id, 'lat': lat, 'lon': lng});
	},


	/**
	 * Sets the map object in a mode for inserting data
	 */
	insertDetails: function () {
		var geoCoder = new GClientGeocoder(VDB.utils.cache);
		geoCoder.getLocations(this._marker.getLatLng(), this.showMapCreateState.bind(this));
		this._marker.disableDragging();
		VDB.application.lockedMarker = this;
	},


	/**
	 * invokes map.showMode with a custom config object
	 * @param {Object} response
	 */
	showMapCreateState: function (response) {
		if (!response.Placemark) {
			this._vdbMap._application.setMessage('Ongeldige locatie', 'Er konden niet genoeg locatiegegevens gevonden worden', true);
			this._vdbMap._map.removeOverlay(this._marker);
			return;
		}
		
		if (response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.DependentLocality) {
			var addressData = response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.DependentLocality;
			var street      = addressData.Thoroughfare.ThoroughfareName;
			var city        = addressData.DependentLocalityName;
			var postcode    = addressData.PostalCode.PostalCodeNumber;

		} else {
			var street = 'Onbekende locatie';
			var city   = response.Placemark[0].AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
		}

		var config = {
			address: street,
			postcode: postcode,
			city: city,
			type: this._type,
			lat: this._marker.getLatLng().lat(),
			lon: this._marker.getLatLng().lng()
		}

		var addrDescr = city ? city + ', ' : ''; 
		addrDescr+= postcode ? postcode + ', ' : '';
		addrDescr+= street ? street + ', ' : '';
		this._vdbMap.trackEvent(this._vdbMap._typesDescr[this._type],'Formulier',addrDescr);
		this._vdbMap.showMode('create', config);
	},


	/**
	 * Adds the marker to the map
	 */
	addToMap: function () {
		this._vdbMap._map.addOverlay(this._marker);
		//create array
		//this._markerClusterArray.push(this._marker);

		if (this._isNew == true) {
			var wrapper = new Element('div', {'class': 'infowindow'});

			if (this._type == 'idea') {
				var title = new Element('h2', {'text': 'Nieuw idee'});
				var insertDetails = new Element('span', {'text': 'Beschrijf dit idee', 'class': 'describe'});
			} else if (this._type == 'problem') {
				var title = new Element('h2', {'text': 'Nieuw probleem'});
				var insertDetails = new Element('span', {'text': 'Beschrijf dit probleem', 'class': 'describe'});
			}

			var remove = new Element('span', {'text': 'Verwijderen', 'class': 'remove'});

			var text    = new Element('p', {'text': 'Dit icoontje is ook te verslepen naar een andere locatie'});
			var options = new Element('p').adopt(insertDetails, remove);
			var that = this;

			insertDetails.addEvent('click', this.insertDetails.bind(this));
			remove.addEvent('click', function () {
				that.removeFromMap();
				that._vdbMap.setInsertionMode('normal');
			});

			GEvent.addListener(this._marker, 'click', function () {
				this.openInfoWindow(wrapper);
			});

			wrapper.adopt(title, text, options);
			this._marker.openInfoWindow(wrapper);
		}
	},


	/**
	 * remove a marker from the map
	 */
	removeFromMap: function () {
		this._vdbMap.trackEvent('Melding', 'Verwijderen');
		this._vdbMap._map.removeOverlay(this._marker);

		if ($('panel-info').getStyle('display') == 'block')
			$('panel-info').setStyle('display', 'none');
	}
});