// Map variable, can be used to call API functions (for example:
// map.getMapCenter())
var map;

// The global layers that can be turned on/off.  Each layer has 
// separate boolean "*On" that controls the visibility.
var cameraLayer;
//var cameraLayerOn;

var workLayer;
//var workLayerOn;

var queueLayer;
//var queueLayerOn;

var weatherLayer;
//var weatherLayerOn;

var warningLayer;
//var warningLayerOn;

var centralParkingLayer;
//var centralParkingLayerOn;

var centralMCParkingLayer;

var centralHandicapParkingLayer;

var centralBusParkingLayer;

var centralTruckParkingLayer;

var commuterParkingLayer;
//var commuterParkingLayerOn;

var startStopLayer;
var routeLayer;

var vaglagServerLayerOn;

// Map initiation function, creates a new SpatialAceMap with a
// specified view to be placed in the "exampleMap" <DIV>
// element.
function init(clientSettings) {
    // WMSUrl changed by Ingemar Nilsson
    var spatialAceWMSUrl = window.location.protocol + "//" + window.location.host + "/SpatialAceWMS/";
    //var spatialAceWMSUrl = "http://bl-webmap1/SpatialAceWMS/";
    var viewName = "LPV.View0";
    var directoryName = "tpv4/";

    var userXml = "rwc/config/clientSettings.xml"
    if (clientSettings)
        userXml = 'rwc/config/' + clientSettings;

    var xmlPath = window.location.protocol + "//" + window.location.host + "/" + directoryName + userXml ;    
    
    //*var mainUserXml = parseXml(userXml);
    map = new SpatialAceMap(spatialAceWMSUrl, viewName, "spatial-web-map", null, "main", mapInit, null, xmlPath);    
}


// Custom map initiation, called when the map has loaded but
// before it is drawn, given as an argument to the
// SpatialAceMap created in init()
function mapInit(inMap) {


    var tempLayer = map.getAllLayers()[0];
    tempLayer.enableClientObjects(); //prepare for sending client objects to server, for printing in FireFox and Safari
	
    warningLayer = inMap.addObjectLayer("warningLayer", "warningLayer");
    warningLayer.show(); //draw();    
	
	queueLayer = inMap.addObjectLayer("queueLayer", "queueLayer");
    queueLayer.show(); //draw();	

	workLayer = inMap.addObjectLayer("workLayer", "workLayer");
    workLayer.show(); //draw();	

    weatherLayer = inMap.addObjectLayer("weatherLayer", "weatherLayer");
    weatherLayer.show(); //draw();
		
    cameraLayer = inMap.addObjectLayer("cameraLayer", "cameraLayer");
    cameraLayer.show(); //draw();	
  
    centralParkingLayer = inMap.addObjectLayer("centralParkingLayer", "centralParkingLayer");
    centralParkingLayer.show(); //draw();

    centralMCParkingLayer = inMap.addObjectLayer("centralMCParkingLayer", "centralMCParkingLayer");
    centralMCParkingLayer.show();

    centralBusParkingLayer = inMap.addObjectLayer("centralBusParkingLayer", "centralBusParkingLayer");
    centralBusParkingLayer.show();

    centralHandicapParkingLayer = inMap.addObjectLayer("centralHandicapParkingLayer", "centralHandicapParkingLayer");
    centralHandicapParkingLayer.show();

    centralTruckParkingLayer = inMap.addObjectLayer("centralTruckParkingLayer", "centralTruckParkingLayer");
    centralTruckParkingLayer.show();

	commuterParkingLayer = inMap.addObjectLayer("commuterParkingLayer", "commuterParkingLayer");
    commuterParkingLayer.show(); //draw();		
    
    routeLayer = inMap.addObjectLayer("routeLayer", "routeLayer");	
    routeLayer.show(); //draw();
    
    startStopLayer = inMap.addObjectLayer("startStopLayer", "startStopLayer");
    startStopLayer.show(); //draw();

    var mapDiv = document.getElementById("spatial-web-map");
	
	
	//* Setting inMap.defaultTool should allow the map to switch back to the MoveTool
	//* after "shift-zooming", instead of switching back to the "standard defaultTool" (i.e. the panTool). 
	inMap.defaultTool = new MoveTool(inMap, startStopLayer, mapDiv, inMap.panTool, null, null);
	//inMap.currentTool = inMap.defaultTool;	
	inMap.setTool(inMap.currentTool);
	
	
	
	
    inMap.registerOnMouseOverEventHandler (myMouseOverEventHandler);
    inMap.registerOnMouseOutEventHandler  (myMouseOutEventHandler);
    inMap.registerOnClickEventHandler     (myOnClickEventHandler); //in map.html
    inMap.registerOnNewGeoRectEventHandler(onNewGeoRect);       
    
    if(typeof onMapIsReady != 'undefined')
        onMapIsReady(inMap); //in map.html

}

function setCustomGeoObjectInfoboxTimeout(geoObj){
    var timeOut = 2000; //2000 = 2 seconds
    if (geoObj)
        geoObj.infoBoxTimeout = timeOut
}





function onNewGeoRect(theMap){	
    if (map_is_print_page){ //in map.html        
        updatePrintImage();
    }
}

function getCustomAttrLayer(){
    return map.getAllLayers()[0];
}

function updatePrintImage()
{
    
    if (isFireFox || isSafari3)
    {

        if (typeof(map.customAttributes) != 'undefined')
            map.customAttributes = null;
        
        map.customAttributes = new Object();
        //* Copy custom attributes from the serverlayer to the map
        var serverLyr = getCustomAttrLayer();
        for (att in serverLyr.customAttributes)
        {
            if (typeof(serverLyr.customAttributes[att]) == 'function')
                continue;
            map.customAttributes[att] = serverLyr.customAttributes[att];
        }
        
        
        //push the client objects to the server
        var objectsToDrawOnServer= new Array();        
        if (routeLayer)        
            objectsToDrawOnServer = routeLayer.getGeoObjectArray();
        
        map.updatePrintImage(false, true, objectsToDrawOnServer);                    
        
    }
}




function showHideLayer(layer, on, imageId, onImageSrc, offImageSrc, boxElementId) {    
    var image = document.getElementById(imageId);    
    if (on) {
	layer.hide();
	image.src = offImageSrc;	
    } else {
	layer.show();
	image.src = onImageSrc;	
    }
    
    setElementEnabledClass(boxElementId, !on, 'drawer-header', 'drawer-header-disabled')
    
    return !on;
}

//created by Ingemar Nilsson
function serverLayerIsVisible(inMap, layerName){
	var lyrCol;    
	var lyr;
	var isVisible = false;
	
    lyrCol = inMap.getAllLayers();
    for(var i = 0; i < lyrCol.length; i++){
        lyr = lyrCol[i];                
        if (i == 0){   
            for(var j = 0; j < lyr.sublayerID.length; j++){
                if (lyr.sublayerName[j] == layerName){ //'Vaglag'
                    isVisible = !lyr.sublayerID[j].isHidden;
                    hit = true;
                    break;
                }
            }
            break;
        }         
    }
	return isVisible;
}
function showHideServerLayer(inMap, layerName, on, imageId, onImageSrc, offImageSrc, boxElementId) {
    var image = document.getElementById(imageId);        
    var lyrCol;
    var hit = false;
	var lyr;
	
	
    lyrCol = inMap.getAllLayers();
    for(var i = 0; i < lyrCol.length; i++){
        lyr = lyrCol[i];                
        if (i == 0){   
            for(var j = 0; j < lyr.sublayerID.length; j++){
                if (lyr.sublayerName[j] == layerName){ //'Vaglag'
                    lyr.sublayerID[j].isHidden = !on;	
                    hit = true;
                    break;
                }
            }
            break;
        }         
    }   
    if (hit && lyr){
        if (on){
            image.src = onImageSrc;            
        }else{
            image.src = offImageSrc;
        }        
        on = !on;    
        lyr.refresh();
        setElementEnabledClass(boxElementId, !on, 'drawer-header', 'drawer-header-disabled')
        
    }       
    return on;
}

function setElementEnabledClass(elementId, enabled, enabledClass, disabledClass){ 
    var element = document.getElementById(elementId);
    if (element){
        if (enabled)
            element.className = enabledClass
        else
            element.className = disabledClass
        
    }
}

function showHideWithPicture(elementId, imageId){ 
    
    var element = document.getElementById(elementId);
    var image = document.getElementById(imageId);    
    if (element.style.display != 'none' ) {
		element.style.display = 'none';
		image.src = "pic/expand16.png";
    } else {
		element.style.display = '';
		image.src = "pic/collapse16.png";
    }
}

function showHide(elementId){
    var element = document.getElementById(elementId);
    if (element.style.display != "none" ) 
    {
	    element.style.display = 'none';
    } 
    else 
    {
	    element.style.display = '';
    }
}

function myMouseOverEventHandler(theMap, theGeoObject)
{
    var selectable = false;
    
    
    //is the object selectable?
    if (theGeoObject[RP_SELECTABLE_NAME] == RP_SELECTABLE_VALUE){        
        selectable = !map_is_print_page;
    }
    
    //the object is selectable
    if (selectable){
        //* Change the cursor to pointer to indicate selectable to the user
        theGeoObject.clientNode.style.cursor = 'pointer'
        for(var i = 0; i < theGeoObject.clientNode.childNodes.length; i++){
            var child = theGeoObject.clientNode.childNodes[i];
            if (child && child.style)
                child.style.cursor = 'pointer'
        }        
    }
    
	var infoBox = theGeoObject.infoBox;
	if (infoBox == null)
	{		
		return;
	}
	
	if (infoBox.className != "cameraInfoBox")
	{
		return;
	}

	var infoBoxComponent = infoBox.firstChild;
	
	while (true)
	{
		if (infoBoxComponent.tagName == "IMG")
		{
			infoBoxComponent.src = addDateQueryString(infoBoxComponent.src);
			return;
		}
		else
		{
			infoBoxComponent = infoBoxComponent.nextSibling();
			if (infoBoxComponent == null)
				return;
		}
	}
}

function myMouseOutEventHandler(theMap, theGeoObject)
{    
    //* Handle cursor changes when leaving an object here! /krsa                
}


//* /krsa
// Returns the geoobjects found at a specified point. A SpatialAceMap object and a point with x and y variables
// must be supplied. If a layer name or list of layer names is supplied, only those layers will be searched,
// otherwise (or if layersToSearch is set to 'all') all object layers will be searched.
// filterAttributeNames and filterAttributeValues can be set to allow only those objects that have the
// attribute with the name and value specified to be passed back. These arrays must be of equal length.
function getGeoObjectsAtPoint(aMap, point, layersToSearch, filterAttributeNames, filterAttributeValues)
{
    // Sanity check
    if (!aMap || !point || !point.x || !point.y)
        return;

    // Determine what layers to search        
    var layers = new Array();
    var layersType = typeof layersToSearch;
    // layersToSearch not defined search all object layers    
    
    //some fix by Ingo here, typeof undefined, string etc....             
    
    if ( layersType == "undefined"  )    
        layers = aMap.getObjectLayers();     
    else if ( layersType == "string" )
        if (layersToSearch == "all")
            layers = aMap.getObjectLayers(); //search all
        else
            layers[0] = aMap.getObjectLayerById( layersToSearch ); //search by id        
    else if (layersType == "array") //array of ids
        for (var i = 0; i < layersToSearch.length; i++)
            layers[i] = aMap.getObjectLayerById( layersToSearch[i] );


    // No object layers with the given name(s) found!
    if (!layers[0] || layers[0] == null)
        return;

            
    // Determine attribute filter
    var filterSearch = false;
    var nameType  = typeof(filterAttributeNames);
    var valueType = typeof(filterAttributeValues);
    if (nameType != "undefined" && valueType != "undefined")
    {
        if ( nameType == "string" && valueType != "array")
        {
            var name = filterAttributeNames;
            filterAttributeNames = new Array();
            filterAttributeNames[0] = name;
            
            var value = filterAttributeValues;
            filterAttributeValues = new Array();
            filterAttributeValues[0] = value;
            
            filterSearch = true;
        }
        else if ( nameType == "array" && valueType == "array" && 
                  filterAttributeNames.length == filterAttributeValues.length)
        {
            filterSearch = true;
        }
    }
    
    
    // Let's perform the search!
    var hitObjects = new Array();
    var hitObjectCount = 0;
       
    // Loop over all layers tagged for search. 
    for (var layerNum = 0; layerNum < layers.length; layerNum++)
    {
        // Get the layer and see that it exists.
        var lyr = layers[layerNum]; //ingo: changed "layer" to "lyr" som global variable with name layer create problems...
        if (!lyr || lyr == null)
            continue;
        if(lyr.isHidden)//only search in visible layers
            continue;
        
        // Get the geoobjects and check that there are any.
        var geoObjects = lyr.getGeoObjectArray();
        if (!geoObjects || geoObjects == null || !geoObjects.length || geoObjects.length <= 0)
            continue;
            
            
        
        for (var objNum = 0; objNum < geoObjects.length; objNum++)
        {
            // Fetch the next object and check that it is OK.
            var object = geoObjects[objNum];
            if (!object || object == null || !object.boundingArea)
                continue;
                
            // Check for hit.
            if ( object.boundingArea.inside( point.x, point.y ) )
            {
                if (!filterSearch) // Do not filter hits - return all objects
                {
                    hitObjects[hitObjectCount++] = object;
                }
                
                else // Filter hits
                {
                    var attrs = object.attributes;
                    //if (!attrs || !attrs.length || attrs.length <= 0)
                    if (attrs && attrs.length && attrs.length > 0) //changed by Ingo
                    {
                        // Check all attributes against the filter.
                        for (var attrNum = 0; attrNum < attrs.length; attrNum++)
                        {
                            var attr = attrs[attrNum];
                            if (!attr || attr == null)
                                continue;
                                
                            // Check the attribute against each filter condition.
                            for (var filterNum = 0; filterNum < filterAttributeNames.length; filterNum++)
                            {
                                if (attr.name == filterAttributeNames[filterNum] && attr.value == filterAttributeValues[filterNum])
                                {
                                    hitObjects[hitObjectCount++] = object;
                                }
                            }
                        }
                    }
                }
            } // End of hit test.
        } // All objects in layer tested.
    } // Search complete!
    
    return hitObjects;
}

function htmlMarkup2Text(s){
    if (s){
        while(s.indexOf('<') > 0)
            s = s.replace('<', '&lt;');
        while(s.indexOf('>') > 0)
            s = s.replace('>', '&gt;');            
    }
    return s;
}

//Ingemar Nilsson
function lineBreakText(sIn, minLen, maxLen, outLinfeed, inSpace, inLinefeed, outHyphen){
    var sOut = new String()
    var space1 = inSpace ? inSpace : ' ';
    var space2 = space1 + space1; //space2 = double spaces
    var inNL   = inLinefeed ? inLinefeed : '\n';
    var outNL  = outLinfeed ? outLinfeed : '\n';
    var outHyp = outHyphen  ? outHyphen : ''; //no real hyphenate in the algorithm, just brute break line if more than max len...
        
    //...remove all double spaces
    while(sIn.indexOf(space2) >= 0)
        sIn = sIn.replace(space2, space1);
    
    //...get the min/max len
    minLen = parseInt(minLen);
    maxLen = parseInt(maxLen);            
    if (isNaN(minLen))  minLen = 35;
    if (isNaN(maxLen))  maxLen = 45;
    if (minLen < 1)      minLen = 1;            
    if (maxLen < minLen) maxLen = minLen;
                   
    
    //split input string by space into an array
    var inParts = sIn.split(space1);            
    
    //loop all parts (words) and build a new output array
    var outParts = [];
    var outPart = '';            
    var inPartLines;
    var outPartEnd;                
    for(var i = 0; i <inParts.length; i++){
        var inPart = inParts[i];        
        //check each part for new line characters already there...
        inPartLines = inPart.split(inNL);        
        for(var j = 0; j <inPartLines.length; j++){                
            //...preserve any linebreaks inside each part (as long as they are not in the end of the part)
            if (j < inPartLines.length - 1)
                outPartEnd = outNL;
            else
                outPartEnd = space1
            outPart += inPartLines[j] + outPartEnd;
            //if we reach above the minLen, this is a new line
            if (outPart.length >= minLen){
                outPart  = outPart.substr(0, outPart.length - space1.length);
                outParts[outParts.length] = outPart;
                outPart = "";
            }                
        }
    }
    //...make sure we get the last line
    if (outPart.length > 0){
        outPart  = outPart.substr(0, outPart.length - space1.length);
        outParts[outParts.length] = outPart;
    }
    
    //...now we must adjust the resulting lines since some of them may too long..
    var tooLong = true;
    var okPart;
    var tooLongPart;
    while(tooLong){
        tooLong = false;
        for(var i = 0; i < outParts.length; i++){
            outPart = outParts[i];
            if (outPart.length > maxLen){
                //...the part was to long, split the parts
                okPart      = outPart.substr(0, maxLen) + outHyp;
                tooLongPart = outPart.substr(maxLen, outPart.length - maxLen)
                outParts[i] = okPart;                        
                //merge the tooLongPart with the next line, if any
                if (i < outParts.length - 1)
                    tooLongPart += space1 + outParts[i + 1];                        
                outParts[i+1] =  tooLongPart;
                //we got a hit, so time to go another round
                tooLong = true;
                break;
            }
        }
    }
    
    //construct the result string
    sOut = outParts.join(outNL);
    return sOut;
}

