
$jq.fn.insitenav = function(op) {

  var ins = $jq.fn.insitenav;
  ins.o = [];
  ins.op = {};
  ins.c = {
    menuClass   : 'ins-js-enabled',
    isParent : 'ins-parent',
    arrowClass  : 'ins-arrow'
  };
  if ($jq.easing.easeOutOvershoot) { //set default easing
    insiteEasingShow = 'easeOutOvershoot';
  } else {
    insiteEasingShow = 'linear';
  };
  if ($jq.easing.easeInTurbo) {
    insiteEasingHide = 'easeInTurbo';
  } else {
    insiteEasingHide = 'linear';
  };  
  ins.defaults = {
    multiColumn  : true,
    dualColumn  : 4, //if a submenu has at least this many items it will be divided in 2 columns
    tripleColumn  : 12, //if a submenu has at least this many items it will be divided in 3 columns
	quadColumn  : 18, //if a submenu has at least this many items it will be divided in 3 columns
    hoverClass  : 'sfHover',
    delay    : 100, //make sure menus only disappear when intended, 500ms is advised by Jacob Nielsen
    animationShow  : {width:'show'},
    speedShow    : 0,
    easingShow      : insiteEasingShow,
    animationHide  : {width:'hide',opacity:'hide'},
    speedHide    : 0,
    easingHide      : insiteEasingHide,
    autoArrows  : true, //Adds span elements to parent li elements, projecting arrow images on these items to indicate submenus. I added an alternative image file with white arrows.
    onShow    : function(){}, //callback after showing menu
    onHide    : function(){} //callback after hiding menu
  };
  

  //Merge default settings with o function parameter
  var o = $jq.extend({},ins.defaults,op);
  if (!o.insitenavWidth) {
  o.insitenavWidth = $jq('ul:first li:first', this).width(); //if no width is set in options try to read it from DOM
  } else {
  $jq('ul li', this).width(o.insitenavWidth) //if width is set in invocation make sure this width is true for all submenus
  }

  this.each(function() {
    
    //Check dom for submenus
    var parentLi = $jq('li:has(ul)', this);
    parentLi.each(function(){
      if (o.autoArrows) { //Add autoArrows if requested
      $jq('>a',this).append('<span class="'+ins.c.arrowClass+'"></span>');
      }
      $jq(this).addClass(ins.c.isParent);
    });
    
    $jq('ul',this).css({left: 'auto',display: 'none'}); //The script needs to use display:none to make the hiding animation possible

    //Divide menu in columns
    //Set width override
    if (o.multiColumn) {
    var uls = $jq('ul',this);
    uls.each(function(){
      var ulsize = $jq('>li:not(.ins-parent)',this).length; //Skip list items added by Lavalamp plugin
      if (ulsize >= o.dualColumn) {
        if (ulsize >= o.tripleColumn) {
          $jq(this).width(3*o.insitenavWidth).addClass('multicolumn triplecolumn');
        } if (ulsize >= o.quadColumn) {
          $jq(this).width(4*o.insitenavWidth).addClass('multicolumn quadcolumn');
        }else {
          $jq(this).width(2*o.insitenavWidth).addClass('multicolumn dualcolumn');
        }
      }
    });
    }

    var root = this, zIndex = 1000;

    function getSubmenu(ele) {
      if (ele.nodeName.toLowerCase() == 'li') {
        var submenu = $jq('> ul', ele);
        return submenu.length ? submenu[0] : null;
      } else {
        return ele;
      }
    }

    function getActuator(ele) {
      if (ele.nodeName.toLowerCase() == 'ul') {
        return $jq(ele).parents('li')[0];
      } else {
        return ele;
      }
    }

    function hideinsitenavUl() {
      var submenu = getSubmenu(this);
      if (!submenu) return;
      $jq.data(submenu, 'cancelHide', false);
      setTimeout(function() {
        if (!$jq.data(submenu, 'cancelHide')) {
          $jq(submenu).animate(o.animationHide,o.speedHide,o.easingHide,function(){ o.onHide.call(submenu); });
        }
      }, o.delay);
    }

    function showinsitenavUl() {
      var submenu = getSubmenu(this);
      if (!submenu) return;
      $jq.data(submenu, 'cancelHide', true);
      $jq(submenu).css({zIndex: zIndex++}).animate(o.animationShow,o.speedShow,o.easingShow,function(){ o.onShow.call(submenu); });
      if (this.nodeName.toLowerCase() == 'ul') {
        var li = getActuator(this);
        $jq(li).addClass('hover');
        $jq('> a', li).addClass('hover');
      }
    }
    
    // Bind Events.
    $jq('li', this).unbind().hover(showinsitenavUl, hideinsitenavUl);

  });

};

 $jq(document).ready(function() {
      $jq('ul.dropNav').insitenav();
    });

