(function($){
    var AccordionItem = function( element, index, parentInstance, options ){
      var default_options = {
        onClass: 'on',
        offClass: 'off',
        usePicto: true
      };
  
      this.options  = $.extend( default_options, options );

      this.$element       = $( element );
      this.index          = index;
      this.parentInstance = parentInstance;
      this.opened         = false;

      this.initialize();
    };

    AccordionItem.prototype.initialize = function(){
      this.$content     = this.$element.next( '.content' );

      if ( this.options.usePicto ){
        this.$triggerOn   = $( '<a href="#" class="trigger triggerOn" title="plus">&nbsp;</a>' );
        this.$triggerOff  = $( '<a href="#" class="trigger triggerOff" title="moins">&nbsp;</a>' );

        this.$element.prepend( this.$triggerOn );
        this.$element.prepend( this.$triggerOff );

        this.$triggerOn.click( $.proxy( function( event ){ 
          event.preventDefault();
          this.parentInstance.changeTo( this.index );
        }, this ));

        this.$triggerOff.click( $.proxy( function( event ){ 
          event.preventDefault();
          this.parentInstance.close( this.index );
        }, this ));
      }

      else {
        var heading   = this.$element.html();
        this.$trigger = $( '<a href="#">' + heading + '</a>' );
        this.$element.html( this.$trigger );

        this.$trigger.click( $.proxy( function( event ){
          event.preventDefault();
          if ( this.opened ){
            this.parentInstance.close( this.index );
          }

          else {
            this.parentInstance.changeTo( this.index );
          }
        }, this ));
      }
    };

    AccordionItem.prototype.show = function( now ){
      if ( now ){
        this.$content.show();
      }

      else {
        this.$content.slideDown();
      }

      if ( this.options.usePicto ){
        this.$triggerOn.hide();
        this.$triggerOff.show();
      }

      this.$element.removeClass( this.options.offClass ).addClass( this.options.onClass );
      this.opened = true;
    };

    AccordionItem.prototype.hide = function(){
      this.$content.slideUp();

      if ( this.options.usePicto ){
        this.$triggerOn.show();
        this.$triggerOff.hide();
      }

      this.$element.removeClass( this.options.onClass ).addClass( this.options.offClass );
      this.opened = false;
    };


    $.AccessibleAccordion = function( element, options ){
      var default_options = {
        usePicto: true,
        onClass: 'on',
        offClass: 'off',
        openFirst: null
      };
  
      this.options  = $.extend( default_options, options );
      this.$element = $( element );
      this.initialize();
    };
  
    $.AccessibleAccordion.prototype.extend = $.extend;
  
    $.AccessibleAccordion.prototype.extend({ 
      initialize: function(){
        this.headings = [];
        this.current  = null;

        this.$element.find( '.heading' ).each( $.proxy( function( i, $heading ){
          this.headings[i] = new AccordionItem( $heading, i, this, { 
            usePicto: this.options.usePicto,
            onClass: this.options.onClass,
            offClass: this.options.offClass
          });
        }, this ));

        this.$element.find( '.triggerOff' ).hide();
        this.$element.find( '.content' ).hide();

        if ( this.options.openFirst !== null ){
          this.current = this.options.openFirst;
          this.headings[ this.current ].show( true );
        }
      },


      changeTo: function( index ){
        if ( index !== this.current ){
          if ( this.current !== null ){
            this.headings[ this.current ].hide();
          }

          this.current = index;
          this.headings[ this.current ].show();
        }
      },


      close: function( index ){
        if ( index === this.current ){
          this.headings[ this.current ].hide();
          this.current = null;
        }
      }
    });
  
  
    $.fn.accessibleAccordion = function( options ){
      return this.each( function(){
        ( new $.AccessibleAccordion( this, options ) );
      });
    };

  // dom ready
  $( function(){
    $( '.accessible-accordion' ).accessibleAccordion();
  });
})(jQuery);
