/**
 * @author Shea Frederick
 */
Ext.namespace('Ext.ux');
 
/**
 * @class GMapPanel
 * @extends Ext.Panel
 */
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
    initComponent: function(){
        var defConfig = {
            plain: true,
            zoomLevel: 3,
            yaw: 180,
            pitch: 0,
            zoom: 0,
            gmapType: 'map',
            border: false
        }
        
        Ext.applyIf(this,defConfig);
        Ext.ux.GMapPanel.superclass.initComponent.call(this);        
    },

    afterRender: function(){

        var wh = this.ownerCt.getSize();
        Ext.applyIf(this, wh);
        
        Ext.ux.GMapPanel.superclass.afterRender.call(this);    
        
        if (this.gmapType === 'map') {
	        var config = this.mapTypes ? {mapTypes: this.mapTypes} : {};					
          this.gmap = new GMap2(this.body.dom, config);
					this.gmap.addMapType(G_PHYSICAL_MAP);
        }
        
        if (this.gmapType === 'panorama'){
            this.gmap = new GStreetviewPanorama(this.body.dom);
        }
        
        if (this.controls && this.gmapType === 'map') {
	        if (Ext.isArray(this.controls)) {
	            Ext.each(this.controls, function(control) {
		            this.gmap.addControl(control);
	            }, this);
            } else if (typeof this.controls === 'object') {
	            this.gmap.addControl(this.control);
            }

            delete this.controls;
        }

        if (this.featureConfig) {
	        if (typeof this.featureConfig === 'string') {
		        this.featureConfig = [this.featureConfig];
	        }
	
            Ext.each(this.featureConfig, function(feature) {
	            eval('this.gmap.' + feature + '();');
            }, this);

            delete this.featureConfig;
        }
        
        if (typeof this.setCenter === 'object') {
            if (typeof this.setCenter.geoCodeAddr === 'string'){
                this.geoCodeLookup(this.setCenter.geoCodeAddr);
            } else {
                if (this.gmapType === 'map') {
                    var point = new GLatLng(this.setCenter.lat, this.setCenter.lng);
                    this.gmap.setCenter(point, this.zoomLevel);    
                }
                if (typeof this.setCenter.marker === 'object' && typeof point === 'object') {
                    this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear);
                }
            }
            if (this.gmapType === 'panorama') {
                this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter.lng), {
	                yaw: this.yaw, 
	                pitch: this.pitch, 
	                zoom: this.zoom
	            });
            }
        }

				/* first set of options is for the visual overlay.*/
        var boxStyleOpts = {
						opacity: .2
					,	border: "1px solid #15428B"
        }

        /* second set of options is for everything else */
        var otherOpts = {
    	    	buttonHTML: "<img src='images/zoombutton.gif' />"
  	      ,	buttonZoomingHTML: "<img src='images/zoombutton.gif' />"
	        ,	buttonStartingStyle: {width: '48px', height: '27px', marginLeft: '50px', marginTop: '-70px'}
					,	overlayRemoveTime: 300
        };

        /* third set of options specifies callbacks */
/*				
        var callbacks = {
          buttonclick: function(){GLog.write("Looks like you activated DragZoom!")},
          dragstart: function(){GLog.write("Started to Drag . . .")},
          dragging: function(x1,y1,x2,y2){GLog.write("Dragging, currently x="+x2+",y="+y2)},
          dragend: function(nw,ne,se,sw,nwpx,nepx,sepx,swpx){GLog.write("Zoom! NE="+ne+";SW="+sw)}
        };
  
        this.gmap.addControl(new DragZoomControl(boxStyleOpts, otherOpts, callbacks));
*/				
        this.gmap.addControl(new DragZoomControl(boxStyleOpts, otherOpts));

        var dt = new Ext.util.DelayedTask();
        dt.delay(300, function(){
            this.addMarkers(this.markers);
        }, this);

        this.on('resize', this.gmap.checkResize, this.gmap);
				
				this.changeView(G_PHYSICAL_MAP);
				
    },

    onResize: function(w, h){
        if (typeof this.gmap == 'object') {
            this.gmap.checkResize();
        }
        
        Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);
    },

    setSize: function(width, height, animate){
        if (typeof this.gmap == 'object') {
            this.gmap.checkResize();
        }
        
        Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);
    },

    getMap: function(){
        return this.gmap;
    },

    addMarkers: function(markers) {
        if (Ext.isArray(markers)){
            for (var i = 0; i < markers.length; i++) {
                var mkr_point = new GLatLng(markers[i].lat,markers[i].lng);
                this.addMarker(mkr_point,markers[i].marker,false,markers[i].setCenter);
            }
        }        
    },

    addMarker: function(point, marker, clear, center){
        Ext.applyIf(marker,G_DEFAULT_ICON);

        if (clear === true){
            this.gmap.clearOverlays();
        }

        if (center === true) {
            this.gmap.setCenter(point, this.zoomLevel);
        }
        
        var mark = new GMarker(point,marker);
        this.gmap.addOverlay(mark);
    },

    geoCodeLookup: function(addr) {
        this.geocoder = new GClientGeocoder();
        this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));
    },

    addAddressToMap: function(response) {
        if (!response || response.Status.code != 200) {
            Ext.MessageBox.alert('Error', 'Code '+response.Status.code+' Error Returned');
          } else {
            place = response.Placemark[0];
            addressinfo = place.AddressDetails;
            accuracy = addressinfo.Accuracy;
            if (accuracy === 0) {
                Ext.MessageBox.alert('Unable to Locate Address', 'Unable to Locate the Address you provided');
            }else{							
                if (accuracy < 7) {
                    Ext.MessageBox.alert('Address Accuracy', 'The address provided has a low accuracy.<br><br>Level '+accuracy+' Accuracy (8 = Exact Match, 1 = Vague Match)');
                }else{
                    point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                    if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
                        this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true);
                    }
                }
            }
          }
    },

    changeView: function(view) {
	    this.gmap.setMapType(view);
    },
		
		toggleGroup: function(type) {			
      for (var i = 0; i < this.markerGroups[type].length; i++) {
        var marker = this.markerGroups[type][i];
        if (marker.isHidden()) {
          marker.show();
        } else {
          marker.hide();
        }
      } 
    }

});

Ext.reg('gmappanel',Ext.ux.GMapPanel); 
