﻿var categories = new Array();
var categoryItems = new Array();
var map;
var infowindow;
var urlParams = {};
var mapBounds = new google.maps.LatLngBounds(new google.maps.LatLng(40.2400059745, -111.671333), new google.maps.LatLng(40.269714, -111.631488741));
//var mercator;

function initialize() {
    var myLatlng = new google.maps.LatLng(40.249251, -111.649278);
    var myOptions = {
        zoom: 18,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.SATELLITE,
        mapTypeControlOptions: {
            mapTypeIds: ["byuMap", google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.TERRAIN]
        }
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    /*var byuOptions = {
        getTileUrl: function (a, zoom) {
            if (a.x > 12444 || a.x < 12440 || a.y > 24752 || a.y < 24747)
                return "http://map.byu.edu/byu/blank.jpg";
            else
                return "http://map.byu.edu/byu/Tile_" + a.x + "_" + a.y + "_16.jpg";
        },
        tileSize: new google.maps.Size(256, 256),
        isPng: true,
        name: 'BYU',
        maxZoom: 16,
        minZoom: 16
    };*/

    var byuOptions = {
        getTileUrl: function (a, zoom) {
		
			var ymax = 1 << zoom;
			
			var zFactor=Math.pow(2,zoom);
			
			var tileBounds = new google.maps.LatLngBounds(
			                  map.getProjection().fromPointToLatLng( new google.maps.Point( (a.x)*256/zFactor, (a.y+1)*256/zFactor ) ),
		                      map.getProjection().fromPointToLatLng( new google.maps.Point( (a.x+1)*256/zFactor, (a.y)*256/zFactor ) )
			             );
			
			var y = ymax - a.y -1;
			
			if (mapBounds.intersects(tileBounds)) {
                return "http://map.byu.edu/maptiles/" + zoom + "/" + a.x + "/" + y + ".png";
			}
			else
				return "http://map.byu.edu/maptiles/blank.png";
        },
        tileSize: new google.maps.Size(256, 256),
        isPng: true,
        name: 'Campus',
        maxZoom: 17,
        minZoom: 13
    };

	//mercator = new google.maps.MercatorProjection(17+1);
    var byuMapType = new google.maps.ImageMapType(byuOptions);

    map.mapTypes.set("byuMap", byuMapType);

    infowindow = new google.maps.InfoWindow();

    loadPushpinTypes();

    //changeOverflowForMobile();
    touchScroll('menu_body');

    $('#searchText').keyup(function (e) {
        var code = (e.keyCode ? e.keyCode : e.which);
        if (code == 13) { //Enter keycode
            $('#searchButton').trigger('click');
        }
    });

    $('#searchButton').click(function (e) {
        var search = $('#searchText');

        if (categoryItems['search'] != null) {
            $('#searchInfo').remove();
            for (var i in categoryItems['search'])
                categoryItems['search'][i].marker.setMap(null);
        }

        var html = '<div class="marker_category" id="searchInfo"><a href="#" class="marker_category_header rightBackground" id="category_search">Search Results</a><div id="category_icons_search" class="hidden"></div></div>';
        $("#menu_body_pushpinTypes").prepend(html);
        $("#category_search").click(showHidePushpinCategory);

        $.ajax({
            url: '/Services/ProxyRequest',
            data: ({ url: 'SearchMapJson?query=' + search.attr('value') }),
            success: searchLoaded,
            error: dataLoadError,
            dataType: 'json'
        });
    });

    var e,
            d = function (s) { return decodeURIComponent(s.replace(/\+/g, " ")); },
            q = window.location.search.substring(1),
            r = /([^&=]+)=?([^&]*)/g;

    while (e = r.exec(q))
        urlParams[d(e[1])] = d(e[2]);
}

function searchLoaded(data) {

    categoryItems['search'] = data.d.Buildings.concat(data.d.ParkingLots).concat(data.d.TourLocations).concat(data.d.Pushpins);

    var count = 0;

    for (var i in data.d.Buildings) {
        var color = categories[4].Color.substring(1);
        var myLatLng = new google.maps.LatLng(data.d.Buildings[i].Latitude, data.d.Buildings[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + data.d.Buildings[i].LegendKey + '|' + color + '|ffffff';
        categoryItems['search'][i].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d.Buildings[i]
        });

        google.maps.event.addListener(categoryItems['search'][i].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3>' + (this.pushpinInfo.ImageUrl != null ? '<img src="' + this.pushpinInfo.ImageUrl + '" alt="' + this.pushpinInfo.Acronym + '" />' : '') + this.pushpinInfo.Description + '</div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems['search'][i], 'search', image);
        count++;
    }

    for (var i in data.d.ParkingLots) {

        var points = data.d.ParkingLots[i].PolygonPoints.split(',');
        var paths = new Array();
        categoryItems['search'][count].Color = data.d.ParkingLots[i].ParkingLotType.Color;
        var color = '#' + categoryItems['search'][count].Color;

        var minLat = 1000;
        var maxLat = -1000;
        var minLong = 1000;
        var maxLong = -1000;

        for (var b = 0; b < (points.length - 1); b += 2) {
            paths.push(new google.maps.LatLng(points[b], points[b + 1]));

            if (points[b] > maxLat)
                maxLat = points[b];
            if (points[b] < minLat)
                minLat = points[b];
            if (points[b + 1] > maxLong)
                maxLong = points[b + 1];
            if (points[b + 1] < minLong)
                minLong = points[b + 1];
        }

        categoryItems['search'][count].marker = new google.maps.Polygon({
            paths: paths,
            map: map,
            fillColor: color,
            strokeColor: color,
            pushpinInfo: data.d.ParkingLots[i],
            clickable: data.d.ParkingLots[i].Name != null && data.d.ParkingLots[i].Name != ""
        });

        categoryItems['search'][count].marker.centerLatLng = new google.maps.LatLng((Number(maxLat) + Number(minLat)) / 2, (Number(maxLong) + Number(minLong)) / 2);

        if (data.d.ParkingLots[i].Name != null && data.d.ParkingLots[i].Name != "") {
            google.maps.event.addListener(categoryItems['search'][count].marker, 'click', function () {
                infowindow.content = '<div class="bubble">' + (this.pushpinInfo.Name != null ? '<h3>' + this.pushpinInfo.Name + '</h3>' : '') + (this.pushpinInfo.Description != null ? this.pushpinInfo.Description : '') + '</div>';
                infowindow.setPosition(this.centerLatLng);
                infowindow.open(map);
            });
        }

        addMapCategoryToMenu(categoryItems['search'][count], 'search');


        count++;
    }

    for (var i in data.d.TourLocations) {

        var color = categories[5].Color.substring(1);
        var myLatLng = new google.maps.LatLng(data.d.TourLocations[i].Latitude, data.d.TourLocations[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + (Number(i) + 1) + '|' + color + '|ffffff';
        categoryItems['search'][count].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d.TourLocations[i]
        });

        google.maps.event.addListener(categoryItems['search'][count].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3><p><a href="http://map.byu.edu/Enhanced#TourLocation=' + this.pushpinInfo.ID + '">See tour.</a></p><p class="disclaimer">(Requires <a href="http://www.microsoft.com/getsilverlight/">Microsoft Silverlight</a>.)</p></div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems['search'][i], 'search', image);
        count++;
    }

    for (var i in data.d.Pushpins) {
        var color = categories[data.d.Pushpins[i].TypeID].Color.substring(1);
        var myLatLng = new google.maps.LatLng(data.d.Pushpins[i].Latitude, data.d.Pushpins[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + (Number(i) + 1) + '|' + color + '|ffffff';
        categoryItems['search'][count].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d.Pushpins[i]
        });

        google.maps.event.addListener(categoryItems['search'][count].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3>' + (this.pushpinInfo.ImageUrl != null ? '<img src="' + this.pushpinInfo.ImageUrl + '" alt="' + this.pushpinInfo.Acronym + '" />' : '') + this.pushpinInfo.Description + '</div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems['search'][i], 'search', image);
        count++;
    }

    if (count == 0) {
        $("#category_search").append("<p>No results</p>");
    }

    $("#category_search").trigger('click');
}

function loadPushpinTypes() {
    $.ajax({
        url: '/Services/ProxyRequest',
        dataType: 'json',
        data: { "url": "GetPushpinTypes" },
        success: function (data) {
            for (var i in data.d) {
                categories[data.d[i].ID] = data.d[i];
                var obj = data.d[i];
                var html = '<div class="marker_category"><a href="#" class="marker_category_header rightBackground" id="category_' + obj.ID + '">' + obj.Name + '</a><div id="category_icons_' + obj.ID + '" class="hidden">' + obj.Description + '</div></div>';
                $("#menu_body_pushpinTypes").append(html);
                $("#category_" + obj.ID).click(showHidePushpinCategory);
            }

            if (urlParams['building'] != undefined) {
                $("#category_4").trigger('click');
            }
            if (urlParams['parking'] != undefined) {
                $("#category_6").trigger('click');
            }
        }
    });
}

function addPushpinToMenu(obj, typeID, image) {
    var div = $('#category_icons_' + typeID);
    var name = obj.Name;

    if (obj.Acronym != undefined && obj.Acronym != null && obj.Acronym != "")
        name += ' (' + obj.Acronym + ')';

    var newDiv = $('<div class="pushpinKey"><img src="' + image + '" alt="' + obj.Name + '" /><div><h3>' + name + '</h3></div></div><div style="clear:both;height:0;"></div>');
    div.append(newDiv);
    newDiv.click(function () {
        google.maps.event.trigger(obj.marker, 'click');
    });
}

function addMapCategoryToMenu(obj, typeID) {
    var div = $('#category_icons_' + typeID);
    var newDiv = $('<div class="pushpinKey noclick"><div style="background-color:' + obj.Color + ';width:26px;height:20px;float:left;clear:left;margin:0;"></div><div><h3>' + obj.Name + '</h3></div></div><div style="clear:both;height:0;"></div>');
    div.append(newDiv);
}

function showHidePushpinCategory() {
    var obj = $(this);
    var id = obj.attr('id').substring(9);
    infowindow.close();

    obj.siblings('.hidden').toggle();
    if (obj.hasClass('rightBackground')) {
        obj.removeClass('rightBackground');
        obj.addClass('downBackground');

        for (var i in categoryItems[id]) {
            if (categoryItems[id][i].Color != undefined && categoryItems[id][i].marker != undefined) {
                categoryItems[id][i].marker.setMap(map);
            }
            else if (categoryItems[id][i].ParkingLots == undefined) {
                categoryItems[id][i].marker.setVisible(true);
            }
            else {
                for (var a in categoryItems[id][i].ParkingLots) {
                    categoryItems[id][i].ParkingLots[a].marker.setMap(map);
                }
            }
        }
    }
    else {
        obj.removeClass('downBackground');
        obj.addClass('rightBackground');

        for (var i in categoryItems[id]) {
            if (categoryItems[id][i].Color != undefined && categoryItems[id][i].marker != undefined) {
                categoryItems[id][i].marker.setMap(null);
            }
            else if (categoryItems[id][i].ParkingLots == undefined) {
                categoryItems[id][i].marker.setVisible(false);
            }
            else {
                for (var a in categoryItems[6][i].ParkingLots) {
                    categoryItems[id][i].ParkingLots[a].marker.setMap(null);
                }
            }
        }
    }

    requestPushpins(obj.attr('id').substring(9));
    return false;
}

function requestPushpins(categoryId) {

    if (categoryItems[categoryId] == undefined && categoryId != "search") {
        if (categoryId == 4) {
            $.ajax({
                url: '/Services/ProxyRequest',
                data: ({ url: 'GetBuildings' }),
                success: buildingsLoaded,
                error: dataLoadError,
                dataType: 'json'
            });
        }
        else if (categoryId == 5) {
            $.ajax({
                url: '/Services/ProxyRequest',
                data: ({ url: 'GetTourLocations' }),
                success: toursLoaded,
                error: dataLoadError,
                dataType: 'json'
            });
        }
        else if (categoryId == 6) {
            $.ajax({
                url: '/Services/ProxyRequest',
                data: ({ url: 'GetParkingLotTypesJson' }),
                success: parkingLotsLoaded,
                error: dataLoadError,
                dataType: 'json'
            });
        }
        else {
            $.ajax({
                url: '/Services/ProxyRequest',
                data: ({ url: 'GetPushpins?pushpinTypeId=' + categoryId }),
                success: pushpinsLoaded,
                error: dataLoadError,
                dataType: 'json'
            });
        }
    }

}

function dataLoadError() {
    alert('Unable to load data');
}

function buildingsLoaded(data) {
    categoryItems[4] = data.d;
    var color = categories[4].Color.substring(1);

    var acronym = urlParams['building'];

    for (var i in data.d) {
        var myLatLng = new google.maps.LatLng(data.d[i].Latitude, data.d[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + data.d[i].LegendKey + '|' + color + '|ffffff';
        //var marker =
        categoryItems[4][i].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d[i]
        });

        google.maps.event.addListener(categoryItems[4][i].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3>' + (this.pushpinInfo.ImageUrl != null ? '<img src="' + this.pushpinInfo.ImageUrl + '" alt="' + this.pushpinInfo.Acronym + '" />' : '') + this.pushpinInfo.Description + '</div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems[4][i], 4, image);

        if (acronym != undefined && acronym.toLowerCase() == categoryItems[4][i].Acronym.toLowerCase())
            google.maps.event.trigger(categoryItems[4][i].marker, 'click');
    }
}

function toursLoaded(data) {
    categoryItems[5] = data.d;
    var color = categories[5].Color.substring(1);
    for (var i in data.d) {
        var myLatLng = new google.maps.LatLng(data.d[i].Latitude, data.d[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + (Number(i) + 1) + '|' + color + '|ffffff';
        categoryItems[5][i].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d[i]
        });

        google.maps.event.addListener(categoryItems[5][i].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3><p><a href="http://map.byu.edu/Enhanced#TourLocation=' + this.pushpinInfo.ID + '">See tour.</a></p><p class="disclaimer">(Requires <a href="http://www.microsoft.com/getsilverlight/">Microsoft Silverlight</a>.)</p></div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems[5][i], 5, image);
    }
}

function parkingLotsLoaded(data) {
    categoryItems[6] = data.d;
    for (var i in data.d) {
        for (var a in data.d[i].ParkingLots) {

            var points = data.d[i].ParkingLots[a].PolygonPoints.split(',');
            var paths = new Array();
            var color = data.d[i].Color;

            var minLat = 1000;
            var maxLat = -1000;
            var minLong = 1000;
            var maxLong = -1000;

            for (var b = 0; b < (points.length - 1); b += 2) {
                paths.push(new google.maps.LatLng(points[b], points[b + 1]));

                if (points[b] > maxLat)
                    maxLat = points[b];
                if (points[b] < minLat)
                    minLat = points[b];
                if (points[b + 1] > maxLong)
                    maxLong = points[b + 1];
                if (points[b + 1] < minLong)
                    minLong = points[b + 1];
            }

            categoryItems[6][i].ParkingLots[a].marker = new google.maps.Polygon({
                paths: paths,
                map: map,
                fillColor: color,
                strokeColor: color,
                pushpinInfo: data.d[i].ParkingLots[a],
                clickable: data.d[i].ParkingLots[a].Name != null && data.d[i].ParkingLots[a].Name != ""
            });

            categoryItems[6][i].ParkingLots[a].marker.centerLatLng = new google.maps.LatLng((Number(maxLat) + Number(minLat)) / 2, (Number(maxLong) + Number(minLong)) / 2);

            if (data.d[i].ParkingLots[a].Name != null && data.d[i].ParkingLots[a].Name != "") {
                google.maps.event.addListener(categoryItems[6][i].ParkingLots[a].marker, 'click', function () {
                    infowindow.content = '<div class="bubble">' + (this.pushpinInfo.Name != null ? '<h3>' + this.pushpinInfo.Name + '</h3>' : '') + (this.pushpinInfo.Description != null ? this.pushpinInfo.Description : '') + '</div>';
                    infowindow.setPosition(this.centerLatLng);
                    infowindow.open(map);
                });
            }
        }

        addMapCategoryToMenu(data.d[i], 6);
    }
}

function pushpinsLoaded(data) {
    categoryItems[data.d[0].TypeID] = data.d;
    var color = categories[data.d[0].TypeID].Color.substring(1);
    for (var i in data.d) {
        var myLatLng = new google.maps.LatLng(data.d[i].Latitude, data.d[i].Longitude);
        var image = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + (Number(i) + 1) + '|' + color + '|ffffff';
        categoryItems[data.d[0].TypeID][i].marker = new google.maps.Marker({
            position: myLatLng,
            map: map,
            icon: image,
            pushpinInfo: data.d[i]
        });

        google.maps.event.addListener(categoryItems[data.d[0].TypeID][i].marker, 'click', function () {
            infowindow.content = '<div class="bubble"><h3>' + this.pushpinInfo.Name + '</h3>' + (this.pushpinInfo.ImageUrl != null ? '<img src="' + this.pushpinInfo.ImageUrl + '" alt="' + this.pushpinInfo.Name + '" />' : '') + this.pushpinInfo.Description + '</div>';
            infowindow.open(map, this);
        });

        addPushpinToMenu(categoryItems[data.d[i].TypeID][i], data.d[i].TypeID, image);
    }
}

function isTouchDevice() {
	try {
		document.createEvent("TouchEvent");
		return true;
	}
	catch(e) {
		return false;
	}
}

function touchScroll(id){
	if(isTouchDevice()){ //if touch events exist...
		var el=document.getElementById(id);
		var scrollStartPos=0;

		document.getElementById(id).addEventListener("touchstart", function(event) {
			scrollStartPos=this.scrollTop+event.touches[0].pageY;
			//event.preventDefault();
		},false);

		document.getElementById(id).addEventListener("touchmove", function(event) {
			this.scrollTop=scrollStartPos-event.touches[0].pageY;
			event.preventDefault();
		},false);

		document.getElementById(id).addEventListener("touchend", function(event) {
			event.allowDefault();
		},false);
	}
}

