﻿var _s2sMapSettings = {};
$.ajaxSetup({ cache: false });

function setMapOptions(options) {

    if (options) {
        $.extend(_s2sMapSettings, options);
    }
}

function IsValidCallBack(callback) {
    return null != callback && (typeof callback == "function");
}


var S2SMap = {
    _routes: [],
    geocoder: function () {
        return new google.maps.Geocoder();
    },

    loadMap: function (element, latlng, options, bounds) {
        var $settings = {
            center: latlng,
            zoom: 11,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: true,
            mapTypeControlOptions: {
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
            },
            navigationControl: true,
            navigationControlOptions: {
                style: google.maps.NavigationControlStyle.SMALL
            }
        };

        if (options) {
            $.extend($settings, options);
        }

        map = new google.maps.Map(element, $settings);

        if (bounds) {
            var mapBounds = new google.maps.LatLngBounds(
                new google.maps.LatLng(viewport.SouthWest.Latitude, viewport.SouthWest.Longitude),
                new google.maps.LatLng(viewport.NorthEast.Latitude, viewport.NorthEast.Longitude)
            );

            map.fitBounds(mapBounds);
        }

        return map;
    },


    detectLocation: function (onSuccess) {


        var browserSupportFlag = new Boolean();

        // Try W3C Geolocation (Preferred)
        if (navigator.geolocation) {
            browserSupportFlag = true;
            navigator.geolocation.getCurrentPosition(function (position) {
                onSuccess(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
            }, function () {
                handleNoGeolocation(browserSupportFlag);
            });
            // Try Google Gears Geolocation
        } else if (google.gears) {
            browserSupportFlag = true;
            var geo = google.gears.factory.create('beta.geolocation');
            geo.getCurrentPosition(function (position) {
                onSuccess(google.maps.LatLng(position.latitude, position.longitude));
            }, function () {
                handleNoGeoLocation(browserSupportFlag);
            });
            // Browser doesn't support Geolocation
        } else {
            browserSupportFlag = false;
            handleNoGeolocation(browserSupportFlag);
        }

        function handleNoGeolocation(errorFlag) {
            if (errorFlag == true) {
                onSuccess(newyork);
            }
        }
    },

    getTopUsers: function (number, page, onComplete) {

        var route = S2SRoutes.getRoute("api", "topusers");
        bounds = $map.getBounds();
        var southWest = bounds.getSouthWest();
        var northEast = bounds.getNorthEast();

        var data = {
            neLatitude: northEast.lat(),
            neLongitude: northEast.lng(),
            swLatitude: southWest.lat(),
            swLongitude: southWest.lng(),
            count: number == null ? 10 : number,
            page: page == null ? 1 : page,
            c: function () { return new Date().getTime() }
        };


        $.getJSON(route.Url, data, function (data) {
            onComplete(data);
        });
    },

    getSpots: function (number, page, onComplete) {

        var route = S2SRoutes.getRoute("api", "spots");
        bounds = $map.getBounds();
        var southWest = bounds.getSouthWest();
        var northEast = bounds.getNorthEast();

        var data = {
            neLatitude: northEast.lat(),
            neLongitude: northEast.lng(),
            swLatitude: southWest.lat(),
            swLongitude: southWest.lng(),
            count: number == null ? 10 : number,
            page: page == null ? 1 : page,
            c: function () { return new Date().getTime() }
        };


        $.getJSON(route.Url, data, function (data) {
            onComplete(data);
        });
    },

    displaySpotMarkers: function (map, spots, fitBounds) {

        var bounds = new google.maps.LatLngBounds();

        for (var i = 0; i < spots.length; i++) {
            this.displaySpotMarker(map, spots[i], null);
        }

        if (fitBounds) {
            map.fitBounds(bounds);
        }
    },

    markers: [],

    displaySpotMarker: function (map, spot, bounds) {

        if (bounds != undefined && bounds != null) {

            bounds.extend(spot);
        }

        var point = new google.maps.LatLng(spot.Location.Latitude, spot.Location.Longitude);

        this.displayCameraMarker(map, point, spot.Name);
    },

    displayCameraMarker: function (map, point, title) {

        var root = location.protocol + '//' + location.host;
        var image = new google.maps.MarkerImage(root + '/assets/images_v2/gmap-icon/camera.png'
                                                , new google.maps.Size(25, 36)
                                                , new google.maps.Point(0, 0)
                                                , new google.maps.Point(12, 16));

        var shadow = new google.maps.MarkerImage(root + '/assets/images_v2/gmap-icon/shadow-camera.png'
                                                , new google.maps.Size(33, 22)
                                                , new google.maps.Point(0, 0)
                                                , new google.maps.Point(6, 0));

        var marker = new google.maps.Marker({
            position: point,
            map: map,
            icon: image,
            shadow: shadow,
            title: title == null ? "" : title
        });

        this.markers[S2SMap.markers.length] = marker;

        return marker

    },

    clearMarkers: function () {


        while (S2SMap.markers.length != 0) {
            var marker = S2SMap.markers.pop();
            marker.setMap(null);
        }


    },

    centerMap: function (map, geometry, zoom, onComplete) {
        map.fitBounds(geometry.viewport);
        map.setCenter(geometry.location);
        if (IsValidCallBack(onComplete)) {
            onComplete();
        }
    },

    reverseGeoCode: function (latLng, onSuccess, onError) {

        if (latLng == null)
            return;

        this.geocoder().geocode(
                        { 'latLng': latLng },
						function (results, status) {

						    if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
						        if (IsValidCallBack(onSuccess)) {
						            onSuccess(results)
						        }
						    }
						    else {
						        if (IsValidCallBack(onError)) {
						            onError(status)
						        }
						    }
						});

    },

    geoCode: function (address, onSuccess, onError) {

        if (address === "")
            return;


        this.geocoder().geocode(
                        { 'address': address },
						function (results, status) {

						    if (status == google.maps.GeocoderStatus.OK && results.length > 0) {

						        if (IsValidCallBack(onSuccess)) {
						            onSuccess(results)
						        }
						    }
						    else {
						        if (IsValidCallBack(onError)) {
						            onError(status)
						        }

						    }
						});

    },
    geoSearchCache: function (address, result) {
        var route = S2SRoutes.getRoute("api", "geosearchcache");

        var northEast = result.geometry.viewport.getNorthEast();
        var southWest = result.geometry.viewport.getSouthWest();

        var vp = {
            "southwest": {
                lat: southWest.lat(),
                lng: southWest.lng()
            },
            "northeast": {
                lat: northEast.lat(),
                lng: northEast.lng()
            }
        };
        $.extend(result.geometry.viewport, vp);

        var loc = {
            lat: result.geometry.location.lat(),
            lng: result.geometry.location.lng()
        };


        $.extend(result.geometry.location, loc);

        $.post(route.Url, {
            'q': address,
            'gr': JSON.stringify(result)
        });
    },
    reverseGeoCode: function (latlng, onSuccess, onError) {

        this.geocoder().geocode(
                               { 'latLng': latlng },
							   function (results, status) {
							       if (status == google.maps.GeocoderStatus.OK && results && results.length > 0) {
							           if (IsValidCallBack(onSuccess)) {
							               onSuccess(results);
							           }
							       }
							       else {
							           if (IsValidCallBack(onError)) {
							               onError(status)
							           }
							       }
							   });

    },

    parseAddress: function (results) {

        var addressInfo = { city: null, state: null, country: null };
        for (var i = 0; i < results.length; i++) {
            for (var j = 0; j < results[i].address_components.length; j++) {
                var address_part = results[i].address_components[j];
                for (var k = 0; k < address_part.types.length; k++) {

                    var type = address_part.types[k];

                    if (type == "locality" && null == addressInfo["city"]) {
                        $.extend(addressInfo, { city: address_part.short_name });
                    }
                    else if (type == "administrative_area_level_1" && null == addressInfo["state"]) {
                        $.extend(addressInfo, { state: address_part.short_name });
                    } else if (type == "country" && null == addressInfo["country"]) {
                        $.extend(addressInfo, { country: address_part.short_name });
                    }

                    if (addressInfo.city != null && addressInfo.state != null && addressInfo.country != null) {
                        break;
                    }

                }

                if (addressInfo.city != null && addressInfo.state != null && addressInfo.country != null) {
                    break;
                }
            }

            if (addressInfo.city != null && addressInfo.state != null && addressInfo.country != null) {
                break;
            }
        }

        var formattedAddress = (addressInfo.city == null ? "" : addressInfo.city) +
										   (addressInfo.state ? ", " + addressInfo.state : "") +
										   (addressInfo.country ? ", " + addressInfo.country : "").trim();

        while (formattedAddress.startsWith(",")) {
            formattedAddress = formattedAddress.substring(1);
        }

        $.extend(addressInfo, { formattedAddress: formattedAddress.trim() });

        return addressInfo;
    },

    locationSearch: function (address, onAddressFound) {

        $this = this;

        $this.geoCode(address, function (results) {
            if (IsValidCallBack(onAddressFound)) {
                var addressInfo = $this.parseAddress(results);
                onAddressFound(results, addressInfo);
            }
        },
            function (status) {
                alert(status);
            });
    }
}

var S2SInterface = {

    _lastSearch: "",
    _routes: [],
    _cachedGeoSearches: [],
    _currentSearch: null,
    _searchTimeout: null,
    bindMainSearch: function (searchForm, onSearchCompleted) {


        // Don't want to submit the form without ajax
        $(searchForm).submit(function (event) {
            event.preventDefault();
            return false;
        });

        $searchInput = $("input", searchForm);

        $searchInput.bind("keyup", function (event) {
            event.preventDefault();
            if (event.keyCode == 13) {
                attempSearch($searchInput.val());
            }
            return false;
        });

        $("#search-button", searchForm).click(function (event) {
            event.preventDefault();
            attempSearch($searchInput.val());
        });


        function attempSearch(address) {

            if (address.trim() === "") {
                return;
            }

            S2SMap.locationSearch(address, function (results, addressInfo) {
                onSearchCompleted(results, addressInfo.formattedAddress);
            });
        }
    },

    bindLikes: function () {
        $("a[class=like]").click(function (event) {

            event.preventDefault();
            var self = $(this);

            $.getJSON(self.attr("href"), function (data) {
                var likesCount = data.Response;
                var text = "Liked by you";
                if (likesCount > 1) {
                    text += " and "
                            + likesCount - 1
                            + "person"
                            + (likesCount - 1 == 0 ? "" : "s");
                }
                $("#" + $(self).attr("like-id")).html(text);
                $(self).html("Liked!");
                $(self).attr("href", "#");
                $(self).fadeOut().remove();
            });
        });
    },

    bindToolTips: function () {

        $(".tip").tooltip({
            effect: 'slide',
            position: 'center right',
            offset: [10, 10],
            tip: '.ttip'
        });
    },

    bindOverlays: function () {

        var over = $("a[rel*=#modal]").overlay({
            // some expose tweaks suitable for modal dialogs
            expose: {
                color: '#FFF',
                loadSpeed: 200,
                opacity: 0.5
            },

            onBeforeLoad: function () {
                if (this.getTrigger().attr("href") !== "#") {
                    // grab wrapper element inside content

                    var loadActivity = this.getContent().find(".activity")
                    var wrap = this.getContent().find(".contentWrap")
                    wrap.hide();
                    wrap.html("");
                    var self = this;

                    loadActivity.show();
                    wrap.load(this.getTrigger().attr("href"), function () {
                        loadActivity.hide()
                        wrap.show();
                    });
                }

                $(".closem").click(function () {
                    $("a[rel*=#modal]").overlay().close();
                });
            },

            closeOnClick: false

        });
    },

    flashSuccess: function showSuccess(message) {

        showNotification(message, 'success');
    },

    _loader: null,

    showLoader: function (selector, text) {
        text = text == null || text === "" ? "Loading..." : text;
        var options = {
            spinner: "<span><img src='assets/images_v2/ajax-loader-large.gif'  alt='Loading...' />&nbsp;<em>" + text + "</em></span>"
        };

        S2SInterface._loader = $(selector).busyBox(options);
    },

    hideLoader: function () {
        if (S2SInterface._loader != null) {
            S2SInterface._loader.busyBox('close');
            //S2SInterface._loader.remove();
            S2SInterface._loader = null;
        }
    },

    setCurrentLocation: function (location) {

        setCookie("currentlocation", location, 365);

        if (S2SState.isLoggedIn) {
            //save it to the user
            var route = S2SRoutes.getRoute("api", "setcurrentlocation");

            $.post(route.Url, {
                location: location
            });
        }

    },

    showNotification: function (message, type, callback) {

        notifyCallBack = callback;

        var $notification = $("#notification");
        switch (type) {
            case 'error':
                $notification.removeClass("success notice");
                $notification.addClass("error");
                break;
            case 'success':
                $notification.removeClass("error notice");
                $notification.addClass("success");
                break;
            case '':
            case 'notice':
                $notification.removeClass("error success");
                $notification.addClass("success");
                break;

        }

        $notification.css('top', $("bodd").scrollTop());
        $notification.css('width', $(document).width());

        $("#notification-text").html(message);

        $notification.slideDown(aniSpeed, function () {
            $("#notification").delay(1000).slideUp(aniSpeed, function () {
                if (IsValidCallBack(callback)) {
                    callback();
                }
            });
        });
    },

    spotTemplateSelector: null,

    spotListSelector: null,

    spotContainerSelector: null,

    noSpotsSelector: null,

    paginationContainerSelector: null,

    clearSpots: function () {
        $(S2SInterface.spotListSelector).empty();
    },


    displayPagination: function (pagination, onComplete, paginationSelector) {
        //"Pager":{"FirstItem":1,"HasNextPage":true,"HasPreviousPage":false,"LastItem":10,"PageNumber":1,"PageSize":10,"TotalItems":16,"TotalPages":2}}

        var options = {
            items_per_pages: pagination.PageSize,
            current_page: pagination.PageNumber - 1,
            num_display_entries: 5,
            prev_show_always: true,
            next_show_always: true,
            callback: onComplete
        };

        var selector = S2SInterface.paginationContainerSelector;
        if (paginationSelector != undefined && paginationSelector != null) {
            selector = paginationSelector;
        }
        $(selector).pagination(pagination.TotalItems, options);
    },


    displaySpots: function (spots) {

        S2SInterface.clearSpots();

        if (spots.length == 0) {
            $(this.spotContainerSelector + " " + this.spotListSelector).hide();
            $(this.spotContainerSelector + " " + this.paginationContainerSelector).hide();
            $(this.noSpotsSelector).show();
        } else {
            $(this.spotContainerSelector + " " + this.spotListSelector).show();
            $(this.spotContainerSelector + " " + this.paginationContainerSelector).show();
            $(this.noSpotsSelector).hide();

            $.each(spots, function (i, item) {

                var idStr = ObjectIdConverter.toHexString(item.Id.Value);
                var createdOn = eval(item.CreatedOn.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
                var url = item.Permalink + "_" + idStr;

                $.extend(item, {
                    NarrativeP: item.Narrative.toPreview(40, "[More]", "/spots/" + url),
                    Url: url,
                    IdS: idStr,
                    CreatedOnDisplay: dateFormat(createdOn, dateFormat.masks.mediumDate),
                    CreatedOnUTC: dateFormat(createdOn, dateFormat.masks.isoUtcDateTime)
                });

                $(S2SInterface.spotTemplateSelector).tmpl(item)
                .appendTo(S2SInterface.spotListSelector)
                .fadeIn();
            });

            $(".prettydate").prettyDate();
            S2SInterface.bindLikes();
        }

    },

    clearUsers: function () {
        $(S2SInterface.userListSelector).empty();
    },

    userTemplateSelector: null,

    userListSelector: null,

    userContainerSelector: null,

    displayUsers: function (users) {

        S2SInterface.clearUsers();

        if (users.length == 0) {
            $(this.userContainerSelector + " > h3").hide();
        } else {
            $(this.userContainerSelector + " > h3").show();

            $.each(users, function (i, item) {

                var lastActivityAt = eval(item.LastActivityAt.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
                $.extend(item, {
                    LastActivityAtDisplay: dateFormat(lastActivityAt, dateFormat.masks.mediumDate),
                    LastActivityAtUTC: dateFormat(lastActivityAt, dateFormat.masks.isoUtcDateTime)
                });

                $(S2SInterface.userTemplateSelector).tmpl(item)
                .appendTo(S2SInterface.userListSelector)
                .fadeIn();
            });

            $(".prettydate").prettyDate();
        }
    }
}


var S2SForm = {

    bindAjaxForm: function (options, onSuccess, onError) {

        var $formSettings = {
            theForm: "#form",
            errorContainer: "#errorContainer",
            validationRules: {},
            validatonMessages: {}

        };

        $.extend($formSettings, options);

        var $form = $($formSettings.theForm);
        var $errorContainer = $($formSettings.errorContainer);
        var $activityContainer = $($formSettings.activityContainer);

        var validation = $form.validate({
            errorClass: "invalid",
            errorContainer: $errorContainer,
            errorLabelContainer: $("ul", $errorContainer),
            wrapper: "li",
            rules: $formSettings.validationRules,
            messages: $formSettings.validationMessages,
            submitHandler: function (form) {
                $("button", $form).attr("diabled", "disabled")
                                .addClass("disabled");
                $activityContainer.show();
                var data = $form.serialize();

                $.ajax({
                    type: "POST",
                    url: $form.attr("action"),
                    data: data,
                    dataType: "json",
                    complete: function () {
                        $activityContainer.hide();
                    },
                    success: function (data) {
                        if (true == data.isSuccessful) {
                            if (IsValidCallBack(onSuccess)) {
                                onSuccess(data);
                            }
                        } else {
                            var errors = {};
                            $.each(data.ErrorMessages, function (index, errorMessage) {
                                var elementName = errorMessage.Name != "" ? errorMessage.Name : "title";
                                errors[elementName] = errorMessage.Message;
                            });
                            validation.showErrors(errors);
                            $("button", $form).attr("disabled", "")
                                .removeClass("disabled");
                            
                            if (IsValidCallBack(onError)) {
                                onError(data.ErrorMessages);
                            }
                        }
                    }
                });
            },
            invalidHandler: function (e, valid) {
                var errors = validation.numberOfInvalids();
                if (errors) {
                    $errorContainer.show()
                }
                else {
                    $errorContainer.hide()
                }
            }
        });
    }
}

var S2SRoutes = {


    getRoute: function (controller, action) {
        $controller = controller.toLowerCase();
        $action = action.toLowerCase();

        for (var i = 0; i < scriptRoutes.length; i++) {
            var item = scriptRoutes[i];
            if (item.Controller.toLowerCase() == $controller &&
                item.Action.toLowerCase() == $action) {
                return item;
            }
        }
    }
}

var S2SUtils = {

    isIE: function () {
        return navigator.appName == "Microsoft Internet Explorer";
    }
}
