﻿
//Properties
var pageSize = 10; //We want 10 results per page
var params = {}; //Our params object
var map;
var locations = new Array();
var currentLocationIndex;
var fromLocationLatLon;
var SealyLocation = function(latLong, number, name, address, phone) {
    this.latLong = latLong;
    this.number = number;
    this.name = name;
    this.address = address;
    this.phone = phone;
};

//on DOM load
$j(function() {
//    if (window.location.search == "") {
//        $j("#locatorHero").show();
//        return;
//    }

    params = $j.getAllQueryStrings();
    prepareQuery();
});


//Prepare and validate our call
function prepareQuery() {
    var valid = true;
    var method;
   
    //make sure we have all of our required params
    if (params.ZipCode == undefined) {
        $j("#locatorHero").show();
        return;
    } else {
        if ((params.ZipCode.length != 5) ||
        (isNaN(params.ZipCode))) {
            $j("#locatorHero").show();
            return;
        }
    }
    if ((params.Distance == undefined) ||
        (params.Distance.length == 0)) {
        params.Distance = 10;
    }
    if ((params.Product == undefined) ||
        (params.Product.length == 0)) {
        params.Product = "xml";
        params.ProductXML = "<products>";
        $j("select.brand:eq(0) option").each(
            function() {
                if (($j(this).attr("value") == undefined) || ($j(this).attr("value") == "")) return;
                params.ProductXML += "<product>" + $j(this).attr("value") + "</product>";
            }
        );
        params.ProductXML += "</products>";
    }
    if ((params.ProductXML == undefined) ||
        (params.ProductXML.length == 0)) {
        params.ProductXML = "";
    }
    if ((params.PageSize == undefined) ||
        (params.PageSize > 10)) {
        params.PageSize = pageSize;
    }
    if (params.PageNum == undefined) {
        params.PageNum = 1;
    }
    if (params.Name == undefined) {
        params.Name = "";
    }

    getResults();
}

function getResults() {
    $j("#locatorResultsGrid").show();
    $j("#locatorLoadingImage").show();
    $j.ajax({
        type: "POST",
        url: "/SealyDealerLocator2010/DealerLocator.asmx/FindRetailersStructByZipCodePlusNamePlusDistance_Paged",
        //processData: false,
        data: unescape(JSON.stringify(params)), //"ZipCode=27263&Distance=10&Product=xml&ProductXML=<Products><Product>Sealy Posturepedic</Product><Product>TrueForm</Product></Products>",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        traditional: true,
        success: function(response) {
            //process results
            processResults(response.d);
        },
        error: function(req, status, error) {
            processError(req, status, error);
        },
        complete: function(req, status) {
            $j("#locatorLoadingImage").hide();
        }
    });
}

function processResults(data) {
    $j("#locatorHero").hide();
    $j("#locatorNoResults").hide();
    $j("#locatorResults").show();
    //map
    locations.length = 0;
    for (var i = 0; i < data.Retailers.length; i++) {
        var retailer = data.Retailers[i];
        retailer["mapNumber"] = i + 1;
        var viewAllLocationsParams = {
            Name: retailer.Name,
            ZipCode: params.ZipCode,
            Distance: params.Distance,
            ret: escape(window.location.href)
        }
        retailer["viewAllLocationsLink"] = window.location.protocol + "//" + window.location.host + window.location.pathname + "?" + $j.param(viewAllLocationsParams);
        
        locations.push(new SealyLocation(
                                    new VELatLong(retailer.Latitude, retailer.Longitude),
                                    retailer.mapNumber,
                                    retailer.Name,
                                    retailer.Address + "<br/>" + retailer.City + ", " + retailer.State + " " + retailer.Zip,
                                    retailer.PhoneNumber
                                  ));
    }
    mapInit();
    //process template
    var s = $j("#tmpl_Locator").parseTemplate(data.Retailers);
    //apply template
    $j("#locatorResultsGrid tbody").html(s);
    //Summary
    $j("#locatorResultsSummary").html(data.TotalRetailers + ((params.Name == "") ? " retailer" : " \"" + params.Name + "\"") + " locations were found within " + params.Distance + " mile(s) of " + params.ZipCode);
    if (params.ret != null) {
        $j("#locatorResultsSummary").append("<br/><a href='" + unescape(params.ret) + "' style='text-decoration:none'><img src='/common/images/map/back.png' align='absmiddle' /> Back to search results</a>");
    }
    //Paging
    $j("#locatorResultsPagingNav").empty()
    if (data.TotalRetailers > pageSize) {
        $j("#locatorResultsPagingNav").append(renderPager(data.TotalRetailers));
    } 
    
    //Set map number click event
    $j(".mapListIcon").click(
        function() {
            $j.scrollTo("#locatorMap",200);
        }
    );
}

function processError(req, status, error) {
    $j("#locatorHero").hide();
    $j("#locatorNoResults").show();
    $j("#locatorResults").hide();
    //$j("#locatorResultsSummary").html("There was an error retrieving the results.");
    //$j("#locatorResultsGrid tbody").empty().append("<tr><td><h2>No retailers found</h2></td></tr>");
}

function processNoResults() {
    //$j("#locatorResultsSummary").html("No retailers matched your search criteria");
    //$j("#locatorResultsGrid tbody").empty().append("<tr><td><h2>No retailers found</h2></td></tr>");
    $j("#locatorHero").hide();
    $j("#locatorResults").hide();
    $j("#locatorNoResults").show();
}

//Paging
function pagerClick(pageNum) {
    params.PageNum = pageNum;
    getResults();
}

function renderPager(totalResults) {
    var buttonClickCallback = pagerClick;
    var $pager = $j('<span class="pages"></span>');
    var startPage = 1;
    var endPage = 9;
    var pageCount = Math.ceil(totalResults / params.PageSize);

    if (params.PageNum > 4) {
        startPage = params.PageNum - 4;
        endPage = params.PageNum + 4;
    }

    if (endPage > pageCount) {
        startPage = pageCount - 8;
        endPage = pageCount;
    }

    if (startPage < 1) {
        startPage = 1;
    }
    
    // add in the previous and next buttons
    $pager.append(renderButton('first', params.PageNum, pageCount, buttonClickCallback))
          .append(renderButton('prev', params.PageNum, pageCount, buttonClickCallback));

    // loop thru visible pages and render buttons
    for (var page = startPage; page <= endPage; page++) {

        var currentButton = $j('<a href="javascript:void(0)" class="page-number">' + (page) + '</a>');

        page == params.PageNum ? currentButton.addClass('pgCurrent') : currentButton.click(function() { buttonClickCallback(this.firstChild.data); });
        currentButton.appendTo($pager);
    }

    // render in the next and last buttons
    $pager.append(renderButton('next', params.PageNum, pageCount, buttonClickCallback))
          .append(renderButton('last', params.PageNum, pageCount, buttonClickCallback));

    return $pager;
}

function renderButton(buttonType, pageNum, pageCount, buttonClickCallback) {

    var buttonLabel = "";
    var destPage = 1;

    // work out destination page for required button type
    switch (buttonType) {
        case "first":
            destPage = 1;
            buttonLabel = "&#171; " + buttonLabel;
            break;
        case "prev":
            destPage = pageNum - 1;
            buttonLabel = "&#8249; " + buttonLabel;
            break;
        case "next":
            destPage = pageNum + 1;
            buttonLabel = buttonLabel + " &#8250;";
            break;
        case "last":
            destPage = pageCount;
            buttonLabel = buttonLabel  + " &#187;";
            break;
    }
    
    var $Button = $j('<a href="javascript:void(0)" class="pgNext">' + buttonLabel + '</a>');

    // disable and 'grey' out buttons if not needed.
    if (buttonType == "first" || buttonType == "prev") {
        pageNum <= 1 ? $Button.addClass('pgEmpty') : $Button.click(function() { buttonClickCallback(destPage); });
    }
    else {
        pageNum >= pageCount ? $Button.addClass('pgEmpty') : $Button.click(function() { buttonClickCallback(destPage); });
    }

    return $Button;
}

//map functions

function mapInit() {
    if (map == undefined) {
        map = new VEMap('locatorMap');

        switch (window.location.hostname.toLowerCase()) {
            case "www.sealy.com":
                map.SetCredentials("Aoe4hKNbNlKGKkuw9jDwVtJUTSCXLZLTjHc6L6S4u5UPAEGcJ62dnQvYwF1aNNjh");
                break;
            case "sealycomdev.sealy.com":
                map.SetCredentials("AqlJY90OA5gocKTPqUh3lbWMyRbDx7GvURAMHL47pYaBFMCzXQTXDW8i-jGbk_3Y");
                break;
            case "sealycomqa.sealycommunity.com":
                map.SetCredentials("AlOiG3ZjrKxiVylNcAbiN5G_lST2iW09-JMRl0OaEf0Uq4tNLh4LDlyC-EytZWi9");
                break;
            case "sealycomtest.sealycommunity.com":
                map.SetCredentials("AtOfQy_F-rl63XHs0K1gPhMzeKMCux4S_S7JkoH6s-mLNMK4SahOf_DgZKQTqXFb");
                break;
        }
        
        //set the map width
        var mapWidth = $j("#locatorResults").width() - 2;
        $j("#locatorMap").width(mapWidth);
        //$j("#locatorMapControls").width(mapWidth);
        //hide dashboard
        map.HideDashboard();
        map.LoadMap();
        // Let me know when a birdseye scene is available
        map.AttachEvent("onobliqueenter", BirdsEyeHandler);
        map.AttachEvent("onobliqueleave", BirdsEyeHandler);
        //Set style change handler
        map.AttachEvent("onchangemapstyle", MapStyleChange);
        //Run it so we can set our button state initially
        MapStyleChange();
        //Set up button handlers
        $j("#btnRoad").click(function() { map.SetMapStyle(VEMapStyle.Road); });
        $j("#btnAerial").click(function() { map.SetMapStyle(VEMapStyle.Aerial); });
        $j("#btnHybrid").click(function() { map.SetMapStyle(VEMapStyle.Hybrid); });
        $j("#btnBird").click(function() { map.SetMapStyle(VEMapStyle.Birdseye); });
        $j("#btnZoomIn").click(function() { Zoom(1); });
        $j("#btnZoomOut").click(function() { Zoom(-1); });
        $j("#btnBack").click(function() { ShowAllResults(); });
        //hovers
        $j("#btnRoad,#btnAerial,#btnHybrid,#btnBird,#btnZoomIn,#btnZoomOut").hover(
            function() {
                $j(this).addClass("hover");
            },
            function() {
                $j(this).removeClass("hover");
            }
        );
        //zoom clicks
        $j("#btnZoomIn,#btnZoomOut").mouseup(function() {
            $j(this).removeClass("active");
        }).mousedown(function() {
            $j(this).addClass("active");
        });

    }
    
    map.Clear();
    try {
        var points = new Array();
        for (var i = 0; i < locations.length; i++) {
            points.push(locations[i].latLong);
            var pin = new VEShape(VEShapeType.Pushpin, locations[i].latLong);
            pin.SetTitle(locations[i].name);
            var description = locations[i].address;
            if (!params.nf) {
                description += "<br/><div id='pushPinCtrls'><a href='javascript:void(0)' onclick='showInfo(" + locations[i].number.toString() + ")'>More Info</a> | ";
                description += "<a href='javascript:void(0)' onclick='ZoomToLocation(" + locations[i].latLong.Latitude.toString() + ", " + locations[i].latLong.Longitude.toString() + ")'>Zoom</a> | ";
                description += "<a href='javascript:void(0)' onclick='directionsSingleLocation(" + i + ")'>Directions</a></div>";
            }
            pin.SetDescription(description);
            pin.SetCustomIcon("<img src='/common/images/map/mapPin_" + locations[i].number.toString() + ".png' />")
            map.AddShape(pin);
        }
        map.SetMapView(points);
        //map.ShowMiniMap(200, 100);             


    } catch (e) {
        alert(e.message);
    }
}

function Zoom(factor) {
    var zoomLevel = map.GetZoomLevel() + factor;
    map.SetZoomLevel(zoomLevel);
}
function ZoomToLocation(Latitude, Longitude,isFromList) {
    if (isFromList) $j.scrollTo("#locatorMap", 200);
    map.SetCenterAndZoom(new VELatLong(Latitude, Longitude), 18);
    $j("#btnBack").show();
}
function ShowAllResults() {
    mapInit();
    $j("#btnBack").hide();
}

function MapStyleChange() {
    switch (map.GetMapStyle()) {
        case VEMapStyle.Aerial:
            $j("#btnAerial").addClass("active");
            $j("#btnBird,#btnRoad,#btnHybrid").removeClass("active");
            break;
        case VEMapStyle.Birdseye:
            $j("#btnBird").addClass("active");
            $j("#btnAerial,#btnRoad,#btnHybrid").removeClass("active");
            break;
        case VEMapStyle.Road:
            $j("#btnRoad").addClass("active");
            $j("#btnAerial,#btnBird,#btnHybrid").removeClass("active");
            break;
        case VEMapStyle.Hybrid:
            $j("#btnHybrid").addClass("active");
            $j("#btnRoad,#btnAerial,#btnBird").removeClass("active");
            break;
    }

}

function BirdsEyeHandler() {
    if (map.IsBirdseyeAvailable()) {
        $j("#btnBird").show();
    } else {
        $j("#btnBird").hide();
    }
}

function showInfo(loc) {
    $j("#locatorResultsGrid td").css("background-color", "#ffffff"); 
    $j.scrollTo($j("#loc" + loc).parent(), 200);
    $j("#loc" + loc).parent().nextUntil("tr").andSelf().css("background-color", "#eeeeee"); 
    return false;
}


//Directions
function backToResults() {
    $j("#directions").empty();
    $j("#locatorFromAddress").hide();
    $j("#locatorResultsHeader,#locatorResultsGrid").show();
    mapInit();
}

function directionsSingleLocation(index) {
    $j("#locatorFromAddress").show();

    map.Clear();
    var i = index;
    currentLocationIndex = index;
    
    $j("#directionsTo").html("<div id='directionsBox'><b>To:</b> <br /><h1>" + locations[currentLocationIndex].name + "</h1>" +
                            " " + locations[currentLocationIndex].address + "<br />" + locations[currentLocationIndex].phone + "</div>");

    try {
        var points = new Array();
        points[0] = locations[i].latLong;
        var pin = new VEShape(VEShapeType.Pushpin, locations[i].latLong);
        pin.SetTitle(locations[i].name);
        pin.SetDescription(locations[i].address);
        pin.SetCustomIcon("<img src='common/images/map/mapPin_1.png' />");
        map.AddShape(pin);
        map.SetMapView(points);
        //map.ShowMiniMap(200, 100);
        $j.scrollTo("#locatorFromAddress", 200);
    } catch (e) {
        alert(e.message);
    }
}

function getDirections() {
    $j("#locatorResultsHeader,#locatorResultsGrid").hide();
    map.Clear();
    var locs = new Array();
    if ($j.trim($j("#txtLocatorFromAddress").val()) == "") {
        alert("Please enter a valid address");
        return;
    }
    locs.push($j("#txtLocatorFromAddress").val());
    locs.push(locations[currentLocationIndex].latLong);
    var options = new VERouteOptions;
    // Otherwise what's the point?
    options.DrawRoute = true;

    // So the map doesn't change:
    //options.SetBestMapView = false;

    // Call this function when map route is determined:
    options.RouteCallback = showTurns;

    // Show as miles
    options.DistanceUnit = VERouteDistanceUnit.Mile;

    // Show the disambiguation dialog
    options.ShowDisambiguation = true;

    map.GetDirections(locs, options);

    $j.scrollTo("#locatorMap", 200);


}
function showTurns(route) {
    var turns = "<h3>Turn-by-Turn Directions</h3>";

    turns += "<b>From:</b> <br />" + $j("#txtLocatorFromAddress").val() + "<br /><br />";

    turns += "<p><b>Distance:</b> " + route.Distance.toFixed(1) + " miles";

    turns += "<br/><b>Time:</b> " + GetTime(route.Time) + "</p>";


    // Unroll route and populate DIV
    var legs = route.RouteLegs;
    var leg = null;
    var turnNum = 0;  // The turn #

    // Get intermediate legs
    for (var i = 0; i < legs.length; i++) {
        // Get this leg so we don't have to derefernce multiple times
        leg = legs[i];  // Leg is a VERouteLeg object

        var legNum = i + 1;
        //turns += "<br/><b>Distance for leg " + legNum + ":</b> " + leg.Distance.toFixed(1) + " miles" +
        //         "<br/><b>Time for leg "     + legNum + ":</b> " + GetTime(leg.Time) + "<br/><br/>";

        // Unroll each intermediate leg
        var turn = null;  // The itinerary leg
        var legDistance = null;  // The distance for this leg


        turns += "<ol class='drive'>";

        for (var j = 0; j < leg.Itinerary.Items.length; j++) {
            turnNum++;

            turn = leg.Itinerary.Items[j];  // turn is a VERouteItineraryItem object


            //turns += "<b>" + turnNum + "</b>\t" + turn.Text;
            turns += "<li><b>" + turn.Text + "</b>";

            legDistance = turn.Distance;

            // So we don't show 0.0 for the arrival
            if (legDistance > 0) {
                // Round distances to 1/10ths
                turns += " (" + legDistance.toFixed(1) + " miles";

                // Append time if found
                if (turn.Time != null) {
                    turns += "; " + GetTime(turn.Time);
                }

                turns += ")";
            }
        }

        turns += "</ol>";

        turns += "<br/>";
        //               }

        // Populate DIV with directions
        SetDirections(turns);
    }
}

function SetDirections(s) {
    $j("#directions").html(s);
}

// time is an integer representing seconds
// returns a formatted string
function GetTime(time) {
    if (time == null) {
        return ("");
    }

    if (time > 60) {                                 // if time == 100
        var seconds = time % 60;       // seconds == 40
        var minutes = time - seconds;  // minutes == 60
        minutes = minutes / 60;    // minutes == 1


        if (minutes > 60) {                                     // if minutes == 100
            var minLeft = minutes % 60;        // minLeft    == 40
            var hours = minutes - minLeft;   // hours      == 60
            hours = hours / 60;          // hours      == 1

            return (hours + " hour(s), " + minLeft + " minute(s), " + seconds + " second(s)");
        }
        else {
            return (minutes + " minutes, " + seconds + " seconds");
        }
    }
    else {
        return (time + " seconds");
    }
}
