// Object containing all the info about the current cycle.
// NOTE: we need this because there can be multiple cycles on the same page.
function lvsysCyclerParams() 
{
    this.id = "";
    this.fx = 'fade';
    this.speed = 500;   // transition
    this.timeout = 4000; // still time
    this.pause = true; // enable pause on hover
    this.pauseOnPagerHover = true; // enable pause on hover of a pager 'link' (a thumb)
    this.pager = null;

    this.pagerAnchorBuilder = function (idx, slide) {
        var imgObj = $(slide).find('img');
        var src = (imgObj != null) ? imgObj.attr('src') : null;
        var thumb = (imgObj != null) ? imgObj.attr('thumb') : null;
        if (typeof thumb != "undefined" && thumb != null) {
            src = thumb; // use custom thumb if we have one.
        }

        // custom fit
        var width = 50;
        var height = 50;
        var attrImgCropTo = $(this.pager).attr("imgCropTo");
        if (typeof attrImgCropTo != "undefined" && attrImgCropTo != null) {
            var tokens = attrImgCropTo.split('x');
            if (tokens.length > 1) {
                width = tokens[0] * 1;
                height = tokens[1] * 1;
            }
        }

        var html = "";
        if (src != null) {
            html = '<a href="#"><img src="' + src + '" width="' + width + '" height="' + height + '"/></a>';
        } else {
            html = '<a href="#"><img src="admin/img/video-play-50x50.png" width="' + width + '" height="' + height + '"/></a>';
        }
        return html;
    }


    //For single videos
    this.isSingleton = false;
    this.isSingleVideo = false;
    this.autoStartSingleVideo = false;
    this.loopSingleVideo = false;
}

function lvsysCycler() 
{
    // Cycle gives the incorrect value for nextSlide when it first runs;
    // This variable enables us to compensate.
    var initialized = false;

    // How often to check YouTube videos, in milliseconds
    var pollInterval = 500;
    // How long before the end of a YouTube video to start
    // moving on, in seconds.
    var videoEndSlack = .25;

    // Storage variables, initialized in _cycleStartSlides()
    var nextIndex = 0;
    var cycleIndexes = new Array();
    var cycles = new Array();
    var players = new Array();
    // Managed from _cycleOnBefore
    var nextSlides = new Array();

    // Parameters for YouTube videos
    var params = { allowScriptAccess: "always", wmode: "transparent" };

    // Parameters passed in by the user
    var userParamsObjArray = new Array();

    // For YouTube video resumption of the cycle;
    // Start over with the next slide
    var _cycleResumeCycle = function (i_iCycleNumber) {
        var localParams = userParamsObjArray[i_iCycleNumber];
        localParams.before = _cycleOnBefore;
        localParams.delay = 0;
        localParams.startingSlide = nextSlides[i_iCycleNumber];
        initialized = false;

        var currentPanelType = $("#" + cycles[i_iCycleNumber]).children().eq(localParams.startingSlide).attr("panelType");
        if (currentPanelType == 'chromeFix') {
            localParams.timeout = 5;
        }

        if (localParams.pager != null) {
            $(localParams.pager).html("");    // clear the nav
        }
        $("#" + cycles[i_iCycleNumber]).cycle(localParams);
    }

    // Check any active YouTube players to see if those
    // cycles are ready to move on.
    var _cycleUpdatePlayerInfo = function() {

        // For each YouTube player, make sure it exists, and if it
        // does, check to see if the video is over.  If it is, clear
        // the player (originally set in _cycleOnBefore) and move on with the
        // next slide in that cycle.

        var numKeys = players.length;
        for (var i = 0; i < numKeys; i++) {
            if (players[i] != null) {
                var ytplayer = document.getElementById(players[i]);
                if (ytplayer && ytplayer.getDuration) {
                    if ((ytplayer.getCurrentTime() > 0) && (ytplayer.getCurrentTime() > (ytplayer.getDuration() - videoEndSlack))) {
                        var localParams = userParamsObjArray[i];
                        if (!localParams.isSingleVideo || localParams.loopSingleVideo) {
                            players[i] = null;
                            _cycleResumeCycle(i);
                        } else {
                            ytplayer.seekTo(.1, true);
                            ytplayer.pauseVideo();
                        }
                    }
                }

            }

        }

    }

    var _prepYouTube = function(cycleIndex, targetElement, autoStart) {
        // Add the player to the players array so it gets checked by
        // _cycleUpdatePlayerInfo()
        players[cycleIndex] = $(targetElement).attr("divId");

        // Get the information to feed to the player itself from the
        // slide's HTML attributes.
        var targetContent = $(targetElement).attr("targetContent");
        var divId = $(targetElement).attr("divId");
        var height = $(targetElement).attr("height");
        var width = $(targetElement).attr("width");

        // Create the actual video.  Make sure it starts right away,
        // and that javascript is enabled.
        swfobject.embedSWF(
				    "http://www.youtube.com/v/" +
				    targetContent + "?version=3&border=0&showsearch=0&showinfo=0&autoplay=" + autoStart +
				    "&enablejsapi=1&playerapiid=" + divId,
        		        divId, width, height, "8", null, null, params,
	  			    { id: divId });
    }

    var _prepFlowplayer = function (cycleIndex, targetElement, autoStart) {

        // Set this player to 'null', because only YouTube videos
        // need to be processed by _cycleUpdatePlayerInfo().
        players[cycleIndex] = null;

        // Get player information from the slide's HTML attributes
        var targetContent = $(targetElement).attr("targetContent");
        var divId = $(targetElement).attr("divId");
        var height = $(targetElement).attr("height");
        var width = $(targetElement).attr("width");
        $("#" + divId).css("height", height).css("width", width);

        // Stop the current cycle.  We'll restart it from the
        // onFinish event, but onBegin doesn't happen fast enough
        // to stop the cycle on the first load in some browsers,
        // so we'll do it here.  And again, we need to pause so that
        // the video loads.
        $('#' + cycles[cycleIndex]).cycle('pause');

        //Create the flowplayer player and set it to 
        //restart it when the video ends.
        $f(divId, "http://releases.flowplayer.org/swf/flowplayer-3.1.5.swf", {
            clip: {
                url: targetContent,
                autoPlay: autoStart,
                autoBuffering: true,

                onFinish: function () {
                    var localParams = userParamsObjArray[cycleIndex];
                    if (!localParams.isSingleVideo) {
                        _cycleResumeCycle(cycleIndex);
                    } else {
                        localParams.before = _cycleOnBefore;
                        localParams.delay = 0;
                        localParams.startingSlide = nextSlides[cycleIndex] - 1;
                        initialized = false;

                        var currentPanelType = $("#" + cycles[cycleIndex]).children().eq(localParams.startingSlide).attr("panelType");
                        if (currentPanelType == 'chromeFix') {
                            localParams.timeout = 5;
                        }

                        $("#" + cycles[cycleIndex]).cycle(localParams);
                    }
                }
            }
        });
    }

    // The _cycleOnBefore function runs before every transition in the cycle
    var _cycleOnBefore = function (currSlideElement, nextSlideElement, options, forwardFlag) {
        // The first time this runs, currSlide is incorrect; it's set as 0 twice.
        // The first time through, compensate so nextSlides is set properly.
        var nextSlideNumber = options.nextSlide;
        if (!initialized) {
            nextSlideNumber = nextSlideNumber - 1;
            initialized = true;
        }

        // Initialize general variables
        var thisCycle = $(nextSlideElement).parent().attr("id");
        var currentSlideType = $(nextSlideElement).attr("panelType");
        var thisCycleIndex = cycleIndexes[thisCycle];

        // Set the next slide.  nextSlideNumber is actually the CURRENT
        // slide, so when we're done with the current video (if applicable)
        // we want to move on to nextSlideNumber + 1.
        nextSlides[thisCycleIndex] = nextSlideNumber + 1;

        if (currentSlideType == "chromeFix") {
            //  $('#' + thisCycle).cycle('next');
        }
        else if (currentSlideType == "youtube") {
            // Check the slide type.  Images don't need any processing, and
            // youtube and flowplayer need to be handled separately.
            $('#' + thisCycle).cycle('pause');

            // Add the player to the players array so it gets checked by
            // _cycleUpdatePlayerInfo()
            _prepYouTube(thisCycleIndex, nextSlideElement, 1);

            // Pause the cycle.  We'll actually be restarting it with the
            // next slide, but if we STOP it instead the whole thing stops,
            // so pause instead.
            $('#' + thisCycle).cycle('pause');


        } else if (currentSlideType == "flowplayer") {

            var autoStart = true;
            var localParams = userParamsObjArray[thisCycleIndex];
            if (localParams.isSingleVideo && !localParams.loopSingleVideo) {
                autoStart = false;
            }
            _prepFlowplayer(thisCycleIndex, $(nextSlideElement), autoStart);

        } else {

            // Clear the player; this is likely an image, and in any
            // case doesn't need to be processed by _cycleUpdatePlayerInfo().
            players[thisCycleIndex] = null;
        }



    }

    // This function MUST be named onYouTubePlayerReady() because the YouTube API expects it.
    var onYouTubePlayerReady = function(playerId) {
    }

    // Initialize the cycles for all divs of the appropriate class.
    // (Actually, you can use any JQuery selector here.)
    var _cycleStartSlides = function(slideShowClass, paramsObjArray) {

        // If the user passes only one set of parameters, use it for
        // every cycle.  If there are fewer parameter sets than cycles,
        // use the last one to fill in the rest.
        if (paramsObjArray == null || paramsObjArray.length == 0) {
            for (i = 0; i < $(slideShowClass).length; i++) {
                var newParams = new lvsysCyclerParams();
                userParamsObjArray[i] = newParams;
            }
        } else if (paramsObjArray.length < $(slideShowClass).length) {
            for (i = 0; i < paramsObjArray.length; i++) {
                userParamsObjArray[i] = paramsObjArray[i];
            }
            for (i = paramsObjArray.length; i < $(slideShowClass).length; i++) {
                userParamsObjArray[i] = paramsObjArray[paramsObjArray.length - 1];
            }
        } else {
            userParamsObjArray = paramsObjArray;
        }


        // Loop through the cycle constructs
        for (i = 0; i < userParamsObjArray.length; i++) 
        {
            // Get this individual cycle
            var thisCycle = userParamsObjArray[i].id;
            if ("#" + thisCycle == "#") {
                // Do nothing; thisCycle is empty
            } else {

                // Add standard parameters to user object
                var localParams = userParamsObjArray[i];
                localParams.before = _cycleOnBefore;

                // Initialize the storage arrays
                cycles[i] = thisCycle;
                cycleIndexes[thisCycle] = i;
                players[i] = null;

                // Correct for crashes on Chrome when video follows Flowplayer
                $(".chrome *[panelType='flowplayer']").each(function() {
                    if ($(this).next().attr("panelType") == "youtube" || $(this).next().attr("panelType") == "flowplayer") {
                        $(this).after("<div panelType='chromeFix'></div>");
                    }
                });
                // Same fix, but applies only if the first panel is video, and the last panel is Flowplayer
                if ($("#" + thisCycle).children("*:last").attr("panelType") == "flowplayer") 
                {
                    if ($("#" + thisCycle).children("*:first").attr("panelType") == "flowplayer" ||
                        $("#" + thisCycle).children("*:first").attr("panelType") == "youtube") 
                    {
                        $("#" + thisCycle).children("*:last").after("<div panelType='chromeFix'></div>");
                    }
                }

                // If the cycle consists of a single video, the default is to not autostart,
                // and not loop.  If both of those conditions are overridden, run as usual.
                // If not, handle that separately here.

                // If there's just a single Flowplayer, by now we'll have added a chromeFix, so
                // check for that as well.
                var runCycle = true;
                if ($("#" + thisCycle).children().length == 1 ||
                    ($("#" + thisCycle).children().length == 2 &&
                    $("#" + thisCycle).children("*:first").attr("panelType") == "flowplayer")) {
                    if (localParams.autoStartSingleVideo && localParams.loopSingleVideo) {

                        if ($("#" + thisCycle).children("*:last").attr("panelType") == "youtube") {
                            $("#" + thisCycle).children("*:last").after("<div panelType='chromeFix'></div>");
                        }

                    } else {
                        // Save singleVideo status
                        if ($("#" + thisCycle).children("*:first").attr("panelType") == "youtube" ||
                            $("#" + thisCycle).children("*:first").attr("panelType") == "flowplayer") {
                            userParamsObjArray[i].isSingleVideo = true;
                        }

                        // We automatically check restart the cycle when the video is done, so if
                        // it's going to loop, just add a new panel and go on as normal.
                        if (localParams.loopSingleVideo) {
                            if ($("#" + thisCycle).children("*:last").attr("panelType") == "youtube") {
                                $("#" + thisCycle).children("*:last").after("<div panelType='chromeFix'></div>");
                            }
                        }

                        runCycle = false;
                        var autoStart = 0;
                        if (localParams.autoStartSingleVideo) {
                            autoStart = 1;
                        }
                        if ($("#" + thisCycle).children("*:first").attr("panelType") == "youtube") {
                            _prepYouTube(i, $("#" + thisCycle).children("*:first"), autoStart);
                        }
                        if ($("#" + thisCycle).children("*:first").attr("panelType") == "flowplayer") {
                            _prepFlowplayer(i, $("#" + thisCycle).children("*:first"), localParams.autoStartSingleVideo);
                        }


                    }
                }

                // Now go ahead and actually run the cycle
                $("#" + thisCycle).show();
                if (runCycle) {
                    $("#" + thisCycle).cycle(localParams);
                }
            }
        }

        // Start the player monitor.  If there are no
        // current players, it won't do anything.
        setInterval(_cycleUpdatePlayerInfo, pollInterval);
    }
    // This function must be externalized so it can be called from within the page.
    this.startSlides = _cycleStartSlides;
}

