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

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

  var amxRenderers = {
    // new implementation: DONE
    selectBooleanCheckbox: function(amxNode){
      amx.registerInputValue(amxNode, "value");
      var field = amx.createField(amxNode);
      var $node = field.$node;
      var isOn = amx.isValueTrue(amxNode.value);
      var disable = field.isDisable;
      // set state
      if (isOn){
        $node.addClass("on");
      }else{
        $node.addClass("off");
      }

      var $checkbox = $("<div class='checkbox'><div class='img-check'></div></div>");
      field.$value.append($checkbox);

      if (amxNode.text){
        var $text = $("<div class='checkbox-text'>" + amxNode.text + "</div>");
        field.$value.append($text);
      }

      if(disable){
        $node.addClass("amx-disabled");
      }


      if (!field.isReadOnly && !disable){
        $node.tap(function(event){
          if (amx.acceptEvent()){

            var newValue = !isOn;
            // set the amxNode value so that it stays in sync
            amxNode.value = newValue;
            var vce = new amx.ValueChangeEvent(!newValue, newValue);
            amx.processAmxEvent($node,"valueChange","value",newValue, vce);

            // update the UI (in case it is not a EL)
            isOn = !isOn;
            if (isOn){
              $node.addClass("on").removeClass("off");
            }else{
              $node.addClass("off").removeClass("on");
            }
          }
        });
      }
    // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
	adf.mf.api.amx.applyRequiredMarker(amxNode, field);
      return $node;

    },

    // new implementation: DONE
    selectBooleanSwitch: function(amxNode){
      amx.registerInputValue(amxNode, "value");
      var field = amx.createField(amxNode);
      var $node = field.$node;
      var isOn = amx.isValueTrue(amxNode.value);
      // set state
      if (isOn){
        $node.addClass("on");
      }else{
        $node.addClass("off");
      }

      if(field.isDisable){
        $node.addClass("amx-disabled");
      }

      var onLabel = amxNode.onLabel || "ON";
      var offLabel = amxNode.offLabel || "OFF";

      if (!field.isReadOnly){
        var $switch = $("<div class='switch'></div>");
        field.$value.append($switch);
        var $labelOn = $("<label class='label-on'>" + amx.getTextValue(onLabel) + "</label>");
        $switch.append($labelOn);
        var $labelOff = $("<label class='label-off'>" + amx.getTextValue(offLabel) + "</label>");
        $switch.append($labelOff);
        var $button = $("<div class='switch-button'></div>");
        $switch.append($button);

        if(!field.isDisable){
          $node.tap(function(){
            if (amx.acceptEvent()){

              var newValue = !isOn;
              // set the amxNode value so that it stays in sync
              amxNode.value = newValue;
              var vce = new amx.ValueChangeEvent(!newValue, newValue);
              amx.processAmxEvent($node,"valueChange","value",newValue, vce);

              // update the UI (in case it is not a EL)
              isOn = !isOn;
              if (isOn){
                $node.addClass("on").removeClass("off");
              }else{
                $node.addClass("off").removeClass("on");
              }
            }
          });
        }
      }else{
        var $readOnlyLabel = $("<div class='readOnlyLabel'></div>");
        $readOnlyLabel.html((isOn)?amx.getTextValue(onLabel):amx.getTextValue(offLabel));
        field.$value.append($readOnlyLabel);
      }
    // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
	adf.mf.api.amx.applyRequiredMarker(amxNode, field);
	return $node;

    },


    // new implementation: DONE
    selectOneButton: function(amxNode){
      amx.registerInputValue(amxNode, "value");
      var field = amx.createField(amxNode);
      var $node = field.$node;

      var $selectItemsContainer = $("<div class='selectItemsContainer'></div>");
      if(field.isReadOnly){
        $selectItemsContainer = $("<div class='readOnlyLabel'></div>");
      }
      field.$value.append($selectItemsContainer);

      //always horizontal
//      if (amxNode.layout && amxNode.layout === "vertical"){
//        $node.addClass("vertical");
//      }

      if(field.isDisable){
        $node.addClass("amx-disabled");
      }

      // event handling
      if(!field.isDisable){
        $selectItemsContainer.tap(".amx-selectItem",function(event){
          if (amx.acceptEvent() && !field.isReadOnly){
            var $selectItem = $(this);
            var oldValue;
            if ($selectItemsContainer.find(".amx-selected").length > 0){
              oldValue = $selectItemsContainer.find(".amx-selected").data("labelValue").value;
            }
            $selectItemsContainer.find(".amx-selectItem").removeClass("amx-selected");
            $selectItem.addClass("amx-selected");
            var labelValue = $selectItem.data("labelValue");
            var newValue = labelValue.value;
            // set the amxNode value so that it stays in sync
            amxNode.value = newValue;
            var vce = new amx.ValueChangeEvent(oldValue, newValue);
            amx.processAmxEvent($node,"valueChange","value",newValue, vce);
          }
        });
      }

      return getSelectItemLabelValues(amxNode).done(function(labelValues){
        $.each(labelValues,function(idx,labelValue){
          if(field.isReadOnly){
            if (amxNode.value == labelValue.value)
            {
              $selectItemsContainer.html(labelValue.label);
            }
          }else{
            var $selectItem = $("<div class='amx-selectItem'>" + labelValue.label + "</div>");
            $selectItem.data("labelValue",labelValue);

            $selectItem.css("width",100/labelValues.length+"%");
//            if(amxNode.layout !== "vertical"){
//              $selectItem.css("width",99/labelValues.length+"%");
//            }

            $selectItemsContainer.append($selectItem);
            if (amxNode.value == labelValue.value)
            {
              $selectItem.addClass("amx-selected");
            }
          }

        })

      }).pipe(function(){
      // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
      adf.mf.api.amx.applyRequiredMarker(amxNode, field);
        return $node;
      });

    },

    // new implementation: DONE
    selectOneRadio: function(amxNode){
      amx.registerInputValue(amxNode, "value");
      var field = amx.createField(amxNode);
      var $node = field.$node;

      // TODO: look at the selectOneButton, and follow the pattern to create the similar HTML
      //       and skin it css
      // The RADIO button should all be done with DIV to do the ciricle and all

      var $selectItemsContainer = $("<div class='selectItemsContainer'></div>");
      if(field.isReadOnly){
        $selectItemsContainer = $("<div class='readOnlyLabel'></div>");
      }
      field.$value.append($selectItemsContainer);

      if(field.isDisable){
        $node.addClass("amx-disabled");
      }

      // event handling
      if(!field.isDisable && !field.isReadOnly){
        $selectItemsContainer.tap(".amx-selectItem",function(event){
          if (amx.acceptEvent() && !field.isReadOnly){
            var $selectItem = $(this);
            var oldValue;
            if ($selectItemsContainer.find(".amx-selected").length > 0){
              oldValue = $selectItemsContainer.find(".amx-selected").data("labelValue").value;
            }
            $selectItemsContainer.find(".amx-selectItem").removeClass("amx-selected");
            $selectItem.addClass("amx-selected");
            var labelValue = $selectItem.data("labelValue");
            var newValue = labelValue.value;
            // set the amxNode value so that it stays in sync
            amxNode.value = newValue;
            var vce = new amx.ValueChangeEvent(oldValue, newValue);
            amx.processAmxEvent($node,"valueChange","value",newValue, vce);
          }
        });
      }

      return getSelectItemLabelValues(amxNode).done(function(labelValues){
        $.each(labelValues,function(idx,labelValue){
          if(field.isReadOnly){
            if (amxNode.value == labelValue.value)
            {
              $selectItemsContainer.html(labelValue.label);
            }
          }else{
            var $selectItem = $("<div class='amx-selectItem'><div class='radio'><div class='innerCircle'><div class='smallCircle'/></div>" + labelValue.label + "</div></div>");

            // TODO: NEED to display the element to create the radio buttons to be like the design
            $selectItem.data("labelValue",labelValue);

            $selectItemsContainer.append($selectItem);
            if (amxNode.value == labelValue.value)
            {
              $selectItem.addClass("amx-selected");
            }
          }

        })

      }).pipe(function(){
      // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
      adf.mf.api.amx.applyRequiredMarker(amxNode, field);
        return $node;
      });

    },

    // TODO: finish implementing with the new way (right now, lot of code from oneRadio)
    selectManyCheckbox: {
      create: function(amxNode){
        amx.registerInputValue(amxNode, "value");
        var field = amx.createField(amxNode);
        var $node = field.$node;

        var $selectItemsContainer = $("<div class='selectItemsContainer'></div>");
        if(field.isReadOnly){
          $selectItemsContainer = $("<div class='readOnlyLabel'></div>");
        }
        field.$value.append($selectItemsContainer);

        if(field.isDisable){
          $node.addClass("amx-disabled");
        }

        // event handling
        if(!field.isDisable){
          $selectItemsContainer.tap(".amx-selectItem",function(event){
            if (amx.acceptEvent() && !field.isReadOnly){
              var $selectItem = $(this);
              var oldValues = [];
              $selectItemsContainer.find(".amx-selectItem.amx-selected").each(function(){
                oldValues.push($(this).data("labelValue").value);
              });
              $selectItem.toggleClass("amx-selected");
              var values = [];
              $selectItemsContainer.find(".amx-selectItem.amx-selected").each(function(){
                values.push($(this).data("labelValue").value);
              });
              // set the amxNode value so that it stays in sync
              amxNode.value = values;
              var vce = new amx.ValueChangeEvent(oldValues, values);
              amx.processAmxEvent($node,"valueChange","value",values, vce);
            }
          });
        }

        // render the children and return the deferred for the $node
        return getSelectItemLabelValues(amxNode).done(function(labelValues){
          $.each(labelValues,function(idx,labelValue){
            var values = amxNode.value;
            if(!$.isArray(values)){
              values = new Array(amxNode.value);
            }
            if(field.isReadOnly){
              if ($.inArray(labelValue.value,values) > -1){
                $selectItemsContainer.append(labelValue.label+",");
              }
            }else{
              var $selectItem = $("<div class='amx-selectItem'><div class='checkbox'><div class='img-check'></div></div><div class='checkbox-text'>" + labelValue.label + "</div>");

              $selectItem.data("labelValue",labelValue);

              $selectItemsContainer.append($selectItem);

              if ($.inArray(labelValue.value,values) > -1){
                $selectItem.addClass("amx-selected");
              }
            }

          })

        }).pipe(function(){
          // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
      	  adf.mf.api.amx.applyRequiredMarker(amxNode, field);
          return $node;
        });

      },
      init: function($node,amxNode){
        var $label = $node.find(".readOnlyLabel");
        $label.width($label.parent().width() - 90);
      }
    },

    // TODO: needs to implement new way
    selectOneChoice: function(amxNode){
      amx.registerInputValue(amxNode, "value");
      // TODO here is the first new way, but we need to continue the new way.
      var field = amx.createField(amxNode);
      var $node = field.$node;

      var $selectItemsContainer = $("<select class='selectItemsContainer'></select>");
      if(amx.isValueTrue(amxNode.readOnly)) {
        $selectItemsContainer = $("<div class='selectItemsContainer'></div>");
      }
      field.$value.append($selectItemsContainer);

      if(amx.isValueTrue(amxNode.disabled)) {
        $selectItemsContainer.attr("disabled",true);
      }

      $selectItemsContainer.bind("change",function(event){
        if (amx.acceptEvent() && !field.isReadOnly && !amx.isValueTrue(amxNode.disabled)){
          var $selectItem = $(this).find("option:selected");
          var labelValue = $selectItem.data("labelValue");
          var newValue = labelValue.value;
          var oldValue = undefined;
          if ($node.data("_oldValue"))
          {
            oldValue = $node.data("_oldValue").value;
          }
          // set the amxNode value so that it stays in sync
          amxNode.value = newValue;
          var vce = new amx.ValueChangeEvent(oldValue, newValue);
          amx.processAmxEvent($node,"valueChange","value",newValue, vce);
          $node.data("_oldValue", labelValue);
        }
      });

      // TODO: need to do the return like above.
      return getSelectItemLabelValues(amxNode).done(function(labelValues){
        $.each(labelValues,function(idx,labelValue){
          if(field.isReadOnly){
            if (amxNode.value == labelValue.value)
            {
              $selectItemsContainer.html(labelValue.label);
            }
          }else{
            var $selectItem = $("<option value='"+labelValue.value+"' class='amx-selectItem'>"+labelValue.label+"</option>");

            $selectItem.data("labelValue",labelValue);

            $selectItemsContainer.append($selectItem);
            if (amxNode.value == labelValue.value)
            {
              $selectItem.attr("selected",true);
              $node.data("_oldValue", labelValue);
            }
          }
        });
      }).pipe(function(){
        if (amx.isValueFalse(amxNode.isReadOnly) && $node.find("option:selected").length > 0){
          $node.data("_oldValue", $node.find("option:selected").data().labelValue);
        }
	    // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
        adf.mf.api.amx.applyRequiredMarker(amxNode, field);
        return $node;
      });


    },

    selectManyChoice: {
      create:function(amxNode){
        // TODO here is the first new way, but we need to continue the new way.
        var field = amx.createField(amxNode);
        var $node = field.$node;

        $selectItemsScreen = $("<div class='transparentScreen selectItemsScreen'></div>");
        field.$value.append($selectItemsScreen);
        $selectItemsScreen.hide();
        var $displayItem = $("<div class='displayItem'><label></label><div class='arrow'><div class='count'></div><div class='img-arrow'></div></div></div>");
        field.$value.append($displayItem);
        var $selectItemsContainer = $("<div class='selectItemsContainer'></div>");
        $selectItemsContainer.hide();
        field.$value.append($selectItemsContainer);
        var $arrow = $displayItem.find(".arrow");
        var $count = $displayItem.find(".count");
//        var $selectItemsTitle = $("<div class='amx-selectItemsTitle'><div class='checkbox'><div class='img-check'></div></div><div class='checkbox-text'>" + amxNode.label + "</div>");
//        $selectItemsContainer.append($selectItemsTitle);

        if(field.isDisable){
          $node.addClass("amx-disabled");
        }

        $selectItemsScreen.tap(function(){
          $selectItemsScreen.hide();
          $selectItemsContainer.hide();
        });

        if(!field.isDisable){
          $displayItem.tap(function(event){
            if(!$node.hasClass("amx-readOnly")){
              show();
              var offset = $displayItem.offset();
              var top = offset.top + $displayItem.height() + 5;
              var left = offset.left;
              $selectItemsContainer.offset({left:left,top:top});
              $selectItemsContainer.width($displayItem.width());
              $arrow.addClass("dropdown");
              // Listen if someone resizes the window:
							$(window).resize(function()
							{
								$selectItemsContainer.offset({left:left,top:top});
								$selectItemsContainer.width($displayItem.width());
							});

            }
          });

//          $selectItemsContainer.tap(".amx-selectItemsTitle .checkbox",function(event){
//            var values = [];
//            $selectItemsContainer.find(".amx-selectItem.amx-selected").each(function(){
//              values.push($(this).data("labelValue").value);
//            });
//            $selectItemsContainer.hide();
//            $selectItemsScreen.hide();
//            $arrow.removeClass("dropdown");
//            amx.processAmxEvent($node,"valueChange","value",values);
//          });

          $selectItemsContainer.tap(".amx-selectItem",function(event){
            if (amx.acceptEvent() && !field.isReadOnly){
              var $selectItem = $(this);
              $selectItem.toggleClass("amx-selected");
              var $label = $displayItem.find("label");
              $label.empty();
              $selectItemsContainer.find(".amx-selectItem.amx-selected").each(function(i){
                if(i > 0){
                  $label.append(",");
                }
                $label.append($(this).data("labelValue").label);
              });
              $count.html($selectItemsContainer.find(".amx-selectItem.amx-selected").size());
            }
          });
        }


        function show(){
          $selectItemsScreen = field.$value.find(".transparentScreen");
          $selectItemsContainer = field.$value.find(".selectItemsContainer");
          $selectItemsScreen.show();
          $selectItemsContainer.show();
        }

        function hide(){
          $selectItemsScreen = field.$value.find(".transparentScreen");
          $selectItemsContainer = field.$value.find(".selectItemsContainer");
          $selectItemsScreen.hide();
          $selectItemsContainer.hide();
        }

        // TODO: need to do the return like above.
        return getSelectItemLabelValues(amxNode).done(function(labelValues){
          var values =  getArrayValue(amxNode.value);
          $count.html(values.length);
          $.each(labelValues,function(idx,labelValue){
            var $selectItem = $("<div class='amx-selectItem'><div class='checkbox'><div class='img-check'></div></div><div class='checkbox-text'>" + labelValue.label + "</div>");

            $selectItem.data("labelValue",labelValue);

            $selectItemsContainer.append($selectItem);

            var index = $.inArray(labelValue.value,values);
            if (index > -1){
              $selectItem.addClass("amx-selected");
              var $label = $displayItem.find("label");
              $label.append(labelValue.label);
              if(index != values.length - 1){
                $label.append(",");
              }
            }


          });

        }).pipe(function(){
        // calls applyRequiredMarker in amx-core.js to determine and implement required/showRequired style
        adf.mf.api.amx.applyRequiredMarker(amxNode, field);
          return $node;
        });

      }
    },

    selectItem: function(amxNode) {
      var $node = $('<label for="'+amxNode.value+'">'+amxNode.label+'</label>');
      return $node;
    }

  }; // /var amxRenderers

  // ------ SelectOneRadio & SelectOneButton ------ //
  // for selectOneRadio and selectOneButton
  function createWithJQMobileCheckboxradio(amxNode){
    var html =  '<div data-role="fieldcontain" class="amx-fieldcontain">'+
    '<fieldset data-role="controlgroup">'+
    '</fieldset>'+
    '</div>';
    var $node = $(html);

    if (amxNode.tagName == "amx:selectOneButton"){
      $node.children("fieldset").attr("data-type","horizontal");
    }

    var $fieldset = $node.find("fieldset");
    var fieldsetId = amx.uuid();

    if(amx.isValueTrue(amxNode.simple)) {
      //here label and showRequired properties are ignored
      $fieldset.prepend('<label>&nbsp;</label>');
    } else {
      if(amxNode.label) {
        $fieldset.prepend('<label>'+amxNode.label+'</label>');
      }
    }

    $node.bind("change",function(){
      var newValue = $node.find("input:checked").attr("value");
      amx.processAmxEvent($node,"valueChange","value",newValue);
    });

    var inputType = "radio";
    // If it is a singleBooleaCheckBox, there is only one checkbox
    if (amxNode.tagName === "amx:selectBooleanCheckbox"){
      inputType = "checkbox";
      addField(inputType,$fieldset,{label:amxNode.label,value:amxNode.value});
      return $node;
    }else{

      return getSelectItemLabelValues(amxNode).done(function(labelValues){
        $.each(labelValues,function(idx,labelValue){
          addField(inputType,$fieldset,labelValue);
        })

      }).pipe(function(){
        return $node;
      });

    }

    function addField(inputType,$fieldset,labelValue){
      var fieldId = amx.uuid();
      var $selectItem = $('<label for="'+ fieldId + '">' + labelValue.label + '</label>');
      $fieldset.append('<input   data-theme="b" id="' + fieldId + '" type="' + inputType + '" name="' + fieldsetId + '" value="' + labelValue.value + '"/>');
      $fieldset.append($selectItem);

    }
  }

  // for selectOneRadio and selectOneButton
  function initWithJQMobileCheckboxradio($node,amxNode){
    var $input = $node.find("input");
    var $label = $node.find("label");


    $input.checkboxradio();
    $node.find("fieldset[data-role='controlgroup']").controlgroup();

    if (typeof amxNode.value !== "undefined"){
      var $selectedInput = $node.find("input[value='" + amxNode.value + "']");
      $selectedInput.prop("checked",true);

    }

    if(amx.isValueTrue(amxNode.disabled)) {
      $input.checkboxradio("disable");
    }

    if(amx.isValueTrue(amxNode.readOnly)) {
      $input.parent().addClass("amx-readOnly");
      $input.attr("readonly",true);
    }

    $input.checkboxradio("refresh");
  }
  // ------ /SelectOneRadio & SelectOneButton ------ //

  // ------ SelectOneChoice & SelectManyChoice ------ //
  function createWithJQMobileSelectmenu(amxNode){
    var fieldId = amx.uuid();
    var html = '<div data-role="fieldcontain">'
    html +='<label for="' + fieldId + '" class="">' + amxNode.label + '</label>';
    html += '</div>';
    var $node = $(html);
    var $select = $("<select id='" + fieldId + "' name='" + fieldId + "'></select>").appendTo($node);

    if (amxNode.tagName === "amx:selectManyChoice"){
      $select.attr("multiple","multiple");
      $select.attr("data-native-menu","false");
    }

      $select.bind("change",function(){
        amx.processAmxEvent($node,"valueChange","value",$select.val());
      });

    // built the options nodes
      return getSelectItemLabelValues(amxNode).done(function (labelValues){
        $.each(labelValues,function(idx,labelValue){
          $select.append("<option class='amx-selectItem' value='" + labelValue.value + "'>" + labelValue.label + "</option>" );
        });

      }).pipe(function(){
        return $node;
      });
  }

  function initWithJQMobileSelectmenu($node,amxNode){
    var $select = $node.find("select");

    $select.selectmenu();
    //$node
    if (typeof amxNode.value !== "undefined"){
      $select.val(amxNode.value);
    }

    if(amx.isValueTrue(amxNode.disabled)) {
      $select.selectmenu("disable");
    }

    if(amx.isValueTrue(amxNode.readOnly)) {
      $select.parent().addClass("amx-readOnly");
      $select.attr("readonly",true);
    }
    $select.selectmenu("refresh");

  }
  // ------ /SelectOneChoice & SelectManyChoice ------ //


  /**
   * Return a $.Deferred that will resolve with a array of {label:,value:}
   * This will look for the amx:selectItem elements or the amx:selectItems elements.
   */
  function getSelectItemLabelValues(amxNode){
    var dfd = $.Deferred();
    var result = [];
    var amxChildren = $(amxNode._xmlNode).children("amx\\:selectItem,amx\\:selectItems");
    if (amxChildren.length > 0){

      amx.serialResolve(amxChildren,function(selectItemOrItems)
      {
        return amx.processXmlNode(selectItemOrItems).done(function(itemAmxNode)
        {
          if (selectItemOrItems.tagName == "amx:selectItem")
          {
            result.push({label:itemAmxNode.label, value:itemAmxNode.value});
          }
          else
          {
            // assume it is a selectItems
            var isArray = adf.mf.internal.util.is_array(itemAmxNode.value);
            $.each(itemAmxNode.value,function(idx,labelValue)
            {
              var itemLabel;
              var itemValue;
              // if this is an array, then it is strongly typed, so assume it has a label and value
              if (isArray)
              {
                itemLabel = labelValue.label;
                itemValue = labelValue.value;
              }
              else
              {
                // Bug 13573502: assume this is a map, so use the key as the label and the value as the value
                itemLabel = idx;
                itemValue = labelValue;
              }
              result.push({label:itemLabel, value:itemValue});
            });
          }
        });
      }).done(function(){
        dfd.resolve(result);
      });
    }else{
      dfd.resolve(result);
    }

    return dfd.promise();
  }

  function getArrayValue(value){
    var values = value;
    if(!$.isArray(values)){
      values = new Array(values);
    }
    return values;
  }

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

})();

