var AdminMapInterface, FrontMapInterface, MapDriver;
// ------------------------------------------------------------------------------------MAP DRIVER
MapDriver = new Class({
        Implements: [Events, Options]
        //Map Driver Options------------------------Map Driver Options
        , options: {
            mapContainerId: 'map_canvas'
            , bindedControl: null
            //Map Center Options
            , mapCenter: {
                lat: 37.4419
                , lng: -122.1419
                , zoom: 5
            }
            , useGeocoderInitAddress: false
            , mapOptions: {}
            , mapUIOptions: {
                defaultUI: true
                , showGoogleBar: false
                , enableDragging: false
            }
            , useGoogleBarCallbacks: false
            , callbacks: {
                onMapLoaded: null
                , googleBar: {
                    generateMarkerHtml: null
                    , markersSetCallback: null
                }
            }
        }
        //Map Driver Elements-----------------------Map Driver Elements
        , map: null
        , bounds: {
            max_lat: null
            , min_lat: null
            , max_lng: null
            , min_lng: null
        }
        //Map Driver Constructor-------------------Map Driver Constructor
        , initialize: function(options) {
            this.setOptions(options);
            //Init Configuration----------------------InitConfiguration
                //Map Options--------------------------Map Options
                var options = this.options;
                if (this.options.useGoogleBarCallbacks) {
                    this.options.mapOptions.googleBarOptions = {
                        onGenerateMarkerHtmlCallback: options.callbacks.googleBar.generateMarkerHtml
                        , onMarkersSetCallback: options.callbacks.googleBar.markersSetCallback
                    }
                }
               
                if (this.options.useGeocoderInitAddress) {
                    var geo = new GClientGeocoder();
                    geo.getLatLng(this.options.useGeocoderInitAddress, this.onMapCenter.bind(this));
                } else {
                    this.loadMap();
                }
        }
        //Map Callbacks----------------------------Map Callbacks
        , onMapCenter: function(latlng) {
            this.options.mapCenter.lat = latlng.lat();
            this.options.mapCenter.lng = latlng.lng();
            this.loadMap();
        }
        , loadMap: function() {
			if (!$(this.options.mapContainerId)) {return;}
			
            this.map = new GMap2($(this.options.mapContainerId), this.options.mapOptions);
            this.map.setCenter(new GLatLng(this.options.mapCenter.lat, this.options.mapCenter.lng), this.options.mapCenter.zoom);
            if (this.options.mapUIOptions.defaultUI) { this.map.setUIToDefault(); }
            if (this.options.mapUIOptions.showGoogleBar) { this.map.enableGoogleBar(); }
            if (this.options.mapUIOptions.ennableDragging) { this.map.enableDragging(); }
           
            this.loadMapEvents();
           
            if (this.options.callbacks.onMapLoaded) {
                this.options.callbacks.onMapLoaded(this);
            }
        }
        , loadMapEvents: function() {
            if (this.options.callbacks.infoWindowOpened) {
                GEvent.bind(this.map, 'infowindowopen', this, this.options.callbacks.infoWindowOpened);
            }
           
        }
    });

//--------------------------------------------------------------------------------------FRONT MAP
FrontMapInterface = new Class({
        Implements: [Events, Options]
        , options: {
            //Map Markers Options-------------------Map Markers Options
            markerIconURL: 'http://woxter.com/img/woxter-icon.png'
            , mapMarkersOptions: {
                draggable: false
                , icon: null
            }
        }
        , mapDriver: null
        , initialize: function (options) {
            this.setOptions(options);
			var woxter_icon = new GIcon(G_DEFAULT_ICON);
			woxter_icon.image = 'http://woxter.com/img/woxter-icon.png';
			woxter_icon.iconSize = new GSize(32, 32);
			woxter_icon.iconAnchor = new GPoint(16, 16);
			woxter_icon.infoWindowAnchor = new GPoint(20, 20);
			this.options.mapMarkersOptions.icon = woxter_icon;
        }
        , init: function (mapDriver) {
            this.mapDriver = mapDriver;

            $$("input[type=hidden]").each(function (address) {
                var point = eval("(" + address.get("value") + ")");
                if (point.lat && point.lng) {
                    this.plotPoint(point, point.sourceLinkId);
                }
            }, this);
               
            this.centerMapPoints();
        }
        , plotPoint: function (point, sourceLinkId) {
            var marker_options = this.options.mapMarkersOptions;

            var marker = new GMarker(new GLatLng(point.lat, point.lng), this.options.mapMarkersOptions);

            GEvent.bind(marker, 'click', this, this.showLocationInfo.bind(marker).pass(point));
            $(sourceLinkId).addEvent('click', this.showLocationInfo.bind(marker).pass(point));
			this.mapDriver.map.addOverlay(marker);

            if (this.mapDriver.bounds.max_lat && this.mapDriver.bounds.min_lat) {
                this.mapDriver.bounds.max_lat = parseInt(Math.max(this.mapDriver.bounds.max_lat, point.lat));
                this.mapDriver.bounds.min_lat = parseInt(Math.min(this.mapDriver.bounds.min_lat, point.lat));
            } else {
                this.mapDriver.bounds.max_lat = parseInt(point.lat);
                this.mapDriver.bounds.min_lat = parseInt(point.lat);
            }

            if (this.mapDriver.bounds.max_lng && this.mapDriver.bounds.min_lng) {
                this.mapDriver.bounds.max_lng = parseInt(Math.max(this.mapDriver.bounds.max_lng, point.lng));
                this.mapDriver.bounds.min_lng = parseInt(Math.min(this.mapDriver.bounds.min_lng, point.lng));
            } else {
                this.mapDriver.bounds.max_lng = parseInt(point.lng);
                this.mapDriver.bounds.min_lng = parseInt(point.lng);
            }
        }
        , centerMapPoints: function () {
            if (!this.mapDriver.bounds || !this.mapDriver.bounds.max_lat) {
                return;
            }
           
            if (this.mapDriver.bounds.max_lat == this.mapDriver.bounds.min_lat) {
                this.mapDriver.map.setCenter(new GLatLng(this.mapDriver.bounds.max_lat, this.mapDriver.bounds.max_lng));
                return;
            }
       
            var map_bounds = this.mapDriver.map.getBounds();
       
            var sw = map_bounds.getSouthWest();
            var ne = map_bounds.getNorthEast();
       
            var y_center = this.mapDriver.bounds.min_lat + Math.abs((this.mapDriver.bounds.max_lat - this.mapDriver.bounds.min_lat)/2);
            var x_center = this.mapDriver.bounds.min_lng + Math.abs((this.mapDriver.bounds.max_lng - this.mapDriver.bounds.min_lng)/2);
            this.mapDriver.map.setCenter(new GLatLng(y_center, x_center));

            while (this.mapDriver.bounds.max_lat > ne.lat()) {
                this.mapDriver.map.zoomOut();
               
                ne = this.mapDriver.map.getBounds().getNorthEast();
            }
       
            // while (this.mapDriver.bounds.min_lng > sw.lng()) {
            //     this.mapDriver.map.zoomOut();
            //    
            //     sw = this.mapDriver.map.getBounds().getSouthWest();
            // }
        }
        , showLocationInfo: function (point) {
           	var node = new Element("div");
			var img = new Element("img", {
					"src": point.img
				});
			var title = new Element("h3", {
					"html": point.title
					, "styles": {
						margin: 0
						, padding: 0
					}
				});
			var node_text = new Element("p", {
					"html": point.loc
				});
			img.inject(node);
			title.inject(node);
			node_text.inject(node);
			this.openInfoWindowHtml(node);
        }
    });

// ----------------------------------------------------------------------------------------ADMIN MAP
AdminMapInterface = new Class({
        Implements: [Events, Options]
        , options: {
            findLocationLinkId: 'findLocation'
            , newLocationPanelId: 'newLocation'
			, showLatLngLabels: false
			, popupOnDragend: false
            //Map Markers Options-------------------Map Markers Options
            , markerIconURL: 'http://woxter.com/img/woxter-icon.png'
            , mapMarkersOptions: {
                draggable: true
                , icon: null
            }
            //Form Inputs Options------------------------Form Inputs Options
            , inputsOptions: {
                addressInputId: null
                , latInputId: null
                , lngInputId: null
            }
        }
        , mapDriver: null
        , new_loc_address: null
        , new_loc_lat: null
        , new_loc_lng: null
        , save_link: null
		, searchWithGoogle: true
        , initialize: function(options) {
            this.setOptions(options);
            this.save_link = new Element('a', {
                    'href': '#'
                    , 'id': 'save_loc'
                    , 'html': 'Save Location'
                    , 'styles': {
                        color: '#0066CC'
                        , display: 'block'
                        , textAlign: 'right'
                        , fontSize: '12px'
                        , marginTop: '20px'
                    }
                });

			// this.options.mapMarkersOptions.icon = this.buildMarker();
			
            this.prepare();
            this.observe();
        }
		, buildMarker: function () {
			var woxter_icon = new GIcon(G_DEFAULT_ICON);
			woxter_icon.image = 'http://woxter.com/img/woxter-icon.png';
			woxter_icon.iconSize = new GSize(32, 32);
			woxter_icon.iconAnchor = new GPoint(16, 16);
			woxter_icon.infoWindowAnchor = new GPoint(20, 20);

			return woxter_icon;
		}
        , observe: function () {
            $(this.options.findLocationLinkId).addEvent('click', this.showMap.bind(this));
            this.save_link.addEvent('click', this.saveNewLocation.bind(this));
        }
        , prepare: function () {
            var panel = $(this.options.newLocationPanelId);
            panel.set('opacity', 0);
           
            var close = new Element('a', {
                href: '#closeMap'
                , text: 'Close'
                , id: 'closeMap'
            });
            var manually = new Element('a', {
                href: '#manualLocation'
                , text: 'Set Location Manually'
                , id: 'locationManually'
            });
            var google = new Element('a', {
                href: '#googleLocation'
                , text: 'Search With Google'
                , id: 'locationGoogle'
            });
           
            close.inject(panel, 'top');
            manually.inject(panel, 'top');
            google.inject(panel, 'top');
           
            close.addEvent('click', this.hideMap.bind(this).pass('no-save-loc'));
            manually.addEvent('click', this.manualLocation.bind(this));
            google.addEvent('click', this.googleLocation.bind(this));
        }
        , showMap: function (event) {
            event.preventDefault();
            $(this.options.newLocationPanelId).tween('opacity', 1);
        }
        , hideMap: function (whithout_save_location) {
			if (whithout_save_location) {
				$(this.options.inputsOptions.latInputId).set('value', '');
	            $(this.options.inputsOptions.lngInputId).set('value', '');				
			}
			
            $(this.options.newLocationPanelId).tween('opacity', 0);
        }
        , manualLocation: function (event) {
            event.preventDefault();

			this.searchWithGoogle = false;

            this.mapDriver.map.disableGoogleBar();
            this.mapDriver.map.clearOverlays();
           
            var marker = new GMarker(this.mapDriver.map.getCenter(), this.options.mapMarkersOptions);
           
            //this.new_loc_lat = this.mapDriver.map.getCenter().lat();
            //this.new_loc_lng = this.mapDriver.map.getCenter().lng();
           
            GEvent.bind(marker, 'click', this, this.popupLocation.bind(this).pass(marker));
			GEvent.bind(marker, 'dragend', this, this.onMarkerDragend);
			if (this.options.popupOnDragend) {
				GEvent.bind(marker, 'dragend', this, this.popupLocation.bind(this).pass(marker));
			}

            this.mapDriver.map.addOverlay(marker);
        }
        , popupLocation: function (marker) {
            var node = new Element("div");
            var node_text = new Element("p", {
                    'html': 'Save Current Location?'
                });

            node_text.inject(node);
            this.save_link.inject(node);
           
            marker.openInfoWindowHtml(node);
        }
        , onMarkerDragend: function (latlng) {
            this.new_loc_lat = latlng.lat();
            this.new_loc_lng = latlng.lng();		
        }
        , googleLocation: function (event) {
			this.searchWithGoogle = true;
			
            this.mapDriver.map.enableGoogleBar();
            this.mapDriver.map.clearOverlays();
        }
        , onMarkersSetCallback: function (results) {
            results.each(function (result) {
//                result.marker.setImage('http://woxtermedia.com/img/woxter-icon.png');
            }, this);
        }
        , onGenerateMarkerHtml: function (marker, html, search) {
            html = new Element('div');

            var styles = {
                fontSize: "12px"
            }

            var title = new Element('strong', {
                    'html': search.region
                });

            var address = new Element('p', {
                    'html': search.streetAddress
                    , 'styles': styles
                });

            var city = new Element('p', {
                    'html': search.city
                    , 'styles': styles
                });

            var country = new Element('p', {
                    'html': search.country
                    , 'styles': styles
                });

            title.inject(html);
            address.inject(html);
            city.inject(html);
            country.inject(html);

            this.new_loc_address = search.streetAddress;
            this.new_loc_lat = search.lat;
            this.new_loc_lng = search.lng;
           
            this.save_link.inject(html);
           
            this.buildMarker(marker);
           
            return html;
        }
        , saveNewLocation: function (event) {
            event.preventDefault();
            var inputAddress = $(this.options.inputsOptions.addressInputId);
            var inputLat = $(this.options.inputsOptions.latInputId);
            var inputLng = $(this.options.inputsOptions.lngInputId);
			
			if (!inputAddress.get('value') || this.searchWithGoogle) {
				inputAddress.set('value', this.new_loc_address);
			}
			
            inputLat.set('value', this.new_loc_lat);
            inputLng.set('value', this.new_loc_lng);
            
			 if(this.options.showLatLngLabels){
				$(this.options.showLatLngLabels).empty();
				var labels, latLabel, lngLabel;
				labels = new Element('ul');
				latLabel = new Element('li', {
					text: 'Latitude: ' + this.new_loc_lat
				});
				lngLabel = new Element('li', {
					text: 'Longitude: ' + this.new_loc_lng
				});
				latLabel.inject(labels);
				lngLabel.inject(labels);
				labels.inject($(this.options.showLatLngLabels));
			}
			
            //Hide Map
            this.hideMap();
        }
    });
