//vim: et:ts=4:sw=4:sts=4:ft=js
Ox.MapPlace = function(options) {

    options = Ox.extend({
        east: 0,
        editing: false,
        geoname: '',
        map: null,
        name: '',
        north: 0,
        selected: false,
        south: 0,
        type: [],
        visible: false,
        west: 0            
    }, options);

    var that = this;

    Ox.forEach(options, function(val, key) {
        that[key] = val;
    });

    update();

    function update() {
        that.points = {
            ne: new google.maps.LatLng(that.north, that.east),
            sw: new google.maps.LatLng(that.south, that.west)
        };
        that.bounds = new google.maps.LatLngBounds(that.points.sw, that.points.ne);
        that.center = that.bounds.getCenter();
        that.lat = that.center.lat();
        that.lng = that.center.lng();
	    Ox.extend(that.points, {
            e: new google.maps.LatLng(that.lat, that.east),
            s: new google.maps.LatLng(that.south, that.lng),
            se: new google.maps.LatLng(that.south, that.east),
            n: new google.maps.LatLng(that.north, that.lng),
            nw: new google.maps.LatLng(that.north, that.west),
            w: new google.maps.LatLng(that.lat, that.west),
        });
        // fixme: use bounds.toSpan()
        that.sizeNorthSouth = (that.north - that.south) *
            Ox.EARTH_CIRCUMFERENCE / 360;
        that.sizeEastWest = (that.east + (that.west > that.east ? 360 : 0) - that.west) *
            Ox.getMetersPerDegree(that.lat);
        that.size = Ox.getArea(
            {lat: that.south, lng: that.west},
            {lat: that.north, lng: that.east}
        );
        if (!that.marker) {
            that.marker = new Ox.MapMarker({
                map: that.map,
                place: that
            });
            that.rectangle = new Ox.MapRectangle({
                map: that.map,
                place: that
            });
        }
        //Ox.print('PLACE', that)
    }

    function editable() {
        return that.map.options('editable') && that.editable;
    }

    that.add = function() {
        //Ox.print('MapPlace add', that)
        that.visible = true;
        that.marker.add();
        return that;
    };

    that.cancel = function() {
        if (editable()) {
            that.undo();
            that.editing = false;
            that.marker.update();
            that.rectangle.deselect();
        }
        return that;
    };

    that.crossesDateline = function() {
        return that.west > that.east;
    }

    that.deselect = function() {
        that.editing && that.submit();
        that.selected = false;
        that.marker.update();
        that.rectangle.remove();
        return that;
    };

    that.edit = function() {
        if (editable()) {
            that.editing = true;
            that.original = {
                south: that.south,
                west: that.west,
                north: that.north,
                east: that.east
            };
            that.marker.edit();
            that.rectangle.select();
        }
        return that;
    }

    that.remove = function() {
        that.editing && that.submit();
        that.selected && that.deselect();
        that.visible = false;
        that.marker.remove();
        return that;
    };

    that.select = function() {
        that.selected = true;
        !that.visible && that.add();
        that.marker.update();
        that.rectangle.add();
        return that;
    };

    that.submit = function() {
        if (editable()) {
            that.editing = false;
            that.marker.update();
            that.rectangle.deselect();
        }
        return that;
    };

    that.update = function() {
        update();
        return that;
    };

    that.undo = function() {
        if (editable()) {
            Ox.forEach(that.original, function(v, k) {
                that[k] = v;
            });
            that.update();
            that.marker.update();
            that.rectangle.update();
        }
        return that;
    };

    return that;

};