﻿// RIGHT CLICK CUSTOM CONTEXT MENU

// Author: David Leghorn    15/06/2007
// Purpose: Script overrides default browser context menu to display a custom (page specific) context menu
// when user right mouse clicks.

// Usage: Import this javascript file and give the context menu Div on your page an id="ContextMenu" (this is
// the default context menu id that this page script is looking for. If your want to use an id other than 
// "ContextMenu" for your context menu div, re-assign the value of the ContextMenuDivId variable within a 
// script block on the page importing this file (note: be sure to re-assign the ContextMenuDivId variables value AFTER this 
// script has been imported) e.g. ContextMenuDivId = "MyContextMenuDivId";


// GLOBAL VARIABLES:

// ContextMenuDivId global variable stores custom context menu's div wrapper id. Defaults to "ContextMenu", 
// however this variable can be re-assigned to any div id via an inline javascript block in the page importing this script 

var ContextMenuDivId = "ContextMenu";

var ContextVisible = false; // flag denoting whether or not custom context menu is visible (currently not used)
var ContextDivRef;  // holds DOM reference to the context menu div object

  
//  FUNCTIONS
   
    // handles document mouse click events - identifies right mouse click events and 
    // calls CustomContextMenu function to display context menu 

    function MouseClickHandler(evt)
    {
        // try catch added 26 july to prevent ie displaying exception message if user clicks on page
        // before page content has completed loading i.e. div id="ContextMenu" does not exist until page 
        // completes load
       
       try
       {
            var contextVis = document.getElementById(ContextMenuDivId).style.visibility;
  
	        if( window.event )
	        { 
	            //alert("event type = " + event.type);
        	
		        if( event.button == 2 )
		        {
			        //alert("right click is ie");
			        event.cancelBubble = true;
			        CustomContextMenu(evt);
			        return false;
		        }
		        else if( event.button == 1)
		        {
		            // short delay allows click event to bubble to link click handler before hiding menu
		            if(contextVis == "visible")
		            {
		                setTimeout("ShowHideObj(ContextMenuDivId,'hidden')",250);
		            }
		        }

	        }
	        else	// FF, NAV etc
	        {
		        if( evt.which == 2 || evt.which == 3)
		        {
			        //alert("right click is firefox");
			        CustomContextMenu(evt);
			        return false;
		        }
		        else if(evt.which == 1)
		        {
		            if(contextVis == "visible")
		            {
		                setTimeout("ShowHideObj(ContextMenuDivId,'hidden')",250);
		            }
		        }
	        }
	        
      }  // end catch
      catch(clickEx)
      {
            // do nothing with catch - we are simply surpressing IE exception message box in the
            // event that the user clicks on page before page content has completely loaded.
            // Could also have assigned the onmousedown and oncontextmenu event handlers in a
            // page load function called via window.onload = (this approach is not used in case
            // it prevents other window.onload events firing as expected in the main pages that are
            // importing this script
            
            // test
           // alert("Error caught - do nothing");
      }
      
    }
    


    // cancels document.oncontextmenu event (fired on right click to show default context menu) 
    // by returning false

    function CancelContext()
    {
	    return false;
    }

    // assign document event handlers to catch right click event and cancel default context menu

    document.onmousedown = MouseClickHandler;
    document.oncontextmenu = CancelContext;


    // DISPLAYS CUSTOM CONTEXT MENU

    function CustomContextMenu(ev)
    {
        ContextDivRef = document.getElementById(ContextMenuDivId);
        var menuLinkMsg = "Open Main Menu";
        calculateMousePos(ev);
        //GetScrollOffset();
        PositionContextMenu();
        // switch open/close main menu text depending on current menu state
       // if(top.MenuState == "visible") { menuLinkMsg = "Close Main Menu"; }
       // document.getElementById("ContextMainMenuLink").innerHTML = menuLinkMsg;
        
        var vis = ContextDivRef.style.visibility;
        
        if(vis == "hidden")
        {
            ContextDivRef.style.visibility = "visible";
        }
    }


    // CALCULATES CONTEXT MENU POSITION i.e. x and y co-ordinates (called by CustomContextMenu() function)

    function PositionContextMenu()
    {
        var menuWidth = ContextDivRef.offsetWidth;
        var menuHeight = ContextDivRef.offsetHeight;
        GetAvailableDisplayArea();
        
        // ensure menu is within page display area boundaries
        if( (PosX + menuWidth) > DisplayAreaWidth)
        {
            PosX = DisplayAreaWidth - menuWidth - 10;
        }   
        if( (PosY + menuHeight) > DisplayAreaHeight )
        {
            PosY = DisplayAreaHeight - menuHeight - 10;
        }
        
        var yOff = GetPageScrollYOffset();
        
        if(IsIE == true)
        {
            ContextDivRef.style.top = parseInt(PosY + yOff) + "px";
        }
        else    // don't think firefox needs to account for scroll offsets with its mouse co-ords??
        {
            ContextDivRef.style.top = parseInt(PosY) + "px";    // PosY - 10 if want first item hovered over
        }
        
        ContextDivRef.style.left = parseInt(PosX) + "px";   // PosX - 15 if want first item hovered over
    }

        
    // CALCULATES MOUSE X AND Y CO-ORDINATES (accomodates for any page scroll offset)

    function calculateMousePos(e)
    {   
        if(IsIE == true ) { e = window.event; }
        
        if (e.pageX || e.pageY)
        {
	        PosX = e.pageX;
	        PosY = e.pageY;
        }
        else if (e.clientX || e.clientY)
        {
	        PosX = e.clientX;
	        PosY = e.clientY;
        }
    }
        
        
    // calculate page y scroll offset (equivalent function defined in universal js)
        
//    function GetScrollOffset()
//    {
//	    if( IsIE == true )
//	    {
//		    Yoffset = document.documentElement.scrollTop;
//	    }
//    		
//	    else
//	    {
//		    Yoffset = window.pageYOffset;
//	    }
//    }

    // passes call to show/hide main menu to top window (front.aspx) and updates Context menu's main menu link
    // text to display 'Open' or 'Close' main menu as appropriate

//    function ContextMainMenuClick()
//    {
//        var visMainMenu;
//        
//        if(top.MenuState == "hidden")
//        {  visMainMenu = "visible"; } 
//        else { visMainMenu = "hidden"; }
//        
//        top.ShowHideMenu('Menu',visMainMenu);  
//    }
