var props_Timeout;
var newPropsPanelContent = "";
//TODO: in the future get this variable dinamically from the sensusIcons
var ADDITIONAL_HEIGHT_SPACE_MULTIPLIER = 1.1;


var domObjectsCache = new Array();

function getElementFromDomById( id ) {
	
	// Get the cached element
	var cachedDomElement = domObjectsCache[ id ];

    // DOM element not cached yet? Cache it now.	
	if ( ! cachedDomElement ) {
		cachedDomElement = document.getElementById( id );
		domObjectsCache[ id ] = cachedDomElement;
	}

	// Return the DOM element
	return cachedDomElement;
}

function LoadWidth(objectID, defaultWidth)
{
	var obj = getElementFromDomById(objectID);
	if (obj != null)
	{
		var cookieValue = getCookie('width_' + objectID);
		if (cookieValue == null || cookieValue == '')
		{
			cookieValue = defaultWidth;
		}

		getElementFromDomById(objectID).style.width = cookieValue + 'px';
	}
}

function SetWidth(objectID, widthValue)
{
    setCookie('width_' + objectID, widthValue);
	
	var uiElement = getElementFromDomById(objectID);
	if ( uiElement && ( uiElement != null ) ) {
		uiElement.style.width = widthValue;
	}
}

function LoadHeight(objectID, defaultHeight)
{
	var obj = getElementFromDomById(objectID);
	if (obj != null)
	{
		var cookieValue = getCookie('height_' + objectID);
		if (cookieValue == null || cookieValue == '')
		{
			cookieValue = defaultHeight;
		}

		getElementFromDomById(objectID).style.height = cookieValue + 'px';
	}
}

function SetHeight(objectID, heightValue)
{
	var obj = getElementFromDomById(objectID);
	if (obj != null)
	{
		setCookie('height_' + objectID, heightValue);
		getElementFromDomById(objectID).style.height = heightValue;
	}
}

function LoadDisplayStyle(objectID, defaultDisplayValue)
{
	var obj = getElementFromDomById(objectID);
	if (obj != null)
	{
		var cookieValue = getCookie('display_' + objectID);
		if (cookieValue == null)
		{
			cookieValue = defaultDisplayValue;
		}

		getElementFromDomById(objectID).style.display = cookieValue;
	}
}
        
function hideUiElementIfExists( nameOfUiElementToPotentiallyHide ) {

    var uiElementToPotentiallyHide = getElementFromDomById( nameOfUiElementToPotentiallyHide );
    
    if ( uiElementToPotentiallyHide && ( uiElementToPotentiallyHide != null ) ) {
        uiElementToPotentiallyHide.style.display = 'none';
    }
}

function setSuperFullScreenModeCookie( enableTheMode ) {
	
	if ( enableTheMode == true ) {
		setCookie( 'superFullScreenMode', 'on' );
	} else {
	    var now       = new Date();
	    var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);

	    setCookie( 'superFullScreenMode', 'off', yesterday );
	}
}

function getSuperFullScreenMode() {

	var cookieValue = getCookie( 'superFullScreenMode' );

	if ( cookieValue && ( cookieValue != null ) && ( cookieValue == 'on' ) ) {
		return true;
	} else {
		return false;
	}
}

function SetDisplayStyle(objectID, displayValue)
{
    // NOTE: we don't care whether the UI object referred to using the 'objectID' parameter actually exists;
	// this function could be called by a page that contains no such element but just wants to pre-initialize
	// the display style cookies to some value

	setCookie('display_' + objectID, displayValue);
	
	var uiElement = getElementFromDomById(objectID);
	if (uiElement && (uiElement != null)) {
		uiElement.style.display = displayValue;
	}
}

function setFullScreen( turnFullScreenOn ) {
	
    if ( turnFullScreenOn == true )
    {
        SetDisplayStyle('divHeader', 'none');
        SetDisplayStyle('divFooter', 'none');
        SetDisplayStyle('rowBreadCrumb', 'none');
        SetDisplayStyle('contentLeftTop', 'none');
        SetDisplayStyle('contentLeftView', 'none');
        SetDisplayStyle('contentLeftBorder', 'none');
        SetDisplayStyle('contentRightTop', 'none');
        SetDisplayStyle('contentRightView', 'none');
        SetDisplayStyle('contentRightBorder', 'none');
        SetDisplayStyle('divInlineSearch', '');
    }	
    else
    {
        SetDisplayStyle('divHeader', '');
        SetDisplayStyle('divFooter', '');
        SetDisplayStyle('rowBreadCrumb', '');
        SetDisplayStyle('contentLeftTop', '');
        SetDisplayStyle('contentLeftView', '');
        SetDisplayStyle('contentLeftBorder', '');
        SetDisplayStyle('contentRightTop', '');
        SetDisplayStyle('contentRightView', '');
        SetDisplayStyle('contentRightBorder', '');
        SetDisplayStyle('divInlineSearch', 'none');
    }
    
	if (typeof resizeDivs == 'function') { // NOTE: sometimes we call this function without first defining 'resizeDivs'
		resizeDivs();
		// Firefox makes errors after the first call, sometimes a second call is required
		resizeDivs();
	}
}

function ToggleFullScreen() {
	
	if (getElementFromDomById('divHeader').style.display == 'none') {
		setFullScreen( false );
	}
	else {
		setFullScreen( true );
	}
}

/**
 * [Cookie] Sets value in a cookie.
 */
// TODO: make dtree defer to this definition?
function setCookie( cookieName, cookieValue, expires ) {

    cookieName = generateShortCookieName( cookieName );

	// Make cookie report-unique
	cookieName = htmlReportUniqueId + "_" + cookieName;

    cookieDefinition = escape( cookieName ) + '=' + escape( cookieValue ) +
	                   ( (expires) ? '; expires=' + expires.toGMTString() : '' ) +
	                   '; path=/';
	
	document.cookie = cookieDefinition;
}

// TODO: make dtree defer to this definition?            
function getCookie( cookieName ) {

    cookieName = generateShortCookieName( cookieName );

	// Make cookie report-unique
	cookieName = htmlReportUniqueId + "_" + cookieName;
		
    var cookieValue = '';
    var posName     = document.cookie.indexOf( escape( cookieName ) + '=' );

    if ( posName != -1 ) {
        
        var posValue = posName + (escape(cookieName) + '=').length;
        var endPos = document.cookie.indexOf(';', posValue);

        if (endPos != -1) {
            cookieValue = unescape(document.cookie.substring(posValue, endPos));
        } else {
            cookieValue = unescape(document.cookie.substring(posValue));
        }
    }

    return cookieValue;
};

/**
 * Shortens a cookie name to a more bit-size-efficient acronym. It always helps to make cookie names and values
 * as short as possible, given the limits browsers impose on cookie sizes.
 * 
 * @param {Object} cookieName   the cookie name to generate a shortened representation for.
 */
function generateShortCookieName(cookieName)
{
 switch (cookieName)
 {
  case 'initializeSession' : cookieName = 'is'; break;
  case 'superFullScreenMode' : cookieName = 'sf'; break;
  case 'zoomingPercentage' : cookieName = 'zp'; break;
  case 'showFunctions' : cookieName = 'sf2'; break;
  case 'last_tab_name' : cookieName = 'lt'; break;
  case 'oldWidthProps' : cookieName = 'owp'; break;
  case 'oldWidthTree' : cookieName = 'owt'; break;
  case 'no_tab_internal_redirect' : cookieName = 'ir'; break;
  case 'p_vw_tree_panel' : cookieName = 'pt'; break;
  case 'p_vw_props_panel' : cookieName = 'pp'; break;
  case 'c_vw_tree_panel' : cookieName = 'ct'; break;
  case 'c_vw_props_panel' : cookieName = 'cp'; break;
  case 'h_vw_tree_panel' : cookieName = 'ht'; break;
  case 'h_vw_props_panel' : cookieName = 'hp'; break;
  case 'ps_vw_tree_panel' : cookieName = 'pst'; break;
  case 'ps_vw_props_panel' : cookieName = 'psp'; break;
  case 't_vw_tree_panel' : cookieName = 'tt'; break;
  case 't_vw_props_panel' : cookieName = 'tp'; break;
  case 'pn_vw_tree_panel' : cookieName = 'pnt'; break;
  case 'vn_vw_tree_panel' : cookieName = 'vnt'; break;
  case 'display_divHeader' : cookieName = 'd0'; break;
  case 'display_rowBreadCrumb' : cookieName = 'd1'; break;
  case 'display_contentLeftTop' : cookieName = 'd2'; break;
  case 'display_contentRightTop' : cookieName = 'd3'; break;
  case 'display_contentLeftView' : cookieName = 'd4'; break;
  case 'display_contentRightView' : cookieName = 'd5'; break;
  case 'display_contentLeftBorder' : cookieName = 'd6'; break;
  case 'display_divInlineSearch' : cookieName = 'd7'; break;
  case 'display_contentRightBorder' : cookieName = 'd8'; break;
  case 'display_divFooter' : cookieName = 'd9'; break;
  case 'display_hideFunctionsButtonDiv' : cookieName = 'da'; break;
  case 'display_divProps' : cookieName = 'db'; break;
  case 'last_page_in_p_t_tree': cookieName = 'lp1'; break;
  case 'last_page_in_pn_vw_tree': cookieName = 'lp2'; break;
  case 'last_page_in_vn_vw_tree' : cookieName = 'lpv'; break;  
  case 'last_page_in_f_t_tree': cookieName = 'lp3'; break;
  case 'last_page_in_d_t_tree': cookieName = 'lp4'; break;
  case 'last_page_in_a_t_tree': cookieName = 'lp5'; break;
  case 'last_page_in_r_t_tree': cookieName = 'lp6'; break;
  case 'last_view_in_p_t_tree': cookieName = 'lv1'; break;
  case 'last_view_in_pn_vw_tree': cookieName = 'lv2'; break;
  case 'last_view_in_vn_vw_tree' : cookieName = 'lvv'; break;  
  case 'last_view_in_f_t_tree': cookieName = 'lv3'; break;
  case 'last_view_in_d_t_tree': cookieName = 'lv4'; break;
  case 'last_view_in_a_t_tree': cookieName = 'lv5'; break;
  case 'last_view_in_r_t_tree': cookieName = 'lv6'; break;
  case 'last_view_among_procs': cookieName = 'lv7'; break; // A very special case for the procs level of the procs tab  
  case 'height_divContent': cookieName = 'h0'; break;
  case 'height_tblContent': cookieName = 'h1'; break;
  case 'height_divImage': cookieName = 'h2'; break;
  case 'height_divResizeLeft': cookieName = 'h3'; break;
  case 'height_divResizeRight': cookieName = 'h4'; break;
  case 'height_divTree': cookieName = 'h5'; break;
  case 'height_divProps': cookieName = 'h6'; break;
  case 'width_divImage': cookieName = 'w0'; break;
  case 'width_divTree': cookieName = 'w1'; break;
  case 'width_divProps': cookieName = 'w2'; break;
  case 'open_nodes_ids_p_t_tree': cookieName = 'o1'; break;
  case 'open_nodes_ids_pn_vw_tree': cookieName = 'o2'; break;
  case 'open_nodes_ids_vn_vw_tree': cookieName = 'o3'; break;
  case 'open_nodes_ids_f_t_tree': cookieName = 'o4'; break;
  case 'open_nodes_ids_d_t_tree': cookieName = 'o5'; break;
  case 'open_nodes_ids_a_t_tree': cookieName = 'o6'; break;
  case 'open_nodes_ids_r_t_tree': cookieName = 'o7'; break;
  case 'selected_node_id_p_t_tree': cookieName = 's1'; break;
  case 'selected_node_id_pn_vw_tree': cookieName = 's2'; break;
  case 'selected_node_id_vn_vw_tree': cookieName = 's3'; break;
  case 'selected_node_id_f_t_tree': cookieName = 's4'; break;
  case 'selected_node_id_d_t_tree': cookieName = 's5'; break;
  case 'selected_node_id_a_t_tree': cookieName = 's6'; break;
  case 'selected_node_id_r_t_tree': cookieName = 's7'; break;
  
  default: cookieName = cookieName; // If we can't shorten the name, use the long one (defensive programming)
 }
 
 return cookieName;
}

/**
 * Checks to see if we've landed on the right page in the current view. If not, redirects to the appropriate page.
 */
function ensureOnRightPage( current_tab_id, thisPagesPrimaryViewSibling ) {

    // Find out what the last accessed view prior to this page load was; if it was a different view
    // from the present one, then redirect to the page in the currently desired view that the user accessed last in it 
    var last_tab_name = getCookie( 'last_tab_name' );
    var disableFurtherTabInternalRedirects = getCookie( 'no_tab_internal_redirect' );
        
    if ( ( ! disableFurtherTabInternalRedirects ) || ( disableFurtherTabInternalRedirects != 'true' ) ) { 
    	    	
        var last_page_in_this_tab_url = getCookie( 'last_page_in_' + current_tab_id );
        if ( ( last_page_in_this_tab_url ) && ( last_page_in_this_tab_url.length > 0 ) ) {
	        		        	
		    if ( ( last_tab_name ) && ( last_tab_name.length > 0 ) && ( last_tab_name != current_tab_id ) ) {
		        // Yes indeed, we are coming from a page in another view. Let's see if we can redirect
		        // to another, more appropriate (=last-viewed) page in this current view	        	
	        	
	            // Yes, we can redirect
	            // First, ensure we don't start an infinite cycle of redirects
	            setCookie( 'last_tab_name',                  '' ); // TODO: use constants for these cookie names/prefixes
	            setCookie( 'last_page_in_' + current_tab_id, '' );
	            
	            // Do the actual redirect
	            window.location.replace( last_page_in_this_tab_url );
	        }
        }

    	if ( ( ! do_not_read_last_view_cookie ) && ( viewName ) ) {

        	// We do not have any specific page to redirect to. However, there may still be a remembered
        	// preference for which view the user looked last at.
        	if ( is_this_entity_a_process ) {
        		last_view_in_this_tab = getCookie( 'last_view_among_procs' );
        	} else {
        	    last_view_in_this_tab = getCookie( 'last_view_in_' + current_tab_id );
        	}
                
        	if ( ( last_view_in_this_tab ) && ( last_view_in_this_tab != null ) &&
        	     ( last_view_in_this_tab != 'undefined' ) && ( last_view_in_this_tab.length > 0 ) ) {
        		
        		if ( last_view_in_this_tab != viewName ) {
        		                    	        			
                    do_not_update_last_view_cookie = true;
                    	        			
	                window.location.replace( '../' + last_view_in_this_tab + '/' + last_view_in_this_tab + '.html' );
        		}
        	}
    	
    	}
    }
    setCookie( 'no_tab_internal_redirect', '' ); // Whether this cookie was set or not, it should be no more; clear it
    
    // If we are still here (i.e., on this page, not having redirected elsewhere), update the cookies
    // that state what the last accessed view and the last accessed page within that view were
    setCookie( 'last_tab_name',                  current_tab_id );
    setCookie( 'last_page_in_' + current_tab_id, thisPagesPrimaryViewSibling );
}


/**
 * Sends the browser to a given URL and disables any further redirects from that URL to other URL's under that tab.
 */
function followLinkNoRedirects( urlToFollow ) {
    
    setCookie( 'no_tab_internal_redirect', 'true' ); // TODO: store this cookie name in a constant
     
    window.location = urlToFollow;
}

/**
 * Sends the browser to a given URL and disables any further redirects from that URL to other URL's under that tab.
 */
function followLinkNoRedirects1( urlToFollow ) {
    
    setCookie( 'no_tab_internal_redirect', 'true' ); // TODO: store this cookie name in a constant
     
    window.location.href = urlToFollow;
}


/**
 * Performs the same thing as 'followLinkNoRedirects()' but does not prevent possible subsequent redirects.
 */
function followLink( urlToFollow ) {
    window.location = urlToFollow;
}


/**
 * Calculates the name of the view that it proper to have for a given entity type...
 */
function generateProperView( defaultView, is_process ) {
            
   if ( is_process == 'true' ) {
       better_view = getCookie( 'last_view_among_procs' );
   } else {
       better_view = getCookie( 'last_view_in_' + '${.globals.tree_name}' );
   }

   if ( (better_view) && ( better_view != null ) && ( better_view.length > 0 ) ) {
       return better_view;
   } else {
       return defaultView;
   }
}


/**
 * Hides the tree panel if the user hid it before in the current view (this preference gets remembered in a cookie).
 */
function adjustTreePanelVisibility( current_view_id ) {

    var treeDiv = getElementFromDomById( 'divTree' );
    if ( treeDiv != null ) { // Ensure the tree div is there before doing things to it
	    var treeVisibility = getCookie( current_view_id + '_tree_panel' );
	    if ( ( treeVisibility != null ) && ( treeVisibility == 'hidden' ) ) {
	        treeDiv.style.width = 0;
	    }
	}
}


/**
 * Hides the props panel if the user hid it before in the current view (this preference gets remembered in a cookie).
 */
function adjustPropertiesPanelVisibility( current_view_id ) {

    var propsDiv = getElementFromDomById( 'divProps' );
    if ( propsDiv != null ) { // Ensure the props div is there before doing things to it
	    var propsVisibility = getCookie( current_view_id + '_props_panel' );
	    if ( ( propsVisibility != null ) && ( propsVisibility == 'hidden' ) ) {
	        propsDiv.style.width = 0;
	    }
    }
}

function updatePropsPanel()
{
	var propsDiv = getElementFromDomById( 'divProps' );
	if ( propsDiv != null ) {
		// Remember old props panel content; we'll reset it on mouse-out
		oldPropsPanelContent = propsDiv.innerHTML;
		
		// We ARE showing the props panel. Therefore, update its contents.
		propsDiv.innerHTML = newPropsPanelContent;
	}
}

/**
 * Defines what is done when the mouse enters an interactive icon's image map area: updates the props panel or
 * dispays a popup.
 */
function processIconMouseOver( event, popupText, propsPanelInnerHtml ) {

    // Do different things depending on whether the props panel is shown or not
	if ( ! propsPanelHidden ) {
		
		var propsDiv = getElementFromDomById( 'divProps' );
		if ( propsDiv != null ) {
			props_Timeout = window.setTimeout("updatePropsPanel()", 500);
			newPropsPanelContent = propsPanelInnerHtml;
		}
	}
	else {
		// We are NOT showing the props panel. Therefore, show a popup.
		processIconMouseOverAsPopupEvent( event, popupText );
	}
}

/**
 * Defines what is done when the mouse leaves an interactive icon's image map area: updates the props panel or
 * hides a previously displayed popup.
 */
function processIconMouseOut( event ) {

    // Do different things depending on whether the props panel is shown or not
    if ( ! propsPanelHidden ) {
		window.clearTimeout(props_Timeout);
	}
	else {
		// Just hide the popup
		processIconMouseOutAsPopupEvent( event );
	}
}

/**
 * Shows a popup with given text.
 */
function processIconMouseOverAsPopupEvent( event, popupText ) {
    var popupContentToShow = popupText;
    show( event, popupContentToShow );
}

/**
 * Hides the displayed popup.
 */
function processIconMouseOutAsPopupEvent( event ) {
    hide( event );
}

/**
 * Opens a given link in a new browser window (tab). Can be used to open not only web pages but also local files.
 *  
 * @param {Object} url  the URL of the link to open.
 */
function openLinkInNewWindow( url ) {
	window.open( url, '', '' );
}

function startApplication( cmd ) {
	WSH = new ActiveXObject( "WScript.Shell" );
    WSH.run( cmd );
}

function handleZoomDropdownChange(isProcess) {
  var zoomDropdownElement = getElementFromDomById( 'zoomDropdownElement' );

  if ( zoomDropdownElement && ( zoomDropdownElement != null ) ) {

      var newZoom = zoomDropdownElement.options[ zoomDropdownElement.selectedIndex ].value;
      
      if ( newZoom && ( newZoom != null ) ) {
          resizeDiagram( newZoom, isProcess );
      }
  }
}



/**
 * Updates a given main diagram image with data from an AlternativeImage object.
 *
 * @param updateImageNotSeparator if 'true', means update main image, if 'false' -- update separator.
 */
function updateMainDiagramImage( mainDiagramImageElementToUpdate, alternativeImage, filenameSliceInsertion,
                                                                                    updateImageNotSeparator ) {
    
    if ( updateImageNotSeparator == true ) {
        mainDiagramImageElementToUpdate.src = '../../../../di_' + viewName + '/' +
                                             alternativeImage._imageFilenamePreSlicePart +
                                             filenameSliceInsertion +
                                             alternativeImage._imageFilenamePostSlicePart;
    } 
	else if ( updateImageNotSeparator == false ) 
	{
		mainDiagramImageElementToUpdate.style.backgroundImage = 'url(../../../../di_' + viewName + '/' + alternativeImage._imageFilenamePreSlicePart + filenameSliceInsertion + alternativeImage._imageFilenamePostSlicePart + ')'
		mainDiagramImageElementToUpdate.style.backgroundRepeat = 'repeat-y';
    }
}


/**
 * Tells whether the responsible function-toggle is currently set to 'on'.
 */
function areFunctionsOn() {
	
    var hideFunctionsButtonElement = getElementFromDomById( 'hideFunctionsButtonDiv' );
	
	if ( hideFunctionsButtonElement && ( hideFunctionsButtonElement != null ) && ( hideFunctionsButtonElement.style.display != 'none' ) ) {
		return true;
	} else {
	   return false;	
	}	
}

/**
 * @param shouldShow 'true' means functions should be shown, 'false' means they shouldn't.
 * @param isProcess 'true' means that a process is selected and we're viewing activity flow
 */
function doFunctionToggle( shouldShow, isProcess ) {
               
    // Param checking 
    if ( ( shouldShow != true ) && ( shouldShow != false ) ) {
        return;
    }
                
    var mainDiagramImageElement    = getElementFromDomById( 'mainDiagramImage' );                        
    var showFunctionsButtonElement = getElementFromDomById( 'showFunctionsButtonDiv' );
    var hideFunctionsButtonElement = getElementFromDomById( 'hideFunctionsButtonDiv' );

    if ( mainDiagramImageElement && ( mainDiagramImageElement != null ) && showFunctionsButtonElement && ( showFunctionsButtonElement != null ) && hideFunctionsButtonElement && ( hideFunctionsButtonElement != null ) ) {

        if ( currentAlternativeImage && ( currentAlternativeImage != null ) && alternativeImages && alternativeImages.length ) {
        
            for ( var i = 0; i < alternativeImages.length; i ++ ) {
            
                if ( ( alternativeImages[ i ]._zoomingPercentage == currentAlternativeImage._zoomingPercentage ) &&
                     ( alternativeImages[ i ]._showFunctions == shouldShow.toString() ) ) {

                    currentAlternativeImage = alternativeImages[ i ];
                    updateMainDiagramImage( mainDiagramImageElement, currentAlternativeImage, '', true );
                    break;
                }
            }
        }

        if ( shouldShow == true ) {
            SetDisplayStyle('showFunctionsButtonDiv', 'none');
            SetDisplayStyle('hideFunctionsButtonDiv', '');
			
			/* REMOVE
            showFunctionsButtonElement.style.display = 'none';
            hideFunctionsButtonElement.style.display = 'block';
            */
        }
        else {
            SetDisplayStyle('showFunctionsButtonDiv', '');
            SetDisplayStyle('hideFunctionsButtonDiv', 'none');
					
		    /* REMOVE
            showFunctionsButtonElement.style.display = 'block';
            hideFunctionsButtonElement.style.display = 'none';
            */               
        }
    }
    
    // Save the new function toggle setting to a cookie
    setCookie( 'showFunctions', shouldShow );
    
    // now update the areas on the screen is we're viewing activities
    resetImageMap(getCookie('zoomingPercentage'), isProcess)
}

/**
 * Resets the image areas depending on the zooming factor and on the fact that we're viewing the activity flow of a process
 *
 * @param zoomingPercentage the zooming factor applied to the canvas
 * @param isProcess Boolean telling if we're viewing the activity flow of a process
 */
function resetImageMap( zoomingPercentage, isProcess ) {
    var newZoomingFactor = zoomingPercentage / 100;
    var multiplyConstant;

    if (isProcess && areFunctionsOn()) {
        multiplyConstant = ADDITIONAL_HEIGHT_SPACE_MULTIPLIER;
    } else {
        multiplyConstant = 1.0;
    }
    
    if ( imageMapAreas && imageMapAreas.length ) {
        for ( var i = 0; i < imageMapAreas.length; i++ ) {
            var htmlImageMapAreaElementId = 'imageMapArea_' + i;
            var htmlImageMapAreaElement   = getElementFromDomById( htmlImageMapAreaElementId );
            
            if ( htmlImageMapAreaElement && ( htmlImageMapAreaElement != null ) ) {
                var iconHeight = imageMapAreas[ i ]._bottom_right_y - imageMapAreas[ i ]._top_left_y;
                var newYPosition = multiplyConstant * imageMapAreas[ i ]._top_left_y;
                htmlImageMapAreaElement.coords = ( newZoomingFactor * imageMapAreas[ i ]._top_left_x )     + ',' +
                                                 ( newZoomingFactor * newYPosition )    + ',' +
                                                 ( newZoomingFactor * imageMapAreas[ i ]._bottom_right_x ) + ',' +
                                                 ( newZoomingFactor * (newYPosition + iconHeight) );
            }
        }
    }

    // Save the new zoom setting in a cookie
    setCookie( 'zoomingPercentage', zoomingPercentage ); 
}

/**
 * Resets the image on the zooming factor and on the fact that we're viewing the activity flow of a process
 *
 * @param zoomingPercentage the zooming factor applied to the canvas.
 * @param isProcess Boolean telling if we're viewing the activity flow of a process.
 */
function resizeDiagram( zoomingPercentage, isProcess ) {

    // Reset the image
    var mainDiagramImageElements = new Array();
    var separators               = new Array();
    if ( viewName != 'ps_vw' ) {
        var mainDiagramImageElement = getElementFromDomById( 'mainDiagramImage' );
        mainDiagramImageElements[ mainDiagramImageElements.length ] = mainDiagramImageElement;
    } else {
        for ( var i = 0; i < mainImageCount; i++ ) {
            var mainDiagramImageElement = getElementFromDomById( 'mainDiagramImage_' + i );
            mainDiagramImageElements[ mainDiagramImageElements.length ] = mainDiagramImageElement;     
            
            if ( i < mainImageCount -1 ) { // there is one less separators than images
                var separator = getElementFromDomById( 'mainDiagramImageSeparator_' + i );
               separators[ separators.length ] = separator;
            }      
        }
    }
    if ( currentAlternativeImage && ( currentAlternativeImage != null ) && alternativeImages && alternativeImages.length ) {
        
        for ( var i = 0; i < alternativeImages.length; i ++ ) {
            if ( ( alternativeImages[ i ]._zoomingPercentage == zoomingPercentage ) &&
                 ( alternativeImages[ i ]._showFunctions == currentAlternativeImage._showFunctions ) ) {

               currentAlternativeImage = alternativeImages[ i ];
                                             
               for ( var i = 0; i < mainDiagramImageElements.length; i++ ) {
               
                   if ( viewName != 'ps_vw' ) {
                        updateMainDiagramImage( mainDiagramImageElements[ i ], currentAlternativeImage, '', true );
                   } else {
                        updateMainDiagramImage( mainDiagramImageElements[ i ], currentAlternativeImage, 'p-' + i + '_' + 'i-i_', true );
                        if ( i < separators.length ) { // there is one less separators than images
                            updateMainDiagramImage( separators[ i ], currentAlternativeImage, 'p-' + i + '_' + 'i-s_', false );
                        }                                
                   }
               }
               
               break;
           }
        }
    }

    // Reset the image map
    resetImageMap( zoomingPercentage, isProcess );
    
    // Save the new zoom setting in a cookie
    setCookie( 'zoomingPercentage', zoomingPercentage ); 
}


// BEGIN: Define the AlternativeImage class
 
/**
 * A descriptor of the main diagram image (or typical image slice, in proc schema view). Does not necessarily
 * represent an actual image (i.e. in proc schema view), just encapsulates data for *an* image.
 */
function AlternativeImage() { }
AlternativeImage.prototype._zoomingPercentage;
AlternativeImage.prototype._showFunctions;
AlternativeImage.prototype._imageFilenamePreSlicePart;
AlternativeImage.prototype._imageFilenamePostSlicePart;

// END: Define the AlternativeImage class


// BEGIN: Define the ImageMapArea class

function ImageMapArea() { }
ImageMapArea.prototype._top_left_x;     // the 'normal' setting, not multiplied by any zooming factor
ImageMapArea.prototype._top_left_y;     // the 'normal' setting, not multiplied by any zooming factor
ImageMapArea.prototype._bottom_right_x; // the 'normal' setting, not multiplied by any zooming factor
ImageMapArea.prototype._bottom_right_y; // the 'normal' setting, not multiplied by any zooming factor

// END: Define the ImageMapArea class

