(function($){
  var currentTarget;
  var defaultStyle = {
    menu: {
      listStyleType: "none",
      position:      "absolute",
      margin:        0,
      padding:       0,
      border:        "1px solid darkgray",
      cursor:        "default",
	  backgroundColor: "white",
      zIndex:        999
    },
    item: {
      color:           "black",
      backgroundColor: "white",
      padding:         "2px 20px 2px 20px",
      whiteSpace:      "nowrap"
    },
    hoverItem: {
      color:           "white",
      backgroundColor: "#3060B0"
    },
    containerItem: {      // IE 7 doesn't support "data:image/gif;base64" urls
      backgroundImage:    "url(images/jquery.n-contextmenu.arrow.gif)",
      backgroundPosition: "95%",
      backgroundRepeat:   "no-repeat"
    },
    separator: {
      borderTop: "1px solid darkgray"
    },
	relativeTo: null,
	overflowMaxItemNum: 15,
	overflowWidth: "200px",
	overflowHeight: "250px"
  }
  //add by APN
  $.nestedContextMenuSource = function() {
	return currentTarget;
  };
  $.contextMenuSource = function() {
	return currentTarget;
  };
  $.contextMenuDefaultStyle = function(){
	 return defaultStyle.menu;
  };
  $.closeContextMenu = function() {
	closeCurrentMenu();
  };
  $.fn.contextMenu = function(menu, userStyle, onShow) {
    if (typeof userStyle == "function") {
      onShow = userStyle;
      userStyle = {};
    }
	//APN added to fix IE6 index problem
	if ( $.fn.bgiframe ) $(menu).bgiframe();
	var userStyle1 = {containerItem: {      // IE 7 doesn't support "data:image/gif;base64" urls
      backgroundImage:    "url(/images/jquery.n-contextmenu.arrow.gif)",
      backgroundPosition: "95%",
      backgroundRepeat:   "no-repeat"
    }};
	//add by apn
	onShow = function(t){
		currentTarget = $(t.target);
	};
	var style = $.extend({}, defaultStyle, userStyle, userStyle1); //create new style object each time to avoid overwrite of default style
    var data = { menu: menu, style: style, onShow: onShow }; 
    this.bind("contextmenu", data, onContextMenu);
    this.bind("click", data, onClick);
  };

  // Only one context menu should
  // be visible at a time
  var currentMenu;

  function onContextMenu(e) {
    closeCurrentMenu();

    if (e.data.onShow &&
        e.data.onShow.apply(this, [e]) == false) return;
                                  
    currentMenu = e.data.menu;
    $(document).bind("click", currentMenu, closeCurrentMenu);
    $(window).bind("blur", currentMenu, closeCurrentMenu);
    hideMenu(e.data.menu);
    showMenu(e.data.menu, e.data.style, e.pageX, e.pageY);
    return false;
  }

  function closeCurrentMenu() {
    if (!currentMenu) return;

    $(document).unbind("click", currentMenu, closeCurrentMenu);
    $(window).unbind("blur", currentMenu, closeCurrentMenu);
    hideMenu(currentMenu);
    currentMenu = null;
  }

  function onClick(e) {
	/*
    if (e.button == 0 && e.ctrlKey) {
      return onContextMenu(e);
    }
	*/
    if (e.button == 0) {
      return onContextMenu(e);
    }
  }

  function showMenu(menu, style, x, y) {
    menu = $(menu);
    if (menu.is(":visible")) return;
    menu.find("ul")
        .css(style.menu)
        .prev("li")
        .css(style.containerItem)
        .end()
        .parent("li")
        .css(style.containerItem);

    menu.find("li")
        .css(style.item)
        //.bind("click", onItemClick) //modify by APN, disable the function so that when click parent menu, the click event response
        .bind("mouseenter", style, onItemEnter);

    menu.find("li[separator]")
        .css(style.separator);
	if (typeof(style.relativeTo)!='undefined' && style.relativeTo!=null && style.relativeTo!=''){
		x = $(currentTarget).position().left + 8;
		y = $(currentTarget).position().top + 8;
	}
	//show scroll bar if number of li is more than maxItemNum
	
    menu.css(style.menu)
		.css("left", x)
		.css("top", y);
	if (menu.children("li").length > style.overflowMaxItemNum){
		menu.css("overflow", "scroll");
		menu.css("width", style.overflowWidth);
		menu.css("height", style.overflowHeight);
	}
    menu.show();
  }

  // Hide submenus in reverse order

  function hideMenu(menu) {
    var submenus = $(menu).find("ul")
                          .get()
                          .reverse();
    $(submenus).hide();
    $(menu).hide();
  }

  function getSubmenu(item) {
    item = $(item);
    var submenu = item.next();
    if (!submenu.is("ul")) {
      submenu = item.children();
    }
    if (submenu.is("ul")) {
      return submenu;
    }
  }

  // Return false for items that have submenus
  // So that clicking on such items doesn't close menu

  function onItemClick(e) {
    if (this == e.target) {
      return !getSubmenu(this);
    }
  }

  function onItemEnter(e) {
    var self = this;
    var style = e.data;
    var menu = $(this).parent();

    menu.children("li").each(function() {
      var item = $(this);
      var submenu = getSubmenu(item);
      if (submenu) {
        var x = menu.width();
        var y = item.position().top - 1;
		if ( $.browser.msie && /6.0/.test(navigator.userAgent) ) {
			//half indent not working under IE6
			self == this ? showMenu(submenu, style, x, y) : hideMenu(submenu);
		} else {
			//less indent
			self == this ? showMenu(submenu, style, x/2, y+20) : hideMenu(submenu);
		}
      }
      item.css(self == this ? e.data.hoverItem : e.data.item);
    });
  }
})(jQuery);

