﻿// vars
var map;
var marker;
var geocoder;
var keyword;
var resetFunc;
var somethingHasMoved;
var markers = [];
var lastPoint;
var mgr;
var showDebug = false;
var departmentsData = [];

var onlyMapMode = onlyMapMode || null;

// icon
var bicon = new GIcon(G_DEFAULT_ICON);
bicon.image = "/App_Themes/Bunnpris/images/icon_b.png";
bicon.shadow = "/App_Themes/Bunnpris/images/icon_b_shadow.png";
bicon.iconSize = new GSize(19.0, 25.0);
bicon.shadowSize = new GSize(32.0, 25.0);
bicon.iconAnchor = new GPoint(9.0, 12.0);
bicon.infoWindowAnchor = new GPoint(9.0, 12.0);

// map setup

$(document).ready(function () {

    if ($("#map").size() > 0) {

        // map setup
        map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(61.88, 8.17), 6);
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        mgr = new MarkerManager(map);
        geocoder = new GClientGeocoder();
        geocoder.setViewport(new GLatLngBounds(new GLatLng(57.6234441829121, 2.9443359375), new GLatLng(71.73449853519226, 33.57421875)));  // set search bounds to norway

    }
});

// data setup

function loadData(data) {

    departmentsData = data;

    addDepartmentsToMap();

    if (!search() && document.location.hash.length > 1)
        showDepartmentInfo(document.location.hash.substr(1));

    // add listeners
    GEvent.addListener(map, "move", function () { somethingHasMoved = true; });
    GEvent.addListener(map, "click", function (overlay, latlng) {
        somethingHasMoved = true;
        if (latlng != undefined && latlng != null)
            placeMarker(latlng, null);
    });

    // search 
    $("#h1large .search").keyup(function () {
        search();
    });
    $(".btnSearch").click(function () {
        search();
        return false;
    });

    // prevent enter from submitting search
    $("#h1large .search").keypress(function (e) {
        if (e.keyCode == 13) {
            return false;
        }
    });

    if (onlyMapMode == null) {
        $("a.department").live("click", function () {
            log("Clicking " + $(this).parents("tr").attr("class"));
            showDepartmentInfo($(this).parents("tr").attr("class"));
        });

        $("#col2b input").click(function () {
            filterDepartmentsList();
        });
    }

    hideLoader();
}


function log(msg) {
    if (showDebug)
        console.log((new Date).getTime() + " " + msg);
}

// show clients position
function reset() {
    log("reset start");

    if (resetFunc != null) {
        resetFunc();
        return;
    }

    resetFunc = function() {
        var point = new GLatLng(61.88, 8.17);
        map.setCenter(point, 6);
        placeMarker(point);
    };
    resetFunc();

    somethingHasMoved = false;
    var activeKey = keyword;
    yqlgeo.get('visitor', function(o) {
        resetFunc = function() {
            ajaxClosest(o.place.centroid.latitude, o.place.centroid.longitude);
        };

        if (activeKey == keyword && !somethingHasMoved) {
            resetFunc();
        }
    });

    log("reset end");
}

// iterates through the table and adds departments to the map
function addDepartmentsToMap() {
    log("addDepartmentsToMap start");
    removeDepartmentsFromMap();

    markers = [];
    $(departmentsData).each(function(n,val){
        if (val.visible === false)
            return;

        var lat = parseFloat(val.PosLat);
        var lng = parseFloat(val.PosLng);
        var _point = new GLatLng(lat, lng);
        var _tmarker = new GMarker(_point, { icon: bicon });
        var _depId = val.ID;
        GEvent.addListener(_tmarker, "click", function() {
            if (onlyMapMode != null) {
                log("Clicking (infowindow) " + val.Title + " #" + _depId);
                _tmarker.openInfoWindowHtml(getDepartmentHtml2(val));
            } else {
                log("Clicking (not infowindow) " + val.Title + " #" + _depId);
                showDepartmentInfo(_depId, false);
            }
            placeMarker(_point);
            document.location = "#" + _depId;

        });
        //map.addOverlay(tmarker);
        markers.push(_tmarker);
        val.Marker = _tmarker;
        
    });
    
    mgr.addMarkers(markers, 1);
    mgr.refresh();
    log("addDepartmentsToMap end");
}

function removeDepartmentsFromMap() {
    log("removeDepartmentsFromMap: start");
    mgr.clearMarkers();
    //for (var i = 0; i < markers.length; i++)
    //    map.removeOverlay(markers[i]);
    log("removeDepartmentsFromMap: end");
}

function sortDepartmentsList() {
    log("sortDepartmentsList: start");

    if (marker == null)
        return;

    var currentPoint = marker.getLatLng();

    for (var i = 0; i < departmentsData.length; i++) {
        departmentsData[i].Dist = departmentsData[i].Marker.getLatLng().distanceFrom(currentPoint);
    }

    departmentsData.sort(function(a, b) { return parseFloat(a.Dist) - parseFloat(b.Dist) });

    $("#departments tbody").html("");
    j = 20;
    for (var i = 0; i < j; i++) {
        if (departmentsData[i] == undefined)
            break;
            
        if (departmentsData[i].visible === false) {
            j++;
            continue;
        }
        $("#departments tbody").append("<tr class=\"" + departmentsData[i].ID + "\"><td><a href=\"#" + departmentsData[i].ID + "\" class=\"department\">" + departmentsData[i].Title + "</a></td>"
                                +"<td>" + (departmentsData[i].OpenOnSunday ? "<img src=\"/App_Themes/bunnpris/images/icon_sondagsopen.png\" alt=\"\" />" : "") + "</td>"
                                + "<td>" + (departmentsData[i].Tipping ? "<img src=\"/App_Themes/bunnpris/images/icon_tipping.png\" alt=\"\" />" : "") + "</td>"
                                + "<td>" + (departmentsData[i].Post ? "<img src=\"/App_Themes/bunnpris/images/icon_posten.png\" alt=\"\" />" : "") + "</td>"
                                + "<td>" + (departmentsData[i].Rikstoto ? "<img src=\"/App_Themes/bunnpris/images/icon_rikstoto.png\"  alt=\"\" />" : "") + "</td>"
                                + "<td style=\"text-align: right\">" + Math.round(departmentsData[i].Dist/1000) + "km</td>"
            +"</tr>");
    }

    // sort
    log("sortDepartmentsList: end");
}

function filterDepartmentsList() {
    log("filterDepartmentsList: start");
    var sundayOpen = $("#openonsunday").attr('checked');
    var tipping = $("#tipping").attr('checked');
    var post = $("#post").attr('checked');
    var rikstoto = $("#rikstoto").attr('checked');

    for (var i = 0; i < departmentsData.length; i++) {
        if ((sundayOpen && !departmentsData[i].OpenOnSunday)) {
            departmentsData[i].visible = false;
        } else if ((tipping && !departmentsData[i].Tipping)) {
            departmentsData[i].visible = false;
        } else if ((post && !departmentsData[i].Post)) {
            departmentsData[i].visible = false;
        } else if ((rikstoto && !departmentsData[i].Rikstoto)) {
            departmentsData[i].visible = false;
        } else {
            departmentsData[i].visible = true;
        }
    }

    addDepartmentsToMap();  // update map
    sortDepartmentsList();
    log("filterDepartmentsList: end");
}

function placeMarker(point, zoom) {

    if (zoom != null && zoom != undefined)
        map.setCenter(point, zoom);

    if (onlyMapMode != null) {
        return;
    }

    if (lastPoint != null && point.lat() == lastPoint.lat() && point.lng() == lastPoint.lng())
        return;

    if (marker != null)
        map.removeOverlay(marker);

    marker = new GMarker(point, { draggable: true });

    GEvent.addListener(marker, "dragend", function() {
        sortDepartmentsList();
    });

    map.addOverlay(marker);



    lastPoint = point;
    sortDepartmentsList();
}

function getDeparmentSearchString(o) {
    return (o.Title + " " + o.PostCode + " " + o.City + " " + o.Address).toLowerCase();
}

function showDepartmentInfo(id, focus) {

    log("Showing department: " + id);
    
    $("#departments .department").removeClass("selected");

    var dep;
    var point;
    for (var i = 0; i < departmentsData.length; i++) {
        if (departmentsData[i].ID == id) {
            dep = departmentsData[i];
            point = new GLatLng(departmentsData[i].PosLat, departmentsData[i].PosLng);
            break;
        }
    }
    if(focus!==false)
        placeMarker(point, 11);


    if (onlyMapMode != null) {
        setTimeout(function () {
            GEvent.trigger(dep.Marker, "click");
        }, 1000);
    } else {
        try {
            $("#departments tr." + id).find(".department").addClass("selected");
        } catch (e) { }
        $("#departmentInfo").html(getDepartmentHtml(dep));
    }
}

function getDepartmentHtml(dep) {
    var title = dep.Title;
    var city = dep.City;
    var address = dep.Address;
    var postalcode = dep.PostCode;
    var phone = dep.Phone;
    var cellphone = dep.Cellphone;
    var fax = dep.Fax;
    var email = dep.Email;
    var description = dep.Description;
    var opening = (dep.ShowOpening1 ? dep.Opening : "") + (dep.ShowOpening2 ? dep.Opening2 : "") + (dep.ShowOpening3 ? dep.Opening3 : "") + (dep.ShowOpening4 ? dep.Opening4 : "") + (dep.ShowOpening5 ? dep.Opening5 : "") + (dep.ShowOpening6 ? dep.Opening6 : "");
    var manager = dep.Manager;

    var html = "<h2>" + title + "</h2>"
                    + (description.length > 0 ? "<br />" + description : "")
                    + "<div class='hr'/>"
                    + opening
                    + "<div class='hr'/>"
                    + "<table style='width: 100%'>"
                    + "<tr><th>Adresse:</th><td>" + address + "</td></tr>"
                    + "<tr><th></th><td>" + postalcode + " " + city + "</td></tr>"
                    + "<tr><th>Telefon:</th><td>" + phone + "</td></tr>"
                    + "<tr><th>Telefaks:</th><td>" + fax + "</td></tr>"
                    + "<tr><th>E-post:</th><td><a href='mailto:" + email + "'>" + email + "</a></td></tr>"
                    + "<tr><th>Kjøpmann:</th><td>" + manager + "</td></tr>"
                    + "</table>"
                    + (title.indexOf("Gourmet") > 0 ? "<br /><a href=\"/bunnpris--gourmet\">Les mer om Bunnpris & Gourmet</a>" : "");

    return html;
}

function getDepartmentHtml2(dep) {
    var title = dep.Title;
    var city = dep.City;
    var address = dep.Address;
    var postalcode = dep.PostCode;
    var phone = dep.Phone;
    var cellphone = dep.Cellphone;
    var fax = dep.Fax;
    var email = dep.Email;
    var description = dep.Description;
    var opening = (dep.ShowOpening1 ? dep.Opening : "") + (dep.ShowOpening2 ? dep.Opening2 : "") + (dep.ShowOpening3 ? dep.Opening3 : "") + (dep.ShowOpening4 ? dep.Opening4 : "") + (dep.ShowOpening5 ? dep.Opening5 : "") + (dep.ShowOpening6 ? dep.Opening6 : "");
    var manager = dep.Manager;

    var icons =
                (dep.OpenOnSunday ? "<img src=\"/App_Themes/bunnpris/images/icon_sondagsopen.png\" alt=\"\" style=\"padding-bottom: 3px\" />" : "")
                + (dep.Tipping ? "<img src=\"/App_Themes/bunnpris/images/icon_tipping.png\" alt=\"\" style=\"padding-bottom: 3px\" />" : "")
                + (dep.Post ? "<img src=\"/App_Themes/bunnpris/images/icon_posten.png\" alt=\"\" style=\"padding-bottom: 3px\" />" : "")
                + (dep.Rikstoto ? "<img src=\"/App_Themes/bunnpris/images/icon_rikstoto.png\"  alt=\"\" />" : "")

    var html = "<h2>" + title + "</h2>"
                    + "<br />"
                    + (description.length > 0 ? description : "")
                    + opening
                    + "<br />"
                    + "<table style='width: 100%; height: 100px'>"
                    + "<tr><th>Adresse:</th><td>" + address + "</td><td rowspan=\"6\" style=\"vertical-align:bottom; width:10px\">" + icons + "</a></tr>"
                    + "<tr><th></th><td>" + postalcode + " " + city + "</td></tr>"
                    + "<tr><th>Telefon:</th><td>" + phone + "</td></tr>"
                    + "<tr><th>Telefaks:</th><td>" + fax + "</td></tr>"
                    + "<tr><th>E-post:</th><td><a href='mailto:" + email + "'>" + email + "</a></td></tr>"
                    + "<tr><th>Kjøpmann:</th><td>" + manager + "</td></tr>"
                    + "</table>"
                    + (title.indexOf("Gourmet") > 0 ? "<br /><a href=\"/bunnpris--gourmet\">Les mer om Bunnpris & Gourmet</a>" : "");

    return html;
}

///
/// Search department
///

function search() {
    showLoader();
    keyword = $("#h1large .search").val();
    if (keyword == "") {
        reset();
        hideLoader();
        return false;
    }

    var activeKeyword = keyword;
    setTimeout(function () {

        if (activeKeyword != keyword)
            return;

        // run ajax search
        if (ajaxSearch(keyword)) {
            return;
        }

        hideLoader();
    }, 600);
    return true;
}

function ajaxSearch(keyword) {

    log("searchPage: ajax start");

    if (keyword == null || keyword.length < 3)
        return false;

    geocoder.getLocations(keyword + " ,norway", function (response) {


        // google fallback response
        var glat = 0;
        var glng = 0;
        if (response.Placemark != null) {
            place = response.Placemark[0];
            log("searchPage: Google search result: " + place.address);
            glat = place.Point.coordinates[1];
            glng = place.Point.coordinates[0];
        }

        // server search
        $.ajax({
            type: "POST",
            url: "/MapSearchService.asmx/Search",
            data: "{'keyword':'" + keyword + "', 'fallbackLat':'" + glat + "', 'fallbackLng':'" + glng + "'}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: searchCallback
        });

        if (pageTracker != undefined)
            pageTracker._trackEvent('Map', 'Search', keyword);
    });

    return true;
}

function ajaxClosest(lat, lng) {
    var zoom = 12;
    $.ajax({
        type: "POST",
        url: "/MapSearchService.asmx/GetClosest",
        data: "{'lat':'" + lat + "', 'lng':'" + lng + "'}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: searchCallback
    });
}

// callback func for server search
function searchCallback(r) {

    log("searchPage: server responded");

    var zoom = zoom || 14;

    if (r.d.payload != null) {

        // find store
        var department = null;
        for (var i = 0; i < departmentsData.length; i++) {
            if (departmentsData[i].ID == parseInt(r.d.payload)) {
                department = departmentsData[i];
                break;
            }
        }

        // show position on map
        var lat = parseFloat(department.PosLat);
        var lng = parseFloat(department.PosLng);
        placeMarker(new GLatLng(lat, lng), zoom);

        // show store info
        if (onlyMapMode != null) {
            setTimeout(function () {
                GEvent.trigger(department.Marker, "click");
            }, 1000);
        } else {
            showDepartmentInfo(department.ID);
        }

    }
    hideLoader();
    log("searchPage: ajax end");
}

/*
function searchPage(keyword) {

    log("searchPage start");

    if (keyword == null || keyword.length < 3)
        return false;

    showLoader();

    var match = null;
    if (keyword.toLowerCase() == "trondheim") {
        match = new GLatLng(63.429, 10.394);
    } else if (keyword.toLowerCase() == "bergen") {
        match = new GLatLng(60.39, 5.334);
    } else if (keyword.toLowerCase() == "oslo") {
        match = new GLatLng(59.929, 10.739);
    } else {
        for (var i = 0; i < departmentsData.length; i++) {
            if (departmentsData[i].visible !== false && (getDeparmentSearchString(departmentsData[i]).indexOf(keyword.toLowerCase()) > 0)) {
                var lat = parseFloat(departmentsData[i].PosLat);
                var lng = parseFloat(departmentsData[i].PosLng);

                if (onlyMapMode != null) {
                    log("searchPage: Click");
                    setTimeout(function () {
                        log(departmentsData[i].Marker);
                        GEvent.trigger(departmentsData[i].Marker, "click");
                    }, 1000);
                } else {
                    log("searchPage: showDepartmentInfo");
                    showDepartmentInfo(departmentsData[i].ID);
                }

                match = new GLatLng(lat, lng);
                break;
            }
        }
    }

    log("searchPage end");
    hideLoader();

    if (match != null) {

        //map.setCenter(point, 12);
        placeMarker(match, 14);
        return true;
    }
    return false;
}

// Google map search 

// addAddressToMap() is called when the geocoder returns an
// answer.  It adds a marker to the map with an open info window
// showing the nicely formatted version of the address and the country code.
function G_addAddressToMap(response) {

    if (!response || response.Status.code != 200) {
        log("Google: Sorry, we were unable to geocode that address");
        reset();
    } else {
        place = response.Placemark[0];

        log("Google search result: " + place.address);
        if (place.AddressDetails.Country.CountryName != "Norge") {
            reset();
            return;
        }
        point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);

        zoom = place.AddressDetails.Accuracy < 4 ? 9 : 11;
        zoom = place.AddressDetails.Accuracy < 3 ? 8 : zoom;
        zoom = place.AddressDetails.Accuracy < 2 ? 7 : zoom;

        placeMarker(point, zoom);
    }
}

// showLocation() is called when you click on the Search button
// in the form.  It geocodes the address entered into the form
// and adds a marker to the map at that location.
function G_showLocation(address) {
    geocoder.getLocations(address + " ,norway", G_addAddressToMap);
}
*/

function showLoader() {
    $("#mapLoader").show();
}
function hideLoader() {
    $("#mapLoader").hide();
}