var googleMap = new Class(
{
    initialize: function(element, address) {
        this.map = null;
        this.address = address;
        this.point = null;
        this.widget = null;
        this.geocoder = null;
        this.active = false;
        this.element = $(element);
        this.ctrl = new Hash({map: null,
                              composite: null,
                              scale: null});
    },
    
    attach: function(elements) {
        if (this.element) {
            new Hash(elements).each(function(key, val) {
                el = $(val);
                el.active = el.effect('background-color', {duration: 250});
                el.active.set('#ffffff');
                el.hover = el.effect('background-color', {duration: 250});
                el.hover.set('#ffffff');
                el.setStyle('cursor', 'pointer');
                this.ctrl.set(key, el);
            }.bind(this));
            
            this.widget = new Element('div').setProperty('id', 'googlemap_slider')
                                            .setStyle('position', 'absolute')
                                            .setStyle('top', '8px')
                                            .setStyle('left', '95px')
                                            .setStyle('opacity', 0.4)
                                            .setStyle('z-index', '11');
            this.widget.fx = this.widget.effect('left');
            this.widget.injectAfter(this.ctrl.get('scale'));
    
            this.ctrl.get('map').addEvent('click', this.switchMap.bind(this))
                                .addEvent('mouseover', this._hover.pass(['map', true], this))
                                .addEvent('mouseout', this._hover.pass(['map', false], this));
            this.ctrl.get('composite').addEvent('click', this.switchComposite.bind(this))
                                      .addEvent('mouseover', this._hover.pass(['composite', true], this))
                                      .addEvent('mouseout', this._hover.pass(['composite', false], this));
            this.ctrl.get('scale').addEvent('click', this.switchZoom.bind(this))
                                  .addEvent('mouseover', this._activate.pass(['scale', true], this))
                                  .addEvent('mouseout', this._activate.pass(['scale', false], this));
            this._select('composite');
            this._updateMarker(3);
        }
    },
    
    switchMap: function() {
        if (this.map) {
            this.map.setMapType(G_NORMAL_MAP);
            this._select('map');
        }
    },
    
    switchComposite: function() {
        if (this.map) {
            this.map.setMapType(G_SATELLITE_MAP);
            this._select('composite');
        }
    },

    switchZoom: function(evt) {
        evt = new Event(evt);
        x = evt.client.x - $('layout').getLeft();        
        if (x >= 692 && x <= 760) {
            ratio = 69/6;
            scale = evt.client.x - this.ctrl.get('scale').getCoordinates().left - 10;            
            scale = Math.floor(scale / ratio);
            this.zoom(scale);
        }
    },
    
    show: function() {
        if (this._initGoogleMap()) {
            this.active = true;
        }
    },
    
    hide: function() {
        if (this.active) {
            this.element.setStyle('display', 'none');
            this.active = false;
        }
    },
    
    zoom: function(scale) {
        if (this.map) {
            this.map.setCenter(this.point, scale + 14);
            this._updateMarker(scale);
        }
    },
    
    _hover: function(el, flag) {
        this.ctrl.get(el).hover.stop();
        this.ctrl.get(el).hover.start((flag) ? '#e5e5e5' : ((this.ctrl.get(el).flag) ? '#cbd7e6' : '#ffffff'));
    },
    
    _activate: function(el, flag) {
        this.ctrl.get(el).active.stop();
        this.ctrl.get(el).active.start((flag) ? '#cbd7e6' : '#ffffff');
    },
    
    _select: function(el) {
        this.ctrl.each(function(key, ctrl) {
            ctrl.active.start((el == key) ? '#cbd7e6' : '#ffffff');
            ctrl.flag = (el == key);
        });
    },
    
    _updateMarker: function(scale) {    
        offset = Math.ceil(scale * 12);
        this.widget.fx.start(offset + 102);
    },
    
    _initGoogleMap: function() {
        if (!this.element) {
            return false;
        }
        
        this.element.setStyle('display', 'block');

        if (!this.map) {
            if (GBrowserIsCompatible()) {
                this.map = new GMap2(this.element);
                this.geocoder = new GClientGeocoder();
                if (this.geocoder) {
                    this.geocoder.getLatLng(
                        this.address,
                        function(point) {
                            if (!point) {
                                alert('Cannot find location ' + this.address);
                            } else {
                                var marker = new GMarker(point);
                                this.map.setCenter(point, 17);
                                this.map.addControl(new GSmallZoomControl());
                                this.map.addOverlay(marker);
                                this.map.setMapType(G_SATELLITE_MAP);
                                this.point = point;
                            }
                        }.bind(this));
                }
                this._updateMarker(3);
            }
            window.addEvent('unload', GUnload);
        }

        return true;
    }
});
