$(document).ready( function(){

    $('#balloon' ).css({opacity:0, display:'none'});
    $('.taste_description_container h3, .taste_description_container p' ).css({opacity:0, display:'none'});

    window.containerElement        = $( '#products .products_container' );
    window.labelContainerElement   = $( '#products .products_labels_container' );

    $.extend( $.easing, {
        easeInBack: function (x, t, b, c, d, s) {
            if (s == undefined) s = 1.70158;
            return c*(t/=d)*t*((s+1)*t - s) + b;
        },
        easeOutBack: function (x, t, b, c, d, s) {
            if (s == undefined) s = 1.70158;
            return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
        },
        easeInOutSine: function (x, t, b, c, d) {
            return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
        },
        easeInSine: function (x, t, b, c, d) {
            return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
        },
        easeOutSine: function (x, t, b, c, d) {
            return c * Math.sin(t/d * (Math.PI/2)) + b;
        }
    } );
});
    /*$.ajax (
        {
            url:        dataUrl,
            context:    document.body,
            success:    initProducts,
            error:      productsError
        }
    );*/
        
    var ProductData = function(){
        var _name;
        var _imageUrl;
        var _tasteId;
        var _packageId;
        var _packageDescriptionShort;
        var _packageDescriptionLong;
        var _tasteDescriptionShort;
        var _tasteDescriptionLong;
        var _nutritional;
        var _jQuery;
        var _labelJQuery;
        var _imageLoaded = false;
        var _width;
        var _height;
        var _productUrl;
        var _interactionEnabled;
        var _isRepresenter;
        var _isOverview;
        
        return {
            createFromJSon              :function ( pJSON, pIsOverview ) {
                this._isOverview = pIsOverview;
                this.setName ( pJSON.name );
                this.setImageUrl ( pJSON.imageUrl );
                this.setTasteId ( pJSON.tasteId );
                this.setPackageId ( pJSON.packageId );
                this.setPackageDescriptionShort ( pJSON.packageDescriptionShort );
                this.setPackageDescriptionLong ( pJSON.packageDescriptionLong );
                this.setTasteDescriptionShort ( pJSON.tasteDescriptionShort );
                this.setTasteDescriptionLong ( pJSON.tasteDescriptionLong );
                this.setNutritional ( pJSON.nutritional );
                this.setProductUrl(pJSON.productUrl );
                this.setIsRepresenter(pJSON.isRepresenter);
                this.init();
            },

            init :function(){
                //initialize the jquery object for the product image
                var jQ = $( '<a href="#" class="product_holder"><img alt="' + this.getName() + '" /></a>' );
                this.setJQuery ( jQ );
                jQ.find ( 'img' ).load( delegate ( this, this.imageReady ) );
                var live = $.browser.msie ? new Date().getTime() : 0;
                jQ.find ( 'img' ).attr ( 'src', this.getImageUrl() + '?' + live  );
                setTimeout( delegate ( this, this.imageReady ), 1000 );

                //initialize the jquery object for the product label
                if ( this._isOverview )
                    this.setLabelJQuery( $( '<p>' + this._name + '</p>' ) );
                else
                    this.setLabelJQuery( $( '<p>' + this._packageDescriptionShort + '</p>' ) );
            },
            doHover :function(){
                this._jQuery.find( 'img' ).stop().dequeue().animate (
                    {
                        bottom:30
                    }, 500, 'easeOutSine'
                );

                this._labelJQuery.addClass('selected');
                this._labelJQuery.stop().dequeue().animate (
                    {
                        top:5
                    }, 100
                );
                    
                var e = $.Event ( 'hover_product' );
                e.product = this;
                this._jQuery.trigger( e );
            },
            doHoverOut :function(){
                //if ( !this._interactionEnabled ) return;
                //console.log ( 'hover out: ' + this._name );
                this._jQuery.find( 'img' ).stop().dequeue().animate (
                    {
                        bottom:0
                    }, 300, 'easeInSine'
                );
                    this._labelJQuery.removeClass('selected');
                this._labelJQuery.stop().dequeue().animate (
                    {
                        top:0
                    }, 100
                );
                var e = $.Event ( 'hover_out_product' );
                e.product = this;
                this._jQuery.trigger( e );
            },
            doSelect :function(){
                var e = $.Event ( 'selectproduct' );
                e.product = this;
                this._jQuery.trigger( e );
                return false;
            },
            imageReady :function(){
                if ( this._imageLoaded ) return;
                this._imageLoaded = true;
                var disp = this._jQuery.css ( 'display' );
                this._jQuery.css ( {display:'block'} );

                this._width = this._jQuery.find( 'img' ).width();
                this._height = this._jQuery.find( 'img' ).height();

                this._jQuery.css ( {display:disp} );
                this._jQuery.trigger('imageloaded');
            },
            interactionEnabled:function( pValue ){
                this._jQuery.hover( delegate ( this, this.doHover ), delegate ( this, this.doHoverOut ) );
                this._jQuery.click( delegate ( this, this.doSelect ) );
            },

            setName                     :function( pValue ){this._name = pValue},
            setImageUrl                 :function( pValue ){this._imageUrl = pValue},
            setTasteId                  :function( pValue ){this._tasteId = pValue},
            setPackageId                :function( pValue ){this._packageId = pValue},
            setPackageDescriptionShort  :function( pValue ){this._packageDescriptionShort = pValue},
            setPackageDescriptionLong   :function( pValue ){this._packageDescriptionLong = pValue},
            setTasteDescriptionShort    :function( pValue ){this._tasteDescriptionShort = pValue},
            setTasteDescriptionLong     :function( pValue ){this._tasteDescriptionLong = pValue},
            setNutritional              :function( pValue ){this._nutritional = pValue},
            setJQuery                   :function( pValue ){this._jQuery = pValue},
            setLabelJQuery              :function( pValue ){this._labelJQuery = pValue},
            setProductUrl               :function( pValue ){this._productUrl = pValue},
            setIsRepresenter            :function( pValue ){this._isRepresenter = pValue},

            getName                     :function(){return this._name},
            getImageUrl                 :function(){return this._imageUrl},
            getTasteId                  :function(){return this._tasteId},
            getPackageId                :function(){return this._packageId},
            getPackageDescriptionShort  :function(){return this._packageDescriptionShort},
            getPackageDescriptionLong   :function(){return this._packageDescriptionLong},
            getTasteDescriptionShort    :function(){return this._tasteDescriptionShort},
            getTasteDescriptionLong     :function(){return this._tasteDescriptionLong},
            getNutritional              :function(){return this._nutritional},
            getJQuery                   :function(){return this._jQuery},
            getLabelJQuery              :function(){return this._labelJQuery},
            getWidth                    :function(){return this._width},
            getHeight                   :function(){return this._height},
            getProductUrl               :function(){return this._productUrl},
            getIsRepresenter            :function(){return this._isRepresenter},

            getImageReady               :function(){
                return this._imageLoaded
            }
        }
    }

    var ProductDetailManager = function(){

        var _products/*ProductData:Array*/;
        var _leftPos;
        var _hoverProductHandler;
        var _hoverOutProductHandler;
        var _hideBalloonTimeout;
        var _pageData;
        
        return {startUp:function ( pProducts, pPageData )
            {
                this._pageData = pPageData;
                this._products = pProducts;
                var currProd;
                this._imageReadyHandler = delegate ( this, this.checkImagesReady );
                this._hoverProductHandler = delegate ( this, this.hoverProduct );
                this._hoverOutProductHandler = delegate ( this, this.hoverOutProduct );
                for ( var p in this._products )
                {
                    currProd = this._products [ p ];
                    containerElement.append ( currProd.getJQuery() );

                    currProd.getJQuery().bind ( 'imageloaded', this._imageReadyHandler );
                    currProd.getJQuery().bind ( 'hover_product', this._hoverProductHandler );
                    currProd.getJQuery().bind ( 'hover_out_product', this._hoverOutProductHandler );
                    currProd.getJQuery().css ( {display:'none'} );
                }

                this._imageReadyHandler();
            },
            checkImagesReady:function(){
                var allReady = true;
                var currProd;
                for ( var p in this._products )
                {
                    if ( !this._products [ p ].getImageReady() )
                    {
                        allReady = false;
                        break;
                    }
                }

                if ( allReady )
                {
                    for ( var p in this._products )
                    {
                        currProd = this._products [ p ];
                        currProd.getJQuery().unbind ( 'imageloaded', this._imageReadyHandler );
                        currProd.getJQuery().css ( {display:'block'} );
                    }

                    this.positionProducts();
                }
            },
            hoverProduct:function( evt ){
                if ( this._selectedProduct ) return;

                clearTimeout ( this._hideBalloonTimeout );

                $('#balloon' ).css({display:'block'});
                $('#balloon p').html( evt.product.getPackageDescriptionShort() + '<span>' + evt.product.getPackageDescriptionLong() +'</span>' );

                $('#balloon').dequeue().animate({
                    left:parseInt( evt.product.getJQuery().css('left') ) + evt.product.getWidth() / 2 - 150,
                    opacity:1
                }, 500, 'easeInOutSine' );
            },
            hoverOutProduct:function( evt ){
                clearTimeout ( this._hideBalloonTimeout );
                this._hideBalloonTimeout = setTimeout ( delegate ( this, this.hideBalloon ), 500 );
            },
            hideBalloon:function(evt){
                $('#balloon').dequeue().animate({
                    opacity:0
                }, 200 );
            },
            positionProducts:function(){
                var currProd;
                var totalWidth = 0;
                var maxHeight = 0;
                var _PRODUCT_MARGIN = 20;//px

                for ( var p in this._products )
                {
                    currProd = this._products [ p ];
                    totalWidth += Math.max( currProd.getWidth(), 75 ) + _PRODUCT_MARGIN;

                    if ( currProd.getHeight() > maxHeight )
                        maxHeight = currProd.getHeight();
                }

                totalWidth -= _PRODUCT_MARGIN;

                var pos = this._leftPos = totalWidth / -2;
                
                var count = 0;
                for ( var p in this._products )
                {
                    currProd = this._products [ p ];

                    //initial positioning/animation 
                    ( function( currProd ){


                        currProd.getJQuery()
                        .css ({
                            left:pos + 'px',
                            width: currProd.getWidth() + 'px'
                        })

                        if ( currProd.getIsRepresenter() )
                        {
                            currProd.getJQuery()
                            .find ( 'img' )
                            .css( {bottom:0} )
                            
                            currProd.interactionEnabled(true);
                        }
                        else
                        {
                            currProd.getJQuery()
                            .find ( 'img' )
                            .css({bottom:-currProd.getHeight() + 'px'})
                            .delay( count * 110 )
                            .animate ( {bottom:0}, 500, 'easeOutBack', function(){
                                currProd.interactionEnabled(true);
                            } );
                        }

                        labelContainerElement.append ( currProd.getLabelJQuery() );

                        var min = 0;
                        if ( currProd.getWidth() < 75 )
                            min = 75 - currProd.getWidth();
                        currProd.getLabelJQuery().css({
                            left: ( pos - ( min / 2 ) ) + 'px',
                            width: Math.max( currProd.getWidth(), 75 ) + 'px',
                            display:'block'
                        });

                    })( currProd );


                    pos += Math.max( currProd.getWidth(), 75 ) + _PRODUCT_MARGIN;
                    count++;
                }


                $('.taste_description_container h3, .taste_description_container p' ).css({left:(this._leftPos - 50) + 'px'});


                var position = this._leftPos;
                $('.taste_description_container h3, .taste_description_container p' ).each ( function( i ){
                    $(this).css ( { display:'block'} );
                    $(this).delay ( i * 100 ).animate({
                        left:position,
                        opacity:1
                    }, 500);
                } );
            }
        }
    }

    var ProductOverviewManager = function (){

        var _products/*ProductData:Array*/;
        var _leftPos;

        var _imageReadyHandler;
        var _selectProductHandler;
        var _hoverProductHandler;
        var _hoverOutProductHandler;

        var _selectedProduct;
        var _hideBalloonTimeout;

        return {
            startUp:function ( pProducts  )
            {
                this._products = pProducts;
                var currProd;
                this._imageReadyHandler = delegate ( this, this.checkImagesReady );
                this._selectProductHandler = delegate ( this, this.selectProduct );
                this._hoverProductHandler = delegate ( this, this.hoverProduct );
                this._hoverOutProductHandler = delegate ( this, this.hoverOutProduct );
                for ( var p in this._products )
                {
                    currProd = this._products [ p ];
                    containerElement.append ( currProd.getJQuery() );

                    currProd.getJQuery().bind ( 'imageloaded', this._imageReadyHandler );
                    currProd.getJQuery().bind ( 'selectproduct', this._selectProductHandler );
                    currProd.getJQuery().bind ( 'hover_product', this._hoverProductHandler );
                    currProd.getJQuery().bind ( 'hover_out_product', this._hoverOutProductHandler );
                    currProd.getJQuery().css ( {display:'none'} );
                }

                this._imageReadyHandler();
            },
            checkImagesReady:function(){
                var allReady = true;
                var currProd;
                for ( var p in this._products )
                {
                    if ( !this._products [ p ].getImageReady() )
                    {
                        allReady = false;
                        break;
                    }
                }

                if ( allReady )
                {
                    for ( var p in this._products )
                    {
                        currProd = this._products [ p ];
                        currProd.getJQuery().unbind ( 'imageloaded', this._imageReadyHandler );
                        currProd.getJQuery().css ( {display:'block'} );
                    }

                    this.positionProducts();
                }
            },
            selectProduct:function( evt ){

                $('#balloon' ).css({display:'none'});
                
                this._selectedProduct = evt.product;

                var currProd;
                for ( var p in this._products )
                {
                    currProd = this._products[p];
                    currProd.getJQuery().unbind ( 'selectproduct', this._selectProductHandler );
                    currProd.getJQuery().stop().dequeue().animate (
                        {
                            opacity:( currProd == this._selectedProduct ? 1 : 0 )
                        }, 500
                    );

                    //ie can not animate opacity on 24 bit pngs.
                    if ( $.browser.msie && $.browser.version <= 8 && currProd != this._selectedProduct )
                        currProd.getJQuery().hide();
                    
                    currProd.getJQuery().animate (
                        {
                            left:_leftPos + 'px'
                        }, 500,
                        currProd == this._selectedProduct ? delegate ( this, this.navigateSelectedProduct ) : null
                    );
                }
                

                $('.products_labels_container p').animate (
                    {
                        opacity:0
                    }, 500
                );
            },
            navigateSelectedProduct:function(){
                window.location.href = this._selectedProduct.getProductUrl();
            },
            hoverProduct:function( evt ){
                if ( this._selectedProduct ) return;

                clearTimeout ( this._hideBalloonTimeout );
                
                $('#balloon' ).css({display:'block'});
                $('#balloon p').html( evt.product.getTasteDescriptionShort() );

                $('#balloon').dequeue().animate({
                    left:parseInt( evt.product.getJQuery().css('left') ) + evt.product.getWidth() / 2 - 150,
                    opacity:1
                }, 500, 'easeInOutSine' );
            },
            hoverOutProduct:function( evt ){
                clearTimeout ( this._hideBalloonTimeout );
                this._hideBalloonTimeout = setTimeout ( delegate ( this, this.hideBalloon ), 500 );
            },
            hideBalloon:function(evt){
                $('#balloon').dequeue().animate({
                    opacity:0
                }, 200 );
            },
            positionProducts:function(){
                var currProd;
                var totalWidth = 0;
                var maxHeight = 0;
                var _PRODUCT_MARGIN = 20;//px

                for ( var p in this._products )
                {
                    currProd = this._products [ p ];
                    totalWidth += Math.max( currProd.getWidth(), 75 ) + _PRODUCT_MARGIN;

                    if ( currProd.getHeight() > maxHeight )
                        maxHeight = currProd.getHeight();
                }

                totalWidth -= _PRODUCT_MARGIN;

                var pos = _leftPos = totalWidth / -2;
                var count = 0;
                for ( var p in this._products )
                {
                    currProd = this._products [ p ];
                    
                    ( function( currProd  ){

                        currProd.getJQuery().css ( {
                            left:pos + 'px',
                            width: currProd.getWidth() + 'px'
                        } ).find ( 'img' ).css({
                            bottom:-currProd.getHeight() + 'px'
                        }).delay( count * 110 ).animate ( {
                            bottom:0
                        }, 500, 'easeOutBack', function(){
                            currProd.interactionEnabled(true);
                        } );

                        labelContainerElement.append ( currProd.getLabelJQuery() );
                        
                        var min = 0;
                        if ( currProd.getWidth() < 75 )
                            min = 75 - currProd.getWidth();

                        currProd.getLabelJQuery().css({
                            left: ( pos - ( min / 2 ) ) + 'px',
                            width: Math.max( currProd.getWidth(), 75 ) + 'px',
                            display:'block'
                        });

                    })( currProd );
                    
                    pos += Math.max( currProd.getWidth(), 75 ) + _PRODUCT_MARGIN;
                    count++;
                }
            }
        }
    }

    /*if ( testForOverview )
    {
        //FAKE PRODUCT CALL FOR OVERVIEW
        initProducts({
            type: 'overview',
            page_data:{
                //geen pagedata nodig voor overview
            },
            products: [
            {
                name: 'Banana',
                imageUrl: 'assets/test/products/banana.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Banana&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Guana-bana',
                imageUrl: 'assets/test/products/guanabana.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Guanabana&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Guave',
                imageUrl: 'assets/test/products/guave.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Guave&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Lychee',
                imageUrl: 'assets/test/products/lychee.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Lychee&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Mango',
                imageUrl: 'assets/test/products/mango.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Mango&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Papaya',
                imageUrl: 'assets/test/products/papaya.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Papaya&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Passion Fruit',
                imageUrl: 'assets/test/products/passion_fruit.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Passion Fruit&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/tropical.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Tropical&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/tropical_2.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Tropical&rsquo;.',
                productUrl:'taste_detail.html'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/tropical_3.png',
                tasteDescriptionShort:'De korte beschrijving van de smaak &lsquo;Tropical&rsquo;.',
                productUrl:'taste_detail.html'
            }
        ]});
    }
    else
    {
        //FAKE PRODUCT CALL FOR DETAIL
        initProducts({
            type: 'detail',
            page_data:{
                //smaak, ingredients, nutritional must be added to template.
            },
            products: [
            {
                name: 'Banana',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Guana-bana',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Guave',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg',
                isRepresenter:true
            },
            {
                name: 'Lychee',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Mango',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Papaya',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Passion Fruit',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            },
            {
                name: 'Tropical',
                imageUrl: 'assets/test/products/banana.png',
                packageDescriptionShort: '50 cl PET',
                packageDescriptionLong: 'Handig voor onderweg'
            }
        ]});
    }*/

function initProducts ( pData ){
    var currProd, products = [];
    for ( var i in pData.products )
    {
        currProd = new ProductData();
        currProd.createFromJSon( pData.products [ i ], pData.type == 'overview' );
        products.push ( currProd );
    }

    if ( pData.type == 'overview' )
    {
        var p = new ProductOverviewManager();
        p.startUp ( products );
    }
    else
    {
        var p = new ProductDetailManager();
        p.startUp ( products, pData.page_data );
    }
}

function productsError ( pData ){

}
