/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. */
/* ------------------------------------------------------ */
/* ------------------- amx-panels.js -------------------- */
/* ------------------------------------------------------ */

(function() {
// TODO finish the migration from "amx.*" to "adf.mf.api.amx.*" and "adf.mf.internal.amx.*"

  var amxRenderers = {

    panelPage:
    {
      create: function(amxNode)
      {
        var $node = $("<div></div>");
        // render the facet header if present
        var headerDfd, facetPrimaryDfd, facetHeaderDfd,  facetSecondaryDfd;

        if (amxNode.facets.primary || amxNode.facets.header || amxNode.facets.secondary)
        {
          var $header = $("<div class='amx-panelPage-header'></div>");

          if (amxNode.facets.primary)
          {
            var $facetPrimary = $("<div class='amx-panelPage-facet-primary'></div>").appendTo($header);
            facetPrimaryDfd = amx.renderSubNodes(amxNode.facets.primary,$facetPrimary);
          }

          if (amxNode.facets.header)
          {
            var $facetHeader = $("<div class='amx-panelPage-facet-header'></div>").appendTo($header);
            facetPrimaryDfd = amx.renderSubNodes(amxNode.facets.header,$facetHeader);
          }

          if (amxNode.facets.secondary)
          {
            var $facetSecondary = $("<div class='amx-panelPage-facet-secondary'></div>").appendTo($header);
            facetPrimaryDfd = amx.renderSubNodes(amxNode.facets.secondary,$facetSecondary);
          }

          headerDfd = $.when(facetPrimaryDfd, facetHeaderDfd,  facetSecondaryDfd).done(function()
          {
            $node.append($header);
          });
        }

        // NOTE 1) If the headerDfd is undefined (not facets), the $.when will be immediately resolved (so it works both case)
        // NOTE 2) This return a differed and not the $node. We are using the pipe() method to filter the resolution of the return resolved.
        return $.when(headerDfd).pipe( function()
        {
          var $content = $("<div class='amx-panelPage-content amx-scrollable'></div>").appendTo($node);

          return amx.renderSubNodes(amxNode,$content).pipe( function()
          {
            if (amxNode.facets.footer)
            {
              var $footer = $("<div class='amx-panelPage-footer'></div>");
              var $facetFooter = $("<div class='amx-panelPage-facet-footer'></div>").appendTo($footer);
              return amx.renderSubNodes(amxNode.facets.footer,$facetFooter).pipe( function()
              {
                $node.append($footer);
                return $node;
              });
            }
            else
            {
              return $node;
            }
          });
        });
      },

      postDisplay: function($node,amxNode)
      {
        // 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)
        {
          $content = $node.find(".amx-panelPage-content");
          var scrollLeft = storedData.scrollLeft;
          if (scrollLeft != null)
            $content.scrollLeft(scrollLeft);
          var scrollTop = storedData.scrollTop;
          if (scrollTop != null)
            $content.scrollTop(scrollTop);
        }
      },

      refresh: function($node, newAmxNode, propertiesChanged)
      {
        // Save the scroll positions since this component never does 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)
      {
        $content = $node.find(".amx-panelPage-content");
        var scrollLeft = $content.scrollLeft();
        var scrollTop = $content.scrollTop();
        if (scrollLeft != null || scrollTop != null)
        {
          var storedData =
          {
            scrollLeft: scrollLeft,
            scrollTop: scrollTop
          };
          adf.mf.api.amx.setClientState(amxNodeId, storedData);
        }
      }
    },

    panelFormLayout:
    {
      create: function(amxNode)
      {
        // Generate the outer structure:
        var $node = $("<div class='amx-panelFormLayout amx-scrollable'></div>");
        var $body = $("<div class='amx-panelFormLayout_body'></div>");
        $body.appendTo($node);

        // Apply the labelAlignement marker class:
        var labelPositionStyle = "amx-label-position-start"; // default is "start"
        if (amxNode.labelPosition != null)
        {
          if (amxNode.labelPosition === "end")
            labelPositionStyle = "amx-label-position-end";
          else if (amxNode.labelPosition === "center")
            labelPositionStyle = "amx-label-position-center";
          else if (amxNode.labelPosition === "topStart")
            labelPositionStyle = "amx-label-position-topStart";
          else if (amxNode.labelPosition === "topCenter")
            labelPositionStyle = "amx-label-position-topCenter";
          else if (amxNode.labelPosition === "topEnd")
            labelPositionStyle = "amx-label-position-topEnd";
        }
        $node.addClass(labelPositionStyle);

        var fieldHalignStyle = "amx-field-halign-end"; // default is "end"
        if (amxNode.fieldHalign != null)
        {
          if (amxNode.fieldHalign === "start")
            fieldHalignStyle = "amx-field-halign-start";
          else if (amxNode.fieldHalign === "center")
            fieldHalignStyle = "amx-field-halign-center";
        }
        $node.addClass(fieldHalignStyle);

        // Apply the label/field widths:
        if (labelPositionStyle != "amx-label-position-topStart" &&
            labelPositionStyle != "amx-label-position-topCenter" &&
            labelPositionStyle != "amx-label-position-topEnd")
        {
          $node.addClass("amx-layout-one-row");

          // If labels are on the same row as the fields then we need to add the sizing row and assign the values:
          $sizing = $("<div class='amx-panelFormLayout_sizing'><div class='field-label'></div><div class='field-value'></div></div>");
          $sizing.appendTo($body);

          var labelWidth = amxNode.labelWidth;
          if(this._nonNegativeNumberRegExp.test(labelWidth))
          {
            labelWidth = labelWidth+"px";
          }
          var valueWidth = amxNode.fieldWidth;
          if(this._nonNegativeNumberRegExp.test(valueWidth))
          {
            valueWidth = valueWidth+"px";
          }
          var labelIsPercent = (labelWidth == null ? false : labelWidth == this._nonNegativePercentRegExp.exec(labelWidth));
          var fieldIsPercent = (valueWidth == null ? false : valueWidth == this._nonNegativePercentRegExp.exec(valueWidth));
          var labelIsPx = !labelIsPercent && (labelWidth == null ? false : labelWidth == this._nonNegativePxRegExp.exec(labelWidth));
          var fieldIsPx = !fieldIsPercent && (valueWidth == null ? false : valueWidth == this._nonNegativePxRegExp.exec(valueWidth));
          if (labelIsPercent && fieldIsPercent)
          {
            // normalize the percents and use both
            labelWidth = parseFloat(labelWidth);
            valueWidth = parseFloat(valueWidth);
            totalPercent = labelWidth + valueWidth;
            labelWidth = 100*labelWidth/totalPercent + "%";
            valueWidth = 100*valueWidth/totalPercent + "%";
            $sizing.find(".field-label").css("width", labelWidth);
            $sizing.find(".field-value").css("width", valueWidth);
          }
          else if (labelIsPx || (labelIsPx && fieldIsPx))
          {
            // label gets pixels, field becomes undefined
            $sizing.find(".field-label").css("width", labelWidth);
          }
          else if (fieldIsPx)
          {
            // field gets pixels, label becomes undefined
            $sizing.find(".field-value").css("width", valueWidth);
          }
          // Any other scenarios will result in both widths being ignored.
        }
        else
        {
          $node.addClass("amx-layout-separate-rows");
        }
        return amx.renderSubNodes(amxNode,$body).pipe(function(){
          return $node;
        });
      },

      _nonNegativeNumberRegExp: new RegExp(/^[0-9]+[.]?[0-9]*$/),
      
      _nonNegativePercentRegExp: new RegExp(/[0-9]+[.]?[0-9]*[%]/),

      _nonNegativePxRegExp: new RegExp(/[0-9]+[.]?[0-9]*[p][x]/)
    },

    panelLabelAndMessage: function(amxNode) {
      var field =  amx.createField(amxNode);
      var $node =  field.$node;
      var $fieldValue = $node.find(".field-value");
      amx.renderSubNodes(amxNode,$fieldValue);
	  // calls applyRequiredMarker to determine and implement required/showRequired style
      adf.mf.api.amx.applyRequiredMarker(amxNode, field);
      return $node;
    },

    panelGroupLayout: function(amxNode)
    {
      var $rootNode;
      var $childWrapperParent;
      var layout = amxNode.layout;
      var isHorizontal = (layout === "horizontal");
      var isWrap = (layout === "wrap");
      var halign = (!isWrap ? amxNode.halign : null);
      var valign = (isHorizontal ? amxNode.valign : null);

      if (isHorizontal)
      {
        $rootNode = $("<div class='amx-scrollable'></div>");
        var $table = $("<table></table>").appendTo($rootNode);
        $childWrapperParent = $("<tr></tr>").appendTo($table);
        if (halign == "center")
        {
          $table.attr("align", "center");
        }
        else if (halign == "end")
        {
          // The first child of a horizontal layout must be an empty "100%-wide" cell to force the
          // other cells to be pushed to the end side of the table:
          var $wrapper = $("<td></td>");
          $wrapper.appendTo($childWrapperParent);
          $wrapper.attr("width", "100%");
        }
      }
      else if (isWrap)
      {
        $rootNode = $("<span class='amx-scrollable'></span>");
        $rootNode.addClass("amx-wrap");
      }
      else // isVertical
      {
        $rootNode = $("<div class='amx-scrollable'></div>");
        if (halign == "center")
        {
          $rootNode.attr("align", "center");
        }
        else if (halign == "end")
        {
          if (document.documentElement.dir == "rtl")
            $rootNode.attr("align", "left");
          else
            $rootNode.attr("align", "right");
        }
      }

      return amx.renderSubNodes(amxNode,function($subNode)
      {
        if (isHorizontal)
        {
          var $wrapper = $("<td></td>");
          $wrapper.append($subNode).appendTo($childWrapperParent);
          if (valign == "top" || valign == "middle" || valign == "bottom")
            $wrapper.attr("valign", valign);
        }
        else if (isWrap)
        {
          $rootNode.append($subNode);
        }
        else // isVertical
        {
          $("<div></div>").append($subNode).appendTo($rootNode);
        }
      }).pipe(function()
      {
        return $rootNode;
      });
    }

  }; // /var amxRenderers

  // add this renderer
  amx.registerRenderers("amx",amxRenderers);

})();

