/* 
 * Copyright ¬© 2011 Hydrometeorological Innovative Solutions S.L.
 * All Rights Reserved.

 * This document is the property of Hydrometeorological Innovative Solutions
 * S.L., with the information herein reserved as proprietary to
 * Hydrometeorological Innovative Solutions S.L.

 * No part of this document may be published, reproduced, copied, disclosed in
 * any form or by any means without the written consent of a duly authorized
 * representative of Hydrometeorological Innovative Solutions S.L.
 */
var productInformationCache = new Array();
var productGroupInformationCache = new Array();

function loadViewer(viewerVars)
{
    // create the viewer with the culture
    var viewer = new HydsViewer(viewerVars.div, viewerVars.locale, viewerVars.srid);

    // set the center and the zoom
    viewer.setCenter(viewerVars.centerX, viewerVars.centerY);
    viewer.setZoom(viewerVars.zoomLevel);

    // add the base layers
    viewer.addLayer(viewerVars.baseLayerName, HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+viewerVars.baseLayerName+TILECACHE);

    if(viewerVars.displayRiverLayer)
    {
        viewer.addLayer('rivers', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'rivers'+TILECACHE);
        viewer.setLayerOpacity('rivers', 0.4);
    }

    if(viewerVars.displayCityLayer)
    {
        viewer.addLayer('cities', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'cities'+TILECACHE);
        viewer.setLayerOpacity('cities', 0.4);
    }

    // set the animation parameters
    viewer.setAnimationParams(viewerVars.backward,viewerVars.forward,viewerVars.duration);
    viewer.setNowEpoch(viewerVars.lastObservation);

    // add the components
    if(viewerVars.showClock)
        viewer.addComponent(HydsViewer.COMPONENTS.CLOCK);

    if(viewerVars.showGeneralWindow)
        viewer.addComponent(HydsViewer.COMPONENTS.GENERAL_WINDOW, TILECACHES_WMS+'gdem_green'+TILECACHE, 'gdem_green');

    if(viewerVars.showDetailWindow)
        viewer.addComponent(HydsViewer.COMPONENTS.DETAIL_WINDOW, TILECACHES_WMS+'atlogis_dark'+TILECACHE, 'atlogis_dark');

    if(viewerVars.showValues)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.VALUE, SIGN_VALUES);
        viewer.setValues([viewerVars.values, viewerVars.slaveValues]);
    }

    if(viewerVars.showPalette)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.PALETTE);
        viewer.setPaletteProduct(PALETTE_URL+viewerVars.locale+'/'+viewerVars.paletteName+'.png');
    }

    if(viewerVars.displayRoadsLayer && !viewerVars.displayRoadsOverProduct)
    {
        viewer.addLayer('roads', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'roads'+TILECACHE);
        viewer.setLayerOpacity('roads', 0.4);
    }

    if(viewerVars.shapes != undefined)
    {
        for(var i=0; i < viewerVars.shapes.length; i++)
        {
            console.log(viewerVars.shapes[i]);
            //viewer.addLayer(viewerVars.shapes[i], HydsViewer.LAYERS_TYPE.GML, viewerVars.shapes[i]);
            //viewer.setLayerOpacity(viewerVars.shapes[i], 0);
        }
    }

    // add the product layer
    viewer.addLayer(viewerVars.layerName, viewerVars.layerType, viewerVars.layerUrl, viewerVars.layerCoords);
    viewer.setLayerOpacity(viewerVars.layerName,0.6);

    // add the lightning alarms
    if(viewerVars.showLightningAlarms)
        viewer.addLayer('alarms', HydsViewer.LAYERS_TYPE.LIGHTNING_ALARM, viewerVars.lightningAlarms);

    if(viewerVars.displayRoadsLayer && viewerVars.displayRoadsOverProduct)
    {
        viewer.addLayer('roads', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'roads'+TILECACHE);
        viewer.setLayerOpacity('roads', 0.4);
    }

    if(viewerVars.showBoxes)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.BOXES);

        if(viewerVars.boxes.data_alert > 0)
            viewer.addBox('data_alert', viewerVars.boxes.data_alert_text, viewerVars.boxes.data_alert_color+' generic', null);

        if(viewerVars.boxes.data_alert_slave > 0)
            viewer.addBox('data_alert_slave', viewerVars.boxes.data_alert_text_slave, viewerVars.boxes.data_alert_color_slave+' generic', null);




        if(viewerVars.boxes.no_data_level > 0)
        {
            viewer.addBox('no_data', viewerVars.boxes.no_data_text, viewerVars.boxes.no_data_color+' generic', null);

            if(viewerVars.boxes.no_data_level_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, viewerVars.boxes.no_data_color_slave+' generic', null);
            else if(viewerVars.boxes.frame_state_add_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, 'orange generic', viewerVars.boxes.frame_state_slave);
        }
        else
        {
            if(viewerVars.boxes.no_data_level_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, viewerVars.boxes.no_data_color_slave+' generic', null);

            if(viewerVars.boxes.frame_state_add > 0)
                viewer.addBox('no_data', viewerVars.boxes.no_data_text, 'orange generic', viewerVars.boxes.frame_state);

            if(viewerVars.boxes.frame_state_add_slave > 0 && viewerVars.boxes.no_data_level_slave == 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, 'orange generic', viewerVars.boxes.frame_state_slave);
        }
    }

    viewer.addComponent(HydsViewer.COMPONENTS.SCALE);

    if(viewerVars.showPoints)
        return renderPoints(viewerVars, viewer);
    else
        return viewer;

}

function renderPoints(viewerVars, viewer)
{
    if(viewerVars.pointsCoords != null)
    {
        //add the point mark
        viewer.addLayer('vector', HydsViewer.LAYERS_TYPE.VECTOR);
        for(var i=0; i < viewerVars.pointsCoords.length; i++)
        {
            var isMain = (viewerVars.centerX == viewerVars.pointsCoords[i].lon) && (viewerVars.centerY == viewerVars.pointsCoords[i].lat);
            viewer.addPoint('vector', viewerVars.pointsCoords[i].lon, viewerVars.pointsCoords[i].lat, viewerVars.idPoint, viewerVars.pointsColors[i], isMain);
        }
    }

    return viewer;
}

function loadViewerMedusa(viewerVars)
{
    // create the viewer with the culture
    var viewer = new HydsViewer(viewerVars.div, viewerVars.locale, viewerVars.srid);

    // set the center and the zoom
    viewer.setCenter(viewerVars.centerX, viewerVars.centerY);
    viewer.setZoom(viewerVars.zoomLevel);

    // add the base layers
    viewer.addLayer(viewerVars.baseLayerName, HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+viewerVars.baseLayerName+TILECACHE);

    // set the animation parameters
    viewer.setAnimationParams(viewerVars.backward,viewerVars.forward,viewerVars.duration);
    viewer.setNowEpoch(viewerVars.lastObservation);

    // add the components
    if(viewerVars.showClock)
        viewer.addComponent(HydsViewer.COMPONENTS.CLOCK);

    if(viewerVars.showGeneralWindow)
        viewer.addComponent(HydsViewer.COMPONENTS.GENERAL_WINDOW, TILECACHES_WMS+'gdem_green'+TILECACHE, 'gdem_green');

    if(viewerVars.showDetailWindow)
        viewer.addComponent(HydsViewer.COMPONENTS.DETAIL_WINDOW, TILECACHES_WMS+'atlogis_dark'+TILECACHE, 'atlogis_dark');

    if(viewerVars.showValues)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.VALUE, SIGN_VALUES);
        viewer.setValues([viewerVars.values, viewerVars.slaveValues]);
    }

    if(viewerVars.showPalette)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.PALETTE);
        viewer.setPaletteProduct(PALETTE_URL+viewerVars.locale+'/'+viewerVars.mainProductType+'.png');
    }




    if(viewerVars.displayRiverLayer && !viewerVars.displayRiverOverProduct)
    {
        viewer.addLayer('rivers', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'rivers'+TILECACHE);
        viewer.setLayerOpacity('rivers', 0.6);
    }

    if(viewerVars.displayCityLayer && !viewerVars.displayCityOverProduct)
    {
        viewer.addLayer('cities', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'cities'+TILECACHE);
        viewer.setLayerOpacity('cities', 0.6);
    }

    if(viewerVars.displayRoadsLayer && !viewerVars.displayRoadsOverProduct)
    {
        viewer.addLayer('roads', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'roads'+TILECACHE);
        viewer.setLayerOpacity('roads', 0.4);
    }

    if(viewerVars.displayAirportsLayer != undefined && viewerVars.displayAirportsLayer && !viewerVars.displayAirportsOverProduct)
    {
        viewer.addLayer('aero', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'aero'+TILECACHE);
        viewer.setLayerOpacity('aero', 0.4);
    }



    if(viewerVars.shapes != undefined)
    {
        for(var i=0; i < 1/*viewerVars.shapes.length*/; i++)
        {
            //console.log(viewerVars.shapes[i]);
            //viewer.addLayer(viewerVars.shapes[i], HydsViewer.LAYERS_TYPE.GML, viewerVars.shapes[i]);
            //viewer.setLayerOpacity(viewerVars.shapes[i], 0);
        }
    }

    // add the product layer
    for(var i=0; i < viewerVars.products_length; i++)
    {
        var prod = viewerVars.products[i];
        if(prod != undefined)
        {            
            switch(prod.productType)
            {
                case'satellite':
                case'accumulation_window':
                case'radcast':
                case'reflectivity':
                case'hydroalert':
                    viewer.addLayer(prod.layerName, prod.layerType, prod.layerUrl, prod.layerCoords);
                    viewer.setLayerOpacity(prod.layerName,0.8);
                    break;
            }
        }
    }

    if(viewerVars.displayRiverLayer && viewerVars.displayRiverOverProduct)
    {
        viewer.addLayer('rivers', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'rivers'+TILECACHE);
        viewer.setLayerOpacity('rivers', 0.6);
    }

    if(viewerVars.displayCityLayer && viewerVars.displayCityOverProduct)
    {
        viewer.addLayer('cities', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'cities'+TILECACHE);
        viewer.setLayerOpacity('cities', 0.4);
    }

    if(viewerVars.displayRoadsLayer && viewerVars.displayRoadsOverProduct)
    {
        viewer.addLayer('roads', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'roads'+TILECACHE);
        viewer.setLayerOpacity('roads', 0.6);
    }

    if(viewerVars.displayAirportsLayer != undefined && viewerVars.displayAirportsLayer && viewerVars.displayAirportsOverProduct)
    {
        viewer.addLayer('aero', HydsViewer.LAYERS_TYPE.BASE, TILECACHES_WMS+'aero'+TILECACHE);
        viewer.setLayerOpacity('aero', 0.4);
    }

    if(viewerVars.showGraticule)
    {
        viewer.addLayer('graticule', HydsViewer.LAYERS_TYPE.GRATICULE);
    }

    // add the product layer
    for(var i=0; i < viewerVars.products_length; i++)
    {
        var prod = viewerVars.products[i];
        if(prod != undefined)
        {
            switch(prod.productType)
            {
               case 'lightning':
                    viewer.addLayer(prod.layerName, prod.layerType);
                    for(var j=0; j < prod.lightnings.length; j++)
                    {
                        var l=prod.lightnings[j];
                        viewer.addLightning(prod.layerName, l.x, l.y, l.time);
                    }
                    break;

                case 'lightning_alarm':
                case 'rad-tram_alarm':
                case 'cb-tram_alarm':
                    viewer.addLayer(prod.layerName, prod.layerType, prod.lightningAlarms);
                    break;

                case 'hydroalert_alarm':
                    viewer.addLayer(prod.layerName, prod.layerType, prod.hydroalert_angles);
                    break;

                case 'rad-tram':
                case 'cb-tram':
                    viewer.addLayer(prod.layerName, prod.layerType, prod.trams);
                    break;

                case 'points':
                    //add the point mark
                    viewer.addLayer(prod.layerName, prod.layerType);
                    for(var j=0; j < prod.coords.length; j++)
                    {
                        var lon = prod.coords[j].lon;
                        var lat = prod.coords[j].lat;
                        var isMain = (viewerVars.centerX == lon) && (viewerVars.centerY == lat);
                        viewer.addPoint(prod.layerName, lon, lat, prod.idPoint[j], prod.colors[j], isMain);
                    }
                    break;

                case 'metar':
                    viewer.addLayer(prod.layerName, prod.layerType);
                    for(var j=0; j < prod.metars.length; j++)
                    {
                        viewer.addMetar(prod.layerName, prod.metars[j]);
                    }
                    break;
            }
        }
    }
    
    if(viewerVars.showBoxes)
    {
        viewer.addComponent(HydsViewer.COMPONENTS.BOXES);

        if(viewerVars.boxes.data_alert > 0)
            viewer.addBox('data_alert', viewerVars.boxes.data_alert_text, viewerVars.boxes.data_alert_color+' generic', null);

        if(viewerVars.boxes.data_alert_slave > 0)
            viewer.addBox('data_alert_slave', viewerVars.boxes.data_alert_text_slave, viewerVars.boxes.data_alert_color_slave+' generic', null);




        if(viewerVars.boxes.no_data_level > 0)
        {
            viewer.addBox('no_data', viewerVars.boxes.no_data_text, viewerVars.boxes.no_data_color+' generic', null);

            if(viewerVars.boxes.no_data_level_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, viewerVars.boxes.no_data_color_slave+' generic', null);
            else if(viewerVars.boxes.frame_state_add_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, 'orange generic', viewerVars.boxes.frame_state_slave);
        }
        else
        {
            if(viewerVars.boxes.no_data_level_slave > 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, viewerVars.boxes.no_data_color_slave+' generic', null);

            if(viewerVars.boxes.frame_state_add > 0)
                viewer.addBox('no_data', viewerVars.boxes.no_data_text, 'orange generic', viewerVars.boxes.frame_state);

            if(viewerVars.boxes.frame_state_add_slave > 0 && viewerVars.boxes.no_data_level_slave == 0)
                viewer.addBox('no_data_slave', viewerVars.boxes.no_data_text_slave, 'orange generic', viewerVars.boxes.frame_state_slave);
        }
    }

    return viewer;
}

function renderPoints(viewerVars, viewer)
{
    if(viewerVars.pointsCoords != null)
    {
        //add the point mark
        viewer.addLayer('vector', HydsViewer.LAYERS_TYPE.VECTOR);
        for(var i=0; i < viewerVars.pointsCoords.length; i++)
        {
            var isMain = (viewerVars.centerX == viewerVars.pointsCoords[i].lon) && (viewerVars.centerY == viewerVars.pointsCoords[i].lat);
            viewer.addPoint('vector', viewerVars.pointsCoords[i].lon, viewerVars.pointsCoords[i].lat, viewerVars.idPoint, viewerVars.pointsColors[i], isMain);
        }
    }

    return viewer;
}

/*
 * function that receives the EVENT_ANIMATION_PLAY
 * Simply resume/init the animation
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 */
function viewer_eventAnimationPlay(idElemTrigg){  
  
  viewer.start();//start animation

}
/*
 * function that receives the EVENT_ANIMATION_PAUSE
 * Simply pauses the animation
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 */
function viewer_eventAnimationPause(idElemTrigg){
    viewer.pause();//pause the animation

}
/*
 * function that receives the EVENT_ANIMATION_STOP
 * Not implemented for the moment
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 */
function viewer_eventAnimationStop(idElemTrigg){

}
/*
 * function that receives the EVENT_SET_EPOCH
 * Pauses the animation and set the corresponding frame
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {int} epoch is the epoch to set
 */
function viewer_eventSetEpoch(idElemTrigg,epoch){
   //first check if the element that has triggered the event is not animation_control. If so, just abandon

    if (idElemTrigg=="animation_control")
        return;
   //what to do is pause animation and set the new frame
    viewer.setFrame(epoch);

    triggerEventAnimationPause('viewer');
}
/*
 * function that receives the EVENT_SET_ZOOM_OPTIONS
 * Stablish the new zoom level
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {integer} zoomLevel is the new zoom to stablish
 */
function viewer_eventSetZoomOptions(idElemTrigg,zoomLevel){
       
    viewer.setZoom(zoomLevel);
    
}

/*
 * This function receives the EVENT_SET_PRODUCT_EPOCH event and call functions to do corresponding actions
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {int} epoch is the epoch to set
 * @param {string} productId is the id of the product to show
 * @param {bool} higherValues is the higer values of the product to highlight
 *
 */
    function viewer_eventSetProductEpoch(idElemTrigg,epoch,productId,higherValues){

       var productName=getProductNameById(productId);//first get the product name of the selected one
       //check if id_group_product is stablished. This means we have to obtain info about the frame duration and reload it
            if ('undefined' != typeof(id_group_product))
                 var productDuration=parseInt(getProductDurationById(productId,id_group_product),10);//get the new frame duration and stablish
       setProductAndFrame(productName, productId, epoch,higherValues,productDuration);//call function to set the product and corresponding frame
    }

/**
 * function that receives the EVENT_SET_NOW_EPOCH
 * Restart viewer with the new values
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {int} epoch is the epoch to set
 */    
    function viewer_eventSetNowEpoch(idElemTrigg,epoch){

        viewer.setNowEpoch(epoch);//restart viewer

        var epoch_params = '&start='+(epoch - backward + 2*duration)+'&end='+epoch;
        
        var url = '/frontend.php/es/query/values'+params+epoch_params;

        values = loadHistorical(url);

        viewer.setValues([values.values, null]);
    }

    function loadHistorical(url){

        var valsAndDirs;
        //do an ajax call to obtain values from db
         $.ajax({
            async: false,
            type: "GET",
            url: url,
            dataType: 'json',
            success: function( vars ){
                valsAndDirs=vars;
            }
        });

      return valsAndDirs;

    }
    
/*
 * This function obtains the product name of a corresponding product from its id
 * @param {string} productId is the id of the product to search
 * @return {string} corresponding product name
 */
    function getProductNameById(productId){

      //first check if the product information has been cached before  
        if (typeof(productInformationCache[productId])=="undefined")
            productInformationCache[productId]=getProductInfoById(productId);
     //return values
     return productInformationCache[productId].path;
    
}

/*
 * This function obtains the product name of a corresponding product from its id
 * @param {string} productId is the id of the product to search
 * @return {string} corresponding product name
 */
    function getProductTextById(productId){

      //first check if the product information has been cached before
        if (typeof(productInformationCache[productId])=="undefined")
            productInformationCache[productId]=getProductInfoById(productId);
     //return values
     return productInformationCache[productId].text;

}

/*
 * This function obtains the group product duration of a corresponding product and group
 * @param {string} productId is the id of the product
 * @param {string} groupId is the id of the group
 * @return {string} corresponding product duration
 */
    function getProductDurationById(productId, groupId){

      //first check if the product information has been cached before  
        if (typeof(productGroupInformationCache[productId])=="undefined")
            productGroupInformationCache[productId]=getProductGroupInfoById(productId,groupId);
     //return values
     return productGroupInformationCache[productId].n_cells;
    
}

/*
 * function that receives the EVENT_SET_LAYER_OPTIONS
 * Remove, add or change visibility of some components/layers
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {string} viewerLayerName is the name of the current base layer
 * @param {array} options contains information about the new base layer: name and url
 */
function viewer_eventSetLayerOptions(idElemTrigg,viewerLayerName,options){
    
   //distinguish the actions to do depending on the element that has trigger the event     
        //if the event has been triggered by the layer menu
        if (idElemTrigg=='layer_menu'){
          //depending on the options passed, must do an action or another  
            if (options.layerVisibility)//indicates we want to show or hide a layer
                changeLayersOpacity(viewerLayerName,0);
            else if (options.layerTransparency)//change layer transparency
                changeLayersOpacity(viewerLayerName,0.4);
        }
        else//is a change base layer action
            changeBaseLayer(viewerLayerName,options);
    //finally set a proper zIndex for the current base layer    
    viewer.olMap.getLayersByName(getCurrentBaseLayer())[0].setZIndex(1000);


}
/*
 * function that receives the EVENT_SET_COMPONENT_OPTIONS
 * Changes different values from components
 * @param {string} idElemTrigg is the id of the element that has triggered the event
 * @param {object} viewerComponentName is the name of the components to modify
 * @param {array} options contains new information about the component
 */
function viewer_eventSetComponentOptions(idElemTrigg,viewerComponentName,options){
    
    //depending on the options passed, you do an action or another
    if (options.componentVisibility)//change the visibility of a component
        changeComponentsVisibility(viewerComponentName);
    
    //finally set a proper zIndex for the current base layer    
    viewer.olMap.getLayersByName(getCurrentBaseLayer())[0].setZIndex(1000);

}

/**
 * This function changes the base layer for a new one
 * @param {param} viewerLayerName is the current layer
 * @param {array} options contains the new layer name and the new layer url 
 */
function changeBaseLayer(viewerLayerName,options){
    
    viewer.removeLayer(viewerLayerName);//remove current layer
    viewer.addLayer(options.layer_name, HydsViewer.LAYERS_TYPE.BASE, options.layer_url);//add layer with given url and name
    changeBaseLayerComponent();//changes the base layer of components

}

/**
 * This function changes the opacity of a given layer from a min to a max and viceversa
 * @param {param} viewerLayerName is the layer to change opacity
 * @param {array} minOpacity stablish the minimum opacity
 */
function changeLayersOpacity(viewerLayerName,minOpacity){
    
    //first get current opacity of a layer
    var currentOpacity=viewer.getLayerOpacity(viewerLayerName);

    //obtain folder name from viewer
    var folderName = getViewerFolderName();

    //determine the maximum opacity to be showed. If its the layer of current product is 0.8 otherwise 1
    var maxOpacity = (viewerLayerName == folderName ? 0.6 : 1);

    console.log(folderName);
    //determine max and min opacity depending on special cases
        //first, if minOpacity is equal to 0 (means we have checked the visibility option)
        if (minOpacity == 0){
            //check if transparency is activated to have a maximum of 0.4
            if ($("#layer_menu_transparency").attr('checked'))
                maxOpacity = 0.4;
        }
        //else, we have checked the transparency option
        else{
            //check if the visibility option is deactivated, that means we have to do nothing
              if (!$("#layer_menu_product").attr('checked'))
                  return;
        }
                        
    //finally set the new opacity. Stablish minOpacity if current is higher or the maximum otherwise
    var opacity = (currentOpacity > minOpacity ? minOpacity : maxOpacity);
    console.log(opacity);
    viewer.setLayerOpacity (viewerLayerName,(currentOpacity > minOpacity ? minOpacity : maxOpacity)); 
        
}

/**
 * This function changes the visibility of a component
 * @param {string} viewerLayerName is the name of a component
 */
function changeComponentsVisibility(viewerLayerName){
    
  //obtain the component code 
  var codeComponent=obtainCodeComponent(viewerLayerName);
   //if the code is -1, is an error
        if (codeComponent == -1){
            console.log("[ERROR]: Component "+viewerLayerName+" not found");
            return;
        }
    //now, if the component exists just remove it; otherwise add it
        if (existsComponent(codeComponent))
            viewer.removeComponent(codeComponent);
        else
           insertNewComponent(codeComponent);      
   
}

/**
 * This function returns the code of a component from a name
 * @param {string} viewerLayerName is the name of the component 
 * @return the corresponding code for the name
 */
function obtainCodeComponent(viewerLayerName){
    
    switch (viewerLayerName){
        
        case 'detailed_window':
            return HydsViewer.COMPONENTS.DETAIL_WINDOW;
            
        case 'main_window':
            return HydsViewer.COMPONENTS.GENERAL_WINDOW;
            
        case 'palette':
            return HydsViewer.COMPONENTS.PALETTE;
        
        default:
            return -1;
            
        
    }
}

/**
 *  Searchs for a component and indicates if its on the map or not
 *  @param codeComponent is the component to search
 */
function existsComponent(codeComponent){
    
    for(var i=0; i < viewer.components.length; i++)
    {
        if(viewer.components[i].getType() == codeComponent)
            return true;
    }
    
    return false;
}

/**
 * Search if the general window component is stablished and change its base layer
 */

function changeBaseLayerComponent(){
    
    //look for all components
        for(var i=0; i < viewer.components.length; i++){
           //if the component is general window
            if (viewer.components[i].getType()==HydsViewer.COMPONENTS.GENERAL_WINDOW){
                //first remove the component
                viewer.removeComponent(HydsViewer.COMPONENTS.GENERAL_WINDOW);
                //finally insert again, it will search for the new base layer
                insertNewComponent(HydsViewer.COMPONENTS.GENERAL_WINDOW);
                break;
            }          
    } 

}

/**
 * Inserts a new component depending on its code
 * @param codeComponent is the code of the component to insert
 */
   function insertNewComponent(codeComponent){
   
   //obtain the layer name and its layer url
   var layerName=getCurrentBaseLayer();
   var layerUrl=TILECACHES_WMS+layerName+TILECACHE;
   //get locale and palette name from viewer
   var locale= getLocaleViewer();
   var paletteName = getPaletteNameViewer();
        
   //switch and insert the component that corresponds  
      switch (codeComponent){
        //general window  
        case HydsViewer.COMPONENTS.GENERAL_WINDOW:
         viewer.addComponent(HydsViewer.COMPONENTS.GENERAL_WINDOW, layerUrl, layerName);
         break;
        //detail window, always set atlogis_dark 
        case HydsViewer.COMPONENTS.DETAIL_WINDOW:     
           viewer.addComponent(HydsViewer.COMPONENTS.DETAIL_WINDOW,  TILECACHES_WMS+'atlogis_dark'+TILECACHE, 'atlogis_dark');
           break;
        //set palette   
        case HydsViewer.COMPONENTS.PALETTE:
            viewer.addComponent(HydsViewer.COMPONENTS.PALETTE);
            viewer.setPaletteProduct(PALETTE_URL+locale+'/'+paletteName+'.png');
            break;

         default:
            break;
      }

    }



/*
 * This function find the name of the current map layer. It is used when trigger the event, just to erase this one
 * @return {string} name of current base layer; if not found return "null" string 
 */
function getCurrentBaseLayer(){
    
    var layers,nameL;
    //get all layers with class WMS
    layers=viewer.olMap.getLayersByClass("OpenLayers.Layer.WMS");
    //loop throw all this layers
        for (var i=0; i<layers.length; i++){
            
            nameL=layers[i].name;
            //if name of layer starts with gdem or atlogis, means its the current base layer and return the name
            // this will be change in a future hydsViewer implementation
                if (nameL.split("_")[0]=='gdem' || nameL.split("_")[0]=='atlogis')
                    return nameL;
            
        }
    //if not found return null as string    
    return "null";
}

/**
 * Create a Canvas inside a div
 * @param canvasdiv     A div where you want to insert a canvas
 */
/*BE CAREFUL: There's a function inside flot library called constructCanvas (do not rename this function) */
    function construCanvas(canvasdiv) {
       var canvasWidth     = canvasdiv.width();
       var canvasHeight    = canvasdiv.height();
       var placeholder     = canvasdiv;

       placeholder.html(""); // clear placeholder

       if (canvasWidth <= 0 || canvasHeight <= 0)
           alert("Bad width height arguments for construCanvas: width="+canvasWidth+"Height="+canvasHeight);

       if ($.browser.msie && parseInt($.browser.version) < 9) // excanvas hack
           window.G_vmlCanvasManager.init_(document); // make sure everything is setup

       // the canvas
       var canvas = $(createCanvas(canvasWidth, canvasHeight)).appendTo(placeholder).get(0);

       return canvas;

    }
    
  /**
   * This function parse an string array, check for a element, changes its value and then construct the array again
   * @param {string} stringArray is the array string to be modified
   * @param {string} needle is the element we want to modify
   * @param {string} newValue is the new value to associate with the element
   * @param {string} separator is the character to split the url
   * @return {string} the array with value newValue in the element needle
   */  
    function parseAndConstructString(stringArray,needle,newValue,separator){
       
       //first split the array using the separator indicated
       var url= stringArray.split(separator);
       //find the position of the element needle in the array
       var index=$.inArray( needle, url);
       //substitute its value for the new one
       url[index + 1]=newValue;
       //now we have to construct the array string with the new value
       var newUrl='';
       
            for(var i=0; i< (url.length - 1); i++)
                newUrl+=(url[i]+separator);

        newUrl+=url[i];//in last case don't include the separator!
        //finally return the value 
         return newUrl;
    }

