﻿function GMapMarkerInfoWindowClass()
{
    this.Message = new String();
    this.Size;
}

function GMapMarkerClass()
{
    this.ID = new Number();
    this.InfoWindow;
    this.Coordinate;
    this.Title = new String();
    this.NavigationLink = new String();
}

function ShopsClass() { }

ShopsClass.prototype.LoadCountries = function ()
{
    var objCountriesContainer = document.getElementById("CountriesListContainer");

    var objEffects = new FXEffectsClass();
    var objAJAXLoader = objEffects.ShowAJAXLoader(objCountriesContainer, "Загрузка стран...");

    var objShopsMapper = new ShopsMapperClass();
    objShopsMapper.GetCountries(
    function (data, textStatus, jqXHR)
    {
        Shops.LoadCountriesCallback(data, textStatus, jqXHR, objCountriesContainer, objAJAXLoader);
    },
    function (data, textStatus, jqXHR)
    {
        Shops.LoadCountriesError(data, textStatus, jqXHR, objCountriesContainer, objAJAXLoader);
    });
}

ShopsClass.prototype.LoadCountriesCallback = function (data, textStatus, jqXHR, objCountriesContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objCountriesContainer, objAJAXLoader);

    var objFirstCountry = data[0];
    this.LoadCities(objFirstCountry);
}

ShopsClass.prototype.LoadCountriesError = function (data, textStatus, jqXHR, objCountriesContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objCountriesContainer, objAJAXLoader);
}

ShopsClass.prototype.LoadCities = function (objCountry)
{
    var objGMapContainer = document.getElementById("GMap");

    var objEffects = new FXEffectsClass();
    var objAJAXLoader = objEffects.ShowAJAXLoader(objGMapContainer, "Загрузка городов...");

    var objShopsMapper = new ShopsMapperClass();
    objShopsMapper.GetCities(objCountry.ID,
    function (data, textStatus, jqXHR)
    {
        Shops.LoadCitiesCallback(data, textStatus, jqXHR, objCountry, objGMapContainer, objAJAXLoader);
    },
    function (data, textStatus, jqXHR)
    {
        Shops.LoadCitiesError(data, textStatus, jqXHR, objGMapContainer, objAJAXLoader);
    });
}

ShopsClass.prototype.LoadCitiesCallback = function (data, textStatus, jqXHR, objCountry, objGMapContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objGMapContainer, objAJAXLoader);

    var objLocationCoordinate = objCountry.Coordinate;
    var objMarkersArray = new Array();
    for (i in data)
    {
        var city = data[i];
        if (city.Coordinate && !city.IsSatellite)
        {
            var objMarker = new GMapMarkerClass();
            objMarker.Coordinate = city.Coordinate;
            objMarker.Title = city.LocalizedName;
            objMarker.NavigationLink = "/Shops/?city=" + city.ID;

            objMarkersArray.push(objMarker);
        }
    }

    if (objLocationCoordinate)
    {
        var objGMap = this.LoadGMap(objGMapContainer, objLocationCoordinate);

        if (objGMap && objMarkersArray)
        {
            for (m in objMarkersArray)
            {
                this.AddGMapMarker(objGMap, objMarkersArray[m]);
            }
        }

        $("#CitiesSelectionMode").show();
    }

    var objCitiesContainer = document.getElementById("CitiesListContainer");
    this.PrepareCitiesList(objGMapContainer, objCitiesContainer, data);
}

ShopsClass.prototype.LoadCitiesError = function (data, textStatus, jqXHR, objGMapContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objGMapContainer, objAJAXLoader);
}

ShopsClass.prototype.ToggleSelectionMode = function (sender, strContainerID)
{
    if (sender.className != "controlLinkActive")
    {
        var objList = sender.parentNode.parentNode;
        var objContainer = objList.parentNode.parentNode;

        var objActiveTab;
        for (i in objContainer.childNodes)
        {
            var objChildNode = objContainer.childNodes[i];
            if (objChildNode.id != "CitiesSelectionMode" && objChildNode.nodeType == 1) // Node.ELEMENT_NODE
            {
                if (objChildNode.id == strContainerID)
                    objActiveTab = objChildNode;
                else
                    $(objChildNode).hide();
            }
        }

        if (objActiveTab)
            $(objActiveTab).show();

        for (i in objList.childNodes)
        {
            var objListItem = objList.childNodes[i];
            if (objListItem.nodeType == 1) // Node.ELEMENT_NODE
                objListItem.firstChild.className = "controlLink";
        }

        sender.className = "controlLinkActive";
    }
}

ShopsClass.prototype.LoadCityShops = function (nCityID)
{
    if (nCityID)
    {
        var objGMapWrapperContainer = document.getElementById("GMapWrapper");

        var objEffects = new FXEffectsClass();
        var objAJAXLoader = objEffects.ShowAJAXLoader(objGMapWrapperContainer, "Загрузка Центров Обслуживания Клиентов...");

        var objShopsMapper = new ShopsMapperClass();
        objShopsMapper.GetCityShops(nCityID,
        function (data, textStatus, jqXHR)
        {
            Shops.LoadCityShopsCallback(data, textStatus, jqXHR, objGMapWrapperContainer, objAJAXLoader);
        },
        function (data, textStatus, jqXHR)
        {
            Shops.LoadCityShopsError(data, textStatus, jqXHR, objGMapWrapperContainer, objAJAXLoader);
        });
    }
}

ShopsClass.prototype.LoadCityShopsCallback = function (data, textStatus, jqXHR, objGMapWrapperContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objGMapWrapperContainer, objAJAXLoader);

    var objLocationCoordinate;
    var objMarkersArray = new Array();
    for (i in data)
    {
        var objShopProfile = data[i];

        if (objShopProfile.Address)
        {
            if (!objLocationCoordinate && objShopProfile.Address.City && objShopProfile.Address.City.Coordinate)
                objLocationCoordinate = objShopProfile.Address.City.Coordinate;

            if (objShopProfile.Address.Coordinate)
            {
                var objMarker = new GMapMarkerClass();

                objMarker.ID = objShopProfile.ID;

                objMarker.InfoWindow = new GMapMarkerInfoWindowClass();
                objMarker.InfoWindow.Message = "<span class=\"darkGreen boldText\">" + objShopProfile.LocalizedName + "</span><br /><br /><span class=\"nowrap\">" + objShopProfile.Address.StreetAddress + "</span><br /><span class=\"gray\">Режим работы: " + objShopProfile.WorkingHours + "</span>";
                objMarker.InfoWindow.Event = "mouseover";

                objMarker.Coordinate = objShopProfile.Address.Coordinate;
                objMarker.Title = objShopProfile.LocalizedName;

                objMarkersArray.push(objMarker);
            }
        }
    }

    if (objLocationCoordinate)
    {
        var objGMapContainer = document.getElementById("GMap");
        $(objGMapContainer).show();

        var objGMap = this.LoadGMap(objGMapContainer, objLocationCoordinate);

        if (objGMap && objMarkersArray)
        {
            MARKERS_ARRAY = new Array();

            for (m in objMarkersArray)
            {
                var objMarker = objMarkersArray[m];
                var marker = this.AddGMapMarker(objGMap, objMarker);

                MARKERS_ARRAY.push(marker);

                this.AddShopsTableRowEvent(objGMap, marker, objMarker);
            }
        }
    }
}

ShopsClass.prototype.AddShopsTableRowEvent = function (objGMap, marker, objMarker)
{
    var objRow = document.getElementById("sp" + objMarker.ID).parentNode.parentNode;

    google.maps.event.addDomListener(objRow, "mouseover", function ()
    {
        $(objRow).addClass("highlight");
    });

    google.maps.event.addDomListener(objRow, "mouseout", function ()
    {
        $(objRow).removeClass("highlight");
    });

    google.maps.event.addDomListener(objRow, "click", function ()
    {
        for (i in MARKERS_ARRAY)
        {
            google.maps.event.trigger(MARKERS_ARRAY[i], "mouseout");
        }

        objGMap.setCenter(marker.position);
        google.maps.event.trigger(marker, "mouseover");
    });
}

ShopsClass.prototype.LoadCityShopsError = function (data, textStatus, jqXHR, objGMapWrapperContainer, objAJAXLoader)
{
    var objEffects = new FXEffectsClass();
    objEffects.HideAJAXLoader(objGMapWrapperContainer, objAJAXLoader);
}

ShopsClass.prototype.LoadGMap = function (objGMapContainer, objLocationCoordinate)
{
    var objLatLng = new google.maps.LatLng(parseFloat(objLocationCoordinate.Latitude), parseFloat(objLocationCoordinate.Longitude));
    var options = {
        zoom: parseInt(objLocationCoordinate.DefaultZoomLevel),
        center: objLatLng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(objGMapContainer, options);

    return map;
}

ShopsClass.prototype.AddGMapMarker = function (objGMap, objMarker)
{
    var marker;
    if (objGMap && objMarker && objMarker.Coordinate)
    {
        var image = new google.maps.MarkerImage("/Images/gmap_marker.png",
        new google.maps.Size(44, 42),
        null,
        new google.maps.Point(17, 41));

        var shadow = new google.maps.MarkerImage("/Images/gmap_marker_shadow.png",
        new google.maps.Size(44, 42),
        null,
        new google.maps.Point(17, 41));

        var objLatLng = new google.maps.LatLng(parseFloat(objMarker.Coordinate.Latitude), parseFloat(objMarker.Coordinate.Longitude));
        marker = new google.maps.Marker({
            position: objLatLng,
            map: objGMap,
            shadow: shadow,
            icon: image,
            title: objMarker.Title
        });

        this.AttachMarkerInfoWindow(objGMap, marker, objMarker);
        this.AttachMarkerNavigationLink(marker, objMarker);
    }

    return marker;
}

ShopsClass.prototype.AttachMarkerInfoWindow = function (objGMap, marker, objMarker)
{
    if (objMarker.InfoWindow)
    {
        var objInfoWindow = new google.maps.InfoWindow(
        {
            content: objMarker.InfoWindow.Message,
            size: objMarker.InfoWindow.Size ? new google.maps.Size(objMarker.InfoWindow.Size.Width, objMarker.InfoWindow.Size.Height) : null
        });

        google.maps.event.addListener(marker, "mouseover", function ()
        {
            for (i in MARKERS_ARRAY)
            {
                google.maps.event.trigger(MARKERS_ARRAY[i], "mouseout");
            }

            objInfoWindow.open(objGMap, marker);
        });

        if (objMarker.InfoWindow.Event == "mouseover")
        {
            google.maps.event.addListener(marker, "mouseout", function ()
            {
                objInfoWindow.close();
            });
        }
    }
}

ShopsClass.prototype.AttachMarkerNavigationLink = function (marker, objMarker)
{
    if (objMarker.NavigationLink != "")
    {
        google.maps.event.addListener(marker, "click", function ()
        {
            window.location.href = objMarker.NavigationLink;
        });
    }
}

ShopsClass.prototype.PrepareCitiesList = function (objGMapContainer, objCitiesContainer, data)
{
    if (data && 0 < data.length)
    {
        // Чтобы правильно расположить колонки с городами на странице, надо знать ширину блока.
        // Но чаще всего блок со списком изначально скрыт отображающейся картой Google Maps.
        // Таким образом, доступное место под список городов следует определять по активному блоку
        var nContainerWidth = new Number();
        var objjQueryCitiesContainer = $(objCitiesContainer);
        if (objjQueryCitiesContainer.is(":visible"))
            nContainerWidth = objjQueryCitiesContainer.width();
        else
            nContainerWidth = $(objGMapContainer).width();

        nContainerWidth -= 16; // container width - scrollbar width

        var nColumnCount = 3;
        if (500 < nContainerWidth)
        {
            nColumnCount = 4;
            if (900 < nContainerWidth)
                nColumnCount = 5;
            else
                nColumnCount = 4;
        }

        var nCityCount = data.length;

        var nItemsPerColumn = (nCityCount / nColumnCount) | 0;
        if (nCityCount % nColumnCount != 0)
            nItemsPerColumn += 1;

        // Все числа получены эмпирическим путем и ничего не обозначают. Исключительно подгонка на глазок
        var nColumnWidth = nContainerWidth / nColumnCount | 0;
        var nColumnLeftMargin = nColumnWidth * 0.3 | 0
        var nCapsLeftMargin = 0 - (nColumnWidth * 0.11 | 0);

        var chFirstChar = new String();
        for (var i = 0; i < nColumnCount; i++)
        {
            var objColumn = document.createElement("div");
            objColumn.className = "column";
            objColumn.style.width = nColumnWidth + "px";

            var objColumnContent = document.createElement("div");
            objColumnContent.className = "columnContent";
            objColumnContent.style.marginLeft = nColumnLeftMargin + "px";

            objColumn.appendChild(objColumnContent);

            var nStartPos = i * nItemsPerColumn;
            var nEndPos = nStartPos + nItemsPerColumn;

            var objList = document.createElement("ul");

            objColumnContent.appendChild(objList);

            for (var elem = nStartPos; elem < nEndPos; elem++)
            {
                var city = data[elem];
                if (city)
                {
                    var chItemFirstChar = city.LocalizedName.substring(0, 1);

                    var objListItem = document.createElement("li");

                    objList.appendChild(objListItem);

                    if (chItemFirstChar != chFirstChar)
                    {
                        var objSpan = document.createElement("span");
                        objSpan.className = "caps lightGray";
                        objSpan.style.marginLeft = nCapsLeftMargin + "px";

                        var objFirstChText = document.createTextNode(chItemFirstChar);

                        objSpan.appendChild(objFirstChText);
                        objListItem.appendChild(objSpan);
                    }
                    chFirstChar = chItemFirstChar;

                    var objCityLink = document.createElement("a");
                    objCityLink.href = "/Shops/?city=" + city.ID;
                    objCityLink.title = city.LocalizedName;

                    var objCityLinkText = document.createTextNode(city.LocalizedName);

                    objCityLink.appendChild(objCityLinkText);

                    objListItem.appendChild(objCityLink);

                    objList.appendChild(objListItem);
                }
            }

            objCitiesContainer.appendChild(objColumn);
        }
    }
}

var Shops = new ShopsClass();
