/* Carousel.js
 * Designed for use with the New Model Launch Detail page
 * @author Brian Crescimanno <brian.crescimanno@autotrader.com>
 * @requires Prototype.js >= 1.6, Script.aculo.us > 1.8.0
 */

if (typeof Effect == 'undefined'){throw("You must have the script.aculo.us library to use this carousel");}

var Carousel = Class.create({

    vidObj:null,
    initialize: function(id, itemsPerPage, boundViewer) {
        if (!$(id)) return false;
        this.carousel = $(id);
        this.slidebox = this.carousel.down("ul#slidebox");
        this.perPage = itemsPerPage;
        this.carouselItems = this.slidebox.select('li');
        this.mediaFilter = "media-filters";
        this.numItems = this.carouselItems.length;
        this.numPages = Math.ceil(this.numItems / this.perPage);
        this.currentPage = 1;
        this.viewer = $(boundViewer);
       // this.vidObj = null;

        this.addButtons();
        this.checkButtons();
        this.showPageIndicators();
        this.expansionCoords = this.getExpansionCoords();
        this.pageWidth = this.getPageWidth();

        var expandHandler = this.expandHandler.bindAsEventListener(this);
        this.slidebox.observe('click', expandHandler);

        var filterHandler = this.filterHandler.bindAsEventListener(this);
        $(this.mediaFilter).observe('click', filterHandler);

        this.expandHandler(this.carouselItems[0].down(1));

    },

    addButtons: function() {
        /* Add the left & Right Buttons */
        var slideLeft = this.slideLeft.bind(this);
        var slideRight = this.slideRight.bind(this);
        var left = new Element("div", {'id': 'leftbutton'}).observe('click', slideRight);
        var right = new Element("div", {'id': 'rightbutton'}).observe('click', slideLeft);
        this.carousel.insert({top: right}).insert({top: left});
    },

    checkButtons: function() {
        this.currentPage == this.numPages ? $('rightbutton').hide() : $('rightbutton').show();
        this.currentPage == 1 ? $('leftbutton').hide() : $('leftbutton').show();
    },

    showButtons: function() {
        $('rightbutton').show();
        $('leftbutton').show();
    },

    getPageWidth: function() {
        return (this.carouselItems[0].getWidth() + parseInt(this.carouselItems[0].getStyle('margin-right'))) * this.perPage;
    },

    slideLeft: function() {
        this.togglePageIndicators(this.currentPage + 1);
        this.currentPage++;
        this.slide(-this.pageWidth);
    },

    slideRight: function() {
        this.togglePageIndicators(this.currentPage - 1);
        this.currentPage--;
        this.slide(this.pageWidth);
    },

    slide: function(distance) {
        this.showButtons();
        var fadeIn = this.fadeIn.bind(this);
        var fadeOut = this.fadeOut.bind(this);
        new Effect.Move(this.slidebox, {x: distance,
            y: 0,
            mode: 'relative',
            delay: 0.3,
            duration: 0.6,
            fps: 50,
            afterFinish: fadeIn,
            beforeStart: fadeOut});
    },

    fadeOut: function() {
        new Effect.Opacity(this.slidebox, {from: 1.0, to: 0.5, duration: 0.3, fps: 50});
    },

    fadeIn: function() {
        this.checkButtons();
        new Effect.Opacity(this.slidebox, {from: 0.5, to: 1.0, duration: 0.3, fps: 50});
    },

    slideToPageHandler: function(e) {
        var el = e.element();
        if (el.hasClassName('page-indicator')) {
            var toPage = (el.identify().split("-")[1]) * 1;
            if (toPage != this.currentPage) this.slideToPage(toPage);
        }
    },

    slideToPage: function(pageNumber) {
        var distance = (-(pageNumber - this.currentPage)) * this.pageWidth;
        this.togglePageIndicators(pageNumber);
        this.currentPage = pageNumber;
        this.slide(distance);

    },

    togglePageIndicators: function(newPage) {
        $('mcp-' + this.currentPage).removeClassName('active');
        $('mcp-' + newPage).addClassName('active');
    },

    expandHandler: function(e) {
        var el;
        if (Object.isElement(e)) {
            el = e;
        } else {
            e.stop();
            el = e.element();
        }

        if ((el.tagName.toLowerCase() == "img") && (el.up().up().hasClassName('photo'))) {
            setTimeout('mediaCarousel.throwAsis("/no_cache/ac/new_model_launch_details_clicks_001.asis")', 2000);
            this.expand(el);
        } else if ((el.tagName.toLowerCase() == "img") && (el.up().up().hasClassName('spin'))) {
            setTimeout('mediaCarousel.throwAsis("/no_cache/ac/new_model_launch_details_clicks_002.asis")', 1000);
            this.createSpinFrame(el.up().href);
        } else if ((el.tagName.toLowerCase() == "img") && (el.up().up().hasClassName('video'))) {
            setTimeout('mediaCarousel.throwAsis("/no_cache/ac/new_model_launch_details_clicks_003.asis")', 1000);
            this.createVideoFrame(el.up().href, el.getAttribute('alt'));
        }

    },

    expand: function(el) {
        /* Cache variables I need within Effect classes */
        var coords = this.expansionCoords;
        var viewer = this.viewer;
        var imgSrc = el.up().href;
        if (!el.up().up().hasClassName('photo')) {
            imgSrc = el.src;
            var movieImage = new Element("img", {src: imgSrc});
            viewer.update(movieImage);
            var dimensions = movieImage.getDimensions();
            if(dimensions.height==0)dimensions.height=315; //fix for image height not being availible before its fully cached, hopefully the 1st image is always 315 :-)
        }

        /* Create the image element for the full size image */
        var image = new Element("img", {src: imgSrc}).setOpacity(0);

        /* Clone the small image for the slide effect */
        var clonedImage = Element.extend(el.cloneNode(true));
        //document.body.appendChild(clonedImage);
        //IE6 performance issue cloning position before done with absolutize
        $('clonedImage').appendChild(clonedImage);
        Position.absolutize(clonedImage);
        Position.clone(el, clonedImage);
        clonedImage.setStyle({ zIndex: 200, border: "1px solid #333"});
        //document.body.insertBefore(clonedImage, el);//null undefined
        //clonedImage.absolutize().clonePosition(el).setStyle({zIndex: 200, border: "1px solid #333"});

        /* Create an array off effects to pass to parallel*/
        var expandEffects = new Array();
        expandEffects.push(new Effect.Move(clonedImage, {x: coords.width,
            y: coords.height,
            mode: 'absolute',
            sync: true
        }));
        expandEffects.push(new Effect.Opacity(clonedImage, {from: 1.0, to: 0.0, sync: true}));

        /* Run the parallel expansion effects */
        new Effect.Parallel(expandEffects, {fps: 50, duration: 0.7, afterFinish: function() {
            viewer.update(image);
            var dimensions = image.getDimensions();
            if(dimensions.height==0)dimensions.height=315; 
            clonedImage.remove();
            new Effect.Opacity(image, {from: 0.0, to: 1.0, duration: 0.4, fps: 50});
        }});


    },

    getExpansionCoords: function() {
        var top = this.viewer.cumulativeOffset().top + (this.viewer.getHeight() / 2.5);
        var side = this.viewer.cumulativeOffset().left + (this.viewer.getWidth() / 2.5);
        return {height: top, width: side};

    },

    filterHandler: function(e) {
        e.stop();
        var el = e.element();
        var filterName = el.up().identify();
        if (filterName == this.mediaFilter) {
            return;
        }
        var filterType = filterName.split('-')[1];
        this.filter(filterType);
        this.changeActiveFilter(el);
    },

    filter: function(filterType) {
        var count = 0;
        if (filterType == "all") {
            this.carouselItems.invoke('show');
            this.numPages = Math.ceil(this.numItems / this.perPage);
            this.slideToPage(1);
            this.showPageIndicators();

        } else {
            this.carouselItems.each(function(item) {
                if (item.hasClassName(filterType)) {
                    count++;
                    item.show();

                } else {
                    item.hide();
                }
            });
            this.slideToPage(1);
            this.numPages = Math.ceil(count / this.perPage);
            this.showPageIndicators();
        }
    },

    showPageIndicators: function() {
        var mediaIndicators = $('media-indicators');
        mediaIndicators.update("");

        /* Add the pagination controls */
        var indicatorContainer = new Element("div", {id: "media-indicators-box"}).setStyle({width: (this.numPages * 15) + "px"});
        for (var i = 0; i < this.numPages; i++) {
            var indicator = new Element("div", {'class': 'page-indicator', id: "mcp-" + (i + 1)});
            if (this.currentPage - 1 == i) {
                indicator.addClassName('active');
            }
            indicatorContainer.insert(indicator);
        }
        mediaIndicators.insert({top: indicatorContainer});
        var slideToPageHandler = this.slideToPageHandler.bind(this);
        indicatorContainer.observe('click', slideToPageHandler);
    },

    changeActiveFilter: function(el) {
        $(this.mediaFilter).select('a').each(function(filter) {
            if (el == filter) {
                filter.addClassName('active');
            } else {
                filter.removeClassName('active');
            }
        });
    },

    initMovie: function(){
     $("media-viewer").update(new Element("object", {"id":"flashMovie"}));
        this.vidObj =  new VideoController("media-viewer", {width: 530, height: 330, playerID: 'flashMovie', playerPath:'/media/longtailplayer-viral5.swf',playerSkinPath:'/media/playerSkins/player.swf', flashPlayerMin:'9.0.115', isAutoPlayEnabled:false, isMuted:false},'');

           if (!this.vidObj.hasFlashMinPlayer()) {
            var overLayTxt = $('flash-overlay-text').innerHTML;
            this.vidObj.showFlashOverlay(overLayTxt);
        }
    },


    createVideoFrame: function(url, desc) {
        //TODO: CR for 31154 New Model Launch
        //allow ability to utilize streaming URL such as GM for video content in CMS and possibly external URL
        //url = "http://www.mediacollege.com/video-gallery/testclips/20051210-w50s.flv"; //http://www.mediacollege.com/video-gallery/testclips/barsandtone.flv  //http://www.mediacollege.com/video-gallery/testclips/20051210-w50s_56K.flv
        //Player is a 4x3 player, if a 16x9 ratio video is uploaded, it will have white space below the controls
      if(this.vidObj == null)
         this.initMovie();
        
        /* Pass the video URL & description */
       this.vidObj.refreshVideo(url, desc,true);


    },

    createSpinFrame: function(url) {
        /* the first parameter is the URL */
        this.qtObj = new QTObject(url, "qtplayer", "530", "330");
        this.qtObj.setDefaultParams();
        this.qtObj.addParam('scale', 'Aspect'); //Aspect | ToFit
        this.qtObj.showControls(true);
        this.qtObj.write('media-viewer');
        this.qtObj.refreshVideo(url);
    },

    throwAsis: function(url) {
        var img = new Image(),
                cache_kill = new Date().getTime();
        img.id = "throwAsis";
        url = encodeURI(url + $('carouselasis').title);

        img.src = (url.indexOf("?") != -1)
                ? url + "&amp;cache_kill=" + cache_kill
                : url + "?cache_kill=" + cache_kill;
    }
});
