// ------------------------------------------------
// google script
// 
// ------------------------------------------------

function google() {
    return this;
}

google.name = function() {return 'google';}

google.convertCoords = function(coords) {
    return [coords.lat(), coords.lng()];
}

/**
 *  Обработка событий
 *  @static
 */
google.Events = function() {return this;}

google.Events.addListener = function(object, event, handler) {
    switch (event) {
         case "mouseclick":
            GEvent.addListener(object.object(), "click",
                function(overlay, latlng, overlaylatlng) {
                    if (!latlng) return;
                    handler(google.convertCoords(latlng));
                }
            );
            break;
            
        case "dragstart":
            GEvent.addListener(object.object(), "dragstart",
                function() {
                    handler();
                }
            );
            break;

        case "dragend":
            GEvent.addListener(object.object(), "dragend",
                function() {
                    handler();
                }
            );
            break;

        case "zoomchange":
            GEvent.addListener(object.object(), "zoomend", handler);
            break;

        case "moveend":
            GEvent.addListener(object.object(), "moveend",
                function() {
                    handler();
                }
            );
            break;
            
        default:
            GEvent.addListener(object.object(), event,
                function() {
                    handler();
                }
            );
            break;
    }
}

google.Events.removeListener = function(object, handler) { }


// ------------------------------------------------
// Карта
// ------------------------------------------------

/**
 *  Карта
 *  @constructor
 */
google.Map = function(element, options) {
    MapsWrapper.GeoObject.call(this, options);

    this._element = element;
    
    this._object = new GMap2(element);

    var opt = this.options();
    
    //this._object.setMapType(G_HYBRID_MAP);
    this._object.addControl(new GLargeMapControl())
    if (opt.type) this._object.addControl(new GMapTypeControl())
    if (opt.zoom && opt.zoom.scroll) this._object.enableScrollWheelZoom();
    
    return this;
}
google.Map.prototype = new MapsWrapper.GeoObject();

google.Map.prototype._element;

google.Map.prototype.openInfoWindow = function(coords, html) {
    this.object().openInfoWindowHtml(new GLatLng(coords[0], coords[1]), html);
}

google.Map.prototype.center = function(coords, zoom) {
    if (arguments.length == 0) {
        var result = this.object().getCenter();
        return [result.lat(), result.lng()];
    }
    this.object().setCenter(new GLatLng(coords[0], coords[1]), zoom);

    return this;
}

google.Map.prototype.zoom = function(index) {
    if (index != null) {
        this.object().setZoom(index);
        return this;
    }
    else return this.object().getZoom();
}

google.Map.prototype.repaint = function() { }

google.Map.prototype.add = function(object) {
    if (object instanceof google.Layer) {
        object._parent = this;
        object._load();
    }
    else this.object().addOverlay(object.object());

    return this;
}

google.Map.prototype.remove = function(object) {
    if (object instanceof google.Layer) {
        object._unload();
    }
    else this.object().removeOverlay(object.object());
    
    return this;
}

google.Map.prototype.bounds = function() {
    var bounds = this._object.getBounds();
    return new google.Bounds(bounds);
}


// ------------------------------------------------
// Границы
// ------------------------------------------------

/**
 *  Область карты
 *  @constructor
 */
google.Bounds = function(sw, ne) {
    MapsWrapper.GeoObject.call(this);
    
    if (arguments.length == 1) {
        this._object = arguments[0];
        
        this.sw = [this._object.getSouthWest().lat(), this._object.getSouthWest().lng()];
        this.ne = [this._object.getNorthEast() .lat(), this._object.getNorthEast().lng()];
    } else {
        this._object = new VBounds(sw, ne);
        
        this.sw = sw;
        this.ne = ne;
    }
    
    return this;
}
google.Bounds.prototype = new MapsWrapper.GeoObject();

google.Bounds.prototype.sw;
google.Bounds.prototype.ne;

google.Bounds.prototype.southwest = function() {return this.sw;}
google.Bounds.prototype.northeast = function() {return this.ne;}


// ------------------------------------------------
// Слой
// ------------------------------------------------

/**
 *  Слой
 *  @constructor
 */
google.Layer = function() {
    MapsWrapper.GeoObject.call(this);
    
    this._markers = [];
    this._polylines = [];

    return this;
}
google.Layer.prototype = new MapsWrapper.GeoObject();

google.Layer.prototype._parent;
google.Layer.prototype._visible;
google.Layer.prototype._markers;
google.Layer.prototype._polylines;

google.Layer.prototype.add = function(object) {
    if (this._parent != null) this._parent.add(object);

    this._markers.push(object);
    
    return this;
}

google.Layer.prototype.remove = function(object) {
    if (this._parent != null) this._parent.remove(object);

    for (var i = 0; i < this._markers.length; i++) {
        if (this._markers[i] != object) continue;

        this._markers.splice(i, 1);
        break;
    }

    return this;
}

google.Layer.prototype._load = function() {
    for (var i = 0; i < this._markers.length; i++) {
        this._parent.add(this._markers[i]);
    }
}

google.Layer.prototype._unload = function() {
    for (var i = 0; i < this._markers.length; i++) {
        this._parent.add(this._markers[i]);
    }
}


// ------------------------------------------------
// Маркер
// ------------------------------------------------

/**
 *  Маркер
 *  @constructor
 */
google.Marker = function(coords, options) {
    MapsWrapper.GeoObject.call(this, options);

    var opt = {};
    if (options && options.icon) opt.icon = options.icon.object();
    if (options && options.draggable) opt.draggable = true;
    
    this._object = new GMarker(new GLatLng(coords[0], coords[1]), opt);
    if (options && options.draggable) this._object.enableDragging();

    return this;
}
google.Marker.prototype = new MapsWrapper.GeoObject();

google.Marker.prototype._icon;
google.Marker.prototype._hint;

google.Marker.prototype.info = function(text, options) {
    if (options != null)
        this._object.bindInfoWindowHtml(text, {maxWidth: options.width});
    else
        this._object.bindInfoWindowHtml(text);
    
    return this;
}

google.Marker.prototype.hint = function(hint) {
    return this;
}

google.Marker.prototype.coords = function() {
    return google.convertCoords(this.object().getLatLng());
}


// ------------------------------------------------
// Иконка
// ------------------------------------------------

/**
 *  Картинка маркера
 *  @constructor
 */
google.Icon = function(source, width, height) {
    MapsWrapper.GeoObject.call(this);

    var icon = new GIcon();
    icon.image = source;
    icon.size = new GSize(width, height);
    icon.iconAnchor = new GPoint(width / 2, height);
    icon.infoWindowAnchor = new GPoint(width / 2, height);

    this._object = icon;

    return this;
}
google.Icon.prototype = new MapsWrapper.GeoObject();


// ------------------------------------------------
// Маршрут
// ------------------------------------------------

google.Route = function(map, coords, callback) {
    MapsWrapper.GeoObject.call(this);

    this._directions = new GDirections(map.object());
    
    var waypoints = [];
    for (var i in coords) {
        waypoints.push(new GLatLng(coords[i][0], coords[i][1]));
    }
    this._directions.loadFromWaypoints(waypoints);

    var _this = this;
    GEvent.addListener(this._directions, "load",
        function(directions) {
            var polyline = directions.getPolyline();
            _this._object = polyline;
            callback();
        }
    );

    return this;
}
google.Route.prototype = new MapsWrapper.GeoObject();

google.Route.prototype._directions;
