﻿function GoogleMaps(options) {
    var _this = this;

    this.map = null;
    this.container = null;
    this.zoom = 7;
    this.center = null;



    this.markers = [];
    this.houses = [];

    this.ew = null;
    this.ewm = null;

    this.addControl = function(c) {
        if (GBrowserIsCompatible()) {
            _this.map.addControl(c);
        }
    }


    if (GBrowserIsCompatible()) {
        if (typeof options.container != "undefined") {

            $(window).unload(function() {
                GUnload();
            });

            this.container = options.container;
            this.zoom = (typeof options.zoom != "undefined" ? options.zoom : this.zoom);
            this.center = (typeof options.center != "undefined" ? new GLatLng(options.center.lat, options.center.lng, true) : new GLatLng(56.0, 10.5, true));

            this.map = new GMap2(this.container);
            this.map.setCenter(this.center, this.zoom);
            this.map.setUIToDefault();

            _this.ew = new EWindow(_this.map, E_STYLE_HOUSE);
            _this.map.addOverlay(_this.ew);

            _this.ewm = new EWindow(_this.map, E_STYLE_MULTIPLE_HOUSES);
            _this.map.addOverlay(_this.ewm);
        }
    }

    this.foo = false;

    //Adds multiple houses to the map
    this.addHouses = function(items) {
        if (_this.ew != null) {
            _this.map.removeOverlay(_this.ew);
        }
        if (_this.ewm != null) {
            _this.map.removeOverlay(_this.ewm);
        }


        $.each(items, function(i, n) {
            _this.addHouse(n);
        });
        _this.refreshHouses(items);
    }


    //Adds a house marker to the map:
    this.addHouse = function(obj) {
        if (obj != null) {
            if (typeof obj.geo != "undefined") {
                obj.active = true;

                //Check if house exists in list:
                var b = false;
                $.each(_this.houses, function(i, n) {
                    if (n.id == obj.id) {
                        b = true;
                        n = obj;
                        return false;
                    }
                });

                //House not already in list:
                if (!b) {
                    //Add house to list
                    _this.houses[_this.houses.length] = obj;

                    //Fetch marker with this coordinate:
                    var objMarker = _this.getMarker(obj.geo.lat, obj.geo.lng);

                    //Position free: create new marker
                    if (objMarker == null) {
                        objMarker = new GoogleMapsMarker({
                            lat: obj.geo.lat,
                            lng: obj.geo.lng,
                            icon: ICON_HOUSE,
                            active: obj.active
                        });


                        _this.markers[_this.markers.length] = objMarker;
                        _this.map.addOverlay(objMarker.marker);

                        GEvent.addListener(objMarker.marker, "click", function() {
                            _this.clickMarker(objMarker);
                        });
                    }
                }
            }
        }
    }

    this.addSimpleHouse = function(obj) {
        var objMarker = new GoogleMapsMarker({
            lat: obj.lat,
            lng: obj.lng,
            icon: ICON_HOUSE,
            active: true,
            clickable: false
        });

        _this.map.addOverlay(objMarker.marker);
    }


    //Returns the marker position at coordinate lat, lng:
    this.getMarker = function(lat, lng) {
        var obj = null;
        $.each(_this.markers, function(i, n) {
            if (n.lat == lat && n.lng == lng) {
                obj = n;
                return false;
            }
        });
        return obj;
    }


    //Refreshes list of active houses
    this.refreshHouses = function(arr) {
        $.each(_this.houses, function(i, n) {
            var b = false;
            $.each(arr, function(j, m) {
                if (m.id == n.id) {
                    b = true;
                    return false;
                }
            });

            n.active = b;
        });

        _this.refreshMarkers();
    }


    //Returns all active houses (i.e. matching current search):
    this.getActiveHouses = function(lat, lng) {
        return $.grep(_this.houses, function(n, i) {
            return n.active && (n.geo.lat == lat) && (n.geo.lng == lng);
        });
    }

    //Set zoom level to include all current search results:
    this.zoomToAllHouses = function() {
        if (_this.markers.length > 0) {
            var objBounds = new GLatLngBounds();

            var ms = $.grep(_this.markers, function(n, i) {
                return n.active && (n.lat != 0) && (n.lng != 0);
            });

            if (ms.length > 0) {
                $.each(ms, function(i, n) {
                    objBounds.extend(new GLatLng(n.lat, n.lng, true));
                });

                _this.map.setCenter(objBounds.getCenter(), _this.map.getBoundsZoomLevel(objBounds));
            }
        }
    }


    //Hides markers of houses not included in current search results (houses array):
    this.refreshMarkers = function() {
        //Loop through markers

        $.each(_this.markers, function(i, n) {

            var mh = _this.getActiveHouses(n.lat, n.lng);

            if (mh.length > 0) {
                if (mh.length > 1) {
                    n.setIcon(ICON_MULTIPLE_HOUSES);
                }
                else {
                    var d = $.grep(mh, function(m, j) {
                        return m.oldprice;
                    });

                    if (d.length > 0) {
                        n.setIcon(ICON_HOUSE_DISCOUNT);
                    }
                    else {
                        n.setIcon(ICON_HOUSE);
                    }
                }
                n.show();
            }
            else {
                n.hide();
            }
        });

        _this.zoomToAllHouses();
    };



    //Get lat lng of object inside map:
    this.getLatLng = function(obj) {
        var objPos = $(obj).offset();
        var mapPos = $(_this.container).offset();

        var x = objPos.left - mapPos.left;
        var y = objPos.top - mapPos.top;

        x += $(obj).width() / 2;
        y += $(obj).height() / 2;

        return _this.map.fromContainerPixelToLatLng(new GPoint(x, y));
    }

    this.closeHouse = function() {
        if (_this.ew) {
            _this.ew.hide();
        }
        return false;
    }

    this.openHouse = function(options) {

        if (_this.ew != null) {
            _this.map.removeOverlay(_this.ew);
        }

        var house = null;
        var latlng = null;
        var offset = null;

        if (options != null) {
            house = (typeof options.house != "undefined" ? options.house : null);
            latlng = (typeof options.latlng != "undefined" ? options.latlng : null);
            offset = (typeof options.offset != "undefined" ? options.offset : null);
        }

        if (house != null && latlng != null) {
            _this.ew = new EWindow(_this.map, E_STYLE_HOUSE);
            _this.map.addOverlay(_this.ew);


            var objContent = document.createElement("div");
            $(objContent).addClass("content");
            $(objContent).addClass("clearfix");

            $(objContent).append(FR.buildSearchResult(house));

            var objClose = document.createElement("img");
            $(objClose).addClass("close");
            $(objClose).attr("src", "/Site/Images/Icons/close.png");

            $(objClose).click(function() {
                return _this.closeHouse();
            });

            $(objContent).append(objClose);

            _this.ew.openOnMap(latlng, objContent, offset);

            var ewSize = _this.ew.getSize();
            if (ewSize) {
                var tp = _this.map.fromLatLngToDivPixel(latlng);
                tp = new GPoint(tp.x + Math.round(ewSize.width / 2), tp.y - Math.round(ewSize.height / 2));
                _this.map.panTo(_this.map.fromDivPixelToLatLng(tp));
            }
        }
    }

    this.closeMultipleHouse = function() {
        if (_this.ew) {
            _this.ew.hide();
        }
        if (_this.ewm) {
            _this.ewm.hide();
        }
        return false;
    }

    //Handles clicks on a marker
    this.clickMarker = function(objMarker) {
        if (_this.ew != null) {
            _this.map.removeOverlay(_this.ew);
        }
        if (_this.ewm != null) {
            _this.map.removeOverlay(_this.ewm);
        }

        var mh = _this.getActiveHouses(objMarker.lat, objMarker.lng);
        var tp = _this.map.fromLatLngToContainerPixel(objMarker.marker.getLatLng());
        var tl = null;


        var objClose = document.createElement("img");
        $(objClose).addClass("close");
        $(objClose).attr("src", "/Site/Images/Icons/close.png");


        //Multiple houses:
        if (mh.length > 1) {

            _this.ewm = new EWindow(_this.map, E_STYLE_MULTIPLE_HOUSES);
            _this.map.addOverlay(_this.ewm);

            var objDiv = document.createElement("div");
            $(objDiv).addClass("content");

            $(objClose).click(function() {
                return _this.closeMultipleHouse();
            });
            $(objDiv).append(objClose);


            $.each(mh, function(i, n) {
                var objImg = document.createElement("img");
                $(objImg).addClass("house");
                $(objImg).attr("src", (n.oldprice ? ICON_HOUSE_DISCOUNT.image : ICON_HOUSE.image));
                $(objImg).click(function() {
                    var p = _this.map.fromLatLngToContainerPixel(objMarker.marker.getLatLng());
                    var x = $(this).offset().left - $(_this.container).offset().left - p.x + ICON_HOUSE.infoWindowAnchor.x;
                    var y = -($(this).offset().top - $(_this.container).offset().top - p.y + ICON_HOUSE.infoWindowAnchor.y);

                    _this.openHouse({
                        house: n,
                        latlng: objMarker.marker.getLatLng(),
                        offset: new GPoint(x, y)
                    });
                });
                $(objDiv).append(objImg);
            });


            _this.ewm.openOnMarker(objMarker.marker, objDiv);

            var ewmSize = _this.ewm.getSize();

            if (ewmSize) {
                var ptp = new GPoint(tp.x + Math.round(ewmSize.width / 2), tp.y - Math.round(ewmSize.height / 2));
                tl = _this.map.fromContainerPixelToLatLng(ptp);
                _this.map.panTo(tl);
            }



        }
        //Single house:
        else if (mh.length == 1) {
            //tp = new GPoint(tp.x, tp.y - Math.round(ICON_HOUSE.infoWindowAnchor.y / 2));
            _this.openHouse({
                house: mh[0],
                latlng: objMarker.marker.getLatLng(),
                offset: new GPoint(0, ICON_HOUSE.infoWindowAnchor.y)
            });
        }


    };


}



function GoogleMapsMarker(options) {
    var _this = this;
    this.lat = (typeof options.lat != "undefined" ? options.lat : 0);
    this.lng = (typeof options.lng != "undefined" ? options.lng : 0);
    this.icon = (typeof options.icon != "undefined" ? options.icon : ICON_HOUSE);
    this.active = (typeof options.active == "boolean" ? options.active : false);
    this.clickable = (typeof options.clickable == "boolean" ? options.clickable : true);

    this.marker = new GMarker(new GLatLng(this.lat, this.lng, true), { icon: this.icon, clickable: this.clickable });

    this.click = null;

    this.setIcon = function(icon) {
        _this.icon = icon;
        if (_this.icon != null) {
            _this.marker.setImage(_this.icon.image);
        }
    }

    this.show = function() {
        _this.active = true;
        _this.marker.show();
    }

    this.hide = function() {
        _this.active = false;
        _this.marker.hide();
    }

    return this;
}

