﻿var DealersMap = function(container) {
    this._events = new EventsManager();
    this._mapObject = null;
    this._mapContainer = container;
    this._dealers = [];
    this._autoID = 0;

    this._events.registerEvent('click');
    this._events.registerEvent('dealerSelected');
    this._events.registerEvent('dealerAdded');
    this._events.registerEvent('dealerRemoved');
    this._events.registerEvent('dealersCleared');
}

DealersMap.prototype.get_mapObject = function() {
    return this._mapObject;
}

DealersMap.prototype.addDealer = function(dealer, icon) {
    var ret = -1;
    var marker = null;
    
    if (dealer) {
        marker = new GMarker(new GLatLng(dealer.place.x, dealer.place.y), { icon: this._getDealerIcon(icon) });

        if (dealer.id < 0) {
            ret = this._autoID;
            dealer.id = ret;
        } else {
            ret = dealer.id;
        }

        marker.value = dealer.id;

        this._mapObject.addOverlay(marker);
        dealer._marker = marker;

        this._dealers[this._dealers.length] = dealer;
        this._autoID += 1;

        this.notify('dealerAdded', { dealer: dealer });
    }

    return ret;
}

DealersMap.prototype.removeDealer = function(dealer, dontNotify) {
    var foundDealer = null;
    var newList = [];

    if (this._dealers) {
        for (var i = 0; i < this._dealers.length; i++) {
            if (this._dealers[i].id == dealer.id) {
                foundDealer = this._dealers[i];

                if (foundDealer._marker) {
                    this._mapObject.removeOverlay(foundDealer._marker);
                }

                if (!dontNotify) {
                    this.notify('dealerRemoved', { dealer: foundDealer });
                }
            } else {
                newList[newList.length] = this._dealers[i];
            }
        }

        this._dealers = newList;
    }
}

DealersMap.prototype.setMapType = function(mapType) {
    var mt = G_NORMAL_MAP;

    if (mapType) {
        mapType = mapType.toString().toLowerCase();
        if (mapType == 'satellite') {
            mt = G_SATELLITE_MAP;
        } else if (mapType == 'hybrid') {
            mt = G_HYBRID_MAP;
        } else if (mapType == 'terrain' || mapType == 'physical') {
            mt = G_PHYSICAL_MAP;
        }
    }

    this._mapObject.setMapType(mt);
}

DealersMap.prototype.clearDealers = function() {
    if (this._dealers) {
        while (this._dealers.length > 0) {
            this.removeDealer(this._dealers[0], true);
        }

        this.notify('dealersCleared', {});
    }

    this._mapObject.closeInfoWindow();
}

DealersMap.prototype.showDealerInfo = function(dealer, info) {
    var showPos = null;
    var centerPos = null;
    var htmlInfo = null;
    var zoomLevel = this._mapObject.getZoom();

    if (dealer) {
        showPos = new GLatLng(dealer.place.x, dealer.place.y);
        centerPos = new GLatLng(dealer.place.x, dealer.place.y);

        if (!info) {
            htmlInfo = this.getDealerInfoHtml(dealer);
        } else {
            htmlInfo = info;
        }

        this._mapObject.setCenter(centerPos, zoomLevel);
        this._mapObject.openInfoWindowHtml(showPos, htmlInfo);
    }
}

DealersMap.prototype.add_click = function(callback) {
    this._events.addHandler('click', callback);
}

DealersMap.prototype.add_dealerSelected = function(callback) {
    this._events.addHandler('dealerSelected', callback);
}

DealersMap.prototype.add_dealerAdded = function(callback) {
    this._events.addHandler('dealerAdded', callback);
}

DealersMap.prototype.add_dealerRemoved = function(callback) {
    this._events.addHandler('dealerRemoved', callback);
}

DealersMap.prototype.add_dealersCleared = function(callback) {
    this._events.addHandler('dealersCleared', callback);
}

DealersMap.prototype.notify = function(eventName, args) {
    this._events.notify(eventName, this, args);
}

DealersMap.prototype.draw = function() {
    var obj = this;

    if (GBrowserIsCompatible()) {
        this._mapObject = new GMap2(this._mapContainer);
        this._mapObject.setCenter(new GLatLng(20, 20), 1);
        this._mapObject.setUIToDefault();

        GEvent.bind(this._mapObject, 'click', this, function(overlay, latlng) {
            var args = {};
            var dealer = null;

            if (overlay instanceof GMarker) {
                dealer = obj.findDealer(overlay.value);
                args.dealer = dealer;

                obj.notify('dealerSelected', args);
            } else if (latlng) {
                args.place = {};

                args.place.x = latlng.lat();
                args.place.y = latlng.lng();
                args.place.zoom = obj._mapObject.getZoom();

                obj.notify('click', args);
            }
        });
    }
}

DealersMap.prototype.findDealer = function(id) {
    var ret = null;

    if (this._dealers) {
        for (var i = 0; i < this._dealers.length; i++) {
            if (this._dealers[i].id == id) {
                ret = this._dealers[i];
                break;
            }
        }
    }

    return ret;
}

DealersMap.prototype.getDealerInfoHtml = function(dealer) {
    var ret = '';
    
    if(dealer) {
        ret = dealer.address;
    }
    
    return ret;
}

DealersMap.prototype.getLocationsByAddress = function(address, onComplete) {
    var geocoder = null;
    var locations = [];
    var location = null;

    geocoder = new GClientGeocoder();
    geocoder.getLocations(address, function(response) {
        if (!response || response.Status.code != 200) {
            if (typeof (onComplete) != 'undefined') {
                onComplete([]);
            }
        } else {
            for (var i = 0; i < response.Placemark.length; i++) {
                location = response.Placemark[i];
                locations[locations.length] = {
                    address: location.address,
                    x: location.Point.coordinates[1],
                    y: location.Point.coordinates[0],
                    zoom: 14
                }
            }

            if (typeof (onComplete) != 'undefined') {
                onComplete(locations);
            }
        }
    });
}

DealersMap.prototype.getLocationByAddress = function(address, onComplete) {
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(address, onComplete);
}

DealersMap.prototype.setFocus = function(dealer) {
    if (dealer) {
        if (this._mapObject.getZoom() != dealer.place.zoom) {
            this._mapObject.setZoom(dealer.place.zoom);
        }

        this._mapObject.panTo(new GLatLng(dealer.place.x, dealer.place.y));
    }
}

DealersMap.prototype.setZoom = function(level) {
    this._mapObject.setZoom(level);
}

DealersMap.prototype._getDealerIcon = function(customIcon) {
    var ret = new GIcon();
    var image = '/CustomModules/GoogleDealerSearch/Resources/images/dealer_default.png';
    var shadowImage = '/CustomModules/GoogleDealerSearch/Resources/images/dealer_default_shadow.png';

    if (customIcon) {
        if (customIcon.image && customIcon.image.length > 0) {
            image = customIcon.image;

            if (customIcon.shadowImage && customIcon.shadowImage.length > 0) {
                shadowImage = customIcon.shadowImage;
            } else {
                shadowImage = '';
            }
        }
    }

    ret.image = image;
    ret.iconAnchor = new GPoint(32, 32);
    ret.infoWindowAnchor = new GPoint(32, 0);
    ret.iconSize = new GSize(32, 32);

    if (shadowImage.length > 0) {
        ret.shadow = shadowImage;
        ret.shadowSize = new GSize(59, 32);
    }

    return ret;
}

DealersMap.prototype.getMarkers = function() {
    var res = [];
    if (this._dealers) {
        for (var i = 0; i < this._dealers.length; i++) {
            var dealer = this._dealers[i];
            if (!dealer._marker.isHidden())
                res[res.length] = dealer._marker ? dealer._marker : new GMarker(new GLatLng(dealer.place.x, dealer.place.y));
        }
    }
    return res;
}

DealersMap.prototype.doScale = function() {
    var markers = this.getMarkers();
    if (markers && markers.length > 0) {
        var bounds = new GLatLngBounds();
        for (var i = 0; i < markers.length; i++) {
            bounds.extend(markers[i].getPoint());
        }
        this._mapObject.setCenter(bounds.getCenter());
        this._mapObject.setZoom(this._mapObject.getBoundsZoomLevel(bounds));
    }
}

DealersMap.getDistance = function(place1, place2) {
    var pos1 = new GLatLng(place1.x, place1.y);
    var pos2 = new GLatLng(place2.x, place2.y);
    return pos1.distanceFrom(pos2)/1000;
}
