//Currently there is the limitation that only one of these maps may be on a page at a time.
var lct_vars = {
    currentPlaceCatId : 0,
    currentSelectedItem : null,
    currentSelectedSubItem : null,
    currentMarkerIndex : null,
    markerGroups : {},
    storeGroups : {},
    currentGroup : "",
    maxScrollableHeight : 0,
    currentMode : "catBrowse" //{catBrowse,areaSearch}
}

//Used to contain scrolling subItem lists
var scrollingList = {
    list:null,
    listContainer:null,
    scroll : 1,
    scrollSpeed : 1000,
    maxHeight : 0,
    actualHeight : 0,
    currentMargin : 0,
    first:0,
    last:0
}

//Init
function initLocations(){
    var sideListHeight = $(".controls .gMapMarkerList").outerHeight();
    if(sideListHeight > $("#LCT_mapContainer").outerHeight())
    {
        $("#LCT_mapContainer .controlsBg").height(sideListHeight + 100);
        $("#LCT_Map").height(sideListHeight + 100);
        
    }
    //calculate max scrolling height
    lct_vars.maxScrollableHeight = $(".controlsBg").height() - ($(".gMapMarkerList > li").length * $(".gMapMarkerList > li:first").height());
    
    //add focus/blur event handlers to search box
    $(".mod-storelocator-srch input[type=text]").focus(function(){
        $(".mod-storelocator-srch span.desc").hide();
    });
    
    $(".mod-storelocator-srch input[type=text]").blur(function(){
        
        if($.trim($(this).val()).length == 0)
        {
            $(".mod-storelocator-srch span.desc").show();
        }
        else
        {
            $(".mod-storelocator-srch span.desc").hide();
        }
        
    });
    
    //focus on search box
    if($(".mod-storelocator-srch input[type=text]").val().length != 0)
    {
        $(".mod-storelocator-srch input[type=text]").focus();
    }
}

//Loads the map and relative lists with 
//placemarks for the given catId
function loadPlacesForCat(catId)
{
    //Update current mode
    lct_vars.currentMode = "catBrowse";
    
    //Hide and remove area search results
    $(".LCT_searchResults").slideUp("slow", function(){
        $("#LCT_OptResults tbody").empty();
        $("#LCT_PharResults tbody").empty();
    });
    
    if(lct_vars.currentPlaceCatId != catId)
    {
        lct_vars.currentGroup = "cat"+catId;
        $.gMapViewerSettings({hideMarkersOnLoad:true});
        
        if(lct_vars.markerGroups[lct_vars.currentGroup])
        {
            //Grab placemarks from existing array
            $.gMapViewerClearPlacemarks();
            
            $.gMapViewerLoadPlacemarkArray(lct_vars.markerGroups[lct_vars.currentGroup], function(){
                lct_vars.currentSelectedSubItem = null;
                collapseMenu(lct_vars.currentPlaceCatId);
                expandMenu(catId);
                lct_vars.currentPlaceCatId = catId;
            });
        }
        else
        {
            //Query for placemarks via ajax
            $.get(
                "MapRequest.aspx", 
                {"mode":"getPlacesByCat","catId":catId}, 
                function (mapXmlDoc){
                    if(mapXmlDoc)
                    {
                        $.gMapViewerLoadPlacemarks(mapXmlDoc);
                        lct_vars.markerGroups[lct_vars.currentGroup] = $.gMapViewerGetMarkers();
                        lct_vars.storeGroups[lct_vars.currentGroup] = createStoreList(mapXmlDoc);
                        
                        lct_vars.currentSelectedSubItem = null;
                        collapseMenu(lct_vars.currentPlaceCatId);
                        expandMenu(catId);
                        lct_vars.currentPlaceCatId = catId;
                    }
                },
                "xml");
        }
    }
}

//Performs a Google Map bounds search for the specified search string 
function locationSearch()
{
    var searchString = $.trim($(".mod-storelocator-srch input[type=text]").val());
    
    if(searchString.length != 0)
    {
        if(searchString.toLowerCase().indexOf("australia") == -1)
        {
            searchString += " Australia";
        }
    
        $.gMapViewerGeoSearch(searchString, getMarkerByBounds);
    }
    else
    {
        alert("Please enter a suburb or postcode.");
    }
}

//Loads the map and relative lists with 
//placemarks for the given bounds
function getMarkerByBounds(center, bounds)
{
    //Set current mode
    lct_vars.currentMode = "areaSearch";
    
    collapseMenu(lct_vars.currentPlaceCatId);
    selectSubItem(0);
    selectItem(0);
    lct_vars.currentPlaceCatId = 0;
    lct_vars.currentSelectedItem = null;
    lct_vars.currentSelectedSubItem = null;
    lct_vars.currentMarkerIndex = null;
    
    if(center && bounds)
    {
        var neLatLng = bounds.getNorthEast();
        var swLatLng = bounds.getSouthWest();
        
        $.get(
            "MapRequest.aspx", 
            {"mode":"getPlacesByBounds","swLat":swLatLng.lat(),"swLng":swLatLng.lng(),"neLat":neLatLng.lat(),"neLng":neLatLng.lng()}, 
            function (mapXmlDoc){
             
                if(mapXmlDoc)
                {
                    $.gMapViewerSettings({hideMarkersOnLoad:false});
                    $.gMapViewerLoadPlacemarks(mapXmlDoc);
                    lct_vars.markerGroups["geoSearch"] = $.gMapViewerGetMarkers();
                    
                    //display in table
                    lct_vars.storeGroups["geoSearch"] = displayDetailedList(mapXmlDoc);
                }
            },
            "xml");
    }
    else
    {
        alert("Unable to find location");
    }
}

//Loads the map and relative lists with placemarks for the given bounds.
//This function is used to hook into the onMapMoveEnd event so it should 
//only process if the mode is areaSearch.
//i.e. only perform an area search when the user is panning or zooming while in "areaSearch" mode.
function refreshAreaSearch(center, bounds)
{
    if(lct_vars.currentMode == "areaSearch")
    {
        getMarkerByBounds(center, bounds);
    }
}

//Displays the detailed list for the area search results
function displayDetailedList(xmlDoc)
{
    var storeLocNodes = xmlDoc.getElementsByTagName("store");
    var optList = $("#LCT_OptResults tbody");
    var pharList = $("#LCT_PharResults tbody");
    var optCnt = 0;
    var pharCnt = 0;
    
    optList.empty();
    pharList.empty();
    
    if(storeLocNodes.length != 0)
    {
        var rowHTML = "";
        
        var store = {
            id : "",
            type : "",
            title : "",
            addr1 : "",
            addr2 : "",
            city : "",
            postcode : "",
            phone : "",
            fax : "",
            hours : ""
        }
        
        for(var i=0; i<storeLocNodes.length; i++)
        {
            store.id = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "id", 0);
            store.type = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "type", 0);
            store.title = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "title", 0);
            store.addr1 = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "address1", 0);
            store.addr2 = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "address2", 0);
            store.city = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "city", 0);
            store.postcode = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "postcode", 0);
            store.phone = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "phone", 0);
            store.fax = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "fax", 0);
            store.hours = $.gMapViewerGetChildNodeValue(storeLocNodes[i], "hours", 0);
            
            if(store.id != 0 && store.title.length != 0)
            {
                rowHTML = "<tr id=\"lct_detaileItem_"+i+"\" onclick=\"selectResultListItem("+i+");\" class=\"hot\">"+
                    "<td>"+store.title+"</td>"+
                    "<td>"+ $.trim(store.addr1 + store.addr2) +"</td>"+
                    "<td>"+store.city+"</td>"+
                    "<td class='nowrap'>"+store.phone+"</td>"+
                    "<td class='nowrap'>"+store.fax+"</td>"+
                    "<td>"+store.hours+"</td>"+
                "</tr>";
                
                if(store.type.toLowerCase().indexOf("o") > -1)
                {
                    optList.append(rowHTML);
                    optCnt++;
                }
                else if(store.type.toLowerCase().indexOf("p") > -1)
                {
                    pharList.append(rowHTML);
                    pharCnt++;
                }
            }
        }
    }
    
    if(optCnt == 0)
    {
        optList.append("<tr><td colspan=\"6\" class=\"noresults\">No optical stores were found in this area.</td></tr>");
    }
    
    if(pharCnt == 0)
    {
        pharList.append("<tr><td colspan=\"6\" class=\"noresults\">No pharmacy stores were found in this area.</td></tr>");
    }
    
    if(optCnt == 0 && pharCnt == 0)
    {
        $("#LCT_NoResultsMsg").show();
    }
    else
    {
        $("#LCT_NoResultsMsg").hide();
    }
    $(".LCT_searchResults").slideDown("slow");
   
}

function displayStoreInfo(index)
{
    var store = lct_vars.storeGroups[lct_vars.currentGroup][index];
    var rowHTML = "";
    var optList = $("#LCT_OptResults tbody");
    var pharList = $("#LCT_PharResults tbody");
    
    optList.empty();
    pharList.empty();
    
    if(store != null)
    {
        if(store.id != 0 && store.title.length != 0)
        {
            rowHTML = "<tr>"+
                "<td>"+store.title+"</td>"+
                "<td>"+ $.trim(store.addr1 + store.addr2) +"</td>"+
                "<td>"+store.city+"</td>"+
                "<td class='nowrap'>"+store.phone+"</td>"+
                "<td class='nowrap'>"+store.fax+"</td>"+
                "<td>"+store.hours+"</td>"+
            "</tr>";
            
            if(store.type.toLowerCase().indexOf("o") > -1)
            {
                optList.append(rowHTML);
                $("#LCT_OptResults").slideDown("slow");
            }
            else if(store.type.toLowerCase().indexOf("p") > -1)
            {
                pharList.append(rowHTML);
                $("#LCT_PharResults").slideDown("slow");
            }
        }
    }
}

function createStoreList(xmlDoc)
{
    var storeLocNodes = xmlDoc.getElementsByTagName("store");
    var storeList = new Array();
    var store;
    
    for(var i=0; i<storeLocNodes.length; i++)
    {
        store = {
            id : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "id", 0),
            type : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "type", 0),
            title : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "title", 0),
            addr1 : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "address1", 0),
            addr2 : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "address2", 0),
            city : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "city", 0),
            postcode : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "postcode", 0),
            phone : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "phone", 0),
            fax : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "fax", 0),
            hours : $.gMapViewerGetChildNodeValue(storeLocNodes[i], "hours", 0)
        }
        
        storeList.push(store);
    }
    
    return storeList;
}

/** Side Menu functions **/
function collapseMenu(catId)
{
    if(catId != 0)
    {
        var subMenu = $("#placeCat_" + catId + " .subMenu");
        $("a.selected", subMenu).removeClass("selected");
        subMenu.slideUp($("li", subMenu).length * 50 + 500);
    }
}

function expandMenu(catId)
{
    if(catId != 0)
    {
        var targetLI = $("#placeCat_" + catId);
        var markerArray = lct_vars.markerGroups[lct_vars.currentGroup];
        var storeArray = lct_vars.storeGroups[lct_vars.currentGroup];
        
        if(targetLI.length != 0)
        {
            selectItem(targetLI);
            var subMenu = $(".subMenu", targetLI);
            var listUL = $('ul', subMenu);
            var maxVisible = 0;
            
            if(markerArray.length != 0 &&subMenu.length == 0 )
            {
                //add sub items
                targetLI.append("<div class='subMenu'><div class='listOuterBox'><div class='listInnerBox'><ul></ul></div></div></div>");
                
                subMenu = $(".subMenu", targetLI);
                listUL = $('ul', subMenu);
                
                var shortTitle = "";
                for(var i=0; i<markerArray.length; i++)
                {
                    shortTitle = markerArray[i].Title;
                   
                    if(storeArray[i].title != null && storeArray[i].title.length != 0)
                    {
                        shortTitle = storeArray[i].title;
                    }
                    
                    if(shortTitle.length >= 33)
                    {
                        shortTitle = shortTitle.substring(0,33) + "...";
                    }
                    listUL.append("<li id='subItem_"+catId+"_"+i+"'><a href='#' title='"+markerArray[i].Title+"' onclick=\"selectPlacemark('"+i+"');return false;\"><span>"+shortTitle+"</span></a></li>");
                }
                
                maxVisible = markerArray.length;
                //require paging
                if(listUL.height() > lct_vars.maxScrollableHeight)
                {
                    subMenu.height(lct_vars.maxScrollableHeight);
                    
                    subMenu.prepend("<a href='#' class='listSlider-prev'><span class='inactive'></span></a>");
                    subMenu.append("<a href='#' class='listSlider-next'><span></span></a>");
                   
                    var scrList = {
                        list:null,
                        listContainer:null,
                        scroll : 1,
                        scrollSpeed : 1000,
                        maxHeight : 0,
                        actualHeight : 0,
                        currentMargin : 0,
                        first:0,
                        last:0
                    }
                    maxVisible = Math.floor((lct_vars.maxScrollableHeight - ($(".listSlider-prev", subMenu).height() * 2))/$("li:first", subMenu).height());
                    scrList.list = $('ul > li', subMenu);
                    scrList.listContainer = $(".listInnerBox", subMenu);
                    scrList.scroll = maxVisible - 1;
                    scrList.maxHeight = lct_vars.maxScrollableHeight - ($(".listSlider-prev", subMenu).height() * 2);
                    scrList.actualHeight = $(".listInnerBox", subMenu).outerHeight();
                    scrList.first = 0;
                    
                    $(".listOuterBox", subMenu).height(scrList.maxHeight);
                    
                    $(".listSlider-next", subMenu).bind('click', scrollNext);

                    $(".listSlider-prev", subMenu).bind('click', scrollPrev);
                    
                    subMenu.data("scrollingList", scrList);
                    scrollingList = scrList;
                }
            }
            else if(subMenu.length != 0)
            {
                scrollingList = subMenu.data("scrollingList");
            }
          
            if(markerArray.length != 0)
            {
                subMenu.hide().slideDown(maxVisible * 50 + 500);
            }
            
        }
    }
}

//Selects the first level item in the side menu list
function selectItem(newItem)
{
    if(lct_vars.currentSelectedItem && lct_vars.currentSelectedItem.length != 0)
    {
        $("a:first", lct_vars.currentSelectedItem).removeClass("selected");
    }
        
    if(newItem)
    {
        lct_vars.currentSelectedItem = newItem;
        $("a:first", lct_vars.currentSelectedItem).addClass("selected");
    }
}

//When lct_vars.currentMode: 'catBrowse' - Selects the second level item in the side menu list
//Otherwise lct_vars.currentMode: 'areaSearch' - Selects the item in the detailed area search result list
//Note: this is used as a callback for when a placemark is clicked in the map
function selectSubItem(index)
{
    if(lct_vars.currentMode == "catBrowse")
    {
        var id = "subItem_"+lct_vars.currentPlaceCatId+"_"+index;
        var newSubItem = $("#"+id);
        
        if(lct_vars.currentSelectedSubItem == null || lct_vars.currentSelectedSubItem.attr("id") != id)
        {
            
            if(lct_vars.currentSelectedSubItem && lct_vars.currentSelectedSubItem.length != 0)
            {
                $("a:first", lct_vars.currentSelectedSubItem).removeClass("selected");
            }

            if(newSubItem)
            {
                lct_vars.currentSelectedSubItem = newSubItem;
                
                $("a:first", lct_vars.currentSelectedSubItem).addClass("selected");
            }
        }
    }
    else
    {
        $(".LCT_searchResults tr.selected").removeClass("selected");
        $("#lct_detaileItem_"+index).addClass("selected");
    }
}

//Selects the list item and the corresponding placemark on the map.
function selectResultListItem(index)
{
    location.href="#lct_map_top";
    setTimeout(function(){
        $.gMapViewerSelectPlacemark(index);
        $(".LCT_searchResults tr.selected").removeClass("selected");
        $("#lct_detaileItem_"+index).addClass("selected");
        },
        100);
    
}

//Selects the placemark on the map and the corresponding list item
function selectPlacemark(index)
{
    if(lct_vars.currentMarkerIndex && lct_vars.currentMarkerIndex != index)
    {
        $.gMapViewerHidePlacemark(lct_vars.currentMarkerIndex);
    }
    
    $.gMapViewerShowPlacemark(index);
    $.gMapViewerSelectPlacemark(index);
    selectSubItem(index);
    lct_vars.currentMarkerIndex = index;
    
    displayStoreInfo(index);
}

/** Scrolling functions **/
function scrollNext()
{
    scrollingList.first += scrollingList.scroll;  
    if(scrollingList.first > scrollingList.list.length)
    {
        scrollingList.first = scrollingList.list.length - scrollingList.scroll;
    }
 
    scrollingList.last = scrollingList.first + scrollingList.scroll;   
  
    for(var i=scrollingList.first; i < scrollingList.last && i<scrollingList.list.length; i++)
    {
        scrollingList.currentMargin -= $(scrollingList.list[i]).height();
        
        if(scrollingList.actualHeight + scrollingList.currentMargin <= scrollingList.maxHeight)
        {
            scrollingList.currentMargin = scrollingList.maxHeight - scrollingList.actualHeight;

            break;
        }
    }
    
    scrollList();
    return false;
}

function scrollPrev()
{
    scrollingList.first -= scrollingList.scroll;   
    if(scrollingList.first <= 0)
    {
        scrollingList.first = 0;
        scrollingList.currentMargin = 0;
        scrollingList.last = scrollingList.first + scrollingList.scroll;
    }
    else
    {
        scrollingList.last = scrollingList.first + scrollingList.scroll;

        for(var i=scrollingList.first; i < scrollingList.last && i<scrollingList.list.length; i++)
        {
            scrollingList.currentMargin += $(scrollingList.list[i]).height();
  
            if(scrollingList.currentMargin > 0)
            {
                scrollingList.currentMargin = 0;
                break;
            }
        }
    }
    
    scrollList();
    return false;
}

function scrollToItem(idx)
{
    scrollingList.first = idx;   
   
    if(scrollingList.first <= 0)
    {
        scrollingList.first = 0;
        scrollingList.currentMargin = 0;
    }
    else
    {
        for(var i=0; i < scrollingList.first && i<scrollingList.list.length; i++)
        {
            scrollingList.currentMargin -= $(scrollingList.list[i]).height();
        
            if(scrollingList.actualHeight + scrollingList.currentMargin <= scrollingList.maxHeight)
            {
                scrollingList.currentMargin = scrollingList.maxHeight - scrollingList.actualHeight
                break;
            }
        }
    }
    
    scrollList();
}

function scrollList()
{
    var selectedCatMenu = $("#placeCat_" + lct_vars.currentPlaceCatId);
    if(scrollingList.last >= scrollingList.list.length)
    {
        $(".listSlider-next span", selectedCatMenu).addClass("inactive");
    }
    else
    {
        $(".listSlider-next span", selectedCatMenu).removeClass("inactive");
    }
    
    if(scrollingList.first == 0)
    {
        $(".listSlider-prev span", selectedCatMenu).addClass("inactive");
    }
    else
    {
        $(".listSlider-prev span", selectedCatMenu).removeClass("inactive");
    }
    
    scrollingList.listContainer.animate({ marginTop:scrollingList.currentMargin+"px"},scrollingList.scrollSpeed);
}