﻿var HELIENE = HELIENE || {};
HELIENE.Utilities = HELIENE.Utilities || {};
HELIENE.Utilities.PreloadImage = HELIENE.Utilities.PreloadImage || {};

HELIENE.Utilities.PreloadImage = function (src) {
    var i, results = [],
        imageSrcs = src.split(','),
        preload = function (src) {
            var image$, image = new Image();

            image.src = src;
            image$ = $(image);

            if (image$.length) {
                $(document).append(image$);
                results.push(image$);
            }
        };
    for (i = 0; i < imageSrcs.length; ++i) {
        preload(imageSrcs[i]);
    }
    return results;
};

HELIENE.Carousel = function (list$, options) {
    var that = this,
            settings = $.extend({
                buttonSize: 45,
                buttonPrevImage: '/images/carousel/arrow-left.png',
                buttonNextImage: '/images/carousel/arrow-right.png',
                buttonClass: 'button',
                blur: true,
                blurMatrix: [
                    [0, 3, 6, 3],
                    [6, 3, 0, 3],
                    [3, 6, 3, 0],
                    [3, 0, 3, 6],
                    [2, 3, 4, 3],
                    [4, 3, 2, 3],
                    [3, 4, 3, 2],
                    [3, 2, 3, 4]
                ],
                transitionDuration: 500,
                height: 250,
                width: 457,
                inactiveRatio: 0.5,
                border: '0 none',
                labelHeightRatio: 0.08,
                labelPositionRatio: 0.2,
                labelPosition: 'right',
                startIndex: 0
            }, options || {}),

        initButtons = function () {
            var createButton = function (id, onClick) {
                var opt = settings,
                    button$ = $('<a href="#"></a>'),
                    img$ = $('<img src="' + opt[id + 'Image'] + '" />');

                img$.height(opt.buttonSize);
                img$.width(opt.buttonSize);

                button$.addClass(opt.buttonClass || '');
                button$.attr('id', id);
                button$.append(img$);
                button$.height(opt.buttonSize);
                button$.width(opt.buttonSize);
                button$.css({ 'margin-top': -(opt.buttonSize / 2) });
                button$.click(function (e) { e.preventDefault(); });
                button$.click(onClick);

                that[id + '$'] = button$;
                that.container$.append(button$);
            };
            createButton('buttonPrev', prev);
            createButton('buttonNext', next);
        },
        zoomTo = function (image$, width, height, duration, blur) {
            var totalBorder = (borderWidth * 2),
                newWidth = width - totalBorder,
                newHeight = height - totalBorder,
                i = 0,
                blurMatrix = settings.blurMatrix,
                clone$ = null,

                animationSettings = {
                    height: newHeight - totalBorder,
                    width: newWidth - totalBorder,
                    marginTop: -(newHeight / 2),
                    marginLeft: -(newWidth / 2)
                };
            image$.css({ border: settings.border });

            duration = duration || 0;
            blur = blur || false;

            if (blur === true) {
                for (i = 0; i < blurMatrix.length; ++i) {
                    clone$ = image$.clone()
                        .addClass('clone')
                        .animate($.extend(animationSettings, {
                            'padding-top': blurMatrix[i][0],
                            'padding-right': blurMatrix[i][1],
                            'padding-bottom': blurMatrix[i][2],
                            'padding-left': blurMatrix[i][3],
                            opacity: (i < 4 ? 0.12 : 0.18)
                        }), duration);

                    image$.after(clone$);
                }
                image$.css(animationSettings);
            } else {
                image$.animate(animationSettings, duration);
            }
        },
        getNewDimensions = function (image$, maxWidth, maxHeight) {
            var oldHeight = image$.outerHeight(),
                oldWidth = image$.outerWidth(),
                newWidth, newHeight;

            if (oldWidth > oldHeight) {
                newWidth = maxWidth;
                newHeight = oldHeight * newWidth / oldWidth;
            } else {
                newHeight = maxHeight;
                newWidth = oldWidth * newHeight / oldHeight;
            }

            return { width: newWidth, height: newHeight };
        },
        setImageDimensions = function (image$) {
            var activeDimensions = getNewDimensions(image$, that.imgMaxWidth, that.imgMaxHeight),
                inactiveDimensions = getNewDimensions(image$, that.smallWidth, that.smallHeight);

            image$.data({ 'activeWidth': activeDimensions.width, 'activeHeight': activeDimensions.height });
            image$.data({ 'inactiveWidth': inactiveDimensions.width, 'inactiveHeight': inactiveDimensions.height });
        },
        adjustItemImages = function () {
            var first = true;
            $('img.item-image:not(.clone)', that.items$).each(function () {
                var img$ = $(this),
                    dim = (function () {
                        setImageDimensions(img$, width, height);
                    } ()),
                    width = (first ? $(this).data('activeWidth') : img$.data('inactiveWidth')),
                    height = (first ? $(this).data('activeHeight') : img$.data('inactiveHeight')),
                    isBlurred = settings.blur && !first;

                zoomTo($(this), width, height, 0, isBlurred);

                if (!first) {
                    $(this).closest('li').find('a.label-button').hide();
                    $(this).closest('li').find('div.label-footer').hide();
                    $(this).closest('li').find('a.project-label-button').hide();
                }
                first = false;
            });
        },
        adjustLabelImages = function () {
            $('a.label-button img', that.items$).each(function () {
                var height = that.imgMaxHeight * settings.labelHeightRatio,
                    width = $(this).outerWidth() / $(this).outerHeight() * height,
                    link$ = $(this).parent();

                $(this).css({ width: width, height: height });

                link$.css({ 'top': (settings.labelPositionRatio * 100) + '%' })
                if (settings.labelPosition === 'center') {
                    link$.css({ right: (link$.siblings('.item-image').outerWidth() - width) / 2 - ((link$.siblings('.item-image').outerWidth() - link$.parent().outerWidth()) / 2) });
                }
            });
        },
        setOffset = function () {
            var maskWidth = that.mask$.outerWidth(),
                firstItemWidth = that.items$.first().outerWidth(),
                offset = (maskWidth - firstItemWidth) / 2;

            that.list$.css({ left: offset });
        },
        adjustItems = function () {
            adjustItemImages();
            adjustLabelImages();
            setOffset();
        },
        shrink = function (image$) {
            zoomTo(image$, image$.data('inactiveWidth'), image$.data('inactiveHeight'), settings.transitionDuration, settings.blur);
            image$.closest('li').find('a.label-button').fadeTo(settings.transitionDuration, 0);
            image$.closest('li').find('div.label-footer').fadeTo(settings.transitionDuration, 0);
            image$.closest('li').find('a.project-label-button').fadeTo(settings.transitionDuration, 0);
        },
        grow = function (image$) {
            image$.css({ opacity: 1 }).siblings('.clone').remove();
            zoomTo(image$, image$.data('activeWidth'), image$.data('activeHeight'), settings.transitionDuration, false);
            image$.closest('li').find('a.label-button').fadeTo(settings.transitionDuration, 1);
            image$.closest('li').find('div.label-footer').fadeTo(settings.transitionDuration, 1);
            image$.closest('li').find('a.project-label-button').fadeTo(settings.transitionDuration, 1);
        },
        setActive = function () {
            var items$ = that.list$.find('li'),
                images$ = $('>img.item-image:not(.clone)', items$),
                image$ = images$.eq(that.currentIndex);

            image$.addClass('active');
            image$.siblings().removeClass('active');
        },
        moveList = function (direction, callback) {
            var nextIndex = (function () {
                direction = direction || 'left';
                return (direction === 'left' ? that.currentIndex + 1 : that.currentIndex - 1);
            } ()),
                    distance = that.items$.eq(nextIndex).outerWidth(),
                    distArg = (direction === 'left' ? '-=' : '+=') + distance,
                    items$ = that.list$.find('li'),
                    images$ = $('img.item-image:not(.clone)', items$),
                    currentImage$ = images$.eq(that.currentIndex),
                    nextImage$ = images$.eq(nextIndex);

            if (nextIndex < 0 || nextIndex > that.maxIndex || $(':animated', that.list$).length) {
                return false;
            }

            shrink(currentImage$);
            grow(nextImage$);

            that.list$.animate({ left: distArg }, that.transitionDuration, function () {
                that.currentIndex = nextIndex;
                balance();
                setActive();
                if (typeof callback === 'function') {
                    callback();
                }
            });
        },
        prev = function (callback) {
            moveList('right', callback);
        },
        next = function (callback) {
            moveList('left', callback);
        },
        offCentreBy = function () {
            return (that.idealIndex - that.currentIndex);
        },
        balance = function () {
            while (Math.abs(offCentreBy()) > 0) {
                swapImage(offCentreBy() > 0);
            }
        },
        swapImage = function (rightToLeft) {
            var swapItem$,
                left = parseInt(that.list$.css('left'), 10),
                items$ = that.list$.find('li');

            if (rightToLeft === true) {
                swapItem$ = items$.last();
                ++that.currentIndex;
                that.list$.prepend(swapItem$);
                left -= swapItem$.outerWidth();
            } else {
                swapItem$ = items$.first();
                --that.currentIndex;
                that.list$.append(swapItem$);
                left += swapItem$.outerWidth();
            }
            that.list$.css('left', left);
        },
        reveal = function () {
            that.container$.css({ left: 0 });
        },
        borderWidth = parseInt(settings.border, 10);

    that.list$ = list$;
    that.items$ = $('li', that.list$);

    that.container$ = list$.wrap('<div class="mask" />').parent()
        .wrap('<div class="carousel" />').parent();
    that.mask$ = $('.mask', that.container$);

    that.container$.attr('id', that.list$.attr('id'));
    that.list$.removeAttr('id');

    that.container$.height(settings.height);
    that.container$.width(settings.width);
    that.mask$.height(settings.height);

    that.itemMaxHeight = settings.height;
    that.itemMaxWidth = that.mask$.outerWidth() * 0.5;

    that.imgMaxHeight = that.itemMaxHeight - (borderWidth * 2);
    that.imgMaxWidth = that.itemMaxWidth - (borderWidth * 2);

    that.smallWidth = that.imgMaxWidth * settings.inactiveRatio;
    that.smallHeight = that.imgMaxHeight * settings.inactiveRatio;

    that.items$.css({
        height: that.itemMaxHeight,
        width: that.mask$.outerWidth() * 0.33
    });

    that.currentIndex = 0;

    that.itemCount = $('li', that.list$).length;
    that.maxIndex = that.itemCount - 1;
    that.idealIndex = Math.floor(that.itemCount / 2);

    $(window).load(function () {
        var index = 0;
        initButtons();
        adjustItems();
        balance();
        setActive();
        if (settings.startIndex === 0) {
            reveal();
        } else {
            for (index = 0; index < settings.startIndex; ++index) {
                next(index === settings.startIndex - 1 ? reveal : null);
            }
        }
    });
};

(function ($) {
    $.fn.Carousel = function (options) {
        return this.each(function () {
            var carousel = new HELIENE.Carousel($(this), options);
        });
    };

}(jQuery));

$(function () {
    $('#splash-carousel').Carousel({startIndex: 1});
    $('#product-carousel').Carousel({ 
        startIndex: 1,
        width: 850,
        height: 440,
        buttonSize: 105
    });
    $('#projects-carousel').Carousel({
        width: 960,
        height: 400,
        buttonSize: 105,
        blur: false,
        border: '7px solid #fff',
        labelHeightRatio: 0.09,
        labelPositionRatio: 0.07,
        labelPosition: 'center'
    });
});
