(function() {

	Logi.GoogleMap = function (mapElement, addresses, selectedAddress, options) {

		// Geocode address and plot markers
		var getGeoCode = function (apiCenter, apiMap, index) {
			var apiGeocoder = new google.maps.Geocoder();
			
			var centerSet = false;
			apiGeocoder.geocode ({ address : "Austria" }, function (results, status) {
				if (!centerSet) {
					apiMap.setCenter(results[0].geometry.location);
				}
			});
			
			// Check for valid address array
			if (addresses && index >= 0) {
				// Get Lat/Long values from address
				apiGeocoder.geocode({ address: addresses[index].address }, function(results, status) {
					//Logi.log (addresses[index].address, status, google.maps.GeocoderStatus.OK, results, google.maps.GeocoderStatus.ZERO_RESULTS, centerSet);
					if (status == google.maps.GeocoderStatus.OK && results.length) {

						if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
							
							// Center in map on location
							centerSet = true;
														
							apiMap.setCenter(results[0].geometry.location);

							// Create tooltip text
							var title = '';
							if (options.tooltip) title = addresses[index].title + options.tipsuffix;

							/*var apiIcon = new google.maps.Icon ({
								image : 'http://vav.bob-host2.com/web/img/public/pin_blue.png'
							});*/
							
							var opts = {
								position: results[0].geometry.location,
								map: apiMap,
								//icon: apiIcon,
								title: title
							};
							if (addresses[index].poi) {
								opts.icon = 'http://vav.bob-host2.com/web/img/public/pin_blue.png';  
							}
							
							// Add marker to map
							var apiMarker = new google.maps.Marker (opts);

							// Create info window
							var apiInfoWindow = new google.maps.InfoWindow({
								content: addresses[index].details
							});

							// Create 'click' event and attach info window to marker
							if (options.clickable)
								google.maps.event.addListener(apiMarker, 'click', function() {
									apiInfoWindow.open(apiMap, apiMarker);
								});
						}
					}
					if (!centerSet) {
						if (index < addresses.length - 1) {
							getGeoCode(apiCenter, apiMap, index + 1);
						} else {
							Logi.DOM.Element.hide ('mapsearch');
						}
					}

				});
			}
		};

		// Convert map type to Google Map ID
		var getGoogleMapID = function (map) {
			var mapid = google.maps.MapTypeId.ROADMAP;

			switch (map) {
				case 1:
					mapid = google.maps.MapTypeId.SATELLITE;
					break;
				case 2:
					mapid = google.maps.MapTypeId.HYBRID;
					break;
				case 3:
					mapid = google.maps.MapTypeId.TERRAIN;
					break;
			}

			return mapid;
	    };

		var defaults = {
			type: 0,
			width: '600px',
			height: '400px',
			zoom: 9,
			scrollwheel: false,
			clickable: true,
			tooltip: true,
			tipsuffix: ' (click for more)'
		};
		for (var opt in defaults) { options[opt] = options[opt] || defaults[opt]; }

		var maptype = getGoogleMapID (options.type);

		var apiCenter = new google.maps.LatLng(0,0);
		var apiDefaults = {
			mapTypeId: maptype,
			zoom: options.zoom,
			center: apiCenter
		};

		var apiMap = new google.maps.Map(mapElement, apiDefaults);

		var $e = mapElement;
		// Add map class to user div
		if (!Logi.DOM.Element.hasClass($e, 'mapGoogle')) {
			Logi.DOM.Element.addClass($e, 'mapGoogle');
			$e.style.width = options.width;
			$e.style.height = options.height;
		}

		if (addresses && addresses.length > 0) {
			getGeoCode(apiCenter, apiMap, 0);
		}

	};

	var SitePrototype = new Class ({
		
		server : undefined,
		Modules : undefined,
		commands : undefined,
		__construct : function (server) {
			this.server = server;
			this.Modules = {};
			this.commands = {};
		},
		addModule : function (moduleName, objects) {
			this.Modules[moduleName] = objects;
		},
		addCommand : function (commandName, moduleName, command) {
			this.commands[commandName] = { command : command, module : moduleName };
		},
		getData : function (data, onload) {
			if (data instanceof Array) data = data.join ('/');
			Logi.Net.JSON.request (this.server + 'server/data/' + encodeURI (data), null, onload, 'get');
		},		
		getHtml : function (html, onload, parentContainer) {
			if (html instanceof Array) html = html.join ('/');
			var callback = parentContainer ? function (response) {
				Logi.DOM.Element.get (parentContainer).innerHTML = response;
				if (typeof onload == 'function') onload();
			} : onload;
			Logi.Net.Ajax.request (this.server + 'server/html/' + html, null, callback, 'get');
		},
		validateForm : function (data, validator) {
			try {
				return validator (data) !== false;
			} catch (e) {
				Logi.UI.MessageBox.show (Logi.Language.term ("Validation error"), e.message || e.error, function() { 
					Logi.DOM.Element.focus (e.element || (e.elements && e.elements[0]));
				});
				return false;
			}	
		},
		handleAction : function (action, data, callback, options) {
			if (action instanceof Array) action = action.join ('/');
			var actionCallback = Logi.emptyFunction;
			if (typeof callback == 'function') {
				actionCallback = {
					success : callback
				}
			} else {
				actionCallback = Logi.clone (callback);
			}
			if (typeof actionCallback.exception == 'function') {
				var oldSuccess = actionCallback.success;
				actionCallback.success = function (response) {
					if (typeof response == 'string' && response.charAt (0) == '@') {
						actionCallback.exception (response.substring (1));
					} else if (response == 'false') {
						actionCallback.exception();
					} else {
						//DEBUG ONLY
						if (response.indexOf ('Logi_Exception') > -1) {
							Logi.UI.MessageBox.show ('PHP Exception', response, null, { width : 600 });
						}
						var r = response.length ? Logi.Net.JSON.decode (response) : null;
						oldSuccess (r);
					}
				}
			}
			Logi.Net.Ajax.request (this.server + 'server/action/' + action, json_encode (data), actionCallback, options);
		},
		exec : function (clientCommand, args) {
			var cmd = this.commands[clientCommand];
			if (!cmd || typeof cmd.command != 'function') {
				Logi.log ("Invalid command " + clientCommand);
				return false;
			}
			try {
				return cmd.command.apply (Vav.Modules[cmd.module], args || []);
			} catch (e) {
				Logi.log (e);
				return false;
			}
		},
		enableHistoryListener : function (callback) {
			Site.historyListener = new Logi.History.Listener (callback);
		},
		openPopup : function (title, content, options, onOpen) {
			options = options || {};
			options.onClose = options.onClose || true;
			options.roundedBoxManager = options.roundedBoxManager || true;

			var popup = Logi.UI.PopupWindowManager.open (title, content, options, onOpen);
			if (options.contentHeight) {
				popup.contentBar.style.height = options.contentHeight + 'px';
			}
		},
		closePopup : function (onClose) {
			Logi.UI.PopupWindowManager.close (onClose);
		},
		effects : {
			
			popup : function (html, options, onEnd) {
				
				var zIndex = Logi.UI.LayerManager.requestLayer();
				
				options = options || {};
				var div = document.createElement ('DIV');
				div.style.zIndex = zIndex;
				div.className = options.className;
				div.innerHTML = html;
				document.body.appendChild (div);
				
				var baseX = document.body.clientWidth / 2;
				var baseY = document.body.clientHeight / 2;
				
				var i = new Logi.UI.Effects.Iterator ([
					new Logi.UI.Effects.Fade (div, {startOpacity:0,endOpacity:0.9}), 
					new Logi.UI.Effects.Move (div, {x:baseX-options.width/2, y:baseY-options.height/2},{x:baseX, y:baseY}),
					new Logi.UI.Effects.Resize (div, {width: options.width, height: options.height}, {width: 0, height: 0})
				]); 
				
				i.run (function() {
					if (typeof onEnd == 'function') {
						onEnd (div);
					}
				}); 
			}			
			
		}
		
	});
	
	Cms = {
		run : function (server) { Site = Cms = new SitePrototype (server); }
	};

	Logi.QuickUploader = new Class ({
		__construct : function (action, file_field, filter) {
			var baseHref = document.getElementsByTagName ('BASE')[0].href;
			var browse_button = $el (file_field + '_upload');
			
			this.filter = filter;
			var uploader = new plupload.Uploader({
				runtimes : 'gears,flash,html5,html4',
				multipart : false,
				url: baseHref + action + '/' + file_field,
				browse_button : file_field + '_upload',
				flash_swf_url : 'web/js/libraries/plupload/plupload.flash.swf',
				filters : filter 
			});
			this.button = browse_button;
			this.nameInput = $el (file_field);
			this.statusImage = $el (file_field + '_status');
			uploader.bind('QueueChanged', Delegate (this, 'onQueueChanged'));
			uploader.bind('FileUploaded', Delegate (this, 'onFileUploaded'));
			uploader.init();
			
			var itfn = function (item) {
				if (item.id.indexOf (uploader.id) == 0) {
					var bb = cn (browse_button);
					/*bb.addEventListener ('click', function() {
						var it = item.getElementsByTagName ('*')[0];
						try { it.click(); } catch (err) { Logi.DOM.Event.simulateMouseClick (it); };
					}, true);*/
					
					bb.parentNode.insertBefore (item, bb);
					//bb.insertBefore (item, bb.childNodes[0]);
				}
			};
			css_query_iterate (itfn, 'div.plupload');
			css_query_iterate (itfn, 'div.plupload_iframe');
			
			this.uploader = uploader;
		},
		onFileUploaded : function(up, file) {
			if (file.status == plupload.DONE) {
				//\$el ('dealer_location_dialog_logo_file_id').value = file.name;
				
				ajax (up.settings.url, null, Delegate (this, function (result) {
					css_query_iterate (function (item) {
						item.disabled = false;
						item.style.opacity = 1;
						item.style.filter = 'alpha(opacity=100)';
					}, '.Submit');
					
					if (result == 1) {
						this.nameInput.value = file.name;
						this.statusImage.src = 'web/img/public/icons/upload_successful.png';
					} else {
						this.statusImage.src = 'web/img/public/icons/upload_failed.png';
						alert (Logi.Language.term ('Image is too small. Please select another image!'));
					}
				}));
				
				//this.statusImage.src = 'web/img/public/icons/upload_successful.png';
			} else if (file.status == plupload.ERROR) {
				this.statusImage.src = 'web/img/public/icons/upload_failed.png';
			}
		},
		onQueueChanged : function(up, files) {
			css_query_iterate (function (item) {
				item.disabled = true;
				item.style.opacity = 0.1;
				item.style.filter = 'alpha(opacity=10)';
			}, '.Submit');
			up.start();
		}
	});
	
})();

