/* * Copyright (c) 2011 Metropolitan Transportation Authority * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var OBA = window.OBA || {}; // do not add constructor params here! OBA.Popups = (function() { var infoWindow = null; var refreshPopupRequest = null; var stopBubbleListener = null, stopBubbleTrigger = null; function closeInfoWindow() { if(infoWindow !== null) { infoWindow.close(); } infoWindow = null; } // PUBLIC METHODS function showPopupWithContent(map, marker, content) { closeInfoWindow(); infoWindow = new google.maps.InfoWindow({ pixelOffset: new google.maps.Size(0, (marker.getIcon().size.height / 2)), disableAutoPan: false }); google.maps.event.addListener(infoWindow, "closeclick", closeInfoWindow); infoWindow.setContent(content); infoWindow.open(map, marker); } function showPopupWithContentFromRequest(map, marker, url, params, contentFn, routeFilter) { closeInfoWindow(); infoWindow = new google.maps.InfoWindow({ pixelOffset: new google.maps.Size(0, (marker.getIcon().size.height / 2)), disableAutoPan: false, stopId: marker.stopId // to lock an icon on the map when a popup is open for it }); google.maps.event.addListener(infoWindow, "closeclick", closeInfoWindow); var popupContainerId = "container" + Math.floor(Math.random() * 1000000); var refreshFn = function(openBubble) { // pass a new "now" time for debugging if we're given one if(OBA.Config.time !== null) { params.time = OBA.Config.time; } if( typeof refreshPopupRequest !== 'undefined' && refreshPopupRequest !== null) { if ('abort' in refreshPopupRequest) { refreshPopupRequest.abort(); } openBubble = true; } refreshPopupRequest = jQuery.getJSON(url, params, function(json) { if(infoWindow === null) { return; } var preload_content = jQuery("#" + popupContainerId); var scroll = preload_content.scrollTop(); infoWindow.setContent(contentFn(json, popupContainerId, marker, routeFilter)); if(openBubble === true) { infoWindow.open(map, marker); } // hack to prevent scrollbars in the IEs var sizeChanged = false; var content = jQuery("#" + popupContainerId); if(content.height() > 300) { content.css("overflow-y", "scroll") .css("height", "280"); sizeChanged = true; } if(content.width() > 500) { content.css("overflow-x", "hidden") .css("width", "480"); sizeChanged = true; } if(sizeChanged) { infoWindow.setContent(content.get(0)); infoWindow.open(map, marker); } content.scrollTop(scroll); }); }; refreshFn(true); infoWindow.refreshFn = refreshFn; var updateTimestamp = function() { var timestampContainer = jQuery("#" + popupContainerId).find(".updated"); if(timestampContainer.length === 0) { return; } var age = parseInt(timestampContainer.attr("age"), 10); var referenceEpoch = parseInt(timestampContainer.attr("referenceEpoch"), 10); var newAge = age + ((new Date().getTime() - referenceEpoch) / 1000); timestampContainer.text("Data updated " + OBA.Util.displayTime(newAge)); }; updateTimestamp(); infoWindow.updateTimestamp = updateTimestamp; } // CONTENT GENERATION // this method is no longer used.... function getServiceAlerts(r, situationRefs) { var html = ''; var situationIds = {}; var situationRefsCount = 0; if (situationRefs != null) { jQuery.each(situationRefs, function(_, situation) { situationIds[situation.SituationSimpleRef] = true; situationRefsCount += 1; }); } if (situationRefs == null || situationRefsCount > 0) { if (r.Siri.ServiceDelivery.SituationExchangeDelivery != null && r.Siri.ServiceDelivery.SituationExchangeDelivery.length > 0) { jQuery.each(r.Siri.ServiceDelivery.SituationExchangeDelivery[0].Situations.PtSituationElement, function(_, ptSituationElement) { var situationId = ptSituationElement.SituationNumber; if (ptSituationElement.Description && (situationRefs == null || situationIds[situationId] === true)) { html += '
  • ' + ptSituationElement.Description.replace(/\n/g, "
    ") + '
  • '; } }); } } if (html !== '') { html = '

    Service Change:

    '; } return html; } function processAlertData(situationExchangeDelivery) { var alertData = {}; if (situationExchangeDelivery && situationExchangeDelivery.length > 0) { jQuery.each(situationExchangeDelivery[0].Situations.PtSituationElement, function(_, ptSituationElement) { if (ptSituationElement.Affects.hasOwnProperty('VehicleJourneys')) { jQuery.each(ptSituationElement.Affects.VehicleJourneys.AffectedVehicleJourney, function(_, affectedVehicleJourney) { var lineRef = affectedVehicleJourney.LineRef; if (!(lineRef in alertData)) { alertData[lineRef] = {}; } if (!(ptSituationElement.SituationNumber in alertData[lineRef])) { alertData[lineRef][ptSituationElement.SituationNumber] = ptSituationElement; } }); } // a stop can have BOTH route and stop level service alerts if (ptSituationElement.Affects.hasOwnProperty('StopPoints')) { jQuery.each(ptSituationElement.Affects.StopPoints.AffectedStopPoint, function(_, affectedStopPoint) { var stopPointRef = affectedStopPoint.StopPointRef; if (!(stopPointRef in alertData)) { alertData[stopPointRef] = {}; } if (!(ptSituationElement.SituationNumber in alertData[stopPointRef])) { alertData[stopPointRef][ptSituationElement.SituationNumber] = ptSituationElement; } }); } else { return true; } }); } return alertData; } function activateAlertLinks(content) { var alertLinks = content.find(".alert-link"); jQuery.each(alertLinks, function(_, alertLink) { var element = jQuery(alertLink); var idParts = element.attr("id").split("|"); var stopId = idParts[1]; var routeId = idParts[2]; var routeShortName = idParts[3]; element.on("click", function(e) { e.preventDefault(); var alertElement = jQuery('#alerts-' + routeId.hashCode()); if (alertElement.length === 0) { expandAlerts = true; jQuery.history.load(stopId + " " + routeShortName); } else { $("#searchbar").animate({ scrollTop: alertElement.parent().offset().top - jQuery("#searchbar").offset().top + jQuery("#searchbar").scrollTop() }, 500, function() { if (alertElement.accordion("option", "active") !== 0) { alertElement.accordion("option", "active" , 0); } else { alertElement.animate( { opacity : 0 }, 100, function() { alertElement.animate({ opacity : 1 }, 500, "swing"); } ); } }); } }); }); } function getVehicleContentForResponse(r, popupContainerId, marker) { var alertData = processAlertData(r.Siri.ServiceDelivery.SituationExchangeDelivery); var activity = r.Siri.ServiceDelivery.VehicleMonitoringDelivery[0].VehicleActivity[0]; if (activity === null || typeof activity == 'undefined' || activity.MonitoredVehicleJourney === null) { return null; } var vehicleId = activity.MonitoredVehicleJourney.VehicleRef; var vehicleIdParts = vehicleId.split("_"); var blockId = activity.MonitoredVehicleJourney.BlockRef; var vehicleIdWithoutAgency = vehicleIdParts[1]; var blockIdWithoutAgency = blockId.substring(blockId.indexOf("_")+1); // accept multiple "_" chars var routeName = activity.MonitoredVehicleJourney.LineRef; var hasRealtime = activity.MonitoredVehicleJourney.Monitored var html = ''; var content = jQuery(html); var zoomHereLink = content.find("#zoomHere"); zoomHereLink.on("click", function(e) { e.preventDefault(); var map = marker.map; map.setCenter(marker.getPosition()); map.setZoom(16); }); activateAlertLinks(content); return content.get(0); } function getOccupancyApcModeOccupancy(MonitoredVehicleJourney, addDashedLine){ if(MonitoredVehicleJourney.Occupancy === undefined) return ''; var occupancyLoad = ""; //console.log('occupancy: '+ MonitoredVehicleJourney.Occupancy); var stylePrefix = "apcDot"; if (OBA.Config.apcIcons == "false") { stylePrefix = "weeble"; } if(MonitoredVehicleJourney.Occupancy == "seatsAvailable") { var occupancyText = lookupOccupancy("seatsAvailable"); var occupancyClass = stylePrefix + "G"; if (OBA.Config.apcIcons != "false") { occupancyLoad = '' + '' + occupancyText + ''; if (addDashedLine == true) { occupancyLoad += '
    '; } } else { occupancyLoad = ''; } } else if(MonitoredVehicleJourney.Occupancy == "standingAvailable"){ var occupancyText = lookupOccupancy("standingAvailable"); var occupancyClass = stylePrefix + "Y"; if (OBA.Config.apcIcons != "false") { occupancyLoad = '' + '' + lookupOccupancy("standingAvailable") + ''; if (addDashedLine == true) { occupancyLoad += '
    '; } } else { occupancyLoad = ''; } } else if(MonitoredVehicleJourney.Occupancy == "full"){ var occupancyText = lookupOccupancy("full"); var occupancyClass = stylePrefix + "R"; if (OBA.Config.apcIcons != "false") { occupancyLoad = '' + '' + lookupOccupancy("full") + ''; if (addDashedLine == true) { occupancyLoad += '
    '; } } else { occupancyLoad = ''; } } return occupancyLoad; } function lookupOccupancy(siriValue) { return OBA.Config["occupancy_" + siriValue]; } function getOccupancy(MonitoredVehicleJourney, addDashedLine){ return getOccupancyApcModeOccupancy(MonitoredVehicleJourney, addDashedLine); } function isOriginTerminal(MonitoredVehicleJourney) { if (MonitoredVehicleJourney.OriginRef !== 'undefined') { var origin = MonitoredVehicleJourney.OriginRef; if (MonitoredVehicleJourney.MonitoredCall !== 'undefined') { var currentStop = MonitoredVehicleJourney.MonitoredCall.StopPointRef; if (origin === currentStop) { return true; } } } return false; } function getOccupancyForBus(MonitoredVehicleJourney){ var occupancyLoad = getOccupancy(MonitoredVehicleJourney, true); if (occupancyLoad == '') return ''; else return '

    Occupancy: '+occupancyLoad+'

    '; } function getOccupancyForStop(MonitoredVehicleJourney){ var occupancyLoad = getOccupancy(MonitoredVehicleJourney, false); if (occupancyLoad == '') return ''; else return occupancyLoad; } function getStopContentForResponse(r, popupContainerId, marker, routeFilter) { var siri = r.siri; var stopResult = r.stop; var alertData = processAlertData(r.siri.Siri.ServiceDelivery.SituationExchangeDelivery); var html = ''; var content = jQuery(html); var zoomHereLink = content.find("#zoomHere"); zoomHereLink.on("click", function(e) { e.preventDefault(); var map = marker.map; map.setCenter(marker.getPosition()); map.setZoom(16); }); var popupServiceAlertContainer = content.find(".popupServiceAlertContainer:first"); popupServiceAlertContainer.accordion({ header: 'p.popupServiceAlert', collapsible: true, active: false, autoHeight: false, heightStyle: "content" }); marker.setVisible(true); activateAlertLinks(content); (stopBubbleListener !== null)? stopBubbleListener.triggerHandler(stopBubbleTrigger) : null; return content.get(0); } function registerStopBubbleListener(obj, trigger) { stopBubbleListener = obj; stopBubbleTrigger = trigger; return stopBubbleListener; } function unregisterStopBubbleListener() { stopBubbleListener = null; stopBubbleTrigger = null; return null; } //////////////////// CONSTRUCTOR ///////////////////// // timer to update data periodically setInterval(function() { if(infoWindow !== null && typeof infoWindow.refreshFn === 'function') { infoWindow.refreshFn(); } }, OBA.Config.refreshInterval); // updates timestamp in popup bubble every second setInterval(function() { if(infoWindow !== null && typeof infoWindow.updateTimestamp === 'function') { infoWindow.updateTimestamp(); } }, 1000); return { reset: function() { closeInfoWindow(); }, getPopupStopId: function() { if(infoWindow !== null) { return infoWindow.stopId; } else { return null; } }, // WAYS TO CREATE/DISPLAY A POPUP showPopupWithContent: showPopupWithContent, showPopupWithContentFromRequest: showPopupWithContentFromRequest, // CONTENT METHODS getVehicleContentForResponse: getVehicleContentForResponse, getStopContentForResponse: getStopContentForResponse, registerStopBubbleListener: registerStopBubbleListener, unregisterStopBubbleListener: unregisterStopBubbleListener }; })();