﻿<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
    <script src="../ClientGlobalContext.js.aspx"></script>
    <script type="text/javascript" src="Context.js"></script>
    <script type="text/javascript" src="RestRequest.js"></script>
    <script type="text/javascript">
        function twoDigits(num) {
            return num >= 10 ? num.toString() : ('0' + num);
        }

        function getDateString(date) {
            return date.getFullYear() + '-' + twoDigits(date.getMonth() + 1) + '-' + twoDigits(date.getDate());
        }

        function getTimeFilter(filterIndex) {
            var filter = "";
            var now = new Date();
            var from = null;
            var to = null;
            var oneDayMilisec = 86400000;
            switch (filterIndex) {
                // Last month:       
                case 1:
                    to = now.getFullYear() + '-' + twoDigits(now.getMonth() + 1) + '-01';
                    now = new Date(now.getTime() - now.getDate() * oneDayMilisec);
                    from = now.getFullYear() + '-' + twoDigits(now.getMonth() + 1) + '-01';
                    break;
                // Last week:        
                case 2:
                    now = new Date(now.getTime() - now.getDay() * oneDayMilisec);
                    to = getDateString(now);
                    from = getDateString(new Date(now.getTime() - 7 * oneDayMilisec));
                    break;
                // This month:        
                case 3:
                    from = now.getFullYear() + '-' + twoDigits(now.getMonth() + 1) + '-01';
                    break;
                // This week:       
                case 4:
                    from = getDateString(new Date(now.getTime() - now.getDay() * oneDayMilisec));
                    break;
                // Today:         
                case 5:
                    from = getDateString(now);
                    to = getDateString(new Date(now.getTime() + oneDayMilisec));
                    break;
                // Yesterday:       
                case 6:
                    to = getDateString(now);
                    from = getDateString(new Date(now.getTime() - oneDayMilisec));
                    break;
            }
            if (from != null)
                filter += " and resco_loggedon ge " + from;
            if (to != null)
                filter += " and resco_loggedon lt " + to;
            return filter;
        }

        function loadUsers(query) {
        	if (!query) {
				query = "?$select=systemuserid,fullname&$orderby=fullname&$filter=isdisabled eq false";
        		resco_map_user_filter.add(new Option("All Users", -1));
			}

            window.Resco.DataProvider.query("systemusers", query, function (jsonData) {
            	var data = JSON.parse(jsonData);
            	var results = (data && data.value) ? data.value : [];

            	for (var i in results) {
            		var user = results[i];
            		var option = new Option(user.fullname, i);
            		option.userID = user.systemuserid;
            		resco_map_user_filter.add(option);
            	}
				if (data && data["@odata.nextLink"]) {
					var nextUrl = decodeURI(data["@odata.nextLink"]);
            		loadUsers(nextUrl.substr(nextUrl.indexOf('?')));
				}
            	else
            		onUserChanged();

            }, function (err) { Xrm.Utility.alertDialog(err); });
        }

        function getEntityOppText(opp) {
            if (typeof opp.Value == "undefined" || opp.Value < 473220000)
                return "";
            var value = opp.Value - 473220000;
            var texts = ["Created", "Read", "Updated", "Deleted", "Synchronized", "StartEdit", "EndEdit", "AppStarted", "AppStopped", "AppPaused", "AppResumed", "GpsChanged", "GeoFenceEnter", "GeoFenceExit"];
            return texts[value];
        }

        function initEntityFilter(entityList) {
            resco_map_entity_filter.add(new Option("All Entities", 0));
            for (var i in entityList) {
                var option = new Option(entityList[i], i + 1);
                resco_map_entity_filter.add(option);
            }
        }

        function initDeviceFilter(devices) {
        	window.Resco.deviceList = window.Resco.deviceList || {};
			resco_map_device_filter.add(new Option("All Devices", 0));
        	var i = 1;
        	for (var devId in devices) {
        		var option = new Option(devId, i++);
        		option.className = devId;
        		resco_map_device_filter.add(option);

        		if (window.Resco.deviceList[devId])
        			option.text = window.Resco.deviceList[devId];
        		if (window.Resco.deviceList[devId] == undefined) {
        			window.Resco.deviceList[devId] = null;
        			var query = "?$select=resco_deviceid,resco_devicename&$filter=resco_deviceid eq '" + devId + "'";
        			window.Resco.DataProvider.query("resco_mobiledevices", query, function (jsonData) {
        				var data = JSON.parse(jsonData);
        				var results = (data && data.value) ? data.value : [];
        				if (results.length > 0) {
        					var mobileDevice = results[0];
        					window.Resco.deviceList[mobileDevice.resco_deviceid] = mobileDevice.resco_devicename;
        				}
        				else
        					window.Resco.deviceList[devId] = devId;
        				refreshDeviceList();
        			}, function (err) { Xrm.Utility.alertDialog(err); });
        		}
        	}
        }

        function refreshDeviceList() {
        	var options = resco_map_device_filter.options;
        	var len = options.length;
        	for (var i = 1; i < len; i++) {
        		var option = options[i];
        		if (option) {
        			var devId = option.className;
        			var devName = window.Resco.deviceList[devId];
        			if (devName)
        				option.text = devName + ": " + (devId.length > 10 ? (devId.substr(0, 10) + '...') : devId);
        		}
        	}
        }

        function processData(jsonData, newGroups, entityTypes, devices, finishCallback) {
        	var data = JSON.parse(jsonData);
        	var groups = [];
        	var results = (data && data.value) ? data.value : [];
        	for (var i in results) {
        		var entity = results[i];
        		if (entity.resco_latitude && entity.resco_longitude) {
        			var groupName = 'P' + entity.resco_latitude + '_' + entity.resco_longitude;
        			if (groups[groupName])
        				groups[groupName].push(entity);
        			else
        				groups[groupName] = [entity];
        			entityTypes[entity.resco_entityname] = true;
        			devices[entity.resco_deviceid] = "";
        		}
        	}

        	for (var groupName in groups) {
        		var group = groups[groupName];
        		var firstEntity = group[0];
        		var entities = [];
        		for (var j in group) {
        			var entity = group[j];
        			entities.push({
        				entityName: entity.resco_entityname,
        				entityId: entity.resco_entityid,
        				operation: getEntityOppText(entity.resco_operation),
        				loggedOn: entity.resco_loggedon,
        				deviceId: entity.resco_deviceid
        			});
        		}
        		newGroups.push({
        			latitude: firstEntity.resco_latitude,
        			longitude: firstEntity.resco_longitude,
        			entities: entities
        		});
        	}
        	groups = null;

        	if (data && data["@odata.nextLink"]) {
        		var nextUrl = decodeURI(data["@odata.nextLink"]);
        		var iParams = nextUrl.indexOf('?');
        		var query = nextUrl.substr(iParams);
        		window.Resco.DataProvider.query("resco_mobileaudits", query,
					function (res) {
						processData(res, newGroups, entityTypes, devices, finishCallback);
					},
					function (err) { Xrm.Utility.alertDialog(err); }
				);
        		return;
        	}
        	finishCallback();
        }

        function onDataReady(jsonData) {
        	var entityTypes = {};
        	var devices = {};
        	var groups = [];

        	processData(jsonData, groups, entityTypes, devices, function () {
        		var entityFilter = document.getElementById('resco_map_entity_filter');
        		if (entityFilter && entityFilter.length == 0) {
        			var entities = [];
        			for (var type in entityTypes)
        				entities.push(type);
        			var explicitOrder = { applicationstate: 1, gps_tracking: 2, synchronization: 3 };
        			entities.sort(function (e1, e2) {
        				if (e1 == e2) return 0;
        				var explSort1 = explicitOrder[e1];
        				var explSort2 = explicitOrder[e2];
        				if (explSort1 || explSort2) {
        					if (!explSort1) explSort1 = 1000;
        					if (!explSort2) explSort2 = 1000;
        					return explSort1 - explSort2;
        				}
        				return e1 < e2 ? -1 : 1;
        			});
        			initEntityFilter(entities);
        			initDeviceFilter(devices);
        		}
        		window.Resco.MapLoader.initializeMap('map_canvas', groups);
        	});
        }

        function refreshData() {
        	var id = "";
        	var typename = "";
        	var params = window.location.search.substring(1).split('&');
        	for (var i = 0; i < params.length; i++) {
        		var p = params[i];
        		if (p.substring(0, 3) == 'id=')
        			id = p.substring(3).replace(/%7[bBdD]/g, '');
        		else if (p.substring(0, 9) == 'typename=')
        			typename = p.substring(9);
        	}
        	var query = "";
        	switch (typename) {
        		case "resco_mobileaudit":
        			resco_map_filter_body.innerHTML = '';
        			query = "(" + id + ")?$select=resco_entityid,resco_entityname,resco_operation,resco_deviceid,resco_latitude,resco_longitude,resco_loggedon";
        			break;
        		case "systemuser":
        			resco_map_user_selector.innerHTML = '';
        			query = "?$select=resco_entityid,resco_entityname,resco_operation,resco_deviceid,resco_latitude,resco_longitude,resco_loggedon&" +
							"$orderby=resco_loggedon desc&" +
							"$filter=resco_latitude ne null and resco_longitude ne null and _createdby_value eq '" + id + "'" + getTimeFilter(resco_map_time_filter.selectedIndex);
        			if (resco_map_entity_filter.selectedIndex > 0) {
        				filterEntity = resco_map_entity_filter.options[resco_map_entity_filter.selectedIndex].text;
        				query += " and resco_entityname eq '" + filterEntity + "'";
        			}
        			if (resco_map_device_filter.selectedIndex > 0) {
        				filterDevice = resco_map_device_filter.options[resco_map_device_filter.selectedIndex].className;
        				query += " and resco_deviceid eq '" + filterDevice + "'";
        			}
        			break;
        		default:
        			var filterEntity = null;
        			var filterId = id;
        			if (typename != "") {
        				resco_map_entity_selector.innerHTML = '';
        				filterEntity = typename;
        				if (id.length > 0)
        					filterId = id;
        			}
        			else if (resco_map_entity_filter.selectedIndex > 0) {
        				filterEntity = resco_map_entity_filter.options[resco_map_entity_filter.selectedIndex].text;
        			}

        			if (resco_map_user_filter.options.length == 0) {
        				loadUsers();
        				return;
        			}
        			else {
        				var selIndex = resco_map_user_filter.selectedIndex;
        				if (selIndex >= 0) {
        					var selOption = resco_map_user_filter.options[selIndex];
        					query = "?$select=resco_entityid,resco_entityname,resco_operation,resco_deviceid,resco_latitude,resco_longitude,resco_loggedon&" +
									"$orderby=resco_loggedon desc&" +
									"$filter=resco_latitude ne null and resco_longitude ne null";
        					if (selOption.userID)
        						query += " and _createdby_value eq '" + selOption.userID + "'";
							query += getTimeFilter(resco_map_time_filter.selectedIndex);

        					if (resco_map_device_filter.selectedIndex > 0) {
        						filterDevice = resco_map_device_filter.options[resco_map_device_filter.selectedIndex].className;
        						query += " and resco_deviceid eq '" + filterDevice + "'";
        					}

        					if (filterEntity)
        						query += " and resco_entityname eq '" + filterEntity + "'";
        					if (filterId)
        						query += " and resco_entityid eq '" + filterId + "'";
        				}
        				else
        					return;
        			}
        			break;
        	}
        	window.Resco.DataProvider.query("resco_mobileaudits", query, onDataReady, function (err) { Xrm.Utility.alertDialog(err); });
        }

        function cleanEntityFilter() {
			var filter = document.getElementById('resco_map_entity_filter');
        	if (filter) {
        		for (var i = filter.length - 1; i >= 0; i--)
        			filter.remove(i);
        	}
        }

        function cleanDeviceFilter() {
			var filter = document.getElementById('resco_map_device_filter');
        	if (filter) {
        		for (var i = filter.length - 1; i >= 0; i--)
        			filter.remove(i);
        	}
        }

        function onUserChanged() {
        	cleanEntityFilter();
			cleanDeviceFilter();
        	refreshData();
        }

        function onTimeFilterChanged() {
        	cleanEntityFilter();
			cleanDeviceFilter();
        	refreshData();
        }

        function onEntityChanged() {
        	refreshData();
        }

        function onDeviceChanged() {
        	refreshData();
        }

        function onGoogleMapsLoaded() {
        	refreshData();
        }
    </script>
	<script type="text/javascript" src="GoogleMapsLoader.js"></script>
	<style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map_canvas {
        height: 100%;
      }

	</style>
</head>
<body>
    <p id='resco_map_filter_body' style="margin: 8px; font-family: Calibri; font-size: 12px">
        <span id='resco_map_time_selector'>Mobile Auditing:&nbsp;
            <select id="resco_map_time_filter" onchange="onTimeFilterChanged()" style="border: 0px; font-family: Calibri; font-size: 12px; margin: -3px">
                <option>All Events</option>
                <option>Last Month's Events</option>
                <option>Last Week's Events</option>
                <option>This Month's Events</option>
                <option selected="selected">This Week's Events</option>
                <option>Today's Events</option>
                <option>Yesterday's Events</option>
            </select>
        </span>
		<span id='resco_map_user_selector'>&nbsp;User:&nbsp;
            <select id="resco_map_user_filter" onchange="onUserChanged()" style="border: 0px; font-family: Calibri; font-size: 12px; margin: -3px"></select>
        </span>
		<span id='resco_map_entity_selector'>&nbsp;Entity:&nbsp;
            <select id="resco_map_entity_filter" onchange="onEntityChanged()" style="border: 0px; font-family: Calibri; font-size: 12px; margin: -3px">
            </select>
        </span>
		<span id='resco_map_device_selector'>&nbsp;Device:&nbsp;
            <select id="resco_map_device_filter" onchange="onDeviceChanged()" style="border: 0px; font-family: Calibri; font-size: 12px; margin: -3px">
            </select>
        </span>
    </p>
	<div id="map_canvas">
	</div>
</body>
</html>
