text: /**
      @module "montage/ui/native/checkbox.reel"
      @requires montage/core/core
      @requires montage/ui/check-control
  */
  var CheckControl = require("ui/check-control").CheckControl;
      PressComposer = require("composer/press-composer").PressComposer;
  
  /**
  
      @class module:"montage/ui/native/checkbox.reel".Checkbox
      @extends module:montage/ui/check-control.CheckControl
  */
  var Checkbox = exports.Checkbox = CheckControl.specialize({
      enterDocument: {
          value: function (firstTime) {
              this.super(firstTime);
              if (firstTime) {
                  this.element.setAttribute("role", "checkbox");
              }
          }
      },
      _preventFocus: {
          enumerable: false,
          value: true
      },
  
  /**
      Specifies whether the button should receive focus or not.
      @type {boolean}
      @default false
      @event longpress @benoit: no events here?
  */
      preventFocus: {
          get: function () {
              return this._preventFocus;
          },
          set: function (value) {
              this._preventFocus = !!value;
              this.needsDraw = true;
          }
      },
      __pressComposer: {
          enumerable: false,
          value: null
      },
  
      _pressComposer: {
          enumerable: false,
          get: function () {
              if (!this.__pressComposer) {
                  this.__pressComposer = new PressComposer();
                  this.addComposer(this.__pressComposer);
              }
  
              return this.__pressComposer;
          }
      },
  
      // HTMLInputElement/HTMLButtonElement methods
      // click() deliberately omitted (it isn't available on <button> anyways)
  
      prepareForActivationEvents: {
          value: function () {
              this._pressComposer.addEventListener("pressStart", this, false);
          }
      },
  
      // Optimisation
      addEventListener: {
          value: function (type, listener, useCapture) {
              Control.prototype.addEventListener.call(this, type, listener, useCapture);
              if (type === "longAction") {
                  this._pressComposer.addEventListener("longPress", this, false);
              }
          }
      },
  
      _addEventListeners: {
          value: function () {
              this._pressComposer.addEventListener("press", this, false);
              this._pressComposer.addEventListener("pressCancel", this, false);
  
              //fixme: @benoit: we should maybe have a flag for this kind of event.
              // can be tricky with the event delegation for example if we don't add it.
              // same issue for: the pressComposer and the translate composer.
              this._pressComposer.addEventListener("longPress", this, false);
          }
      },
  
      _removeEventListeners: {
          value: function () {
              this._pressComposer.removeEventListener("press", this, false);
              this._pressComposer.removeEventListener("pressCancel", this, false);
              this._pressComposer.removeEventListener("longPress", this, false);
          }
      },
      /**
      Called when the user starts interacting with the component.
      */
      handlePressStart: {
          value: function (event) {
              var that = this;
              if (!this._promise){
                  this.active = true;
                  this._addEventListeners();
              }
  
              if (!this._preventFocus) {
                  this._element.focus();
              } else {
                  this.needsClearFocus = true;
              }
          }
      },
      /**
      Called when the user has interacted with the button.
      */
      handlePress: {
          value: function (event) {
              if (!this._promise){
                  this.active = false;
                  this._dispatchActionEvent();
                  this._removeEventListeners();
              }
          }
      },
  
      handleLongPress: {
          value: function(event) {
              if (!this._promise){
                  // When we fire the "hold" event we don't want to fire the
                  // "action" event as well.
                  this._pressComposer.cancelPress();
                  this._removeEventListeners();
  
                  var longActionEvent = document.createEvent("CustomEvent");
                  longActionEvent.initCustomEvent("longAction", true, true, null);
                  this.dispatchEvent(longActionEvent);
              }
          }
      },
  
      /**
      Called when all interaction is over.
      @private
      */
      handlePressCancel: {
          value: function(event) {
              this.active = false;
              this._removeEventListeners();
          }
      },
  
      /**
      If this is an input element then the label is handled differently.
      @private
      */
      _isInputElement: {
          value: undefined,
          enumerable: false
      },
      isInputElement: {
          get: function() {
              return this._isInputElement !== undefined ? this._isInputElement : (this._isInputElement = (this.element ? (this.element.tagName === "INPUT") : false));
          },
          enumerable: false
      },
      _elementNeedsTabIndexRegex: {
          value: /INPUT|TEXTAREA|A|SELECT|BUTTON|LABEL/
      },
      _elementNeedsTabIndex: {
          value: function () {
              return this.element.tagName.match(this._elementNeedsTabIndexRegex) === null;
          }
      },
      draw: {
  	        value: function () {
  	            this.super();
  
  	            if (this._elementNeedsTabIndex()) {
  	                if (this._preventFocus) {
  	                    this.element.removeAttribute("tabindex");
  	                } else {
  	                    this.element.setAttribute("tabindex", "-1");
  	                }
  	            }
  	            if (this.needsClearFocus) {
  	                this._element.blur();
  
  	                this.needsClearFocus = false;
  	            }
  
  	        }
      }
  
  });