/* ===========================================================================
 * Pelmorex Satellite & Radar + NowCasting
 * Daniel Fu, March 2009
 * Description: common function for VE map and configuration
 * ===========================================================================
 */

var IE6 = /msie|MSIE 6/.test( navigator.userAgent );
Pelm.Map.Tile.delay_ms = 400;
Pelm.lang = lang;
//Pelm.debug = true;
Pelm.debug = false;
var timeoutMapTimer = null;
var msg_css_start = '<div class="rollover-top"></div><div class=\"rollover\"><div class=\"rollovercamera\">';
var msg_css_end = '</div></div><div class="rollover-bottom"></div>';

/*<PROFILED>*/
var cityPlacecode ='';  //caon0696
var cityLocName ='';    //Toronto
var cityProvince ='';   //ON
var cityFlag = 0;       //1:profiled user; 0:un-profiled user
var locationIcon = '/common/images/maps/locationIcon.png'; //marker for profiled and searched city on the map
var fullForecastTxt = new Array();
fullForecastTxt['en'] = 'Full forecast for ';
fullForecastTxt['fr'] = 'Toutes les prévisions pour ';
var defaultMapSavedMsg = new Array();
defaultMapSavedMsg['en'] = 'Default map saved';
defaultMapSavedMsg['fr'] = 'Carte par défaut sauvegardée';

var markerFlag = 0;     //1:location marker yes; 0:no
var markerData = '';     //marker info: latlon; cityname; province abbr
/*<PROFILED>*/

/**
 * Coverage and error messages
 *
 * Note: accented characters need to be converted to HTML entities. You can use
 *       the HTML encoder tool on this site:
 *       http://web.forret.com/tools/html_large.asp
 */

var messages =
{
    'no_coverage' :
    {
        'en' : 'Coverage not available',
        'fr' : 'Couverture non disponible'
    },

    'no_coverage_zoom' :
    {
        'en' : msg_css_start + 'Currently, there is no coverage at this zoom level. Please zoom out to see cloud cover, precipitation, and precipitation type display.' + msg_css_end,
        'fr' : msg_css_start + 'Il n&#8217;y a pas d&#8217;information disponible &agrave; cette &eacute;chelle. Faites un zoom arri&egrave;re pour voir les informations.' + msg_css_end
    },

    'no_coverage_satellite_precipitation' :
    {
        'en' : msg_css_start + 'Currently, there is no cloud cover, precipitation, or precipitation type coverage for this area.' + msg_css_end,
        'fr' : msg_css_start + 'Pr&eacute;sentement, il n&#8217;y a pas de couverture nuageuse, de pr&eacute;cipitations ni d&#8217;information sur le type de pr&eacute;cipitations pour cette r&eacute;gion.' + msg_css_end
    },

    'no_coverage_precipitation' :
    {
        'en' : msg_css_start + 'Currently, there is no precipitation or precipitation type coverage for this area.' + msg_css_end,
        'fr' : msg_css_start + 'Pr&eacute;sentement, il n&#8217;y a pas de pr&eacute;cipitations ni d&#8217;information sur le type de pr&eacute;cipitations pour cette r&eacute;gion.' + msg_css_end
    },

    'session_expired' :
    {
        'en' : msg_css_start + 'Your current session has timed out. Please hit the "Refresh Map" button below the map for the latest images.' + msg_css_end,
        'fr' : msg_css_start + 'Votre session est expir&eacute;e. Veuillez cliquer sur le bouton &quot;rafra&#238;chir la carte&quot; ci-dessous pour les derni&egrave;res images.' + msg_css_end
    },

    'vemap_error' :
    {
        'en' : msg_css_start + 'VEMap could not be loaded.' + msg_css_end,
        'fr' : msg_css_start + 'VEMap could not be loaded.' + msg_css_end
    },

    'coverage_error' :
    {
        'en' : 'Could not load coverage data.',
        'fr' : 'Impossible de charger les données de couverture.'
    },

    'not_available' :
    {
        'en' : 'N/A',
        'fr' : 'N/D'
    },
	'label_past' :
	{
		'en' : 'Past',
		'fr' : 'Passé'
	},

	'label_current' :
	{
		'en' : 'Current',
		'fr' : 'Actuel'
	},

	'label_forecast' :
	{
		'en' : 'Forecast',
		'fr' : 'Prévision'
	}
};

/**
 * Layer mapping
 */
var layer_mapping =
{
    'p' :   //past
    {
        'sat' :
        {
            'ir' : 'noaaport_satir'
        },

        'precip' :
        {
//            'intensity' : 'radar',
//              'type' : 'mosaic'
            'intensity' : 'radar',
            'type' : 'radar_type'
        }
    },

    'f' :   //forecast
    {
        'precip' :
        {
            'intensity' : 'nowcast_dbz',
            'type' : 'nowcast_type'
        }
    }
};

/**
 * Tigra sliders
 */
var A_TPL = {
    'b_vertical' : false,
    'b_watch': true,
    'n_controlWidth': 117,
    'n_controlHeight': 7,
    'n_sliderWidth': 16,
    'n_sliderHeight': 7,
    'n_pathLeft' : 1,
    'n_pathTop' : 0,
    'n_pathLength' : 101,
    's_imgControl': '/common/images/maps/slidebar.gif',
    's_imgSlider': '/common/images/maps/slide.gif',
    'n_zIndex': 1
};

var A_TPL_TIMESTEP = {
    'b_vertical' : false,
    'b_watch': true,
    'n_controlWidth': 117,
    'n_controlHeight': 12,
    'n_sliderWidth':21,
    'n_sliderHeight': 12,
    'n_pathLeft' : 1,
    'n_pathTop' : 3,
    'n_pathLength' : 96,
    's_imgControl': '/common/images/maps/slidebar.gif',
    's_imgSlider': '/common/images/maps/slider_blue.gif',
    'n_zIndex': 1
};

var A_INIT_TIMESTEP =
{
    's_divid'         : 'timestep_slider',
    's_form'          : 'frm_satrad',
    's_name'          : 'timestep_slider_value',
    'n_minValue'      : 0,
    'n_maxValue'      : 11,
    'n_value'         : 11,
    'n_step'          : 1,
    'h_onChange'      : 'Pelm.Map.Tile.showTimeFrameByIndex'
};

var A_SPEED_SLIDER = {
    's_divid'         : 'speed_slider',
    's_form'          : 'frm_satrad',
    's_name'          : 'speed_value',
    'n_minValue'      : 50,
    'n_maxValue'      : 1000,
    'n_value'         : Pelm.Map.Tile.delay_ms,
    'n_step'          : 10,
    'b_reverse'       : true
};

var A_OPACITY_SLIDER = {
    's_divid'       : 'opacity_slider',
    's_form'        : 'frm_satrad',
    's_name'        : 'opacity_all',
    'n_minValue'    : 0,
    'n_maxValue'    : 1,
    'n_value'       : 0.8,
    'n_step'        : 0.05,
    'h_onChange'    : 'updateOpacity',
    'b_reverse'       : true
};

/**
 * @description
 */
function disableTimestepSlider()
{
    Pelm.Console.debug( 'disableTimestepSlider' );
    document.getElementById( Pelm.Map.Tile.timestep_slider.e_slider.id ).style.visiblity = 'hidden';
}
/**
 * @description
 */
function enableTimestepSlider()
{
    Pelm.Console.debug( 'enableTimestepSlider' );
    document.getElementById( Pelm.Map.Tile.timestep_slider.e_slider.id ).style.visiblity = 'visible';
}

/**
 * @description
 * Hide the massege box.
 * @param elemId {string} the message box
 */
function hideIndicator( elemId )
{
    if( document.getElementById( elemId ) )
    {
        document.getElementById( elemId ).style.visibility = 'hidden';
    }
}


/**
 * @description
 * Show the indicator box.
 * @param elemId {string} the message box
 */
function showIndicator( elemId )
{
    if( document.getElementById( elemId ) )
    {
        document.getElementById( elemId ).style.visibility = 'visible';

        if( document.getElementById( 'timestamp' ) )
        {
            document.getElementById( 'timestamp' ).style.color = '#2981da';
        }
    }
}

/**
 * @description
 * Show the no-coverage message box with the msg.
 * @param msg {string} the displaying message
 * @param elemId {string} the message box
 */
function showMSG( msg, elemId )
{
    document.getElementById( elemId ).innerHTML = msg;
    document.getElementById( elemId ).style.visibility = 'visible';
}

/**
 * @description
 * chage the opacity depends on the zoom level whenever the map zoomed.
 */
function handleZoom( e )
{
    Pelm.Console.info( 'handleZoom: ' + Pelm.Map.VE.GetZoomLevel() );
    //Pelm.Console.debug( e );

    var view = Pelm.Map.VE.GetMapView();

    Pelm.Util.setInnerHTML( 'stats_zoom_level', Pelm.Map.VE.GetZoomLevel() );
    Pelm.Util.setInnerHTML( 'stats_lat_lon', Pelm.Map.VE.GetCenter() );
    Pelm.Util.setInnerHTML( 'stats_top_left', view.TopLeftLatLong.Latitude + ', ' + view.TopLeftLatLong.Longitude );
    Pelm.Util.setInnerHTML( 'stats_bottom_right', view.BottomRightLatLong.Latitude + ', ' + view.BottomRightLatLong.Longitude );
    var opacity_val;

    // Change opacity settings based on zoom level
    if( Pelm.Map.VE.GetZoomLevel() >= 1 && Pelm.Map.VE.GetZoomLevel() <= 4 )
    {
        enableTimestepSlider();
    }
    else if( Pelm.Map.VE.GetZoomLevel() >= 5 && Pelm.Map.VE.GetZoomLevel() <= 8 )
    {
        enableTimestepSlider();
/*
        opacity_val = 0.8;

        if( Pelm.Map.Tile.opacity_slider )
        {
            Pelm.Map.Tile.opacity_slider.f_setValue( opacity_val );
        }
*/    
    }
/*
    else
    {
        // show no_coverage message
        Pelm.Map.hideLoading();
        showMSG(messages.no_coverage_zoom[ Pelm.lang ], 'myMSGControl');
    }
*/
}

/**
 * @description
 */
function setRequest()
{
    Pelm.Console.info( 'setRequest:' );

    var past_cnt = 0;
    var future_cnt = 0;

    var past_ids = [];
    var future_ids = [];

    var layer_id;
    var parts;
    var subparts;

    var url = '';

    url += Pelm.Map.Tile.proxy;
    url += '?cb=' + Pelm.Map.Tile.callback;

    // separate past and future layer IDs
    for( var i = 0; i < Pelm.Map.Tile.layer_list.length; i++ )
    {
        layer_id = Pelm.Map.Tile.elem_ids.toggle_prefix + Pelm.Map.Tile.layer_list[ i ];

        if( document.getElementById( layer_id ).checked === true )
        {
            parts = Pelm.Map.Tile.layer_list[ i ].split( "_" );

            if( parts[ 0 ] == 'p' )
            {
                past_ids.push( layer_mapping[ parts[ 0 ] ][ parts[ 1 ] ][ parts[ 2 ] ] );
                past_cnt++;
            }
            else if( parts[ 0 ] == 'f' )
            {
                future_ids.push( layer_mapping[ parts[ 0 ] ][ parts[ 1 ] ][ parts[ 2 ] ] );
                future_cnt++;
            }
            else
            {
                subparts = parts[ 0 ].split( "." );

                for( var j = 0; j < subparts.length; j++ )
                {
                    if( subparts[ j ] == 'p' )
                    {
                        past_ids.push( layer_mapping[ subparts[ j ] ][ parts[ 1 ] ][ parts[ 2 ] ] );
                        past_cnt++;
                    }
                    else if( subparts[ j ] == 'f' )
                    {
                        future_ids.push( layer_mapping[ subparts[ j ] ][ parts[ 1 ] ][ parts[ 2 ] ] );
                        future_cnt++;
                    }
                }
            }
        }
    }

    // past layers
    if( past_cnt > 0 )
    {
        url += '&pl=';
        for( var m = 0; m < past_cnt; m++ )
        {
            url += past_ids[ m ];
            url += ( m < past_cnt - 1 ) ? ',' : '';
        }

        url += '&pi=' + Pelm.Map.Tile.interval + '&pd=' + Pelm.Map.Tile.duration;
    }

    // future layers
    if( future_cnt > 0 )
    {
        url += '&fl=';
        for( var n = 0; n < future_cnt; n++ )
        {
            url += future_ids[ n ];
            url += ( n < future_cnt - 1 ) ? ',' : '';
        }
        url += '&fi=' + Pelm.Map.Tile.interval_future + '&fd=' + Pelm.Map.Tile.duration_future;
    }

    // base layer
    url += '&b=';
    if( past_cnt > 0 )
    {
        url += past_ids[ 0 ];
        Pelm.Map.Tile.base_id = past_ids[ 0 ];
    }
    else if( future_cnt > 0 )
    {
        url += future_ids[ 0 ];
        Pelm.Map.Tile.base_id = future_ids[ 0 ];
    }

    // other stuff
    url += '&r=' + Pelm.Map.Tile.rounded;
    url += ( Pelm.Map.Tile.debug === true ) ? '&dbg=1' : '';

    Pelm.Console.debug( url );

    Pelm.Map.Tile.request_url = url;
}

var refreshMapTimer = null;

/**
 * @description
 * Refresh the map
 */
function refreshMap( eventName )
{
    Pelm.Console.info( 'refreshMap: ' + eventName );
    var layer_id;
//    var checkbox_id;
    Pelm.Map.Tile.stopLoop( 'all', 'auto' );

    if(timeoutMapTimer != null){
        hideIndicator('myMSGControl');
        hideIndicator( 'saveSettingMSG');
        window.clearTimeout( timeoutMapTimer );
        timeoutMapTimer = null;
    }
    //show session time time out message after no activity for 10 mins
    var timeOutFunc = "showMSG( messages.session_expired[ Pelm.lang ], 'myMSGControl')";
    timeoutMapTimer = window.setTimeout( timeOutFunc, 600000 );
/* --------------> comment out for current update, since some of the bugs are not fixed yet 18 Aug 2009
    //add border tiles according the map background.
    var mapstyle = Pelm.Map.VE.GetMapStyle();
    if(mapstyle === 'r'){
        Pelm.Map.Tile.border_path = 'http://gisweb01/arcgiscache/VE_Bing/Layers/_alllayers/';
    }
    else if(mapstyle === 'h' || mapstyle === 'a') {
        Pelm.Map.Tile.border_path = 'http://gisweb01/arcgiscache/VE_Bing_Aerial/Layers/_alllayers/';
    }
//    Pelm.Map.Tile.border_path = 'http://gisweb01/arcgiscache/VE_Bing/Layers/_alllayers/';
    Pelm.Map.Tile.addBorderLayer( 'border', 0.6, 109, true);
<-------------- comment out for current update, since some of the bugs are not fixed yet 18 Aug 2009 */

    Pelm.Map.Tile.toggleButton( true, Pelm.Map.Tile.elem_ids.start, Pelm.Map.Tile.html.start_off );

    if( eventName == 'onendzoom' )
    {
        //handleZoom();
        enableTimestepSlider();
    }

    if( window.Pelm.Map.Tile )
    {
        //// use settings from page (if enabled)
        //if( document.getElementById( 'interval_value' ) && document.getElementById( 'duration_value' ) && document.getElementById( 'round_state' ) )
        //{
        //    Pelm.Map.Tile.interval = document.getElementById( 'interval_value' ).value;
        //    Pelm.Map.Tile.duration = document.getElementById( 'duration_value' ).value;
        //    Pelm.Map.Tile.rounded = ( document.getElementById( 'round_state' ).checked === false ) ? 0 : 1;
        //}

        //if( document.getElementById( 'pi' ) && document.getElementById( 'pd' ) && document.getElementById( 'fi' ) && document.getElementById( 'fd' ) && document.getElementById( 'round_state' ) )
        //{
        //    Pelm.Map.Tile.interval = document.getElementById( 'pi' ).value;
        //    Pelm.Map.Tile.duration = document.getElementById( 'pd' ).value;
        //    Pelm.Map.Tile.interval_future = document.getElementById( 'fi' ).value;
        //    Pelm.Map.Tile.duration_future = document.getElementById( 'fd' ).value;
        //    Pelm.Map.Tile.rounded = ( document.getElementById( 'round_state' ).checked === false ) ? 0 : 1;
        //}
        // autoplay
        if( document.getElementById( 'autoplay' ) )
        {
            Pelm.Map.Tile.autoplay = document.getElementById( 'autoplay' ).checked;
        }

        if( Pelm.Map.VE.GetZoomLevel() > Pelm.Map.Tile.max_zoom_level )
        {
            Pelm.Map.hideLoading();
            showMSG(messages.no_coverage_zoom[ Pelm.lang ],'myMSGControl');

            for( var j = 0; j < Pelm.Map.Tile.layer_list.length; j++ )
            {
                layer_id = Pelm.Map.Tile.layer_list[ j ];
                document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + layer_id ).disabled = true;
            }

            Pelm.Map.Tile.toggleButtonsAll( 'off' );
            disableTimestepSlider();
        }
        else
        {
            Pelm.Map.Tile.init();
            saveMapSettings(0); //create a cookie
            if( Pelm.Map.Tile.has_coverage === true && Pelm.Map.VE.GetZoomLevel() <= Pelm.Map.Tile.max_zoom_level )
            {
                for( var k = 0; k < Pelm.Map.Tile.layer_list.length; k++ )
                {
                    layer_id = Pelm.Map.Tile.layer_list[ k ];
                    document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + layer_id ).disabled = false;
                }
                toggleLogosLegends();
                setRequest();
                Pelm.Map.showLoading();
                Pelm.Map.Tile.sendRequest();
            }
            else
            {
                // Coverage not available
                Pelm.Map.updateStatusBar( 'left', '<span class="status_error">' + messages.no_coverage[ Pelm.lang ] + '</span>' );
            }
            // show coverage messages
            if( Pelm.Map.Tile.coverage_points.noaaport_satir === 0 )
            {
                Pelm.Map.hideLoading();
                showMSG( messages.no_coverage_satellite_precipitation[ Pelm.lang ], 'myMSGControl' );
                Pelm.Map.Tile.toggleButtonsAll( 'off' );
                // disable all checkboxes
                for( var m = 0; m < Pelm.Map.Tile.layer_list.length; m++ )
                {
                    layer_id = Pelm.Map.Tile.layer_list[ m ];
                    document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + layer_id ).disabled = true;
                }
                disableTimestepSlider();
            }
            else if( Pelm.Map.Tile.coverage_points.radar === 0 || Pelm.Map.Tile.coverage_points.mosaic === 0 )
            {
                Pelm.Map.hideLoading();
                showMSG( messages.no_coverage_precipitation[ Pelm.lang ], 'myMSGControl' );

                // disable precipitation checkboxes
                var parts;
                for( var n = 0; n < Pelm.Map.Tile.layer_list.length; n++ )
                {
                    layer_id = Pelm.Map.Tile.layer_list[ n ];
                    parts = layer_id.split( '_' );

                    if( parts[ 2 ] == 'intensity' || parts[ 2 ] == 'type' )
                    {
                        document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + layer_id ).disabled = true;
                    }
                }
            }
            else
            {
                hideIndicator('myMSGControl');
                enableTimestepSlider();
            }
        }
    }
    return;
}

/**
 * @description
 * Add a delay to the onchangeview event.
 * wait for 2.5 second to refresh the map
 */
function handleRefreshMap( e )
{
    Pelm.Console.reset();
    Pelm.Console.info( 'handleRefreshMap:' );
    Pelm.Console.debug( e );

    var view = Pelm.Map.VE.GetMapView();

    Pelm.Util.setInnerHTML( 'stats_zoom_level', Pelm.Map.VE.GetZoomLevel() );
    Pelm.Util.setInnerHTML( 'stats_lat_lon', Pelm.Map.VE.GetCenter() );
    Pelm.Util.setInnerHTML( 'stats_top_left', view.TopLeftLatLong.Latitude + ', ' + view.TopLeftLatLong.Longitude );
    Pelm.Util.setInnerHTML( 'stats_bottom_right', view.BottomRightLatLong.Latitude + ', ' + view.BottomRightLatLong.Longitude );
    if( Pelm.Map.Tile.animating === true )
    {
        Pelm.Map.Tile.stopLoop( 'all', 'auto' );
    }
    enableTimestepSlider();

    if( Pelm.Map.VE.GetZoomLevel() <= Pelm.Map.Tile.max_zoom_level )
    {
        // if the timer is set, clear it and reset it
        if( refreshMapTimer !== null )
        {
            window.clearTimeout( refreshMapTimer );
        }
        refreshMapTimer = window.setTimeout( 'refreshMap( \'' + e.eventName + '\' )', 2500 );
    }
    else
    {
        Pelm.Map.hideLoading();
        showMSG(messages.no_coverage_zoom[ Pelm.lang ], 'myMSGControl' );

        //Pelm.Map.Tile.toggleButton( true, Pelm.Map.Tile.elem_ids.start, Pelm.Map.Tile.html.start_off );
        Pelm.Map.Tile.toggleButtonsAll( 'off' );
    }
}

/**
 * @description
 * update the opacity to the pass in parameter
 * @param val {integer} the value of the opacity, range: 0 - 1
 */
function updateOpacity( val )
{
    var layer_id;
    for( var i = 0; i < Pelm.Map.Tile.layer_list_active.length; i++ )
    {
        layer_id = Pelm.Map.Tile.layer_list_active[ i ];
        // adjust slider
        if( Pelm.Map.Tile[ Pelm.Map.Tile.elem_ids.opacity_prefix + layer_id + Pelm.Map.Tile.elem_ids.slider_suffix ] )
        {
            Pelm.Map.Tile[ Pelm.Map.Tile.elem_ids.opacity_prefix + layer_id + Pelm.Map.Tile.elem_ids.slider_suffix ].f_setValue( val );
        }

        // adjust opacity
            Pelm.Map.Tile.updateOpacity( layer_id, val );
    }
}

/**
 * @description
 * Toggle logos and legends
 * This method supports the toggling of 2 types:
 *   1. Individual - 1 logo and legend for each checkbox
 *   2. Grouped - 1 logo and legend for each group (e.g., past radar,
 *                past + future radar, future radar)
 * Assuming your checkboxes are:
 *   toggle_p_precip_intensity
 *   toggle_p.f_precip_intensity
 *   toggle_f_precip_intensity
 * use the following naming convention:
 *   1. Individual:
 *        logo_p_precip_intensity
 *        logo_p.f_precip_intensity
 *        logo_f_precip_intensity
 *        legend_p_precip_intensity
 *        legend_p.f_precip_intensity
 *        legend_f_precip_intensity
 *   2. Grouped: (ignores the level1)
 *        logo_precip_intensity
 *        legend_precip_intensity
 */
function toggleLogosLegends()
{
    Pelm.Console.info( 'toggleLogosLegends' );

//    var logo_id, legend_id;
    var logo_id;
    var label_start, label_end;
    label_start = messages.label_past[ Pelm.lang ]; // Past
    label_end = messages.label_current[ Pelm.lang ]; // Current
    if( document.getElementById( 'timestep_slider_label_start' ) )
    {
        document.getElementById( 'timestep_slider_label_start' ).innerHTML = label_start;
    }

    if( document.getElementById( 'timestep_slider_label_end' ) )
    {
        document.getElementById( 'timestep_slider_label_end' ).innerHTML = label_end;
    }
    var state, parts;

    for( var i = 0; i < Pelm.Map.Tile.layer_list.length; i++ )
    {
        parts = Pelm.Map.Tile.layer_list[ i ].split( '_' );

        // toggle individual logos and legends

        state = ( document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + Pelm.Map.Tile.layer_list[ i ] ).checked === true ) ? 'visible' : 'hidden';

        logo_id = Pelm.Map.Tile.elem_ids.logo_prefix + Pelm.Map.Tile.layer_list[ i ];
//        legend_id = Pelm.Map.Tile.elem_ids.legend_prefix + Pelm.Map.Tile.layer_list[ i ];

        if( document.getElementById( logo_id ) )
        {
            document.getElementById( logo_id ).style.visibility = state;
        }

//        if( document.getElementById( legend_id ) )
//        {
//            document.getElementById( legend_id ).style.visibility = state;
//        }

        // toggle time step slider labels

        if( document.getElementById( Pelm.Map.Tile.elem_ids.toggle_prefix + Pelm.Map.Tile.layer_list[ i ] ).checked === true )
        {
            if( parts[ 0 ] == 'p' )
            {
                label_start = messages.label_past[ Pelm.lang ]; // Past
                label_end = messages.label_current[ Pelm.lang ]; // Current

                if( Pelm.Map.VE.GetZoomLevel() > 0 && Pelm.Map.VE.GetZoomLevel() < 5 )
                {
                    Pelm.Map.Tile.interval = 20;
                    Pelm.Map.Tile.duration = 4;
                    //Pelm.Map.Tile.opacity_srp = 0.8;
                }
                else
                {
                    Pelm.Map.Tile.interval = 10;
                    Pelm.Map.Tile.duration = 2;
                }
            }
            else if( parts[ 0 ] == 'p.f' )
            {
                Pelm.Map.Tile.interval_future = 30;
                Pelm.Map.Tile.duration_future = 6;
                Pelm.Map.Tile.interval = 30;
                Pelm.Map.Tile.duration = 6;
                label_start = messages.label_past[ Pelm.lang ]; // Past
                label_end = messages.label_forecast[ Pelm.lang ]; // Forecast
            }
            else if( parts[ 0 ] == 'f' )
            {
                Pelm.Map.Tile.interval_future = 30;
                Pelm.Map.Tile.duration_future = 6;
                Pelm.Map.Tile.interval = 30;
                Pelm.Map.Tile.duration = 6;
                label_start = messages.label_current[ Pelm.lang ]; // Current
                label_end = messages.label_forecast[ Pelm.lang ]; // Forecast
            }
/*            else
            {
                label_start = '';
                label_end = '';
            }
*/
            if( document.getElementById( 'timestep_slider_label_start' ) )
            {
                document.getElementById( 'timestep_slider_label_start' ).innerHTML = label_start;
            }

            if( document.getElementById( 'timestep_slider_label_end' ) )
            {
                document.getElementById( 'timestep_slider_label_end' ).innerHTML = label_end;
            }
        }

        // hide all grouped legends

        parts.splice( 0, 1 ); // remove level 1
        //Pelm.Console.error( parts );

        logo_id = Pelm.Map.Tile.elem_ids.logo_prefix + parts.join( '_' );
//        legend_id = Pelm.Map.Tile.elem_ids.legend_prefix + parts.join( '_' );
        //Pelm.Console.debug( logo_id + ', ' + legend_id );

        if( document.getElementById( logo_id ) )
        {
            document.getElementById( logo_id ).style.visibility = 'hidden';
        }

//        if( document.getElementById( legend_id ) )
//        {
//            document.getElementById( legend_id ).style.visibility = 'hidden';
//        }
    }

    for( var h = 0; h < Pelm.Map.Tile.layer_list_active.length; h++ )
    {
        // show active grouped logos and legends

        parts = Pelm.Map.Tile.reverse_map[ Pelm.Map.Tile.layer_list_active[ h ] ].split( '_' );
        parts.splice( 0, 1 ); // remove level 1

        logo_id = Pelm.Map.Tile.elem_ids.logo_prefix + parts.join( '_' );
//        legend_id = Pelm.Map.Tile.elem_ids.legend_prefix + parts.join( '_' );
        //Pelm.Console.debug( logo_id + ', ' + legend_id );

        if( document.getElementById( logo_id ) )
        {
            document.getElementById( logo_id ).style.visibility = 'visible';
        }

//        if( document.getElementById( legend_id ) )
//        {
//            document.getElementById( legend_id ).style.visibility = 'visible';
//        }
    }
}

/**
 * @description
 */
function toggleLayer( elem )
{
    Pelm.Console.info( 'toggleLayer' );

    // prevent unchecking when the selected layer is still loading
    Pelm.Console.debug( 'checked=' +  elem.checked + ', ready_state=' + Pelm.Map.Tile.ready_state );

    //disable the checkboxes before all the tiles are fully loaded
    if( elem.checked === false && Pelm.Map.Tile.ready_state === false )
    {
        elem.checked = true;
        return false;
    }

    var parts = elem.id.split( "_" );

    var checkbox_id;
    var spinner_id;
    var layer_id;
    var quad_id;

    hideIndicator( 'nowcast_indicator' );

    if( elem.checked === true )
    {
        var all_parts = [];

        // remove existing layers
        for( var h = 0; h < Pelm.Map.Tile.layer_list.length; h++ )
        {
            layer_id = Pelm.Map.Tile.getLayerID( Pelm.Map.Tile.layer_list[ h ] );

            if( Pelm.Map.VE.GetTileLayerByID( layer_id ) )
            {
                Pelm.Console.debug( 'Removing ' + layer_id );
                Pelm.Map.VE.DeleteTileLayer( layer_id );
            }
        }

        for( var i = 0; i < Pelm.Map.Tile.layer_list.length; i++ )
        {
            checkbox_id = Pelm.Map.Tile.elem_ids.toggle_prefix + Pelm.Map.Tile.layer_list[ i ];
            spinner_id = Pelm.Map.Tile.elem_ids.spinner_prefix + Pelm.Map.Tile.layer_list[ i ];
            layer_id = Pelm.Map.Tile.getLayerID( Pelm.Map.Tile.layer_list[ i ] );

            // turn off spinner
            //Pelm.Map.Tile.hideSpinner( layer_id );

            if( checkbox_id != elem.id )
            {
                all_parts = checkbox_id.split( "_" );

                if( all_parts[ 1 ] != parts[ 1 ] )
                {
                    if( document.getElementById( checkbox_id ).checked === true )
                    {
                        Pelm.Console.debug( 'Unchecking ' + checkbox_id );
                        document.getElementById( checkbox_id ).checked = false;
                    }
                }
                else
                {
                    if( all_parts[ 2 ] == parts[ 2 ] )
                    {
                        if( all_parts[ 3 ] != parts[ 3 ] )
                        {
                            if( document.getElementById( checkbox_id ).checked === true )
                            {
                                Pelm.Console.debug( 'Unchecking ' + checkbox_id );
                                document.getElementById( checkbox_id ).checked = false;
                            }
                        }
                    }
                }
            }
        }

        Pelm.Map.Tile.initLayerList();
        toggleLogosLegends();
        //toggleLiveData( 'live_data' ); // TODO: this is for testing purposes
        refreshMap();
    }
    else
    {
        var level1s = [];

        // hide layer tiles
        for( var j = 0; j < Pelm.Map.Tile.layer_list_active.length; j++ )
        {
            layer_id = Pelm.Map.Tile.layer_list_active[ j ];
            checkbox_id = Pelm.Map.Tile.elem_ids.toggle_prefix + Pelm.Map.Tile.reverse_map[ layer_id ];
            //Pelm.Console.debug( 'layer_id=' + layer_id + ', checkbox_id=' + checkbox_id + ', elem.id=' + elem.id );

/*
            // hide unchecked stats
            Pelm.Console.highlight( 'layer_id=' + layer_id + ', checkbox_id=' + checkbox_id + ', elem.id=' + elem.id );
            if( document.getElementById( checkbox_id ).checked === false )
            {
                Pelm.Util.setInnerHTML( 'load_percent_' + Pelm.Map.Tile.reverse_map[ layer_id ], '' );
                Pelm.Util.setInnerHTML( 'load_tiles_num_' + Pelm.Map.Tile.reverse_map[ layer_id ], '' );
                Pelm.Util.setInnerHTML( 'load_secs_' + Pelm.Map.Tile.reverse_map[ layer_id ], '' );
                Pelm.Util.setInnerHTML( 'load_bytes_' + Pelm.Map.Tile.reverse_map[ layer_id ], '' );
                Pelm.Util.setInnerHTML( 'load_type_' + Pelm.Map.Tile.reverse_map[ layer_id ], '' );
            }
*/
            if( parts[ 1 ].match( '.' ) )
            {
                level1s = parts[ 1 ].split( '.' );

                var tmp_id;
                var tmp_layer_id;

                for( var k = 0; k < level1s.length; k++ )
                {
                    tmp_id = level1s[ k ] + '_' + parts[ 2 ] + '_' + parts[ 3 ];
                    tmp_layer_id = layer_mapping[ level1s[ k ] ][ parts[ 2 ] ][ parts[ 3 ] ];
                    //Pelm.Console.debug( tmp_id + ' -> ' + tmp_layer_id );
/*
                    if( Pelm.Map.VE.GetTileLayerByID( tmp_layer_id ) )
                    {
                        for( quad_id in Pelm.Map.Tile.tile_cache[ tmp_layer_id ] )
                        {
                            Pelm.Map.Tile.quad_elems[ tmp_layer_id ][ quad_id ].style.display = 'none';
                        }
                    }
*/
                    if( Pelm.Map.VE.GetTileLayerByID( tmp_layer_id ) )
                    {
                        Pelm.Console.debug( 'Removing ' + tmp_layer_id );
                        Pelm.Map.VE.DeleteTileLayer( tmp_layer_id );
                    }
                }
            }
            else
            {
                if( checkbox_id == elem.id )
                {
                    if( Pelm.Map.VE.GetTileLayerByID( layer_id ) )
                    {
/*
                        for( quad_id in Pelm.Map.Tile.tile_cache[ layer_id ] )
                        {
                            Pelm.Map.Tile.quad_elems[ layer_id ][ quad_id ].style.display = 'none';
                        }
*/
                        if( Pelm.Map.VE.GetTileLayerByID( layer_id ) )
                        {
                            Pelm.Console.debug( 'Removing ' + layer_id );
                            Pelm.Map.VE.DeleteTileLayer( layer_id );
                        }
                    }
                }
            }
        }

        Pelm.Map.Tile.initLayerList();
        toggleLogosLegends();
    }
    return true;
}
/**
 * @description
 * save the user settings for the map
 * @param default_flag {boolean} default setting flag. 1:default; 0:other cookie
 */
function saveMapSettings( default_flag )
{
    if(default_flag){
        createCookie(1);
    }
    else{
        var settings = readCookie();
        if((typeof settings) == 'object'){
            if(settings.default_flag == 0){
                createCookie(0);
            }
        }
        else{
            createCookie(0);
        }
    }
}
/**
 * @description
 * create the cookie
 * @param flag {boolean} default setting flag. 1:default; 0:other cookie
 */
function createCookie( flag )
{
    var cookieStr = '';
    cookieStr = 'default_flag=' + flag;
    cookieStr += '|lat=' + Pelm.Map.VE.GetCenter().Latitude;
    cookieStr += '|lon=' + Pelm.Map.VE.GetCenter().Longitude;
    cookieStr += '|zoom_level=' + Pelm.Map.VE.GetZoomLevel();
    cookieStr += '|map_style=' + Pelm.Map.VE.GetMapStyle();

    var inputElems = document.all ? document.all.tags( 'input' ) : document.getElementsByTagName( 'input' );
    for( var i = 0; i < inputElems.length; i++ )
    {
        if( inputElems[ i ].id != '' ){
            if( inputElems[ i ].type == "checkbox" ){
                Pelm.Console.debug( 'id=' + inputElems[ i ].id + ', type=' + inputElems[ i ].type + ', value=' + inputElems[ i ].value + ', checked=' + inputElems[ i ].checked );
                cookieStr += '|' + inputElems[ i ].id + '=' + inputElems[ i ].checked;
            }
            if( inputElems[ i ].id == "speed_value" || inputElems[ i ].id == "opacity_all" || inputElems[ i ].id == "timestep_slider_value"){
                Pelm.Console.debug( 'id=' + inputElems[ i ].id + ', value=' + inputElems[ i ].value );
                cookieStr += '|' + inputElems[ i ].id + '=' + inputElems[ i ].value;
            }
        }
    }
    //adding the marker info to the cookie
    if(markerFlag == 1 && markerData){
        cookieStr += markerData;
    }
    else{
        var settings = readCookie();
        if(settings.markerFlag  == 1){
            markerFlag = 1;
            markerData = '|markerFlag=' + markerFlag + '|markerLat=' + settings.markerLat + '|markerLon=' + settings.markerLon + '|markerCityName=' + settings.markerCityName + '|markerProv=' + settings.markerProv + '|markerPlaceCode=' + settings.markerPlaceCode;
            cookieStr += markerData;
        }
    }

    if(cookieStr){
        Pelm.Console.debug( cookieStr );
        var cookieObj = new Pelm.Cookie();
        cookieObj.create( 've_layers_1.1', cookieStr, 365 );
        if(flag){
            showMSG( defaultMapSavedMsg[lang], 'saveSettingMSG' );
            //remove save settings message after 5 sec
            var timeOutFunc = "hideIndicator( 'saveSettingMSG')";
            timeoutMapTimer = window.setTimeout( timeOutFunc, 5000 );
        }
    }
}
/**
 * @description
 * read the cookie, and convert it to an array
 */
function readCookie( )
{
    var cookieObj = new Pelm.Cookie();
    var cookieStr = cookieObj.read( 've_layers_1.1' );
    if( cookieStr )
    {
        Pelm.Console.debug( cookieStr );
        //convert the cokkie string to an array
        var pairs = cookieStr.split( '|' );
        var keyval;
        var settings = [];
        for( var j = 0; j < pairs.length; j++ )
        {
            keyval = pairs[ j ].split( '=' );
            settings[ keyval[ 0 ] ] = keyval[ 1 ];
            Pelm.Console.debug(keyval[ 0 ] + '=' + settings[ keyval[ 0 ] ]);
        }
        return settings;
    }
    else{return false;}
}
/**
 * @description
 * Initialize the map.
 */
function initMap()
{
    Pelm.Console.info( 'initMap' );

    if( layer_coverage )
    {
        Pelm.Map.Tile.coverage = layer_coverage; // from coverage.js
        // Load VE map
        if( window.VEMap )
        {
            Pelm.Map.VE = new VEMap( Pelm.Map.id );
            /*<TOKEN>*/
            if(typeof token!= 'undefined' && token != ''){
                Pelm.Map.VE.SetClientToken( token );
            }
            /*<TOKEN>*/
            var options = new VEMapOptions();
            options.EnableBirdseye = false;
            options.EnableDashboardLabels = false;
            Pelm.Map.VE.control = null;

            //Pelm.Map.VE.LoadMap( new VELatLong( Pelm.Map.lat, Pelm.Map.lon ), Pelm.Map.zoom, Pelm.Map.style );
            Pelm.Map.VE.LoadMap( new VELatLong( Pelm.Map.lat, Pelm.Map.lon ), Pelm.Map.zoom, Pelm.Map.style,null, null, null, null,options );
            Pelm.Map.VE.Hide3DNavigationControl();

            //Pelm.Map.VE.SetMapMode(Pelm.Map.VE.VEMapMode.Mode2D);
            document.getElementById('MSVE_navAction_View3DMapMode').style.display="none";       //not show bird's eye
            document.getElementById( 'MSVE_navAction_FlatlandMapMode' ).style.display = "none"; // not shoe 2D
            document.getElementById( 'MSVE_navAction_separator0' ).style.display = "none";      //not show separator0
            document.getElementById( 'MSVE_navAction_separator3' ).style.display = "none";      //not show separator3

            // Attach VE events
            Pelm.Map.VE.AttachEvent( 'onendpan', handleRefreshMap );
            Pelm.Map.VE.AttachEvent( 'onendzoom', handleRefreshMap );
            Pelm.Map.VE.AttachEvent( 'onchangemapstyle', handleRefreshMap );
            //disable the onmousewheel event,
            if(!Pelm.Map.Tile._zoomWheel){
                Pelm.Map.VE.AttachEvent( 'onmousewheel', onMouseWheel);
            }
            Pelm.Map.VE.AttachEvent('ontokenexpire', MyHandleTokenExpire);
            Pelm.Map.VE.AttachEvent('ontokenerror', MyHandleTokenError);

            //Pelm.Map.drawCrosshair();
            Pelm.Map.VE.DeleteAllShapes();
            /*<PROFILED>&<LOCATION ICON>*/
            if(cityFlag){
                setLocationIcon(Pelm.Map.lat, Pelm.Map.lon, cityLocName, cityProvince, cityPlacecode);
                markerFlag = 1;
                markerData = '|markerFlag=' + markerFlag + '|markerLat=' + Pelm.Map.lat + '|markerLon=' + Pelm.Map.lon + '|markerCityName=' + cityLocName + '|markerProv=' + cityProvince + '|markerPlaceCode=' + cityPlacecode;
            }
            else{
                var settings = readCookie();
                if(settings.markerFlag  == 1){
                    markerFlag = 1;
                    setLocationIcon( settings.markerLat,settings.markerLon,settings.markerCityName,settings.markerProv,settings.markerPlaceCode );
                }
            }
            /*<PROFILED>&<LOCATION ICON>*/

            // Load tile layers
            enableTimestepSlider(); //handleZoom();
            Pelm.Map.Tile.initLayerList();
            toggleLogosLegends();
            refreshMap();
        }
        else
        {
            Pelm.Map.hideLoading();
            //Pelm.Map.updateStatusBar( 'left', '<span style="color: #FF0000;">' + messages.vemap_error[ Pelm.lang ] + '</span>' );
        }
    }
    else
    {
        Pelm.Map.hideLoading();
        Pelm.Map.updateStatusBar( 'left', '<span class="status_error">' + messages.coverage_error[ Pelm.lang ] + '</span>' );
    }
}

/**
 * @description
 */
function loadCoverage( src )
{
    Pelm.Console.info( 'loadCoverage' );

    var headElem = document.getElementsByTagName( 'head' ).item( 0 );
    var scriptElem = document.createElement( 'script' );

    scriptElem.setAttribute( 'type', 'text/javascript' );
    scriptElem.setAttribute( 'id', 'coverage' );
    scriptElem.setAttribute( 'src', src + '?noCache=' + ( new Date() ).getTime() );
    Pelm.Console.debug( scriptElem.src );

    scriptElem.onreadystatechange = function()
    {
        // IE uses 'loaded', other browsers use 'complete'
        if( this.readyState == 'complete' || this.readyState == 'loaded' )
        {
            initMap();
        }
    };

    headElem.appendChild( scriptElem );

    scriptElem.onload = initMap;
}

/**
 * @description
 * initialize the VE map
 * setting up the defalt parameters
 * centering the map by the passed in parameters: lat long and zoom
 * @param lat {integer} latitude of the map center
 * @param lon {integer} longitude of the map center
 * @param zoom {integer} the zoom level of the map
 * @param profiledFlag {boolean} true: profiled, false: un-profiled
 * @param placecode {string} city placecode
 * @param name {string} city name
 * @param province {string} city province abbr
 */
function Mapinit(lat, lon, zoom, profiledFlag, placecode, name, province)
{
    Pelm.Map.showLoading();
    Pelm.Console.init();
    Pelm.Console.info( 'init:' );

    // Initialize map values
    Pelm.Map.id              = 've_map';
    Pelm.Map.statusbar_id    = 've_statusbar';

    //checking in this order:
    //1.set the default map
    //2.profiled user: using the profiled value to load the map
    //3.un-profiled user: check the cookie and using its value to load the map
    cityFlag = profiledFlag;
    cityPlacecode = placecode;
    cityLocName = name;
    cityProvince = province;

    var settings = readCookie();
    if( (typeof settings) == 'object' ){
        if(settings.default_flag == 1){
            //default map was set
            //set the settings using the cookie's value
            setSettingsFromCookie(settings);
            cityFlag = 0;
        }
        else if(profiledFlag){
            setSettingsFromProfiled(lat, lon, zoom);
        }
        else{
            //default map was not set, but the cookie was set & is not profiled
            //set the settings using the cookie's value
            setSettingsFromCookie(settings);
        }
    }
    else if(profiledFlag){   //profiled
        setSettingsFromProfiled(lat, lon, zoom);
    }
    else{   //the cookie string not returned
        Pelm.Map.lat = 53.0;
        Pelm.Map.lon = -89.0;
        Pelm.Map.zoom = 3;
        Pelm.Map.style = 'h';
    }

/*
    //checking in this order:
    //1.profiled user: using the profiled value to load the map
    //2.set the default map
    //3.un-profiled user: check the cookie and using its value to load the map
    cityFlag = profiledFlag;
    if(profiledFlag == true){   //profiled
        cityPlacecode = placecode;
        cityLocName = name;
        cityProvince = province;

        if(lat!='' && lon!=''){
            Pelm.Map.lat = lat;
            Pelm.Map.lon = lon;
        }
        else{
            Pelm.Map.lat = 53.0;
            Pelm.Map.lon = -89.0;
        }
        //check the zoom level, if it's not set, set the default to 3 or
        //set it to 8 when it is greater than 8
        if(zoom!=''){
            Pelm.Map.zoom = (zoom>8) ? 8 : zoom;
        }
        else{
            Pelm.Map.zoom = 3;
        }
        Pelm.Map.style           = 'h';
    }
    else{       //un-profiled, read the cookie and using the value from cookie
        var settings = readCookie();
        if( (typeof settings) == 'object' )
        {
            //set the basic variables from cookie
            Pelm.Map.lat = settings.lat;
            Pelm.Map.lon = settings.lon;
            Pelm.Map.zoom = settings.zoom_level;
            Pelm.Map.style = settings.map_style;
            Pelm.Map.Tile.delay_ms = settings.speed_value;

            //set the slider value from cookie
            A_SPEED_SLIDER.n_value = settings.speed_value;
            A_OPACITY_SLIDER.n_value = settings.opacity_all;
            A_INIT_TIMESTEP.n_value = settings.timestep_slider_value;

            //set the auto play value as the in the cookie
            if(settings.autoplay == 'true'){
                document.getElementById( 'autoplay' ).checked = true;
                Pelm.Map.Tile.autoplay = true;
            }
            else{
                document.getElementById( 'autoplay' ).checked = false;
                Pelm.Map.Tile.autoplay = false;
            }
            
            //selection checkbox check from the cookie
            var inputElems = document.all ? document.all.tags( 'input' ) : document.getElementsByTagName( 'input' );
            for( var i = 0; i < inputElems.length; i++ )
            {
                if( inputElems[ i ].id != '' ){
                    if( inputElems[ i ].type == "checkbox" ){

                        var blFlag = true;
                        blFlag = settings[inputElems[ i ].id];
                        if(blFlag == 'true'){ 
                            inputElems[ i ].checked = true;}
                        else{
                            inputElems[ i ].checked = false;}
                        Pelm.Console.debug( blFlag );
                    }
                }
            }
        }
        else{   //the cookie string not returned
            Pelm.Map.lat = 53.0;
            Pelm.Map.lon = -89.0;
            Pelm.Map.zoom = 3;
            Pelm.Map.style = 'h';
        }
    }
*/
    Pelm.Map.Tile.timestep_slider = new slider( A_INIT_TIMESTEP, A_TPL_TIMESTEP );
    Pelm.Map.Tile.speed_slider = new slider(A_SPEED_SLIDER, A_TPL);
    if( !IE6 )  //remove the opacity slider for IE6 only
    {
        Pelm.Map.Tile.opacity_slider = new slider(A_OPACITY_SLIDER, A_TPL);
    }
    else{
        document.getElementById('transparencyslider').style.display="none";       //not show slider div
    }
    
    Pelm.Map.Tile.hostname                    = 'http://webmaptiles.weather.ca';
    Pelm.Map.Tile.proxy                       = Pelm.Map.Tile.hostname + '/tileagent_nowcast_live.php';
    Pelm.Map.Tile.basepath                    = Pelm.Map.Tile.hostname + '/images';
    Pelm.Map.Tile.coverage                    = layer_coverage;

    Pelm.Map.Tile.callback          = 'Pelm.Map.Tile.handleResponse';
    Pelm.Map.Tile.layer_ids         = 'noaaport_satir,mosaic';
    Pelm.Map.Tile.base_id           = 'radar';

    //Pelm.Map.Tile.css_class                   = 'MSVE_ImageTile';
    //added for v6.2
    Pelm.Map.Tile.css_class_prefix            = 'MSVE_ImageTile msve_';
    Pelm.Map.Tile.css_class_suffix            = '_tile';

    Pelm.Map.Tile.extension                   = 'png';
    Pelm.Map.Tile.min_zoom_level              = '1';
    Pelm.Map.Tile.max_zoom_level              = '8';
    Pelm.Map.Tile.num_servers                 = '1';
    Pelm.Map.Tile._zoomWheel                 = false;   //false: disable mouse wheel, true: enable mouse wheel

    Pelm.Map.Tile.opacity_srp = 0.8;

    Pelm.Map.Tile.rounded = 0;
    Pelm.Map.Tile.debug = 0;

//-----------------------------------------------------------------------
    // Initialize tile values
    Pelm.Map.Tile.blank_tile_src              = '/common/images/maps/no_coverage.png';

    // define HTML form IDs
    Pelm.Map.Tile.elem_ids.tile_layers        = 'tile_layers_control';
    Pelm.Map.Tile.elem_ids.toggle_prefix      = 'toggle_';
    Pelm.Map.Tile.elem_ids.speed_val          = 'speed_value';
    Pelm.Map.Tile.elem_ids.first              = 'first';
    Pelm.Map.Tile.elem_ids.prev               = 'prev';
    Pelm.Map.Tile.elem_ids.start              = 'start';
    Pelm.Map.Tile.elem_ids.stop               = 'stop';
    Pelm.Map.Tile.elem_ids.next               = 'next';
    Pelm.Map.Tile.elem_ids.last               = 'last';
    Pelm.Map.Tile.elem_ids.spinner_prefix     = 'spinner_';
    Pelm.Map.Tile.elem_ids.spinner_txt_prefix = 'spinner_txt_';
    Pelm.Map.Tile.elem_ids.label_prefix       = 'label_';
    Pelm.Map.Tile.elem_ids.opacity_prefix     = 'opacity_';
    Pelm.Map.Tile.elem_ids.slider_suffix      = '_slider';
    Pelm.Map.Tile.elem_ids.order_prefix       = 'order_';
    Pelm.Map.Tile.elem_ids.logo_prefix        = 'logo_';
    Pelm.Map.Tile.elem_ids.legend_prefix      = 'legend_';
    Pelm.Map.Tile.elem_ids.timestep_num       = 'stats_timestep_num';
    Pelm.Map.Tile.elem_ids.quad_num           = 'stats_quad_num';
    Pelm.Map.Tile.elem_ids.connection_type    = 'stats_connection_type';
    Pelm.Map.Tile.elem_ids.bbox               = 'bbox';

    // define custom HTML tags
    Pelm.Map.Tile.html.date_start             ='<div class="datestamp">';
    Pelm.Map.Tile.html.date_end               ='</div>';
    Pelm.Map.Tile.html.time_start             ='<div class="timestamp" id="timestamp">';
    Pelm.Map.Tile.html.time_end               ='</div>';

    // define CSS class names for playback buttons
    Pelm.Map.Tile.html.first_off              = 'first_off';
    Pelm.Map.Tile.html.first_on               = 'first_on';
    Pelm.Map.Tile.html.prev_off               = 'prev_off';
    Pelm.Map.Tile.html.prev_on                = 'prev_on';
    Pelm.Map.Tile.html.start_off              = 'start_off';
    Pelm.Map.Tile.html.start_on               = 'start_on';
    Pelm.Map.Tile.html.stop_off               = 'stop_off';
    Pelm.Map.Tile.html.stop_on                = 'stop_on';
    Pelm.Map.Tile.html.next_off               = 'next_off';
    Pelm.Map.Tile.html.next_on                = 'next_on';
    Pelm.Map.Tile.html.last_off               = 'last_off';
    Pelm.Map.Tile.html.last_on                = 'last_on';

    // autoplay
    if( document.getElementById( 'autoplay' ) )
    {
        Pelm.Map.Tile.autoplay = document.getElementById( 'autoplay' ).checked;
    }
    else
    {
        Pelm.Map.Tile.autoplay = false;
    }

    Pelm.Map.Tile.toggleButtonsAll( 'off' );
    disableTimestepSlider();
    // load coverage data
    loadCoverage( Pelm.Map.Tile.hostname + '/coverage.js' );
}

/**
 * @dexcription
 * set the settings using the values from the cookis
 * @param settings {array} the array contains cookie values
 */
function setSettingsFromCookie(settings)
{
    //set the basic variables from cookie
    Pelm.Map.lat = settings.lat;
    Pelm.Map.lon = settings.lon;
    Pelm.Map.zoom = settings.zoom_level;
    Pelm.Map.style = settings.map_style;
    Pelm.Map.Tile.delay_ms = settings.speed_value;

    //set the slider value from cookie
    A_SPEED_SLIDER.n_value = settings.speed_value;
    A_OPACITY_SLIDER.n_value = settings.opacity_all;
    A_INIT_TIMESTEP.n_value = settings.timestep_slider_value;

    //set the auto play value as the in the cookie
    if(settings.autoplay == 'true'){
        document.getElementById( 'autoplay' ).checked = true;
        Pelm.Map.Tile.autoplay = true;
    }
    else{
        document.getElementById( 'autoplay' ).checked = false;
        Pelm.Map.Tile.autoplay = false;
    }

    //selection checkbox check from the cookie
    var inputElems = document.all ? document.all.tags( 'input' ) : document.getElementsByTagName( 'input' );
    for( var i = 0; i < inputElems.length; i++ )
    {
        if( inputElems[ i ].id != '' ){
            if( inputElems[ i ].type == "checkbox" ){

                var blFlag = true;
                blFlag = settings[inputElems[ i ].id];
                if(blFlag == 'true'){
                    inputElems[ i ].checked = true;}
                else{
                    inputElems[ i ].checked = false;}
                Pelm.Console.debug( blFlag );
            }
        }
    }
}

/**
 * @dexcription
 * set the settings using the values from the cookis
 * @param lat {integer} latitude of the map center
 * @param lon {integer} longitude of the map center
 * @param zoom {integer} the zoom level of the map
 */
function setSettingsFromProfiled(lat, lon, zoom)
{
    if(lat!='' && lon!=''){
        Pelm.Map.lat = lat;
        Pelm.Map.lon = lon;
    }
    else{
        Pelm.Map.lat = 53.0;
        Pelm.Map.lon = -89.0;
    }
    //check the zoom level, if it's not set, set the default to 3 or
    //set it to 8 when it is greater than 8
    if(zoom!=''){
        Pelm.Map.zoom = (zoom>8) ? 8 : zoom;
    }
    else{
        Pelm.Map.zoom = 3;
    }
    Pelm.Map.style           = 'h';
}

/**
 * @description
 * disable zooming in and out with the scroll wheel
 * Handle onmousewheel event.
 */
function onMouseWheel( e )
{
    return true;
}

/**
 * @description
 * show first, prev, next, last tile image frame by the selection
 * @param frameStr {string} the selected frame string: first, last, next ...
 */
function showTimeFrameByselect( frameStr )
{
    //set the init position to 0 when it's not set
    //alert(Pelm.Map.Tile.pos.all);
    if(!Pelm.Map.Tile.pos.all){Pelm.Map.Tile.pos.all = 0;}
    var frameId = '';
    switch (frameStr){
        case 'first':
            frameId = 0;
            break;
        case 'prev':
            frameId = ( ( Pelm.Map.Tile.pos.all - 1 ) >= 0 ) ? Pelm.Map.Tile.pos.all - 1 : Pelm.Map.Tile.time_elems_all.length - 1;
            break;
        case 'next':
            frameId = ( Pelm.Map.Tile.pos.all < ( Pelm.Map.Tile.time_elems_all.length - 1 ) ) ? Pelm.Map.Tile.pos.all + 1 : 0;
            break;
        case 'last':
            frameId = Pelm.Map.Tile.time_elems_all.length - 1;
            break;
        default : frameId = 0;
    }
    //Pelm.Map.Tile.showTimeFrame( 'all', Pelm.Map.Tile.time_elems_all[ frameId ] );
    Pelm.Map.Tile.showTimeFrameByIndex( frameId );
}

/**
 * @description
 * Search for matching locations for the location search from the JSON file.
 * it was modified to search a city within a specific province when it is provided
 * the search pattern: city_name_string, province_abbr  e.g. toron, on
 * @param srcElem {string} the search string from user input
 * @param destElemId {string} the search input box
 */
function searchLocations( srcElem, destElemId )
{
    var searchStr = srcElem.value;
    if(searchStr.length >2){
        var html = '';
        if( search_ProvLocs && srcElem )
        {
            var size = 0;
            var max_options = 20;
            var cnt = 0;
            var html_options = '';
            var cityName = '';
            var searchCityStr = '';
            var searchProvince = '';
    
            if(searchStr.search(',')>0){
                var seachArray = searchStr.split(",",2);
                searchCityStr = seachArray[0];
                searchProvince = seachArray[1].replace(/^\s+|\s+$/, '');
                if(searchProvince.length>1){
                    searchProvince = searchProvince.toUpperCase();
                }
                else{
                    searchProvince = '';
                }
            }
            else{
                searchCityStr = searchStr;
            }
            
            for( var i in search_ProvLocs ){
                if(searchProvince == ''){
                    for( var j in search_ProvLocs[ i ].locations )
                    {
                        cityName = search_ProvLocs[ i ].locations[ j ][lang];
                        if( searchCityStr.toLowerCase() == cityName.substr( 0, searchCityStr.length ).toLowerCase() )
                        {
                            cnt++;
                            html_options += '<option value="' + search_ProvLocs[ i ].locations[ j ].lat + ',' + search_ProvLocs[ i ].locations[ j ].lon + ',' + cityName + ',' + i + ',' + j + '">' + cityName + ', ' + i + '</option>';
                        }
                    }
                }
                else{
                    if(searchProvince == i.toUpperCase()){
                        for( var k in search_ProvLocs[ i ].locations )
                        {
                            cityName = search_ProvLocs[ i ].locations[ k ][lang];
                            if( searchCityStr.toLowerCase() == cityName.substr( 0, searchCityStr.length ).toLowerCase() )
                            {
                                cnt++;
                                html_options += '<option value="' + search_ProvLocs[ i ].locations[ k ].lat + ',' + search_ProvLocs[ i ].locations[ k ].lon + ',' + cityName + ',' + i + '">' + cityName + ', ' + i + '</option>';
                            }
                        }
                    }
                }
            }
    
            if( cnt == 1 ) { size = 2; }
            else if( cnt < max_options ) { size = cnt; }
            else { size = max_options; }
    
            if( cnt > 0 )
            {
                html += '<select id="search_location" class="searchList_'+ lang +'" onChange="setLocation( this.value,\'search_results\');" size="'+size+'">';
                html += html_options;
                html += '</select>';
            }
            else
            {
                var noFound = new Array();
                noFound['en'] = '--No match found--';
                noFound['fr'] = '--Aucune ville trouvée--';
                html += '<span class="noMatch_'+ lang +'">'+ noFound[lang] +'</span>';
            }
        }
        if( document.getElementById( destElemId ) )
        {
            document.getElementById( destElemId ).innerHTML = html;
            document.getElementById( destElemId ).style.display = 'block';
        }
    }
    else{
        if( document.getElementById( destElemId ) )
        {
            document.getElementById( destElemId ).style.display = 'none';
        }
    }
}

/**
 * @description
 * Center the map over a location based on lat/lon string.
 * from a selected search location OR
 * from a profiled page.
 * @param val {string} contains the lat long and the city name
 * @param destElemId {string} the input box
 */
function setLocation( val,destElemId )
{
    if( document.getElementById( destElemId ) )
    {
        document.getElementById( destElemId ).style.display = 'none';
    }
    
    var coords = val.split( ',' );
    if( coords[2]!=='' )
    {
        document.getElementById( 'city_search' ).value = coords[2] + ', ' + coords[3];
    }    

    Pelm.Map.lat = parseFloat( coords[ 0 ], 10 );
    Pelm.Map.lon = parseFloat( coords[ 1 ], 10 );

    var latlon = new VELatLong( Pelm.Map.lat, Pelm.Map.lon );

    Pelm.Map.VE.SetCenterAndZoom(latlon,8); //set the zoom level to 8 for city search 10 July 2009
    /*<LOCATION ICON>*/
    Pelm.Map.VE.DeleteAllShapes();
    setLocationIcon(Pelm.Map.lat, Pelm.Map.lon, coords[2], coords[3], coords[4]);
    markerFlag = 1;
    markerData = '|markerFlag=' + markerFlag + '|markerLat=' + Pelm.Map.lat + '|markerLon=' + Pelm.Map.lon + '|markerCityName=' + coords[2] + '|markerProv=' + coords[3] + '|markerPlaceCode=' + coords[4];
    /*<LOCATION ICON>*/
    refreshMap();
}

/**
* implement the combination logic
* 1. uncheck the other one of the check box (radar OR Precip Type) if it's checked whenever
*    the user checks either one
* @param me {string} the selected checkbox   
*/

/*-----------------------------------------------------------------*/
function uncheckField(me)
{
    if(me.value =="radar" && me.checked == true){
        document.frm_satrad.toggle_mosaic.checked =false;
        if( Pelm.Map.Tile.tile_cache[ 'mosaic' ] )
        {
            for( quad_id in Pelm.Map.Tile.tile_cache[ 'mosaic' ] )
            {
                Pelm.Map.Tile.quad_elems[ 'mosaic' ][ quad_id ].style.display = 'none';
            }
        }
    }
    else if(me.value =="mosaic" && me.checked == true){
        document.frm_satrad.toggle_radar.checked =false;
        if( Pelm.Map.Tile.tile_cache[ 'radar' ] )
        {
            for( quad_id in Pelm.Map.Tile.tile_cache[ 'radar' ] )
            {
                Pelm.Map.Tile.quad_elems[ 'radar' ][ quad_id ].style.display = 'none';
            }
        }
    }
    else{
        //do nothing when the user select Satellite layer
    }
    Pelm.Map.Tile.toggleLayer( me );
}
/*-----------------------------------------------------------------*/

/**
 * @description
 * Open a new window showing the English or French help.
 */
function loadHelp(URL) {
	day = new Date();
	id = day.getTime();
	eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=800,height=600,left = 275,top = 100');");
}

/**
 * @description
 * empty the value in the city search input box.
 */
function clearMe(formfield)
{
    formfield.value = "";
}

/**
 * Function Name: startAnimate
 * change the animating status and call startLoop
 */
function startAnimate()
{
    document.getElementById( 'autoplay' ).checked = true;
    Pelm.Map.Tile.autoplay = true;
    Pelm.Map.Tile.startLoop( 'all' );
}

/**
 * Function Name: stopAnimate
 * change the animating status and call stopLoop
 */
function stopAnimate()
{
    document.getElementById( 'autoplay' ).checked = false;
    Pelm.Map.Tile.autoplay = false;
    Pelm.Map.Tile.stopLoop( 'all', 'manual' );
}


function MyHandleTokenExpire()
{    // insert code here to handle token expiration
//   alert('token expired');
//   var url="<?php echo $_SERVER[PHP_SELF].'?product=maps'; ?>";
//// Opens the url in the same window
//   window.open(url, "_self");
   window.location.reload();
}
function MyHandleTokenError()
{
   // insert code here to handle token errors
}

/**
 * @description
 * Center the map over a location based on lat/lon string.
 * from a selected search location OR
 * from a profiled page.
 * @param lat {string} contains the lat
 * @param lon {string} contains the lon
 * @param name {string} the city name
 * @param prov {string} the province
 * @param placecode {string} the place code
 */
function setLocationIcon( lat,lon,name,prov,placecode )
{
    var latlon = new VELatLong( lat, lon );
    var shapeLocationIcon = new VEShape(VEShapeType.Pushpin, latlon );
    var titleName,forecastName;
    titleName = name;
    forecastName = name;
    if(lang == 'fr'){
        if(name.length >=21){
            titleName = name.substr(0, 19) + '...';
            forecastName = name.substr(0, 10) + '...';
        }
        else if(name.length >=12){
                forecastName = name.substr(0, 10) + '...';
        }
    }
    else{
        if(name.length >=21){
            titleName = name.substr(0, 19) + '...';
            forecastName = titleName;
        }
    }
    shapeLocationIcon.SetCustomIcon(locationIcon); // if you wanted to set a custom icon
    shapeLocationIcon.SetTitle("<div>" + titleName + ', ' + prov + "</div>");
    shapeLocationIcon.SetDescription("<div><a href='/weather/" + placecode.toLowerCase() + "' target='_blank'>"+ fullForecastTxt[lang] + forecastName + "</a></div>");
    Pelm.Map.VE.AddShape(shapeLocationIcon);
}
