/**
 * jQuery plugin to swap showing and hiding of 2 elements, e.g. a 'Read More'/'Read Less' setup
 *
 * @author Chris Forrette <chris@cubancouncil.com>
 * @param options Object Optional options object passed in to override defaults
 *
 * EXAMPLE USAGE:
 *
 * Javascript:
 *
 * $(document).ready(function() {
 *      $('#desc').expandable();
 * });
 *
 * Example HTML:
 *
 * <div id="desc">
        <div class="passage-wrap">
 *          <div class="desc-short">
 *			    <p>Some description of...</p>                                
 *			    <a href="#" class="see-more-toggle">READ MORE</a>
 *		    </div>
 *		    <div class="desc-long">
 *			    <p>Some description of something self is long enough to be truncated and such.</p>
 *			    <a href="#" class="see-more-toggle">READ LESS</a>
 *          </div>
 *		</div>
 *      <div class="options">
 *          <a href="#" class=".contract-w">Show less!</a>
 *          <a href="#" class=".expand-w">Show more!</a>
 *      </div>
 * </div>
 */
jQuery.fn.expandable = function(options) {
    
    var options = jQuery.extend({
        
        // The selector settings are expected to be inside of the element upon which the .expandable() call is applied to
        // The jQuery.find() method uses these settings to grab the relevant elements
        
        'wrapper': '.passage-wrap', // Selector for wrapper object. This object animates based on content height, has overflow: hidden
        'lessBtn': '.options .contract-w', // Selector for 'show less' button
        'moreBtn': '.options .expand-w', // Selector for 'show more' button
        'short': '.desc-short', // Selector for short content
        'long': '.desc-long', // Selector for long content
        'speed': 500, // Animation speed
        
        // Default init function
        
        'init': function() {
            this.collapsedItem.data('original_height', this.collapsedItem.height()); // Store collapsed content height
            this.expandedItem.data('original_height', this.expandedItem.height()); // Store expanded content height
            this.expandedItem.fadeOut(0); // Hide expanded content
            this.wrapperItem.css('height', this.collapsedItem.data('original_height')); // Set wrapper to collapsed height
            this.expandButton.show(); // Show the 'expand' button
            this.collapseButton.hide(); // Hide the 'collapse' button
        },
        
        // Default expand function
        
        'expand': function() {
            
            var self = this;
            
            // Show 'collapse' button, hide 'expand' button
            
            this.expandButton.hide();
            this.collapseButton.show();
            
            // Animate content
            
            this.collapsedItem.fadeOut(self.speed); // Fade out collapsed content
            this.expandedItem.fadeIn(self.speed); // Fade in expanded content
            self.wrapperItem.animate({'height': self.expandedItem.data('original_height')}, self.speed); // Animate wrapper to 'expanded' content height
            
        },
        
        // Default collapse function
        
        'collapse': function() {
            
            var self = this;
            
            // Show 'collapse' button, hide 'expand' button
            
            this.expandButton.show();
            this.collapseButton.hide();
            
            // Animate content
            
            this.collapsedItem.fadeIn(self.speed); // Fade in collapsed content
            this.expandedItem.fadeOut(self.speed); // Fade out expanded content
            self.wrapperItem.animate({'height': self.collapsedItem.data('original_height')}, self.speed); // Animate wrapper to 'collapsed' content height
            
        }
    }, options);
    
    return this.each(function(i, item) {
        
        // Get collapsed/expanded items, buttons, and wrapper
        
        var wrapper = jQuery(item).find(options.wrapper)
        var expandButton = jQuery(item).find(options.moreBtn);
        var collapseButton = jQuery(item).find(options.lessBtn);
        var expandedItem = jQuery(item).find(options.long);
        var collapsedItem = jQuery(item).find(options.short);
        
        if (wrapper.length && expandButton.length && collapseButton.length && collapsedItem.length && expandedItem.length) {
            
            // Arguments to pass to functions in options
            
            var args = jQuery.extend(options, {
                'wrapperItem': jQuery(item).find(options.wrapper),
                'expandedItem': expandedItem,
                'collapsedItem': collapsedItem,
                'expandButton': expandButton,
                'collapseButton': collapseButton
            });
        
            // Apply 'expand' event
            
            expandButton.click(function(e) {
                e.preventDefault();
                options.expand.apply(args);
                jQuery(item).trigger('expand');
                jQuery(item).trigger('swap');
            });
        
            // Apply 'collapse' event
        
            collapseButton.click(function(e) {
                e.preventDefault();
                options.collapse.apply(args);
                jQuery(item).trigger('collapse');
                jQuery(item).trigger('swap');
            });
            
            // Apply init event
            
            options.init.apply(args);
        }
        
    });
    
};
