define(
    [
        'scripts/knockout-3.3.0','scripts/ACTComponent.js',
        'scripts/CallWebObject.js', "scripts/ACTUtils",
        'jqx/jqxmenu', 'jqx/jqxtooltip',
    ],
       function(ko, ACTComponent, InvokeCallback, ACTUtils, jqxmenu) {

           function PopupMenuComponentViewModel(params, element) {
               var _this = this;
               _this.base = new ACTComponent($(element), params);
               _this.element = element;
               _this.params = params;
               var init = true;

               var $menu = $(element).find('#jqxMenu');

               _this.base.onRefresh = function(obj) {
                   // $menu.jqxMenu("destroy");
                   if(init === true){
                       init = false;
                       return;
                   }

                   if (obj.TriggerClick) {
                      $menu.find("#" + obj.TriggerClick).trigger("itemclick");
                      $menu.jqxMenu("close");  // well jqx won't do it so... i will
                      return;
                   }

                   var maxId = 0;
                   _this.idToMenuItem = {};
                   var setIdToMenuItems = function(menuItem){
                       menuItem.id = "MENU_ITEM_NUMBER_" + (maxId++);
                       // ACTUtils.CreateTooltip($(menuItem.id), menuItem.tooltip, false,  {disabled: true});
                       _this.idToMenuItem[menuItem.id] = menuItem;
                       if (menuItem.items) {
                           for (var i = 0; i < menuItem.items.length; i++) {
                               setIdToMenuItems(menuItem.items[i]);
                           }
                       }
                   };

                   setIdToMenuItems(obj.menuRoot);

                   $menu.jqxMenu("destroy");
                   $menu.jqxMenu({
                       source: obj.menuRoot.items,
                       mode: 'popup',
                       width: obj.width || 100,
                       autoOpenPopup: false,
                       animationShowDuration: 0,
                       animationHideDuration: 0,
                       animationHideDelay: 0,
                       animationShowDelay: 0,
                       popupZIndex: 99999999   // to be on top of dialogboxes
                   });

                   var openMenu = function(xPosition, yPosition){ //set the context menu at the right position
                       var scrollTop = $(window).scrollTop();
                       var scrollLeft = $(window).scrollLeft();
                       var menuHeight = $menu.height();
                       var menuWidth = $menu.width();
                       var windowHeight = $(window).height();
                       var windowWidth = $(window).width();
                       xPosition = xPosition + 5 + scrollTop;
                       yPosition = yPosition + 5 + scrollLeft;
                       //Check if the menu fits in the window.
                       if( yPosition + menuHeight > windowHeight){
                           yPosition = yPosition - menuHeight;
                       }
                       if( xPosition + menuWidth > windowWidth){
                           xPosition = xPosition - menuWidth;
                       }
                       $menu.jqxMenu('open', xPosition, yPosition );
                   };

                   openMenu(obj.xPosition, obj.yPosition);

                   //Hack to change the menuItem to a separator.
                   $("li[item-label='__menuSeparator__']").attr("class", "jqx-menu-item-separator jqx-rc-all");

                   var $tooltip = ACTUtils.CreateTooltip($menu, "", false, {disabled: true});

                   var showTooltip = function(e) {
                       closeTooltip();
                       var $target = $(e.target);
                       var id = $target.attr("id");
                       var menuElement = _this.idToMenuItem[id];
                       var tooltipText = menuElement != null && menuElement.tooltip || "";

                       if (!ACTUtils.StringIsNullOrEmpty(tooltipText)) {
                           $menu.jqxTooltip({content: tooltipText, disabled: false});
                           $menu.jqxTooltip("open", $target.offset().left + $target.width() + 10, $target.offset().top);
                           // do that cause submenus haven't the same zindex of $menu on which we create the tooltip
                           $tooltip.zIndex($(e.target).zIndex() + 1);
                       }
                       return false;
                   };

                   var closeTooltip = function() {
                       $menu.jqxTooltip("close");
                       $menu.jqxTooltip({disabled: true});
                       return false;
                   };

                   $menu.on('shown', function(event) {
                       var $currentElem = $(event.args.element).parent().parent();
                       var $subMenuElem = $(event.args.subMenuElement).parent().parent();
                       var currentElemTop = parseInt($currentElem.css("top").split("px")[0]);
                       var subMenuHeight = $subMenuElem.outerHeight(true);
                       var windowHeight = $(window).outerHeight(true);
                       if (currentElemTop + subMenuHeight > windowHeight)
                       {
                           $subMenuElem.css("top", (windowHeight - subMenuHeight) + "px");
                       }
                       var $subMenuLiElements = $subMenuElem.find("li");
                       $subMenuLiElements.on("mouseenter", showTooltip);
                       $subMenuLiElements.on("mouseleave", closeTooltip);
                   });

                   $menu.on("closed", closeTooltip);

                   $menu.on('itemclick', function (event) {
                       var $li = $(event.target);
                       var id = $li.attr("id");
                       var menuElement = _this.idToMenuItem[id];
                       if (menuElement.ItemClicked) {
                           params.baseModel.onTriggerAction("TriggerClick", [id]);
                           InvokeCallback(params.Model.Id, menuElement.ItemClicked, []);
                       }
                   });

                   var $menuLiElements = $menu.find("li");
                   $menuLiElements.on("mouseenter", showTooltip);
                   $menuLiElements.on("mouseleave", closeTooltip);
               };

               // selection

               _this.base.initialize();
               params.ready(true);

               params.baseModel.resizeFunctions[params.baseModel.resizeFunctions.length] = function(height,width) {

               };
           }

           return {
               createViewModel: function(params, componentInfo) {
                   return new PopupMenuComponentViewModel(params, componentInfo.element);
               }
           };

       });
