/**
 * Create a contentslider gadget.
 *
 * `de_epages.externalcontentUiContentslider()` creates a contentslider gadget.
 *
 * ### Examples
 * Create a simple contentslider gadget with some options.
 *
 * JavaScript:
 *
 *     de_epages('#myContentslider').externalcontentUiContentslider({
 *     automatic: true,
 *     arrows: true,
 *     effect: 'scrollLeft',
 *     'shadow': false,
 *     'border': 'black',
 *     'automatic': false,
 *     'displaytime': 5,
 *     slides: [{
 *     'fullpath': 'de_epages/externalcontent/ui/contentsliderTest_Image1.png',
 *     'name': 'Test1'
 *     }, {
 *     'fullpath': 'de_epages/externalcontent/ui/contentsliderTest_Image1.png',
 *     'name': 'Test2'
 *     }]
 *     });
 *
 * HTML:
 *
 *     <div id="myContentslider"></div>
 *
 *
 * @class jQuery.ui.externalcontentUiContentslider
 *
 * @uses de_epages
 * @uses jQuery.ui.widget
 * @uses jQuery.cycle
 * @uses jQuery.tmpl
 * @since 6.15.1
 */

/**
 * @cfg {Boolean} [automatic] If true, the contentslider advances from one slide to another automatically.
 */

/**
 * @cfg {String} [effect] String specifying the animation between the slides. Possible values: fade, scrollLeft, growY, cover and whatever else the cycle plugin supports for its fx option.
 */

/**
 * @cfg {Boolean} [arrows] If true, show navigation arrows for user to advance manually between slides.
 */

/**
 * @cfg {Boolean} [shadow] If true, add shadow to contentslider box.
 */

/**
 * @cfg {String} [border] Border color for contentslider.
 */

/**
 * @cfg {Array} [slides] Array of slides. A slide is an object with keys: fullpath (String, path to image file), name (String name of image), href (String, optional, href for link to be added around the image), title (String, optional, title for the link around the image).
 */

/**
 * @cfg {Object} [cycleOptions] Options hash to be passed to the underlying instance of the cycle plugin.
 */

/**
 * See `jQuery.ui.externalcontentUiContentslider` for details.
 *
 * @param {Object} options A map of additional options pass to the method.
 * @param {Boolean} [automatic] If true, the contentslider advances from one slide to another automatically.
 * @param {String} [effect] String specifying the animation between the slides. Possible values: fade, scrollLeft, growY, cover and whatever else the cycle plugin supports for its fx option.
 * @param {Boolean} [arrows] If true, show navigation arrows for user to advance manually between slides.
 * @param {Boolean} [shadow] If true, add shadow to contentslider box.
 * @param {String} [border] Border color for contentslider.
 * @param {Array} [slides] Array of slides. A slide is an object with keys: fullpath (String, path to image file), name (String name of image), href (String, optional, href for link to be added around the image), title (String, optional, title for the link around the image).
 * @param {Object} [cycleOptions] Options hash to be passed to the underlying instance of the cycle plugin.
 *
 * @method externalcontentUiContentslider
 * @member jQuery
 *
 * @since 6.15.1
 */

/*
 * @copyright   © Copyright 2006-2012, epages GmbH, All Rights Reserved.
 *
 * @module      de_epages.externalcontent.ui.contentslider
 *
 * @revision    $$
 */
/*jslint nomen: true*/
/*global define*/
define('de_epages/externalcontent/ui/contentslider', [
    'jquery/ui/widget',
    'de_epages',
    '$tmpl!./contentslider',

    'jquery/cycle'
], function ($, de_epages, template) {
    'use strict';
    // Constants.
    var gClassNames = 'contentslider';

    // The actual widget.
    $.widget('ui.externalcontentUiContentslider', {

        options: {
            effect: 'fade',
            arrows: false,
            shadow: true,
            border: 'transparent',
            automatic: true,
            displaytime: 3,
            cycleOptions: {},
            slides: []
        },

        _create: function () {
            var self = this,
                o = self.options,
                $firstImage,
                zIndexOfSlides,
                images;

            if (o.slides.length === 0) {
                return self.destroy();
            }

            // Render template. Leave *src* attribute of *img* tags out for now.
            // We want to start loading the images later.
            $.extend(self, $.tmplItem(template(o), 'elements'));

            self.element
                .empty() // Delete &nbsp; which may have been added to the *self.element* by *CKEditor*.
                .append(self.list, self.pager, self.arrows) // Append template items to *self.element*.
                .addClass(gClassNames) // Add gadget specific css classes.
                .css('border-color', o.border); // Set *border-color*.

            if (o.shadow) {
                self.element.addClass('contentslider-shadow');
            }

            $firstImage = self.list.children('li').first().children();

            if ($firstImage.is('a')) {
                $firstImage = $firstImage.children('img').first();
            }

            // *create* cycle, when *$firstImage* is loaded.
            $firstImage.one('load', function () {
                var containerWidth = self.element.width(),
                    size = {
                        width: containerWidth,
                        height: Math.round(containerWidth / 3) // Aspect ratio is 1:3
                    };

                // Set the slides proposition
                self.list.css(size).children('li').css(size);

                if (o.slides.length > 1) {
                    // Otherwise the *cycle* plugin won't work anyway.
                    self._createCycle();
                }
            });

            // Set *z-index* of control elements.
            zIndexOfSlides = o.slides.length;
            self.pager.css('z-index', zIndexOfSlides + 20);
            if (o.arrows && self.next && self.prev) {
                self.next.css('z-index', zIndexOfSlides + 10);
                self.prev.css('z-index', zIndexOfSlides + 10);
            }

            // Set *src* of *img* elements.
            images = self.list.find('img');
            $.each(o.slides, function (index, slide) {
                images[index].src = slide.fullpath;
            });
        },

        _createCycle: function () {
            var self = this,
                o = self.options;

            self.list.cycle($.extend({}, o.cycleOptions, {
                timeout: o.automatic ? (1000 * o.displaytime) : 0,
                pager: self.pager,
                fx: o.effect
            }, o.arrows ? {
                next: self.next,
                prev: self.prev
            } : {}));
        },

        destroy: function () {
            var self = this;

            // Remove all traces of the widget.
            if (self.list) {
                self.list
                    .cycle('pause') // Otherwise *before* and *after* callbacks are still getting called for some reason.
                    .cycle('destroy');
            }

            self.element.empty().removeClass(gClassNames).removeClass('contentslider-shadow');

            return self._superApply(arguments);
        }
    });

    return de_epages;

});