/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. */
/* ------------------------------------------------------ */
/* ------------------- amx-popup.js --------------------- */
/* ------------------------------------------------------ */
(function()
{
  /**
   * helper function to determine if an offset is
   * within the bounds of the current view
   *
   * @param $view the jquery view for this page
   * @param offset the offset to check
   */
  function isOffsetVisible($view, offset)
  {
    var viewHeight = $view.outerHeight();
    return offset >= 0 && offset <= viewHeight;
  }

  /**
   * helper function to make sure the popupTop is visible
   * and the popup is not larger than the current view
   *
   * @param $view the jquery view for this page
   * @param $popup the current jquery popup node
   * @param popupTop the calculated top offset
   * @param popupLeft the calculated left offset
   */
  function clipPopup($view, $popup, popupTop, popupLeft)
  {
    var outerHeight = $popup.outerHeight(true);
    var viewHeight = $view.outerHeight();
    if (popupTop < 0)
    {
      // the popup would start off of the screen, so move it back to 0
      var popupBottom = viewHeight - (popupTop + outerHeight);
      popupTop = 0;
      $popup.css("bottom","" + popupBottom + "px");
    }
    else
    {
      if (popupTop + outerHeight > viewHeight)
      {
        $popup.css("bottom","0px");
      }
    }
    if(popupLeft<0){
    	// the popup would start off of the screen, so move it back to 0
    	popupLeft = 0;
    }
    
    $popup.css("top","" + popupTop + "px");
    $popup.css("left","" + popupLeft + "px");
  }

  /**
   * helper function to align the popup based on the align value
   * and the alignId control's location.
   *
   * @param $view the jquery view for this page
   * @param $popup the current jquery popup node
   * @param $align the current jquery node to align to
   * @param alignValue the type of alignment to be done
   */
  function alignPopup($view, $popup, $align, alignValue)
  {
    var alignOffset = $align.offset();
    var alignOffsetTop = alignOffset == null ? 0 : alignOffset.top;
    var alignOffsetLeft = alignOffset == null ? 0 : alignOffset.left;
    var alignOuterHeight = $align.outerHeight(true);
    var alignOffsetBottom = alignOffsetTop + alignOuterHeight;

    var popupOuterHeight = $popup.outerHeight(true);

    // align has overlapTop, overlapBottom, before, and after
    // default is after
    var popupTop = 0;
    if (alignValue == "overlapTop")
    {
      // keep the offset at 0 unless the top offset that we are aligning to is visible
      if (isOffsetVisible($view, alignOffsetTop))
      {
        popupTop = alignOffsetTop;
      }
    }
    else if (alignValue == "overlapBottom")
    {
      // keep the offset at 0 unless the bottom offset that we are aligning to is visible
      if (isOffsetVisible($view, alignOffsetBottom))
      {
        popupTop = alignOffsetBottom - popupOuterHeight;
      }
    }
    else if (alignValue == "before")
    {
      // keep the offset at 0 unless the space before the top offset that we are aligning to is visible
      if (isOffsetVisible($view, alignOffsetTop - 1))
      {
        popupTop = alignOffsetTop - 1 - popupOuterHeight;
      }
    }
    else
    {
      // keep the offset at 0 unless the space after the bottom offset that we are aligning to is visible
      if (isOffsetVisible($view, alignOffsetBottom + 1))
      {
        popupTop = alignOffsetBottom + 1;
      }
    }
    
    // ensure left alignment
    var popupLeft = alignOffsetLeft;

    clipPopup($view, $popup, popupTop, popupLeft);
  }

// TODO finish the migration from "amx.*" to "adf.mf.api.amx.*" and "adf.mf.internal.amx.*"
  amx.processShowPopupBehavior = function(showPopupBehaviorXmlNode)
  {
    return amx.processXmlNode(showPopupBehaviorXmlNode).pipe(function(showPopupBehaviorNode)
    {
      var popupId = showPopupBehaviorNode.popupId;
      var alignId = showPopupBehaviorNode.alignId;
      var align   = showPopupBehaviorNode.align;

      // we look for the popup in the amx XML document
      var $view = amx.$bodyPage.find(".amx-view:first");
      var viewXml = $view.data("amxNode")._xmlNode;
      var popupXml = $(viewXml).find("#" + popupId)[0];

      // once we have the popupXml, we need to processXmlNode to evaluate the els
      return amx.processXmlNode(popupXml).pipe(function(popupNode)
      {
        // we set the _renderPopup to force full rendering
        popupNode._renderPopup = true;
        return amx.renderNode(popupNode).pipe(function($popup)
        {
          // Escape any ":" characters or else the jQuery find will fail:
          var alignIdForFind = alignId.replace(/[:]/g, "\\:");
          var $align = $view.find("#" + alignIdForFind);

          // hide the $popup during positioning (since we  have to add it first)
          // Note: z-index did not work here.
          $popup.css("opacity",0);

          // append the screen always
          var $popupTransparentScreen = $("<div class='popupTransparentScreen'></div>");
          var screenId = amx.uuid();
          $popupTransparentScreen.attr("id", screenId);
          amx.$bodyPage.append($popupTransparentScreen);
          $popup.data("screenId", screenId);

          // make the screen perform autodismiss if needed
          var autoDismiss = popupNode.autoDismiss;
          if (amx.isValueTrue(autoDismiss))
          {
            $popupTransparentScreen.tap(function()
            {
              $popupTransparentScreen.remove();
              $popup.remove();
            });
          }

          // need to append first, cause we need to get the $popup's height;
          amx.$bodyPage.append($popup);

          alignPopup($view, $popup, $align, align);

          // now we remove the opacity (not that we set the "" to remove the css property rather to set one
          // in case it is part of a transition)
          $popup.css("opacity","");

          //slide slideup
          var animation = popupNode.animation;
          var hasTransition = true;
          if (animation == "slideUp")
          {
            $popup.css("-webkit-transform","translate(0px,300px)");
          }
          else if (animation == "slideDown")
          {
            $popup.css("-webkit-transform","translate(0px,-300px)");
          }
          else if (animation == "slideLeft")
          {
            $popup.css("-webkit-transform","translate(300px,0px)");
          }
          else if (animation == "slideRight")
          {
            $popup.css("-webkit-transform","translate(-300px,0px)");
          }
          else
          {
            hasTransition = false;
          }

          if (hasTransition)
          {
            setTimeout(function()
            {
              $popup.addClass("transitioning");
              $popup.css("-webkit-transform","translate(0px,0px)");
              $popup.bind("webkitTransitionEnd",function()
              {
                $popup.removeClass("transitioning");
                $popup.unbind("webkitTransitionEnd");
              });
            },
            0);
          }
        });
      });
    });
  };

  amx.processClosePopupBehavior = function($amxNode,closePopupBehaviorXmlNode)
  {
    var $popup = $amxNode.closest(".amx-popup");
    var screenSelector = "#" + $popup.data("screenId") + ".popupTransparentScreen";
    var $popupTransparentScreen = amx.$bodyPage.find(screenSelector);
    $popupTransparentScreen.remove();
    $popup.remove();
  };

  var amxRenderers =
  {
    popup:
    {
      create: function(amxNode)
      {
        // only render when called from
        if (amxNode._renderPopup)
        {
          var $node = $("<div></div>");

          // make sure this responds to dragging for scrolling purposes
          $node.addClass("amx-scrollable");
          return amx.renderSubNodes(amxNode,$node).pipe(function()
          {
            return $node;
          });
        }
        else
        {
          return $("<div class='popup-holder'></div>");
        }
      }
    }
  }

  amx.registerRenderers("amx",amxRenderers);

  // ---------- Popup Transitions ---------- //
  //TODO: put the transitions here.
  // ---------- Popup Transitions ---------- //
})();