/**
 * CartoVisor.js
 * Instituto Geográfico Nacional 
 * http://www.ign.es/ign/es/IGN/home.jsp
 */
function CartoVisor(params,
		    deprecated_longitude_param,
		    deprecated_latitude_param,
		    deprecated_zoom_param)
{
    this.SEARCH_TAB = 0;
    this.PATH_TAB = 1;
    this.SETTINGS_TAB = 2;
    this.cv_paused = false;
    this.carto_element = null;
    this.component_id = null;
    this.urlid = null;
    this.urlbase = "";
    this.longitud = -4.1109804687;
    this.latitud = 40.1352921875;
    this.zoom = 0;
    this.loadedmodules = null;
    this.onloading_any = null;
    this.customSettingsURL = null;
    this.baseLayer = null;
    this.zoomBar = true;
    this.useCartoCiudadZoomLevels = true;
    this.projection = null;

    this.getURLfromElement = function getURLfromElement(element)
    {
        var scripts = element.getElementsByTagName("script");
        for (var i=0;i<scripts.length;i++) 
        {
            var src = scripts[i].getAttribute("src");
            if (src)
                if ((src.indexOf("CartoVisor.js") != -1) && (src.indexOf("CartoVisor.jsp") == -1))
                    return src.replace("CartoVisor.js","");
        }
        return "";
    }
    
    this.getURL = function getURL()
    {
        var head = document.getElementsByTagName("head")[0];
	var url = this.getURLfromElement(head);
	if (url == "")
            url = this.getURLfromElement(document.body);
	return url;
    }
 
    this.isJSLibraryInstalled = function isJSLibraryInstalled(library)
    {
        var addNode=true;
        var nodes=document.getElementsByTagName('script');
        for(var i=0;i<nodes.length;++i)
                if (this.getOnlyName(nodes.item(i).src) == this.getOnlyName(file))
                        return true;
        return false;
    }
    
    this.getOnlyName = function getOnlyName(file)
    {
        var parts = file.split('/');
        return parts[parts.length-1];    
    }
    
    this.addJSFile = function addJSFile(file)
    {
        var retval = true;
        var addNode=true;
        var nodes=document.getElementsByTagName('script');
        for(var i=0;i<nodes.length;++i)
        {
                if (this.getOnlyName(nodes.item(i).src) == this.getOnlyName(file))
                {
                        addNode=false;
                        break;
                }
        }                           
        if (addNode)
        {
            document.write("<script src='" + file + "' type='text/javascript'></script>");
            nodes=document.getElementsByTagName('script');
            for(i=0;i<nodes.length;++i)
		if (this.getOnlyName(nodes.item(i).src) == this.getOnlyName(file))
		{
		    if (nodes.item(i).parentNode.tagName.toLowerCase() == 'head')
			retval = false;
		    break;
		}
        }
        return retval;
    }
    
    this.addCSSFile = function addCSSFile(file)
    {
        var addNode=true;
        var nodes=document.getElementsByTagName('link');
        for(var i=0;i<nodes.length;++i)
                if (nodes.item(i).href.toLowerCase() == file)
                        addNode=false;
        if(addNode)
        {	
            var cssNode=document.createElement('link');
            cssNode.setAttribute('rel','stylesheet');
            cssNode.setAttribute('type','text/css');
            cssNode.setAttribute('href',file);
            document.getElementsByTagName('head')[0].appendChild(cssNode);
        }
    }
    
    this.addBodyJSFile = function addBodyJSFile(file)
    {
        var addNode=true;
        var nodes=document.getElementsByTagName('script');
        for(var i=0;i<nodes.length;++i)
        {
                if (this.getOnlyName(nodes.item(i).src) == this.getOnlyName(file))
                {
                        addNode=false;
                        break;
                }
        }
        if(addNode)
        {	
            var newScript = document.createElement('script');
            newScript.type = 'text/javascript';
            newScript.src = file;
            document.body.appendChild(newScript);
        }
    }    
    
    this.alertCallMessage = function alertCallMessage()
    {
        alert("Cartovisor Script Error Message:\n\n" + 
               "The script that creates the CartoVisor object must be inside the <BODY> tag!!\n" +
                "Example:\n\n" +             
                "<html>\n" + 
                "\t<head>\n" + 
                "\t\t<script src='http://www....../CartoVisor.js' type='text/javascript'></script>\n" + 
                "\t</head>\n" + 
                "\t<body>\n" + 
                "\t\t<div id='mapa'></div>\n" + 
                "\t\t<script type='text/javascript'>\n" + 
                "\t\t\tvar map = new CartoVisor({elementId:'mapa',longitude:-3.71,latitude:40.41,zoom:2});\n" +
                "\t\t</script>\n" + 
                "\t</body>\n" + 
                "</html>\n");
    }

    this.includeFiles = function includeFiles(loaded)
    {
        var cartovisor_jsp = this.urlbase + "CartoVisor.jsp?Element=" + this.getUniqueElID() +
                                                                           "&pagelet_id=" + this.getPageletId() +
                                                                           "&lon=" + this.longitud +
                                                                           "&lat=" + this.latitud +
                                                                           "&zoom=" + this.zoom +
                                                                           ((this.customSettingsURL) ? ("&customSettingsURL=" + encodeURIComponent(this.customSettingsURL)) : "");
        if (loaded)
            this.addBodyJSFile(cartovisor_jsp);
        else
        {
            this.addCSSFile(this.urlbase + "css/screen.css");
            this.addCSSFile(this.urlbase + "css/cv-ol-controls.css");
            this.addCSSFile(this.urlbase + "css/cartovisor.css");	           
            if (!this.addJSFile(this.urlbase + "js/wp_cookie/wp_Cookie.js"))
            {
                this.alertCallMessage();
                return;
            }
            this.addJSFile(this.urlbase + "js/openlayers/OpenLayers.js");
            this.addJSFile(this.urlbase + "js/addopenlayers/ScaleBar.js");
            this.addJSFile(this.urlbase + "js/addopenlayers/CartovisorText.js");
            this.addJSFile(this.urlbase + "js/addopenlayers/CartovisorClick.js");
            this.addJSFile(this.urlbase + "js/addopenlayers/CartovisorMousePosition.js");   
            this.addJSFile(this.urlbase + "js/ajast/ox.ajast.js"); 
            this.addJSFile(this.urlbase + "js/cartovisor/cartovisor-utils.js");       
            this.addJSFile(this.urlbase + "js/cartovisor/cv-dialog.js");    
            this.addJSFile(this.urlbase + "js/cartovisor/cv-search.js"); 
            this.addJSFile(this.urlbase + "js/cartovisor/vc-mailing-address-suggestions.js");    
            this.addJSFile(this.urlbase + "js/cartovisor/vc-mailing-address-control.js");    
            this.addJSFile(this.urlbase + "js/cartovisor/vc-rule-guide.js");
            this.addJSFile(this.urlbase + "js/levenshtein/levenshtein.js");
            this.addJSFile(this.urlbase + "js/wz_tooltip/wz_tooltip.js");
            this.addJSFile(cartovisor_jsp);
        }        
    }
    
    this.setActiveTab = function setActiveTab(tab)
    {
        try
        {
            eval(this.component_id +"_setActiveTab(" + tab + ");");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_setActiveTab(" + tab + ");\"");            
        }
    }
    
    this.hideTab = function hideTab(tab)
    {
        try
        {
            eval(this.component_id +"_setDisplayTab(" + tab + ",false);");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_setDisplayTab(" + tab + ",false);\"");
        }
    }
    
    this.activateLayerSwitcherControl = function activateLayerSwitcherControl(value)
    {
        try
        {
            eval(this.component_id +"_activateLayerSwitcherControl(" + value + ");");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_activateLayerSwitcherControl(" + value + ");\"");
        }
    }

    this.enableZoomWheel = function enableZoomWheel()
    {
        try
        {
            eval(this.component_id +"_enableZoomWheel();");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_enableZoomWheel();\"");
        }
    }

    this.disableZoomWheel = function disableZoomWheel()
    {
        try
        {
            eval(this.component_id +"_disableZoomWheel();");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_disableZoomWheel();\"");
        }
    }

    this.getExtent = function getExtent()
    {
        try
        {
            var extent = null;
            eval("extent=" + this.component_id +"_getExtent();");
            return extent;
        }
        catch(e)
        {
            return null;
        }
    }

    this.setExtent = function setExtent(extent)
    {
        if( typeof extent == "undefined" || !(extent instanceof Object))
        {
            alert("CartoVisor:\nIncorrect parameter");
            return;
        }
        try
        {
            eval(this.component_id +"_setExtent(extent);");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id + "_setExtent(" + this.getSource(extent) + ");\"");
        }
    }
    
    this.setSizeOption = function setSizeOption(option)
    {
        try
        {
            eval(this.component_id +"_setSizeOption(" + option + ");");
        }
        catch(e)
        {   
            eval(this.component_id +"_size_option_buffer = " + option + ";");
        }
    }
    
    this.showTab = function showTab(tab)
    {
        try
        {
            eval(this.component_id +"_setDisplayTab(" + tab + ",true);");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_setDisplayTab(" + tab + ",true);\"");
        }
    }
        
    this.setCustomHelpFunction = function setCustomHelpFunction(helpfunction)
    {        
         eval(this.component_id +"_customHelpFunction = " + helpfunction + ";");
    }
    
    this.setActiveLanguage = function setActiveLanguage(language)
    {
        try
        {
            eval(this.component_id +"_setActiveLanguage('" + language + "');");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_setActiveLanguage('" + language + "');\"");
        }
    }
    
    this.getOpenLayersMap = function getOpenLayersMap()
    {
        try
        {
            var openlayersmap=null;
            eval("openlayersmap = " + this.component_id +"_getOpenLayersMap();");
            return openlayersmap;
        }
        catch(e)
        {
            alert("The component has not loaded yet.\nYou must use the parameter onLoadFunction");
            return null;
        }      
    }

    this.createMarker = function createMarker(opts)
    {
        if( typeof opts == "undefined" || !(opts instanceof Object))
        {
            alert("CartoVisor:\nIncorrect parameter");
            return null;
        }

        if( typeof opts.longitude == "undefined" || (typeof opts.longitude != "number"))
        {
            alert("CartoVisor:\nIncorrect parameter 'longitude'");
            return null;
        }

        if( typeof opts.latitude == "undefined" || (typeof opts.latitude != "number"))
        {
            alert("CartoVisor:\nIncorrect parameter 'latitude'");
            return null;
        }

        if( typeof opts.layername == "undefined" || (typeof opts.layername != "string"))
        {
            alert("CartoVisor:\nIncorrect parameter 'layername'");
            return null;
        }

        if( typeof opts.width == "undefined" || (typeof opts.width != "number"))
        {
            alert("CartoVisor:\nIncorrect parameter 'width'");
            return null;
        }

        if( typeof opts.height == "undefined" || (typeof opts.height != "number"))
        {
            alert("CartoVisor:\nIncorrect parameter 'height'");
            return null;
        }

        if( typeof opts.offset_left == "undefined")
            opts.offset_left = 0;
        else
        {
            if (typeof opts.offset_left != "number")
            {
                alert("CartoVisor:\nIncorrect parameter 'offset_left'");
                return null;
            }
        }

        if( typeof opts.offset_top == "undefined")
            opts.offset_top = 0;
        else
        {
            if (typeof opts.offset_top != "number")
            {
                alert("CartoVisor:\nIncorrect parameter 'offset_top'");
                return null;
            }
        }

        if( typeof opts.url == "undefined" || (typeof opts.url != "string"))
        {
            alert("CartoVisor:\nIncorrect parameter 'url'");
            return null;
        }

        if( typeof opts.onClickFunction != "undefined")
        {
            if( typeof opts.onClickFunction != "function" && !opts.onClickFunction instanceof Array )
            {
                alert("CartoVisor:\nIncorrect 'onClickFunction' parameter");
                return null;
            }
        }

        if( typeof opts.tooltip != "undefined")
        {
            if (typeof opts.tooltip != "string")
            {
                alert("CartoVisor:\nIncorrect 'tooltip' parameter");
                return null;
            }
        }
	
        if( typeof opts.displayLayerInLayerSwitcherIfNewLayer != "undefined")
        {
            if (typeof opts.displayLayerInLayerSwitcherIfNewLayer != "boolean")
            {
                alert("CartoVisor:\nIncorrect 'displayLayerInLayerSwitcherIfNewLayer' parameter");
                return null;
            }
        }

        if( typeof opts.popup != "undefined")
        {
            if (!(opts.popup instanceof Object))
            {
                alert("CartoVisor:\nIncorrect 'popup' parameter");
                return null;
            }
            if((typeof opts.popup.header == "undefined") || (typeof opts.popup.header != "string") ||
               (typeof opts.popup.body == "undefined") || (typeof opts.popup.body != "string"))
            {
                alert("CartoVisor:\nIncorrect 'popup' parameter");
                return null;
            }

            if ((typeof opts.popup.width == "undefined") || (typeof opts.popup.width != "number"))
                opts.popup.width = 150;

             if ((typeof opts.popup.height == "undefined") || (typeof opts.popup.height != "number"))
                opts.popup.height = 70;
        }

        try
        {
	    var retvalue = null;
            eval("retvalue = " + this.component_id +"_createCustomMarker(opts);");
	    return retvalue;
        }
        catch(e)
        {
            var msgerr = e.description;
            try{msgerr=e.toSource();}catch(ose){}
            alert('Cartovisor.\n' + msgerr);
        }
	return null;
    }

    this.cancelQueryMapPoint = function cancelQueryMapPoint()
    {
        try
        {
            eval(this.component_id +"_cancelQueryMapPoint();");
        }
        catch(e)
        {
            var msgerr = e.description;
            try{msgerr=e.toSource();}catch(ose){}
            alert('Cartovisor.\n' + msgerr);
        }
    }

    this.queryMapPoint = function queryMapPoint(opts)
    {
        if( typeof opts == "undefined" || !(opts instanceof Object))
        {
            alert("CartoVisor:\nIncorrect parameter");
            return;
        }

        if( typeof opts.prompt == "undefined" || (typeof opts.prompt != "string"))
        {
            alert("CartoVisor:\nIncorrect parameter 'prompt'");
            return;
        }
        
        if( typeof opts.callbackFunction != "function" && !opts.callbackFunction instanceof Array )
        {
            alert("CartoVisor:\nIncorrect 'callbackFunction' parameter");
            return;
        }

        try
        {
            eval(this.component_id +"_queryMapPoint(opts);");
        }
        catch(e)
        {
            var msgerr = e.description;
            try{msgerr=e.toSource();}catch(ose){}
            alert('Cartovisor.\n' + msgerr);
        }
    }
    
    this.doSearch = function doSearch(value)
    {
        try
        {
            eval(this.component_id +"_doAPISearch('" + value + "');");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_doAPISearch('" + value + "');\"");
        }    
    }
    
    this.doComputePath = function doComputePath(value1,value2)
    {
        try
        {
            eval(this.component_id +"_doAPIComputePath('" + value1 + "','" + value2 + "');");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_doAPIComputePath('" + value1 + "','" + value2 + "');\"");
        }    
    }
    
    this.setZoom = function setZoom(lon,lat,zoomvalue)
    {
        var flon = parseFloat(lon);
        var flat = parseFloat(lat);
        var fzoom = parseInt(zoomvalue);
        try
        {
            eval(this.component_id +"_setAPICenter(" + flon + "," + flat + "," + fzoom + ");");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_setAPICenter(" + flon + "," + flat + "," + fzoom + ");\"");
        }    
    }
    
    this.setOverrideLangSettings = function setOverrideLangSettings(langsettings)
    {
	try
	{
	    eval(this.component_id +"_setOverrideLangSettings(langsettings);");
	}
        catch(e)
        {
            var msgerr = e.description;
            try{msgerr=e.toSource();}catch(ose){}
            alert('Cartovisor.\n' + msgerr);
        }
    }
    
    this.setToolbarButtons = function setToolbarButtons(help,save,load)
    {
        try
        {
            eval(this.component_id +"_reloadToolbar(" + help + "," + save + "," + load + ");");
        }
        catch(e)
        {
            eval(this.component_id +"_command_buffer +=\""+  this.component_id +"_reloadToolbar(" + help + "," + save + "," + load + ");\"");
        }    
    } 
    
    this.getUrlId = function getUrlId()    
    {
        var num = 0;
        var url = document.URL.toString();
        for (var i=0;i<url.length;i++)
            num += url.charCodeAt(i);
        return num.toString();
    }
        
    this.getUniqueElID = function getUniqueElID()    
    {
        return this.carto_element.getAttribute("id");
    }  
    
    this.getPageletId = function getPageletId()    
    {
        return this.getUniqueElID() + "_"+ this.urlid;
    }    
    
    this.getComponentId = function getComponentId()    
    {
        var cid =  "vc_" + this.getPageletId();
        return cid;
    }
        
    this.continueLoading = function continueLoading()    
    {
        document.body.setAttribute("onloading_any",true);
        this.cv_paused = false;        
        this.urlbase = this.getURL();
        this.loadedmodules = document.body.getAttribute("loadedmodules");
        if (!this.loadedmodules)
            document.body.setAttribute("loadedmodules",true);
        this.includeFiles(this.loadedmodules);
    }

    /* deprecated */
    this.setOnLoadFunction = function setOnLoadFunction(onloadfunction)
    {
         eval(this.component_id +"_onload_function = " + onloadfunction + ";");
    }

    this.getSource = function getSource(obj)
    {
        var output = [], temp;
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                temp = i + ":";
                switch (typeof obj[i]) {
                    case "object" :
                        temp += this.getSource(obj[i]);
                        break;
                    case "string" :
                        temp += "\"" + obj[i] + "\"";    // add in some code to escape quotes
                        break;
                    default :
                        temp += obj[i];
                }
                output.push(temp);
            }
        }
        return "{" + output.join() + "}";
    }

    if( typeof params == "undefined" || !(params instanceof Object))
    {
	if ((typeof params == "string") && 
	    (typeof deprecated_longitude_param == "number") &&
	    (typeof deprecated_latitude_param == "number") &&
	    (typeof deprecated_zoom_param == "number"))
	    params = {'elementId':params,
		      'longitude:':deprecated_longitude_param,
		      'latitude:':deprecated_latitude_param,
		      'zoom':deprecated_zoom_param};
	else
	{
	    alert("CartoVisor:\nIncorrect parameters");
	    return;
	}
    }

    if( typeof params.elementId == "undefined" || (typeof params.elementId != "string"))
    {
        alert("CartoVisor:\nIncorrect parameter 'elementId'");
        return;
    }

    if( (typeof params.longitude != "undefined") && (typeof params.longitude == "number"))
        this.longitud = parseFloat(params.longitude);

    if( (typeof params.latitude != "undefined") && (typeof params.latitude == "number"))
        this.latitud = parseFloat(params.latitude);

    if( (typeof params.zoom != "undefined") && (typeof params.zoom == "number"))
        this.zoom = parseInt(params.zoom);

    this.carto_element = document.getElementById(params.elementId);
    if (!this.carto_element)
    {
        alert("CartoVisor:\nCannot find '" + params.elementId + "' element!");
        return;
    }
    
    this.urlid = this.getUrlId();
    this.component_id = this.getComponentId();

    if (typeof params.onLoadFunction != "undefined")
    {
        if( typeof params.onLoadFunction != "function" && !params.onLoadFunction instanceof Array )
        {
            alert("CartoVisor:\nIncorrect 'onLoadFunction' parameter");
            return;
        }
        else
            eval(this.component_id +"_onload_function = " + params.onLoadFunction + ";");
    }
    else
        eval(this.component_id +"_onload_function = null;");

    if( (typeof params.customSettingsURL != "undefined") && (typeof params.customSettingsURL == "string"))
        this.customSettingsURL = params.customSettingsURL;

    if( (typeof params.zoomBar != "undefined") && (typeof params.zoomBar == "boolean"))
    {
        this.zoomBar = params.zoomBar;
        eval(this.component_id +"_zoomBar = this.zoomBar;");
    }
    else
        eval(this.component_id +"_zoomBar = true;");
     
    if( (typeof params.useCartoCiudadZoomLevels != "undefined") && (typeof params.useCartoCiudadZoomLevels == "boolean"))
    {
        this.useCartoCiudadZoomLevels = params.useCartoCiudadZoomLevels;
        eval(this.component_id +"_useCartoCiudadZoomLevels = this.useCartoCiudadZoomLevels;");
    }
    else
        eval(this.component_id +"_useCartoCiudadZoomLevels = true;");

    if( (typeof params.projection != "undefined") && (typeof params.projection == "string"))
    {
        this.projection = params.projection;
        eval(this.component_id +"_projection = this.projection;");
    }
    else
        eval(this.component_id +"_projection = null;");

    if( (typeof params.overrideSettings != "undefined") && (params.overrideSettings instanceof Object))
    {
        this.overrideSettings = params.overrideSettings;
        eval(this.component_id +"_overrideSettings = this.overrideSettings;");
    }
    else
        eval(this.component_id +"_overrideSettings = null;");
    
    if( (typeof params.overrideLangSettings != "undefined") && (params.overrideLangSettings instanceof Object))
    {
        this.overrideLangSettings = params.overrideLangSettings;
        eval(this.component_id +"_overrideLangSettings = this.overrideLangSettings;");
    }
    else
        eval(this.component_id +"_overrideLangSettings = null;");

    if( (typeof params.baseLayer != "undefined") && (params.baseLayer instanceof Object))
    {
        this.baseLayer = params.baseLayer;
        eval(this.component_id +"_baseLayer = this.baseLayer;");
    }
    else
        eval(this.component_id +"_baseLayer = null;");

    if( typeof params.forceTopSuggestions != "undefined")
    {
	if (typeof params.forceTopSuggestions != "boolean")
	{
	    alert("CartoVisor:\nIncorrect parameter 'forceTopSuggestions'");
	    return;
	}
	eval(this.component_id +"_forceTopSuggestions = params.forceTopSuggestions;");
    }
    else
	eval(this.component_id +"_forceTopSuggestions = false;");

    eval(this.component_id +"_command_buffer=''");
    eval(this.component_id +"_size_option_buffer = null;");
    
    if (!document.body['cv_document_maps'])
        document.body['cv_document_maps'] = [];
    document.body['cv_document_maps'].push(this);
         
    // Vemos si en esos instantes hay otro cargandose.
    this.onloading_any = document.body.getAttribute("onloading_any");
    if (!this.onloading_any)
        this.continueLoading();
    else
        this.cv_paused = true; 
}
