define([
    'jquery'
  , 'jqm'
  , 'css!extensions'
], function ($) {
  "use strict";
  // this module adds extensions to JQM

  /* ========================= GALLERY WIDGET ========================= */
  (function( $, undefined ) {

    $.widget( "mobile.carousel", {

        options: {
          bullets: null,
          bulletsPos: null,
          inset: null,
          captions: null,
          captionpos: null,
          captiontheme: null,
          carouseltransition: null,
          heading: "h1,h2,h3,h4,h5,h6,legend"
        },

        _transitionEndEvents : "webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd",

        _create: function () {
          var el = this.element[0],
            o = this.options,
            getAttrFixed = $.mobile.getAttribute;

          // only time we read the DOM config
          o.inset = getAttrFixed(el, "inset", true) || false;
          o.carouseltransition = getAttrFixed(el, "transition", true) || "slide";
          o.bullets = getAttrFixed(el, "bullets", true) || true;
          o.captions = getAttrFixed(el, "captions", true) || false;

          if (o.captions) {
            o.captionspos = getAttrFixed(el, "captions-pos", true) || "bottom";
            o.captionstheme = getAttrFixed(el, "captions-theme", true) || "a";
          }
          if (o.bullets) {
            o.bulletsPos = getAttrFixed(el, "bulletsPos", true) || "bottom";
          }

          this.refresh(true);
        },

        refresh: function (create) {
          var o = this.options,
            el = this.element,
            items = el.children(),
            fragment = document.createDocumentFragment(),
            classes = "ui-carousel",
            barrel,
            label,
            radio,
            item,
            i,
            transition,
            containsLinks,
            captionsContent,
            captionsHeading;

          // loop over images
          for (i = 0; i < items.length; i += 1) {
            var item = items[i];

            // create captions
            if (o.captions) {
              containsLinks = item.children.length === 1 && item.children[0].tagName === "A";
              captionsContent = $( item )
                .find(containsLinks ? "a *" : "*")
                .not("img")
                .wrap( "<div class='ui-carousel-captions-content ui-bar-" + o.captionstheme + " ui-carousel-captions-" + o.captionspos + "'></div>")
                .parent();
              captionsHeading = captionsContent.find(o.heading).addClass("ui-carousel-captions-heading");
            }

            // create radios
            if (o.bullets) {
              // TODO: do this in jQuery...
              radio = document.createElement("input");
                radio.setAttribute("type", 'radio');
                radio.setAttribute("name", 'radio-' + this.uuid );
                radio.setAttribute("value",'radio-' + this.uuid + '-' + i);
                if (i === 0) {
                  radio.checked = true;
                  $(item).addClass("ui-carousel-active");
                }
              // and use data()
              radio.reference = $(item);

              label = document.createElement("label");
                label.setAttribute("data-" + $.mobile.ns + "iconpos", "notext");
                label.appendChild( radio );

              fragment.appendChild( label )
            }
          }

          if (o.inset) {
            classes += " ui-carousel-inset";
          }

          if (o.captions) {
            classes += " ui-carousel-captions";
          }

          if (o.bullets) {
            classes += " ui-carousel-bullets";
            barrel = $("<div id='ui-carousel-barrel-" + this.uuid + "' class='ui-carousel-controls ui-carousel-controls-" + o.bulletsPos +"' />")

            while ( fragment.firstChild ) {
              // browser hangs up if calling this inside append()
              $(fragment.firstChild).children().checkboxradio();
              barrel.append(
                fragment.firstChild
              );
            }
            // remove existing barrel
            if (create === undefined) {
              console.log($("#ui-carousel-barrel-" + this.uuid ));
              $("#ui-carousel-barrel-" + this.uuid ).remove();
            }
            // this always needs to go before the slider
            el[o.bulletsPos === "top" ? "before" : "after"](barrel);

            this._on(barrel.find("input"), { change: "_onChange"});
          }

          // all set, add classes
          el.addClass(classes);
        },

  //       _handleKeydown: function( event ) {
  //         var index = this._value();
  //         if ( this.options.disabled ) {
  //           return;
  //         }
  //
  //         // In all cases prevent the default and mark the handle as active
  //         switch ( event.keyCode ) {
  //           case $.mobile.keyCode.RIGHT:
  //           case $.mobile.keyCode.LEFT:
  //             event.preventDefault();
  //
  //             if ( !this._keySliding ) {
  //               this._keySliding = true;
  //               this.handle.addClass( "ui-state-active" ); /* TODO: We don't use this class for styling. Do we need to add it? */
  //             }
  //
  //             break;
  //         }
  //
  //         // move the slider according to the keypress
  //         switch ( event.keyCode ) {
  //           case $.mobile.keyCode.RIGHT:
  //             this.refresh( index + this.step );
  //             break;
  //           case $.mobile.keyCode.LEFT:
  //             this.refresh( index - this.step );
  //             break;
  //         }
  //       }, // remove active mark
  //
  //       _handleKeyup: function(/* event */) {
  //         if ( this._keySliding ) {
  //           this._keySliding = false;
  //           this.handle.removeClass( "ui-state-active" ); /* See comment above. */
  //         }
  //       },

  //       _bindSwipeEvents: function() {
  //         var self = this,
  //           area = self.element;
  //
  //         // on swipe, change to the next/previous image
  //         if( !!self.options.swipeClose ) {
  //           if ( self.options.position === "left" ) {
  //             area.on( "swipeleft.carousel", function(/* e */) {
  //               // self.close();
  //             });
  //           } else {
  //             area.on( "swiperight.carousel", function(/* e */) {
  //               // self.close();
  //             });
  //           }
  //         }
  //       },

        _completeTransition: function (current, next, events) {
          var self = this,
            o = self.options;
          next.removeClass("in out " + o.carouseltransition)
              .off( events );
          current
          .on( events, self._cleanupTransition(current, events) )
        },

        _cleanupTransition: function (current, events) {
          var self = this,
            o = self.options;
          var classes = o.carouseltransition + " out in";
          current.removeClass(classes)
          current.removeClass("ui-carousel-active").off(events);
        },

        _onChange: function (e) {
          var self = this,
            events = self._transitionEndEvents,
            el = self.element,
            o = self.options,
            // elements
            currentActive = el.children().filter(".ui-carousel-active"),
            nextActive = e.target.reference,

            classes = o.carouseltransition + " out in",
            transition = $.mobile._maybeDegradeTransition( o.carouseltransition );

          // click on active radio
          if (nextActive.hasClass("ui-carousel-active")) {
            return;
          }

          // initialize
          nextActive
            .on( events, self._completeTransition(currentActive, nextActive, events));
          nextActive
            .addClass(transition + " ui-carousel-active in ");

        }
    });

    $.mobile.carousel.initSelector = ":jqmData(role='carousel')";

    //auto self-init widgets
    $.mobile._enhancer.add( "mobile.carousel" );

  })( jQuery );
  /* tranistion workflow
  // first slide
  if (init) {
    current.removeClass("ui-carousel-active in out reverse slide")
    next.css('z-index','-10')
      .addClass("ui-carousel-active ui-carousel-opaque")
      .css('z-index','')

      if (transition !== "none") {
        // > once animation is complete!
        // current.removeClass("ui-carousel-active in out reverse slide")
        // next.removeClass("out in reverse slide")

        next.removeClass("ui-carousel-opaque")
        .addClass("slide in reverse")

      } else {
        current.removeClass("ui-carousel-active in out reverse slide")
        next.removeClass("out in reverse slide")
      }
  } else {
    // > once animation is complete
    current.removeClass("ui-carousel-active in out reverse slide")
    next.css('z-index','-10')
      .addClass("ui-carousel-active ui-carousel-opaque")
      .css('z-index','')

      if (transition !== "none") {
        // > once animation is complete!
        // current.removeClass("ui-carousel-active in out reverse slide")
        // next.removeClass("out in reverse slide")

        next.removeClass("ui-carousel-opaque")
        .addClass("slide in reverse")

      } else {
        current.removeClass("ui-carousel-active in out reverse slide")
        next.removeClass("out in reverse slide")
      }
    current.addClass("slide out reverse");
  }
  */

  /* ========================= ACTION BUTTON EXTENSION ==================== */
  (function( $, undefined ) {

    $.widget( "mobile.textinput", $.mobile.textinput, {
      options: {
        actionBtn: false,
        actionBtnText: "Search",
        actionBtnIcon: "search",
      },

      _create: function(){
        this._super();

        if( !!this.options.actionBtn || this.isSearch ){
          this._addActionBtn();
        }
      },

      actionButton: function(){

        return $( "<a href='#' class='ui-input-action ui-btn ui-icon-" + this.options.actionBtnIcon + " ui-btn-icon-notext ui-corner-all" +
      "' title='" + this.options.actionBtnText + "'>" + this.options.actionBtnText + "</a>" );

      },

      _addActionBtn: function(){

        if( !this.options.enhanced ) {
          this._enhanceAction();
        }

        $.extend( this, {
          _actionBtn: this.widget().find("a.ui-input-action")
        });

      },

      _enhanceAction: function() {

        this.actionButton().appendTo( this.widget() );
        this.widget().addClass( "ui-input-has-action ui-input-search-no-pseudo" );

      },

      _setOptions:function( options ) {
        this._super( options );

        if( options.actionBtn !== undefined && !this.element.is( "textarea, :jqmData(type='range')" ) ) {
          if( options.actionBtn ){
            this._addActionBtn();
          } else {
            this._destroyAction();
          }
        }

        if( options.clearBtnText !== undefined && this._actionBtn !== undefined ) {
          this._actionBtn.text( options.clearBtnText );
        }
      },

      _destroyAction: function() {
        this.element.removeClass( "ui-input-has-clear" );
        this._actionBtn.remove();
      },

      _destroy: function() {
        this._super();
        this._destroyAction();
      }

    });


  })( jQuery );

  return undefined;
});