/*global google:false */
/*exported StoreLocator */

var map;
var mapOptions;
var mapLocation;
var marker;
var currentMarkers = [];
var infoWindow;
var currentInfoWindows = [];

/**
 * The store locator provides the interface to Google Maps and any manipulation of the results.
 */
var StoreLocator = (function ($, ggl) {

    //constructor
    function StoreLocator(constants, localization) {
        this.constants = constants;
      
        this.localization = localization;
    }

    /*
     * Initialize the google map
     */
    StoreLocator.prototype.initialize = function(lat, lng) {
        mapLocation = new ggl.maps.LatLng(lat, lng);
        mapOptions = {
            mapTypeControl: false,
            streetViewControl: false,
            zoomControl: true,
            panControl: true,
            zoom: 4,
            center: mapLocation,
            mapTypeId: ggl.maps.MapTypeId.ROADMAP
        };

        map = new ggl.maps.Map(document.getElementById('map_canvas'), mapOptions);
        $('div').on('touchstart', '.gmnoprint div[title^=Pan]', function() {
            $(this).trigger('click');
            return false;
        });
    };
    
    /*
     * Add Pin and popup information popup in the map for each store
     */
    StoreLocator.prototype.addMarkerAndInfoWindow = function(latitude, longitude, title, content, num) {

        mapLocation = new ggl.maps.LatLng(latitude, longitude);

        marker = new ggl.maps.Marker({
            position: mapLocation,
            animation: ggl.maps.Animation.DROP,
            icon: this.constants.rootUrl + '/Content/images/locationPins/' + num + '.png',
            map: map,
            title: title.toString(),
        });

        currentMarkers.push(marker);

        infoWindow = new ggl.maps.InfoWindow({
            position: mapLocation,
            content: content.toString(),
            disableAutoPan: false,
            pixelOffset: new ggl.maps.Size(0, -25)
        });

        currentInfoWindows.push(infoWindow);

        this.listenToMarkerClick.call(this, marker, infoWindow, content);
    };
    
    /*
     * Add Pin to the position which the user input according to the longitude and latitude
     */
    StoreLocator.prototype.addCurrentLocationMarker = function (latitude, longitude) {
        mapLocation = new ggl.maps.LatLng(latitude, longitude);
      
        marker = new ggl.maps.Marker({
            position: mapLocation,
            clickable: true,
            icon: this.constants.rootUrl + '/Content/images/icons-png/locationPin.png',
            map: map,
            title: this.localization.StoreLocatorPinMsg
        });
        currentMarkers.push(marker);
        map.setCenter(mapLocation);
    };

    /*
     * Add Listener to the Pin in google map, when it is clicked, popup the detail information of the store
     */
    StoreLocator.prototype.listenToMarkerClick = function (marker, infoWindow) {
        var root = this;

        ggl.maps.event.addListener(marker, 'click', function () {
            root.removeAllInfoWindows.call(root);
            root.zoomMap.call(root, map, 15);
            root.setCenter.call(root, map, infoWindow.getPosition());
            infoWindow.open(map);
        });
    };

    /*
     * Set Map center position and zoom level
     */
    StoreLocator.prototype.setMapLocation = function (latitude, longitude, zoom) {
        var coords = new ggl.maps.LatLng(latitude, longitude);
        map.setZoom(zoom);
        map.setCenter(coords);
    };

    /*
     * Remove all the popup information window from the google map
     */
    StoreLocator.prototype.removeAllInfoWindows = function () {
        for (var i in currentInfoWindows) {
            currentInfoWindows[i].setMap(null);
        }
    };
    
    /*
     * Remove all the Pins and popup information window from the google map
     */
    StoreLocator.prototype.removeAllMarkersAndInfoWindows = function () {
        for (var i in currentInfoWindows) {
            currentInfoWindows[i].setMap(null);
        }

        for (i in currentMarkers) {
            currentMarkers[i].setMap(null);
        }
    };

    /*
     * Popup the information window
     */
    StoreLocator.prototype.openInfoWindow = function (latitude, longitude) {
        for (var i in currentInfoWindows) {
            if (this.roundToDecimal.call(this, currentInfoWindows[i].getPosition().lat(), 5) == latitude &&
                this.roundToDecimal.call(this, currentInfoWindows[i].getPosition().lng(), 5) == longitude) {
                currentInfoWindows[i].open(map);
                break;
            }
        }
    };

    /*
     * Set zoom level for google map
     */
    StoreLocator.prototype.zoomMap = function (map, latlng) {
        map.setZoom(latlng);
    };

    /*
     * Set center position of the google map
     */
    StoreLocator.prototype.setCenter = function (map, number) {
        map.setCenter(number);
    };

    StoreLocator.prototype.roundToDecimal = function (value, decimalPlaces) {
        return Math.round(value * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
    };

    return StoreLocator;

})(jQuery, google);
;
/*global BootstrapDialog:false */
/*exported StoreFinder */
'use strict';


/**
 * The store finder has logic that allows end users to find stores based on a location (latitude/longitude)
 */
var StoreFinder =(function($, dialog) {

    //constructor
    function StoreFinder(storeLocator, constants, localization) {
        this.storeLocator = storeLocator;
        this.constants = constants;
        this.localization = localization;
    }

    /*
     * Display store information in a table
     */
    StoreFinder.prototype.addStoreRow = function(store) {
        if (store) {
            var htmlRow = '';
            htmlRow += '<tr itemscope itemtype="http://schema.org/Store">';
            htmlRow += '<td data-th="Store"><span class="numBox">' + store.Num + '</span><a target="_blank" href="' + this.constants.rootUrl + '/Stores/' + store.Url + '" itemprop="name">' + store.StoreName + '</a></td>';
            htmlRow += '<td data-th="Address"  itemscope itemtype="http://schema.org/PostalAddress"><span itemprop="address">' + store.Address + '</span></td>';
            htmlRow += '<td data-th="City/Province" itemscope itemtype="http://schema.org/PostalAddress"><span  itemprop="addressLocality" >' + store.CityProvince + '</span></td>';
            htmlRow += '<td data-th="Phone" itemprop="telephone">' + store.LocalPhone + '</td>';
            htmlRow += '<td data-th="Distance">' + store.Distance + ' km</td>';
            htmlRow += '</tr>';
            $('#tblStores tbody').append(htmlRow);
        }
    };

    /*
     * Get store list information by latitude, longitude and range
     */
    StoreFinder.prototype.getStores = function (lat, lng, range) {

        $('span#rangeInfo').html(range);
        $('#tblStores tbody').html('');

        var root = this;

        root.storeLocator.addCurrentLocationMarker(lat, lng);
        $.ajax({
            url: root.constants.rootUrl + '/api/stores/getStores?lat=' + lat + '&lng=' + lng + '&range=' + range + '&rand=' + Math.floor(Math.random() * 11),
            success: function (data) {
                if (data) {
                    var maxDistance = 0;
                    $.each(data, function (index, store) {
                        var latitude = store.Latitude;
                        var longitude = store.Longitude;
                        var title = store.Title;
                        var content = store.Content;
                        var num = store.Num;
                        if (maxDistance < store.Distance) {
                            maxDistance = store.Distance;
                        }
                        root.storeLocator.addMarkerAndInfoWindow(latitude, longitude, title, content, num);
                        root.addStoreRow.call(root, store);
                    });

                    var zoom = 0;
                    if (maxDistance <= 5) {
                        zoom = 14;
                    } else if (maxDistance <= 10) {
                        zoom = 12;
                    } else if (maxDistance <= 20) {
                        zoom = 10;
                    } else if (maxDistance <= 50) {
                        zoom = 9;
                    } else if (maxDistance <= 100) {
                        zoom = 8;
                    } else if (maxDistance <= 150) {
                        zoom = 7;
                    } else if (maxDistance <= 200) {
                        zoom = 6;
                    }
                    root.storeLocator.setMapLocation(lat, lng, zoom);
                }

                $('i.spinner').hide();
                $('span.current-location-spinner').hide();
            }
        });
    };

    /*
     * Get location from the user input including country, postal and address
     */
    StoreFinder.prototype.GetUserLocation = function (country, postal, address) {
        var root = this;
        var range = $('#Range').val();
        if (country === '' || postal === '') {
            $('i.spinner').hide();
            dialog.alert(root.localization.StoreFinderValidationMessage);
        } else {
            $.getJSON(root.constants.rootUrl + '/api/GeoLocation?country=' + country + '&postal=' + postal + '&address=' + address,
                function(data) {
                    if (data === null) {
                        $('i.spinner').hide();
                        dialog.alert(root.localization.StoreFinderCannotFindLocation);
                    } else {
                        var lat = data.Latitude;
                        var lng = data.Longitude;
                        root.getStores.call(root, lat, lng, range);
                    }
                }
            );
        }
    };
    StoreFinder.prototype.noPosition = function() {
        var root = this;

        root.getStores('', '', -1);
        $('span.current-location-spinner').hide();
        dialog.alert(root.localization.StoreFinderCannotGetYourCurrentLocation);
    };
    StoreFinder.prototype.getCurrentPosition = function(options) {
        var root = this;

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(
                function(pos) {
                    var crd = pos.coords;
                    var range = $('#Range').val();
                    root.getStores.call(root, crd.latitude, crd.longitude, range);
                },
                function() {
                    StoreFinder.prototype.noPosition.call(root);
                },
                options);
        }
        else{
            StoreFinder.prototype.noPosition.call(root);
        }
        
    };

    return StoreFinder;

})(jQuery, BootstrapDialog);;
/*exported StoreDetail */
'use strict';


/**
 * Provides information about a store that was found via the store finder
 */
var StoreDetail = (function($) {

    //constructor
    function StoreDetail(storeLocator, constants) {
        this.storeLocator = storeLocator;
        this.constants = constants;
    }

    StoreDetail.prototype.GetStore = function (storeid) {
        var root = this;

        $.ajax({
            url: root.constants.rootUrl + '/api/stores/GetStoreDetail?storeid=' + storeid,
            success: function (data) {
                if (data) {
                    var store = data;

                    var latitude = store.Latitude;
                    var longitude = store.Longitude;
                    var storeName = store.StoreName;
                    var content = store.Content;
                    root.storeLocator.addMarkerAndInfoWindow(latitude, longitude, storeName, content, 0);
                    var zoom = 15;
                    root.storeLocator.setMapLocation(latitude, longitude, zoom);
                }
            }
        });
    };

    return StoreDetail;

})(jQuery);

;
/*global BootstrapDialog:false */
/*exported storeFinder, StoreInventory */
'use strict';

/**
 * The store finder has logic that allows end users to find stores based on a location (latitude/longitude)
 */
var StoreInventory = (function ($, dialog) {

    //constructor
    function StoreInventory(storeLocator, constants, localization) {
        this.storeLocator = storeLocator;
        this.constants = constants;
        this.localization = localization;
    }

    
    /*
     * Display store information table under the map
     */
    StoreInventory.prototype.addStoreRow = function(store) {
        if (store) {
            var htmlRow = '';
            htmlRow += '<tr itemscope itemtype="http://schema.org/Store">';
            htmlRow += '<td data-th="Store"><span class="numBox">' + store.Num + '</span><a href="' + this.constants.rootUrl + '/Stores/' + store.Url + '" itemprop="name" target="_blank">' + store.StoreName + '</a></td>';
            htmlRow += '<td data-th="City/Province" itemscope itemtype="http://schema.org/PostalAddress"><span  itemprop="addressLocality" >' + store.CityProvince + '</span></td>';
            htmlRow += '<td data-th="Inventory">' + store.Inventory + '</td>';
            htmlRow += '</tr>';
            $('#tblStores tbody').append(htmlRow);
        }
    };

    /*
     * Get stores and related inventory by product item id, longitude, latitude and range.
     */
    StoreInventory.prototype.getStores = function (itemId, lat, lng, range) {
        var root = this;

        $('span#rangeInfo').html(range);
        $('#tblStores tbody').html('');

        root.storeLocator.addCurrentLocationMarker(lat, lng);
        $.ajax({
            url: root.constants.rootUrl + '/api/Product/GetStoreInventory?itemId=' + itemId + '&lat=' + lat + '&lng=' + lng + '&range=' + range + '&rand=' + Math.floor(Math.random() * 11),
            success: function (data) {
                if (data) {

                    var maxDistance = 0;
                    $('#StoresTable').removeClass('hide');
                    $.each(data, function (index, store) {
                        var latitude = store.Latitude;
                        var longitude = store.Longitude;
                        var title = store.Title;
                        var content = store.Content;
                        var num = store.Num;
                        if (maxDistance < store.Distance) {
                            maxDistance = store.Distance;
                        }
                        root.storeLocator.addMarkerAndInfoWindow(latitude, longitude, title, content, num);
                        root.addStoreRow.call(root, store);
                    });

                    var zoom = 0;
                    if (maxDistance <= 5) {
                        zoom = 14;
                    } else if (maxDistance <= 10) {
                        zoom = 12;
                    } else if (maxDistance <= 20) {
                        zoom = 10;
                    } else if (maxDistance <= 50) {
                        zoom = 9;
                    } else if (maxDistance <= 100) {
                        zoom = 8;
                    } else if (maxDistance <= 150) {
                        zoom = 7;
                    } else if (maxDistance <= 200) {
                        zoom = 6;
                    }
                    root.storeLocator.setMapLocation(lat, lng, zoom);
                }

                $('i.spinner').hide();
                $('span.current-location-spinner').hide();
            }
        });

    };
    
    /**
     * Get location information by country, postal and address
     */
    StoreInventory.prototype.GetUserLocation = function (itemId,country, postal, address) {
        var root = this;

        var range = $('#Range').val();

        if (itemId === undefined || itemId === null) {
           
            return false;
        }

        if (country === '' || postal === '') {
            $('i.spinner').hide();
            dialog.alert(root.localization.StoreFinderValidationMessage);
        } else {
            $.getJSON(root.constants.rootUrl + '/api/GeoLocation?country=' + country + '&postal=' + postal + '&address=' + address,
                function(data) {
                    if (data === null) {
                        $('i.spinner').hide();
                        dialog.alert(root.localization.StoreFinderCannotFindLocation);
                    } else {
                        var lat = data.Latitude;
                        var lng = data.Longitude;
                        
                        root.getStores.call(root, itemId, lat, lng, range);
                    }
                }
            );
        }
    };


    /*
     *Get currently user's location  
     */
    StoreInventory.prototype.getCurrentPosition = function (options,itemId) {

        var root = this;

        navigator.geolocation.getCurrentPosition(
            function (pos) {
               
                var crd = pos.coords;
                var range = $('#Range').val();
                root.getStores.call(root, itemId,crd.latitude, crd.longitude, range);
            },
            function () {
                root.getStores('', '', -1);
                dialog.alert(root.localization.StoreFinderCannotGetYourCurrentLocation);
            },
            options);
    };


    return StoreInventory;

})(jQuery, BootstrapDialog);;
