﻿ var map;
 var mapPopup = null;
 var layersLoaded = 0;
 var currentResult;
 var currentHover;
 var bLayerSwitcherVisible = false;
 var bLegendDetailsVisible = false;
 var hoverAndClickScaleLimit = 900000;
 var zoomLevelStation;
 var firstLoad = 0;
// avoid pink tiles
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
    defaultHandlerOptions: {
        'single': true,
        'double': false,
        'pixelTolerance': 0,
        'stopSingle': false,
        'stopDouble': false
    },

    initialize: function(options) {
        this.handlerOptions = OpenLayers.Util.extend(
            {}, this.defaultHandlerOptions
        );
        OpenLayers.Control.prototype.initialize.apply(
            this, arguments
        ); 
        this.handler = new OpenLayers.Handler.Click(
            this, {
                'click': this.trigger
            }, this.handlerOptions
        );
    }, 

    trigger: MapClick

});

OpenLayers.Control.Hover = OpenLayers.Class(OpenLayers.Control, {                
                defaultHandlerOptions: {
                    'delay': 500,
                    'pixelTolerance': 5,
                    'stopMove': false
                },

                initialize: function(options) {
                    this.handlerOptions = OpenLayers.Util.extend(
                        {}, this.defaultHandlerOptions
                    );
                    OpenLayers.Control.prototype.initialize.apply(
                        this, arguments
                    ); 
                    this.handler = new OpenLayers.Handler.Hover(
                        this,
                        {'pause': this.onPause, 'move': this.onMove},
                        this.handlerOptions
                    );
                }, 

                onPause: MapHover,

                onMove: MapHoverEnd });


var directionsPrompt = {None:0, ToHere: 1, FromHere : 2};

function initPage(searchParams){
    winResize();
    $("mapcontainer").setStyle({visibility: 'visible'});
    var extent = new OpenLayers.Bounds(-24215250.556834377, -694659.712689843, 2768854.911678126, 12787609.081947658);
    var initialView = new OpenLayers.Bounds(-14096211.006142187, 4361191.08529922, -7350184.639014062, 7731758.283958595);
    var options = {
        projection: new OpenLayers.Projection("EPSG:900913"),
        displayProjection: new OpenLayers.Projection("EPSG:4326"),
        units: "m",
        maxExtent: extent,
        maxResolution: 20000,
        restrictedExtent: extent,
        numZoomLevels: 18,
        controls: [new OpenLayers.Control.PanZoomBar(),
                   new OpenLayers.Control.MouseDefaults(),
                   new OpenLayers.Control.DragPan()]

    };

    map = new OpenLayers.Map('map', options);
    // create Google Mercator layers
    var gmap = new OpenLayers.Layer.Google(
        "Streets",
        {sphericalMercator: true, maxResolution: 10000}
    );

    var gsat = new OpenLayers.Layer.Google(
        "Satellite",
        {type: G_SATELLITE_MAP, sphericalMercator: true, maxResolution: 10000}
    );
    
    var ghyb = new OpenLayers.Layer.Google(
        "Hybrid",
        {type: G_HYBRID_MAP, sphericalMercator: true, maxResolution: 10000}
    );

    // Create MapGuide Layer
      var options = {
          buffer: 1,
          singleTile: true,
          isBaseLayer: false,
          alpha:true
      };
      
      var url = mgSessionInfo.mgAgentURL;

      var params = {
        session: mgSessionInfo.mgSessionId,
        mapName: mgSessionInfo.mgTrackMapName
      };
      
      var mgTrackLayer = new OpenLayers.Layer.MapGuide("Tracks", url, {session: mgSessionInfo.mgSessionId, mapName: mgSessionInfo.mgTrackMapName}, options );
      mgTrackLayer.events.register("loadend", mgTrackLayer, initialLoad);
      var mgStationLayer = new OpenLayers.Layer.MapGuide("Stations", url, {session: mgSessionInfo.mgSessionId, mapName: mgSessionInfo.mgStationMapName}, options );   
      mgStationLayer.events.register("loadend", mgStationLayer, initialLoad);
      
      // Create search station point layer
       
            
      map.addLayers([gmap, gsat, ghyb, mgTrackLayer, mgStationLayer]);

      var click = new OpenLayers.Control.Click();
      map.addControl(click);
      click.activate();
      
      var hover = new OpenLayers.Control.Hover();
      map.addControl(hover);
      hover.activate();
      
      map.zoomToExtent(initialView);
      map.events.register('mousedown', map, CloseMapPanels);
        
      document.observe('mousedown',CloseMapPanels);
      $('layerSwitcher').observe('mousedown', function(event){Event.stop(event)});
      $('legend').observe('mousedown', function(event){Event.stop(event)});
      if(searchParams)
      {
		if (searchParams['ZOOM']){
			zoomLevelStation = searchParams['ZOOM'];
		}
        searchParams['STRICT'] = '1';
        searchParams['CMD'] = 'search';
        SearchStations(searchParams)
      }
}
window.document.onmousedown = function()
{
    CloseMapPanels();
}



function initialLoad()
{
    layersLoaded++;
    this.events.unregister("loadend", this);
    if(layersLoaded == 2){
        $('map').setStyle({visibility:'visible'});
    }
          
}

  

// **************************** STATION SEARCH ****************************

function SearchClick()
{
    SearchStations({CMD:'search', NAME:$('comboStation').getValue()});
}

function SearchStations(params)
{
    $('resultvalues').hide();
    $('message').hide();
    $('progress').show();
    $('resultvalues').update();   
    $('resultvalues').hide();
    $('progress').show();
    $('resultvalues').update();
    new Ajax.Request('search.ashx', {
        parameters: params,
        onSuccess: SearchDone });
}

function SearchDone(response)
{
    var stationSearch = eval('(' + response.responseText + ')');
    var resultPane = $('resultvalues');
    $('progress').hide();


    if(stationSearch.success)
    {
        var stations = stationSearch.results;
        for(var i=0; i < stations.length; i++)
        {
            var li = new Element('li', {style:'cursor: pointer'});
            li.update(stations[i].StationName.escapeHTML() + ", " + stations[i].StPv.escapeHTML() + " (" + stations[i].SCAC.escapeHTML() + ")");
            li.observe('click', ResultClick.bindAsEventListener(stations[i], li));
            li.observe('mouseover', ResultOver.bindAsEventListener(li));
            li.observe('mouseout', ResultOut.bindAsEventListener(li));
            resultPane.appendChild(li);
        } 
        
        if(stations.length == 1){
            ResultClick.bindAsEventListener(stations[0])(); 
        }
        $('resultvalues').show();
    }
    else
    {
        $('message').update(stationSearch.ErrorMessage.escapeHTML().replace(/\n/g,'<BR />'));
        $('message').show();
    }
}

function ResultClick(e)
{
    var extentFactor = 10000;
    var lonlat = new OpenLayers.LonLat(this.Longitude,this.Latitude);
    lonlat.transform(new OpenLayers.Projection("EPSG:4326") , new OpenLayers.Projection("EPSG:900913"));
    var extent = new OpenLayers.Bounds(lonlat.lon - extentFactor, lonlat.lat - extentFactor,lonlat.lon + extentFactor,lonlat.lat + extentFactor);
	if(zoomLevelStation && firstLoad == 0){
		map.setCenter(lonlat,parseInt(zoomLevelStation));
		firstLoad = 1;
	} else {
		map.zoomToExtent(extent);
	}
    ShowStationInfo(this, lonlat, directionsPrompt.None);    
    
    if(currentResult) currentResult.removeClassName("resultSelect");
    
    var data = $A(arguments);
    currentResult = data[1];
    currentResult.removeClassName("resultHighlight");
    currentResult.addClassName("resultSelect");
}

function ResultOver(e)
{
  if(this != currentResult) this.addClassName("resultHighlight");
}

function ResultOut()
{ 
  if(this != currentResult) this.removeClassName("resultHighlight");
}

function ShowStationInfo(station, lonlat, addressPrompt)
{
    ShowStationCircle(lonlat);    
    if(mapPopup != null) { map.removePopup(mapPopup); } 
    
    var popUpHtml = "<div class=\"mapPopUpTitle\">" + station.StationName.escapeHTML() + " (" + station.StPv.escapeHTML() + ")</div>" + 
                    "<div class=\"mapPopUpDetails\">" + local["CARRIER"] + ": " +  station.SCAC.escapeHTML() + "<br />";

    if (station.Intermodal) {
        popUpHtml += "<div class=\"mapPopUpAddress\">" + station.Address.escapeHTML() + "<BR />" + station.City.escapeHTML() + ", " + station.Prov.escapeHTML() + "</div>";

        switch (addressPrompt) {
            case directionsPrompt.None:
                popUpHtml += "<div class=\"mapPopUpDirections\">Directions:&nbsp;<a href=\"#\" id=\"aToHere\">" + local["TOHERE"] + "</a> - <a href=\"#\" id=\"aFromHere\">" + local["FROMHERE"] + "</a></div>";
                break;
            case directionsPrompt.ToHere:
                popUpHtml += "<div class=\"mapPopUpDirections\">Directions:&nbsp;<span>" + local["TOHERE"] + "</span> - <a href=\"#\" id=\"aFromHere\">" + local["FROMHERE"] + "</a></div>";
                popUpHtml += "<div class=\"mapPopUpDirInput\">" + local["STARTADDR"] + ":<br /><input id=\"addressInput\" type=\"text\" style=\"width:170px\" /><input id=\"inputGoButton\" type=\"button\" value=\"Go\" style=\"width:30px\" /></div>";
                break;
            case directionsPrompt.FromHere:
                popUpHtml += "<div class=\"mapPopUpDirections\">Directions:&nbsp;<a href=\"#\" id=\"aToHere\">" + local["TOHERE"] + "</a> - <span>" + local["FROMHERE"] + "</span></div>";
                popUpHtml += "<div class=\"mapPopUpDirInput\">" + local["ENDADDR"]  + ":<br /><input id=\"addressInput\" type=\"text\" style=\"width:170px\" /><input id=\"inputGoButton\" type=\"button\" value=\"Go\" style=\"width:30px\" /></div>";
                break;
        }
        
    }

                      
    mapPopup = new OpenLayers.Popup.FramedCloud("mapPopup",
                   lonlat,
                   null,
                   popUpHtml,
                   null,
                   true,
                   onPopupClose);
    mapPopup.isAlphaImage = true;
    map.addPopup(mapPopup);

    if (station.Intermodal) {

        switch (addressPrompt) {
            case directionsPrompt.None:
                var toHereLink = $("aToHere");
                var fromHereLink = $("aFromHere");
                toHereLink.observe("click", ShowStationInfo.bind(toHereLink, station, lonlat, directionsPrompt.ToHere));
                fromHereLink.observe("click", ShowStationInfo.bind(fromHereLink, station, lonlat, directionsPrompt.FromHere));
                break;
            case directionsPrompt.ToHere:
                var fromHereLink = $("aFromHere");
                var goButton = $("inputGoButton");
                var inputBox = $("addressInput");
                
                var OpenDirFc = OpenGoogleDirections.bind(goButton, station, lonlat, addressPrompt);
                fromHereLink.observe("click", ShowStationInfo.bind(fromHereLink, station, lonlat, directionsPrompt.FromHere));
                goButton.observe("click", OpenDirFc);
                inputBox.observe("keypress", checkEnter.bindAsEventListener(inputBox, OpenDirFc));
                
                break;
            case directionsPrompt.FromHere:
                var toHereLink = $("aToHere");
                var goButton = $("inputGoButton");
                var inputBox = $("addressInput");
                
                var OpenDirFc = OpenGoogleDirections.bind(goButton, station, lonlat, addressPrompt); 
                toHereLink.observe("click", ShowStationInfo.bind(toHereLink, station, lonlat, directionsPrompt.ToHere));
                goButton.observe("click", OpenDirFc);
                inputBox.observe("keypress", checkEnter.bindAsEventListener(inputBox, OpenDirFc));
                break;
        } 
    }
    
}

function ShowStationCircle(lonlat)
{
    RemoveStationCircle();   
    
    var styles = new OpenLayers.StyleMap({ 
    "default": { 
    pointRadius: 9, 
    strokeColor: "#00008b", 
    strokeWidth: 3,
    strokeOpacity: 0.75, 
    fillOpacity: 0,
    type: "circle" 
    }
    }); 

    // Create a vector layer and give it your style map. 
    var pointLayer = new OpenLayers.Layer.Vector( 
    "PointLayer", {styleMap: styles, isBaseLayer: false} 
    ); 
    
    var aFeatures = [new OpenLayers.Feature.Vector( 
                    new OpenLayers.Geometry.Point( 
                        lonlat.lon, lonlat.lat 
                    )
                )];                 
    
    pointLayer.addFeatures(aFeatures);
    map.addLayer(pointLayer);
}

function RemoveStationCircle()
{
    var pointLayer = map.getLayersByName("PointLayer");
    
    if(pointLayer.length == 1)
    {
        pointLayer[0].destroy();
    }
}

function checkEnter(e, action){ //e is event object passed from function invocation
    var characterCode;
    if(e && e.which){ //if which property of event object is supported (NN4)
        e = e;
        characterCode = e.which; //character code is contained in NN4's which property
    }
    else{
        //e = event;
        characterCode = e.getKey() ;//character code is contained in IE's keyCode property
    }

    if(characterCode == 13){ //if generated character code is equal to ascii 13 (if enter key)
        if(typeof action == 'function')
        {
            action();
        }
        else
        {
            eval(action);
        }
        return false;
    }
    else{
        return true;
    }
}

function OpenGoogleDirections(station, lonlat, addressPrompt) {
    var dirURL = "http://maps.google.com/maps?";
    
    var stationAddress = station.Address + ", " + station.City + ", " + station.Prov + ", " + station.Postal ;
    var params = { saddr: "", daddr: "" };
     switch (addressPrompt) {
        case directionsPrompt.ToHere:
            params.saddr = $("addressInput").value;
            params.daddr = stationAddress;
            break;
        case directionsPrompt.FromHere:
            params.saddr = stationAddress;
            params.daddr = $("addressInput").value;
            break;
    }

    window.open(dirURL + Object.toQueryString(params));
}
// **************************** MAP CONTROLS ****************************

function MinMaxLayerSwitcher()
{
    if(bLegendDetailsVisible) MinMaxLegend();
    var layerElm = $('layerSwitcher');
    var minMaxButton = $("lyrMinMaxBtn");
    var layerDetail = $("layerDetails");
 
    if(bLayerSwitcherVisible){
        layerDetail.hide();
        minMaxButton.setStyle({backgroundPosition: '0px 11px'});
    }else{
        layerDetail.show();
        minMaxButton.setStyle({backgroundPosition: '0px 0px'});
    } 
    
    bLayerSwitcherVisible = !bLayerSwitcherVisible;   
}

function ToggleLayer(layerInfo)
{
    var layer = map.getLayersByName(layerInfo.Name)[0];
    if(layerInfo.IsBaseLayer)
    {
         map.setBaseLayer(layer);       
    }
    else
    {
        layer.setVisibility(!layer.getVisibility());    
    }
}

function MinMaxLegend()
{
    if(bLayerSwitcherVisible) MinMaxLayerSwitcher();
    var legendElm = $('legend');
    var minMaxButton = $("legMinMaxBtn");
    var legDetail = $("legDetails");

    legendElm.setStyle({left: '0px', top: '0px', visibility: 'hidden'});    
    if(bLegendDetailsVisible){
        legDetail.hide();
        minMaxButton.setStyle({backgroundPosition: '0px 11px'});
    }else{
        legDetail.show();
        minMaxButton.setStyle({backgroundPosition: '0px 0px'});
    }
    
    bLegendDetailsVisible = !bLegendDetailsVisible;
    PositionLegend();
    
}

function CloseMapPanels()
{
    if(bLayerSwitcherVisible) MinMaxLayerSwitcher();
    if(bLegendDetailsVisible) MinMaxLegend();
}



// **************************** MAP EVENTS ****************************

function MapClick(e) {
    var scale = map.getScale();
    if(scale <= hoverAndClickScaleLimit)
    {   
	    var pxBuffer = 7;
		var minlonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.xy.x - pxBuffer, e.xy.y + pxBuffer));
		var maxlonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.xy.x + pxBuffer, e.xy.y - pxBuffer));
	    minlonlat.transform(new OpenLayers.Projection("EPSG:900913") , new OpenLayers.Projection("EPSG:4326"));
		maxlonlat.transform(new OpenLayers.Projection("EPSG:900913") , new OpenLayers.Projection("EPSG:4326"));
        new Ajax.Request('search.ashx', {
        parameters: {CMD:'click', MINLON: minlonlat.lon, MINLAT: minlonlat.lat, MAXLON: maxlonlat.lon, MAXLAT: maxlonlat.lat },
        onSuccess: ClickDone });
    }
}

function ClickDone(response)
{
    var stationClick = eval('(' + response.responseText + ')');
    if(stationClick.success && stationClick.results.length > 0) 
    {
        var station = stationClick.results[0];
        var lonlat = new OpenLayers.LonLat(station.Longitude,station.Latitude);
        lonlat.transform(new OpenLayers.Projection("EPSG:4326") , new OpenLayers.Projection("EPSG:900913"));
        ShowStationInfo(station, lonlat, directionsPrompt.None);
    }
}

function MapHover(e)
{
    var scale = map.getScale();
    if(scale <= hoverAndClickScaleLimit )
    { 
        var today = new Date();
		currentHover = today.getTime();
        var pxBuffer = 7;
		var minlonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.xy.x - pxBuffer, e.xy.y + pxBuffer));
		var maxlonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.xy.x + pxBuffer, e.xy.y - pxBuffer));
	    minlonlat.transform(new OpenLayers.Projection("EPSG:900913") , new OpenLayers.Projection("EPSG:4326"));
		maxlonlat.transform(new OpenLayers.Projection("EPSG:900913") , new OpenLayers.Projection("EPSG:4326"));
        new Ajax.Request('search.ashx', {
            parameters: {CMD:'hover', MINLON: minlonlat.lon, MINLAT: minlonlat.lat, MAXLON: maxlonlat.lon, MAXLAT: maxlonlat.lat, UTC:currentHover},
            onSuccess: MapHoverDone }); 
    }   
}

function MapHoverDone(response)
{
    var hover = eval('(' + response.responseText + ')');
    
    if(hover.success &&  currentHover == hover.UTC){
        $('map').setStyle({cursor:"pointer"});
    }
}

function MapHoverEnd(e)
{
    $('map').setStyle({cursor:"default"});    
}

function onPopupClose(evt)
{
    RemoveStationCircle();
    if(mapPopup) { map.removePopup(mapPopup); }
    if(currentResult) currentResult.removeClassName("resultSelect");
    mapPopup = null;
}

// **************************** POSITION & RESIZE ****************************

function winResize()
{
    var side_margin = 10;
    var top_margin = 10;
    
    var min_map_w = 500;
    var min_map_h = 300;
    var min_search_h = 50;
    
    var mapElm = $('mapcontainer');
    var resultsElm = $('results');
    var legendElm = $('legend');
    
    mapElm.setStyle({width:'1px',height:'1px'});
    resultsElm.setStyle({height:'1px'});
    legendElm.setStyle({left: '0px', top: '0px', visibility: 'hidden'});
     
    var winSize = document.viewport.getDimensions();
    var legendSize = legendElm.getDimensions();
    var mapPos = mapElm.cumulativeOffset(); 
    var resPos = resultsElm.cumulativeOffset(); 

    var mapW = winSize.width - mapPos.left - side_margin;
    if(mapW < min_map_w) mapW = min_map_w;
    
    var mapH = winSize.height -  mapPos.top - top_margin;
    if(mapH < min_map_h) mapH = min_map_h;
    
    mapElm.setStyle({width:mapW + 'px', height: mapH + 'px'});
    
    var searchH =winSize.height - resPos.top - top_margin;
    if(searchH < min_search_h) searchH = min_search_h;
    resultsElm.setStyle({height: searchH + 'px'});
    
    PositionLayerSwitcher();
    PositionLegend();
    
}

function PositionLayerSwitcher()
{
    var padding = 2;
    var mapElm = $('mapcontainer');
    var mapSize = mapElm.getDimensions();
    
    var layerElm = $('layerSwitcher');
    var layerSize = layerElm.getDimensions();
     
    var mapPos = mapElm.cumulativeOffset(); 
    var legX = mapPos.left + mapSize.width - layerSize.width;
    var legY = mapPos.top  + padding;
    
    layerElm.setStyle({left: legX + 'px', top: legY + 'px', visibility: 'visible'});    
}

function PositionLegend()
{
    var mapElm = $('mapcontainer');
    var mapSize = mapElm.getDimensions();
    
    var legendElm = $('legend');
    var legendSize = legendElm.getDimensions();
     
    var mapPos = mapElm.cumulativeOffset(); 
    var legX = mapPos.left + mapSize.width - legendSize.width;
    var legY = mapPos.top + mapSize.height - legendSize.height;
    
    legendElm.setStyle({left: legX + 'px', top: legY + 'px', visibility: 'visible'});    
}
