/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. */
(function($)
{
// TODO finish the migration from "amx.*" to "adf.mf.api.amx.*" and "adf.mf.internal.amx.*"

  amx.registerRenderers("amx",
  {
    panelItem:
    {
      create: function(amxNode)
      {
        // Attributes:
        //   animation (String; animation override for this panelItem; use the panelSplitter's by default)
        //   shortDesc (String)

        // Create the top level div that will hhouse all the components used in the splitter.
        var $node = $("<div title='" + this._ensureValidString(amxNode.shortDesc, "") + "'> </div>");
        return amx.renderSubNodes(amxNode, $node).pipe(function()
        {
          return $node;
        });
      },

      _ensureValidString: function(rawValue, defaultValue)
      {
        // TODO is there a shared util we can use instead?
        if (rawValue == null)
          return defaultValue;
        return rawValue;
      },

      init: function($node, amxNode)
      {
      }
    },

    panelSplitter:
    {
      create: function(amxNode)
      {
        // Attributes:
        //   animation (String; default animation for a panelItem)
        //   inlineStyle (String)
        //   navigatorTitle (String)
        //   position (String; CSS length)
        //   selectedItem (String; id of a panelItem child)
        //   shortDesc (String)
        //   styleClass (String)

        // DOM Structure:
        //   root div data-orientation amx-panelSplitter
        //     div amx-panelSplitter_inner
        //       div amx-panelSplitter_navLandscape
        //         navigator facet e.g. listView component (if displaying in landscape mode)
        //       div amx-panelSplitter_contentContainer amx-landscape/amx-portrait amx-noNavigation
        //         div amx-panelItem current/new/old/showing/transitioning/transitioning-slow/face/front/flip
        //       div amx-panelSplitter_screenPortrait
        //       div amx-panelSplitter_button (has optional "disclosed", "no-animate")
        //       div amx-panelSplitter_navPortrait (has optional "no-animate")
        //         navigator facet e.g. listView component (if displaying in portrait mode)

        try
        {
          // Get the initial portrait/landscape mode (updates are handled during resize).
          var orientation = this._getOrientation();

          var position = this._getPosition(amxNode);

          // Create the top level div that will house all the components used in the splitter.
          var $node = $("<div title='" + this._ensureValidString(amxNode.shortDesc, "") + "'> </div>");
          $node.attr("data-orientation", orientation);

          // =-= melges:
          // This is a bit of a hack but we need to create an inner DIV to protect from styling infringing on the
          // splitter content and navigation elements. Without this we would get extra space in both.
          var $inner = $("<div class='amx-panelSplitter_inner'> </div>");
          $inner.appendTo($node);

          //  First thing to check for is that we have a navigator facet.
          if (amxNode.facets.navigator)
          {
            var inLandscape = (orientation == "landscape"); // side-by-side mode
            var $content = $("<div class='amx-panelSplitter_contentContainer amx-scrollable'> </div>").appendTo($inner);
            this._createNavigation(inLandscape, amxNode, $inner, $node, position);
            if (inLandscape)
            {
              $content.addClass("amx-landscape");
              $content.css("left", position.landscape);
            }
            else
              $content.addClass("amx-portrait");
          }
          else
          {
            $content = $("<div class='amx-panelSplitter_contentContainer amx-scrollable'> </div>").appendTo($inner);
            $content.addClass("amx-noNavigation");
          }

          // Render the content.
          // First get a list of all the possible panelItems.
          var viewTags = $(amxNode._xmlNode).children("amx\\:panelItem");

          // Determine if there is already an existing item being displayed.
          // Want to be smart here and only perform the rendering on the Tag that has been identified.
          // as the tag to display. If none has been identified then just grab the first one.
          // We have to handle several use cases here:
          //    1) No item panelItems defined at all.
          //    2) No current panelItem is being displayed and no panelItem has been defined on the component but
          //       one or more panelItems have been defined. In this we just want to grab the first panelItem defined
          //       as a child of the panelSplitter and display it. There is no transition on initial rendering.
          //    3) No current panelItem is being displayed but a selectedItem has been defined and exists. This is an
          //       intial display condition and that item will be displayed.
          //    4) Current panelItem is being displayed and there is a new panelItem to display. In this case
          //       Display the current one and on the post display create the new one and transition it in. (see refresh)
// TODO #5 does not seem to be the way it is handled; instead it seems to use index 0 instead; verify
          //    5) Current panelItem being displayed but the selectedItem is undefined, null or not found. In this case render the
          //       content as an empty div.
          var indexToRender = 0;
          if (amxNode.selectedItem)
          {
            for (var i=0; i<viewTags.length; i++)
            {
              //  Look for a match on the panelItems Id. If one is not founf fall back to the first item
              if (amxNode.selectedItem == viewTags[i].getAttribute("id"))
              {
                indexToRender = i;
                break;
              }
            }
          }

          var contentDfd = amx.renderNode(viewTags[indexToRender]).done(function($viewTag)
          {
            $viewTag.addClass("current");
            $content.append($viewTag);
          });

          return $.when(contentDfd).pipe(function()
          {
            return $node;
          });
        }
        catch (problem)
        {
          console.error(problem);
        }
      },

      init: function($node, amxNode)
      {
      },

      postDisplay: function($node, amxNode)
      {
        try
        {
          // Restore the old scroll position in case this view instance already had one:
          var storedData = adf.mf.api.amx.getClientState(amxNode.id);
          if (storedData != null)
          {
            var $inner = $node.children(".amx-panelSplitter_inner");
            this._restoreScrollPositions($inner.children(".amx-panelSplitter_navLandscape"), storedData.navLandscape);
            this._restoreScrollPositions($inner.children(".amx-panelSplitter_navPortrait"), storedData.navPortrait);
            this._restoreScrollPositions($inner.children(".amx-panelSplitter_contentContainer"), storedData.content);
          }

          // Add resize event listeners
// TODO why?:
          // TODO: Use $node.data("amxNode")
          if (amxNode.facets.navigator)
          {
            var data = {
              'node':    $node,
              'peer':    this,
              'amxNode': amxNode
            };

            // Listen if someone resizes the window:
            $(window).resize(data, this._handleResize);

            // Listen if someone explicitly calls .resize() on my root element:
            $node.resize(data, this._handleResize);
          }

// TODO why?:
          // Now get the current selected ID
        }
        catch (problem)
        {
          console.error(problem);
        }
      },

      refresh: function($node, newAmxNode, propertiesChanged)
      {
        try
        {
          var oldAmxNode = $node.data("amxNode");

          // Handle if an only if "selectedItem" changed:
          if (propertiesChanged.selectedItem && Object.keys(propertiesChanged).length === 1)
          {
            // get the current $content Node
            var $inner = $node.children(".amx-panelSplitter_inner");
            var $content = $inner.children(".amx-panelSplitter_contentContainer");

            if ($node.hasClass("changingSelectedItem"))
            {
              // Changing the selected item too quickly--another one is in progress.
              // TODO need to handle this scenario (if can't clean up the DOM then cover up the navigators when busy)
            }
            $node.addClass("changingSelectedItem");

            // Get all the panelItems XML data.
            var $panelItem = $content.children(".amx-panelItem.current");

            // Find the new selected Item
            var indexToRender = 0;
            if (newAmxNode.selectedItem)
            {
              var viewTags = $(newAmxNode._xmlNode).children("amx\\:panelItem");
              for (var i=0; i<viewTags.length; i++)
              {
                //  Look for a match on the panelItems Id. If one is not found fall back to the first item
                if (newAmxNode.selectedItem == viewTags[i].getAttribute("id"))
                {
                  indexToRender = i;
                  break;
                }
              }
            }

            // Render the newly-selected panelItem
            var contentDfd = amx.renderNode(viewTags[indexToRender]).done(function($viewTag)
            {
              $viewTag.addClass("new");
              $content.append($viewTag);
            });

            // Animate the transition of the old-to-new panelItems
            var peer = this;
            $.when(contentDfd).pipe(function()
            {
              if ($node.attr("data-orientation") == "portrait")
              {
                try
                {
                  var position = peer._getPosition(newAmxNode);
                  peer._undiscloseNavPortrait($node, position);
                }
                catch (problem)
                {
                  console.error(problem);
                }
              }
              var $newPanelItem = $content.children(".new");
              var transitionParams = peer._getTransitionParams(newAmxNode, viewTags[indexToRender]);
              if (transitionParams.type == "slide")
              {
                peer._slide($node, $panelItem, $newPanelItem, transitionParams.direction);
              }
              else if (transitionParams.type == "flip")
              {
                peer._flip($node, $panelItem, $newPanelItem, transitionParams.direction);
              }
              else // no animation
              {
                $newPanelItem.removeClass("new");
                $newPanelItem.addClass("current");
                $panelItem.remove();
                $node.removeClass("changingSelectedItem");
              }
            });
            return true;
          } // end of "selectedItem" change
        }
        catch (problem)
        {
          console.error(problem);
        }

        // Save the scroll positions since this we are not using optimized refreshing:
        this._storeScrollPositions($node, newAmxNode.id);

        return false;
      },

      preDestroy: function($node,amxNode)
      {
        // Store off the current scroll position in case this view instance is ever revisited:
        this._storeScrollPositions($node, amxNode.id);
      },

      _storeScrollPositions: function($node, amxNodeId)
      {
        // Store off the current scroll position in case this view instance is ever revisited:
        var $inner = $node.children(".amx-panelSplitter_inner");
        var storedData =
        {
          navLandscape: this._getScrollPositions($inner.children(".amx-panelSplitter_navLandscape")),
          navPortrait:  this._getScrollPositions($inner.children(".amx-panelSplitter_navPortrait")),
          content:      this._getScrollPositions($inner.children(".amx-panelSplitter_contentContainer"))
        };
        adf.mf.api.amx.setClientState(amxNodeId, storedData);
      },

      _getScrollPositions: function($subNode)
      {
        if ($subNode)
        {
          var scrollLeft = $subNode.scrollLeft();
          var scrollTop = $subNode.scrollTop();
          if (scrollLeft != null && scrollTop != null)
          {
            return {
              scrollLeft: scrollLeft,
              scrollTop: scrollTop
            };
          }
        }
        return null;
      },

      _restoreScrollPositions: function($subNode, scrollPositions)
      {
        if ($subNode && scrollPositions)
        {
          var scrollLeft = scrollPositions.scrollLeft;
          if (scrollLeft != null)
            $subNode.scrollLeft(scrollLeft);
          var scrollTop = scrollPositions.scrollTop;
          if (scrollTop != null)
            $subNode.scrollTop(scrollTop);
        }
      },

      _getTransitionParams: function(amxNodeSplitter, amxNodePanelItem)
      {
        // The panelItem we are going to show has first crack at defining the animation.
        var animation = "none"
        var params = null;

        if (amxNodePanelItem.attributes.animation)
        {
          animation = amxNodePanelItem.attributes.animation.value;
        }
        else if (amxNodeSplitter.animation)
        {
          animation = amxNodeSplitter.animation;
        }
        animation = animation.toLowerCase();

        switch (animation) // TODO what about "start" and "end" variations for RTL?
        {
          case  'flipup':
            params = {"type": "flip", "direction":"up"};
            break;
          case 'flipdown':
            params = {"type": "flip", "direction":"down"};
            break;
          case 'flipleft':
            params = {"type": "flip", "direction":"left"};
            break;
          case 'flipright':
            params = {"type": "flip", "direction":"right"};
            break;
          case  'slideup':
            params = {"type": "slide", "direction":"up"};
            break;
          case 'slidedown':
            params = {"type": "slide", "direction":"down"};
            break;
          case 'slideleft':
            params = {"type": "slide", "direction":"left"};
            break;
          case 'slideright':
            params = {"type": "slide", "direction":"right"};
            break;
          default:
            params = {"type": "none", "direction":"left"};
        }
        return params;
      },

      _slide: function($node, $current, $new, direction)
      {
        var vertical = false;
        var back = false;

        if(direction == "up" || direction == "down")
        {
          vertical = true;
        }

        if(direction == "right" || direction == "down")
        {
          back = true;
        }

        var dfd = $.Deferred();
        // for now, we assume, position $current is 0, 0, and that all views should have same width
        // (fair assumption since the $new was drawn below the $current)
        var width = $current.width(); // should probably take from parent to be safe
        var fromX = back ? (-1) * width : width;
        var currentToX = fromX * -1;
        if(vertical)
        {
          width = $current.height();
          fromX = back ? (-1) * width : width;
          currentToX = fromX * -1;
          $current.height(width);
          $new.height(width);

          $new.css("top", fromX + "px");
        }
        else
        {
          // fix the width of the two view during animation.
          $current.width(width);
          $new.width(width);

          // put the $new in the fromX
          $new.css("left", fromX + "px");
        }

        //$new.addClass("setup");
        $new.removeClass("new").addClass("showing");

        setTimeout(function()
        {
          var currentDfd = $.Deferred();
          var newDfd = $.Deferred();

          $new.addClass("transitioning");

          $current.addClass("transitioning");
          if (vertical)
          {
            $current.css("-webkit-transform", "translate(0," + currentToX + "px)");
          }
          else
          {
            $current.css("-webkit-transform", "translate(" + currentToX + "px,0)");
          }
          $current.bind("webkitTransitionEnd", function()
          {
            $current.removeClass("current").addClass("old");
            $current.removeClass("transitioning");
            $current.remove();
            currentDfd.resolve();
          });

          $new.addClass("transitioning");
          if (vertical)
          {
            $new.css("-webkit-transform", "translate(0," + currentToX + "px)");
          }
          else
          {
            $new.css("-webkit-transform", "translate(" + currentToX + "px,0)");
          }
          $new.bind("webkitTransitionEnd", function()
          {
            $new.removeClass("showing").addClass("current");
            $new.removeClass("transitioning");
            $new.attr("style", "");
            $current.remove();
            newDfd.resolve();
          });

          $.when(currentDfd, newDfd).done(function()
          {
            // =-= melges:
            // jQueryMobile workaround:
            // For now, just to be safe, we wait 400 milliseconds before accepting event.
            // Somehow, on simulator, the jQueryMobile button gets the previous tap event.
// TODO why?:
            // TODO: Remove the time out. Leave the dfd.resolve. If this works send Jeremy a note.
            setTimeout(function()
            {
              dfd.resolve();
              $node.removeClass("changingSelectedItem");
            }, 400);
          });
        }, 1);

        return dfd.promise();
      },

      _flip: function($node, $current, $new, direction)
      {
        var vertical = false;
        var back = false;

        if (direction == "up" || direction == "down")
        {
          vertical = true;
        }

        if (direction == "right" || direction == "up")
        {
          back = true;
        }

        var dfd = $.Deferred();
        // for now, we assume, position $current is 0, 0, and that all views should have same width
        // (fair assumption since the $new was drawn below the $current)
        var width = $current.width();
        var newBaseRotate = (back) ? "rotateY(-180deg)" : "rotateY(180deg)";
        if(vertical)
        {
          width = $current.height();

          $current.height(width);
          $new.height(width);
          newBaseRotate = (back) ? "rotateX(-180deg)" : "rotateX(180deg)";
          $current.addClass("face").css("-webkit-transform", "rotateX(0deg)");
        }
        else
        {
          $current.width(width);
          $new.width(width);
          $current.addClass("face").css("-webkit-transform", "rotateY(0deg)");
        }
        $new.addClass("face").css("-webkit-transform", newBaseRotate);
        $new.removeClass("new").addClass("showing");
// TODO why; what needs fixing?:
        /// FIXME ///
        setTimeout(function()
        {
          var currentDfd = $.Deferred();
          var newDfd = $.Deferred();

          var $inner = $node.children(".amx-panelSplitter_inner");
          var $content = $inner.children(".amx-panelSplitter_contentContainer");
          $content.addClass("transitioning");

          $current.addClass("transitioning-slow");
          var rotateVal = (back) ? "rotateY(+180deg)" : "rotateY(-180deg)";
          if(vertical)
          {
            rotateVal = (back) ? "rotateX(+180deg)" : "rotateX(-180deg)";
          }
          $current.css("-webkit-transform", rotateVal);
          $current.bind("webkitTransitionEnd", function()
          {
            $current.removeClass("current").addClass("old");
            $current.removeClass("transitioning-slow face");
            $current.remove();
            currentDfd.resolve();
          });

          $new.addClass("transitioning-slow");
          if (vertical)
          {
            $new.css("-webkit-transform", "rotateX(0deg)")
          }
          else
          {
            $new.css("-webkit-transform", "rotateY(0deg)")
          }
          $new.bind("webkitTransitionEnd", function()
          {
            $new.removeClass("showing").addClass("current");
            $new.removeClass("transitioning-slow face");
            $content.removeClass("transitioning");
            $new.attr("style", "");
            newDfd.resolve();
          });

          $.when(currentDfd, newDfd).done(function()
          {
            // =-= melges:
            // jQueryMobile workaround:
            // For now, just to be safe, we wait 400 milliseconds before accepting event.
            // Somehow, on simulator, the jQueryMobile button get the previous tap event.
            setTimeout(function()
            {
              dfd.resolve();
              $node.removeClass("changingSelectedItem");
            }, 400);
          });
        }, 1);
        return dfd.promise();
      },

      _getAttribute: function(rawValue, defaultValue)
      {
        if (rawValue == null || rawValue == "")
          return defaultValue;
        return rawValue;
      },

      _getPosition: function(amxNodeSplitter)
      {
        var positionLandscape = this._getAttribute(amxNodeSplitter.position, "31.25%");
        var positionPortrait = "41.67%"; // TODO we ought to expose an API for this
        return {
          landscape: positionLandscape,
          portrait:  positionPortrait
        };
      },

      _getOrientation: function()
      {
        if ($(window).width() < $(window).height())
        {
          return "portrait";
        }
        return "landscape";
      },

      /**
       * Private function to create the navigation content.
       */
      _createNavigation: function(inLandscape, amxNode, $inner, $node, position)
      {
        var $navLandscape = $("<div class='amx-panelSplitter_navLandscape amx-scrollable'> </div>").appendTo($inner);
        $navLandscape.css("width", position.landscape);

        var $screenPortrait = $("<div class='amx-panelSplitter_screenPortrait'> </div>").appendTo($inner);
        $screenPortrait.css("display", "none");

        var $button = $("<div title='" + this._ensureValidString(amxNode.navigatorTitle, "") + "' class='amx-panelSplitter_button'> </div>").appendTo($inner); // TODO same title for disclose and undisclose?

        // Bind the screenPortrait and the button to the toggle code:
        var data = {'node': $node, 'amxNode': amxNode, 'peer': this};
        $screenPortrait.tap(data, this._handleNavPortraitToggle);
        $button.tap(data, this._handleNavPortraitToggle);

        var $navPortrait = $("<div class='amx-panelSplitter_navPortrait amx-scrollable'> </div>").appendTo($inner);
        $navPortrait.css("width", position.portrait);

        if (inLandscape)
        {
          $navPortrait.css("opacity", "0");
$navPortrait.css("display", "none"); // TODO might need to do animation chaining now
          $navPortrait.css("zIndex", "0");
          $button.css("opacity", "0");
$button.css("display", "none"); // TODO might need to do animation chaining now
        }
        else // in portrait
        {
          $navLandscape.css("opacity", "0");
$navLandscape.css("display", "none"); // TODO might need to do animation chaining now
          $navPortrait.css("left", "-" + position.portrait);
        }

        var $initialNavigatorHome = inLandscape ? $navLandscape : $navPortrait;
        var facetNavigatorDfd = amx.renderSubNodes(amxNode.facets.navigator, $initialNavigatorHome);
        return facetNavigatorDfd;
      },

      _handleNavPortraitToggle: function(event)
      {
        try
        {
          var $node = event.data.node;
          var peer = event.data.peer;
          var amxNode = event.data.amxNode;
          var position = peer._getPosition(amxNode);
          var $inner = $node.children(".amx-panelSplitter_inner");
          var $button = $inner.children(".amx-panelSplitter_button");
          var disclosed = $button.hasClass("disclosed");

          if (disclosed)
          {
            // Animate the undisclosure of the navPortrait
            peer._undiscloseNavPortrait($node, position);
          }
          else // undisclosed
          {
            // Animate the disclosure of the navPortrait
            peer._discloseNavPortrait($node, position);
          }
        }
        catch (problem)
        {
          console.error(problem);
        }
      },

      _discloseNavPortrait: function($node, position)
      {
        // 1. set the display of the screenPortrait to block
        var $inner = $node.children(".amx-panelSplitter_inner");
        var $screenPortrait = $inner.children(".amx-panelSplitter_screenPortrait");
        $screenPortrait.css("display", "block");

        // 2. set the opacity of amx-panelSplitter_navPortrait to full
        var $navPortrait = $inner.children(".amx-panelSplitter_navPortrait");
        $navPortrait.addClass("no-animate"); // TODO this doesn't work; might need to do animation chaining now
        $navPortrait.css("opacity", "1");
$navPortrait.css("display", "block"); // TODO might need to do animation chaining now
        $navPortrait.css("zIndex", "1002");
        $navPortrait.removeClass("no-animate");

        // 3. set the left of amx-panelSplitter_navPortrait to be zero
        $navPortrait.css("left", "0px");

        // 4. set the left of the button to be position.portrait
        var $button = $inner.children(".amx-panelSplitter_button");
        $button.css("left", position.portrait);

        // 5. add the disclosed marker class
        $button.addClass("disclosed");
      },
      
      _undiscloseNavPortrait: function($node, position)
      {
        // 1. set the display of the screenPortrait to none
        var $inner = $node.children(".amx-panelSplitter_inner");
        var $screenPortrait = $inner.children(".amx-panelSplitter_screenPortrait");
        $screenPortrait.css("display", "none");

        // 2. set the left of amx-panelSplitter_navPortrait to be -position.portrait
        var $navPortrait = $inner.children(".amx-panelSplitter_navPortrait");
        $navPortrait.css("left", "-" + position.portrait);

        // 3. set the left of the button to be zero
        var $button = $inner.children(".amx-panelSplitter_button");
        $button.css("left", "0px");

        // 4. add the disclosed marker class
        $button.removeClass("disclosed");
      },

      _ensureValidString: function(rawValue, defaultValue)
      {
        // TODO is there a shared util we can use instead?
        if (rawValue == null)
          return defaultValue;
        return rawValue;
      },

      _handleResize: function(event)
      {
        var $node       = event.data.node;
        var $inner      = $node.children(".amx-panelSplitter_inner");
        var peer        = event.data.peer;
        var amxNode     = event.data.amxNode;
        var orientation = peer._getOrientation();
        var position    = peer._getPosition(amxNode);

        // Determine if we are going from portrait to landscape or landscape to portrait
        if ($node.attr("data-orientation") == "portrait" && orientation == "landscape")
        {
          // -- from portrait to landscape --

          // 1. set the left of amx-panelSplitter_navPortrait to be -position.portrait
          var $navPortrait = $inner.children(".amx-panelSplitter_navPortrait");
          $navPortrait.addClass("no-animate"); // TODO this doesn't work; might need to do animation chaining now
          $navPortrait.css("left", "-" + position.portrait);

          // 2. set the opacity of amx-panelSplitter_navPortrait to none
          $navPortrait.css("opacity", "0");
$navPortrait.css("display", "none"); // TODO might need to do animation chaining now
          $navPortrait.css("zIndex", "0");
          $navPortrait.removeClass("no-animate");

          // 3. set the left of the button to be zero
          var $button = $inner.children(".amx-panelSplitter_button");
          $button.addClass("no-animate"); // TODO this doesn't work; might need to do animation chaining now
          $button.css("left", "0px");

          // 4. set the opacity of the button to none
          $button.css("opacity", "0");
$button.css("display", "none"); // TODO might need to do animation chaining now
          $button.removeClass("no-animate");

          // 5. remove the disclosed class from the button
          $button.removeClass("disclosed");

          // 6. set the display of the screenPortrait to none
          var $screenPortrait = $inner.children(".amx-panelSplitter_screenPortrait");
          $screenPortrait.css("display", "none");

          // 7. reparent (appendTo) the amx-panelSplitter_navPortrait children to amx-panelSplitter_navLandscape
          $navPortrait.children().appendTo($inner.children(".amx-panelSplitter_navLandscape"));

          // 8. set the opacity of amx-panelSplitter_navLandscape to full
          var $navLandscape = $inner.children(".amx-panelSplitter_navLandscape");
          $navLandscape.css("opacity", "1");
$navLandscape.css("display", "block"); // TODO might need to do animation chaining now

          // 9. set the left of amx-panelSplitter_contentContainer to be position.landscape
          $content = $inner.children(".amx-panelSplitter_contentContainer");
          $content.css("left", position.landscape);

          // 10. remember our new orientation in a data attribute
          $node.attr("data-orientation", "landscape");
        }
        else if ($node.attr("data-orientation") == "landscape" && orientation == "portrait")
        {
          // -- from landscape to portrait --

          // 1. set the left of amx-panelSplitter_navPortrait to be -position.portrait
          var $navPortrait = $inner.children(".amx-panelSplitter_navPortrait");
          $navPortrait.css("left", "-" + position.portrait);
          $navPortrait.css("zIndex", "1002");

          // 2. set the left of the button to be zero
          var $button = $inner.children(".amx-panelSplitter_button");
          $button.css("left", "0px");

          // 3. set the opacity of amx-panelSplitter_navLandscape to none
          var $navLandscape = $inner.children(".amx-panelSplitter_navLandscape");
          $navLandscape.css("opacity", "0");
$navLandscape.css("display", "none"); // TODO might need to do animation chaining now

          // 4. set the opacity of the button to full
          $button.css("opacity", "1");
$button.css("display", "block"); // TODO might need to do animation chaining now

          // 5. set the left of amx-panelSplitter_contentContainer to be portrait-left in the CSS file
          $content = $inner.children(".amx-panelSplitter_contentContainer");
          $content.css("left", ""); // use blank to purge the custom overide if applicable

          // 6. reparent (appendTo) the amx-panelSplitter_navLandscape children to amx-panelSplitter_navPortrait
          $inner.children(".amx-panelSplitter_navLandscape").children().appendTo($navPortrait);

          // 7. remember our new orientation in a data attribute
          $node.attr("data-orientation", "portrait");
        }
      }
    }
  });
// amx.config.debug.enable = true;

})(jQuery);
