/* How long this movie is in seconds. */
var movieDuration = 0;

/* Intervals that tell us when 25%, 50%, 75% and 100% of the video have been
 * watched. The first three are always pure quarters, but the 100% value is
 * flubbed slightly to take into account that movie videos have a run on
 * trailer that some people might not sit through. */
var triggerIntervals = [0, 0, 0, 0];

/* Because the time reported by the player is fractional we can end up with
 * multiplate possible updates per second. To save time, while playing this is
 * set to the last whole second that we tested an update for, so that it only
 * happens once per second. It's reset back to NULL when the player finishes
 * playing. */
var lastMediaTime = 0;

/* This specified what the playback time was the last time that we triggered a
 * playback log event. */
var lastTriggerTime = 0;

/* The div that contains the current info text. Set the first time the video
 * plays to save lookups later. */
var movieContentTag = null;

/* Set by the loading page, this will be set to the ID of the movie being
 * watched. */
var movieID = null;

/* The states used for the various levels of playback. */
var percentageStates = ["Play25", "Play50", "Play75", "Play100"];

/* Set the URL of the movie being played. */
function setMovieID (id)
{
    movieID = id;
}

/* Trigger a playback event using AJAX for the state and file presented. */
function triggerPlaybackRecording (state)
{
    /* Send a request to the server to tell it what point we've reached. This
     * isn't important enough to do anything with success or failure. */
// Commented out on 01/11/2010 because I started to use TubeMogul inPlay, a
// plugin for JWPlayer that provides analytics and works even when the video is
// posted to Facebook.
//
// Commenting out the AJAX call disables my own special tracking logic
// temporarily while still allowing me to turn it back on if TubeMogul doesn't
// work out the way that I want it to.
//
//    new Ajax.Request ("/cgi-bin/tracker.cgi", {
//       parameters: {
//           state:   state,
//           movieID: movieID
//       }
//    });
}

/* This updates the contents of the div with the id movieContent to contain the
 * HTML fragment that is passed in content. If content is null or undefined,
 * then the contents of the div are erased. */
function updateMovieContent (contentIndex)
{
    /* If the content index is -1, update with no content. Otherwise, update
     * with the content at the given index. */
    if (contentIndex == -1)
    {
        /* Erase and store that we're not displaying any content index here. */
        if (infoText.displayedContentIndex != -1)
        {
            movieContentTag.update ('');
            infoText.displayedContentIndex = -1;
        }
    }
    else
    {
        /* If this is the currently displayed item, do nothing. */
        if (infoText.displayedContentIndex == contentIndex)
            return;

        /* Display it and update the index. */
        movieContentTag.update (infoText.text[contentIndex]);
        infoText.displayedContentIndex = contentIndex;
    }
}

/* This is invoked once a second while the movie is playing, and is used to
 * update the running information about the movie. */
function updateRunningInfo (time)
{
    /* If the time provided is in the array of info information for this movie,
     * then run the update now. */
    var i,biggest=-1;

    /* Loop over all times that are given. */
    for (i = 0 ; i < infoText.timeList.length ; i++)
    {
        /* If this time is in the list, then update to that content and then
         * leave. */
        if (time == infoText.timeList[i])
        {
            updateMovieContent (i);
            return;
        }
        
        /* If the time that we were given is larger than the time at this
         * index, store this index for later. */
        if (time > infoText.timeList[i])
            biggest = i;
    }

    /* If the biggest value is still -1, it means that the time we got isn't
     * bigger than any of the times in the list. This happens when, for
     * example, there is no time for value 0 and the video is first loaded. In
     * that case what we want to do is update with null content so that
     * whatever might be displayed is removed. 
     *
     * Otherwise update with the most recent update for this time period. */
    if (biggest == -1)
        updateMovieContent (-1);
    else
        updateMovieContent (biggest);
}


/* This is invoked by the player while the video is playing and the current
 * time selection has changed. */
function mediaTimeEvent (eventObj)
{
    /* Get duration if we haven't already. */
    if (movieDuration == 0)
    {
        /* Get the duration. */
        movieDuration = Math.floor (eventObj.duration);

        /* Calculate a quarter of the playback. */
        var quarter = Math.floor (movieDuration / 4);

        /* Store in. */
        triggerIntervals[0] = quarter;
        triggerIntervals[1] = quarter * 2;
        triggerIntervals[2] = quarter * 3;
        triggerIntervals[3] = movieDuration - 20;

        /* If the 100% interval is smaller than the 3/4 value, fix it. This
         * video must be really short (should never happen, but you never
         * know). */
        if (triggerIntervals[2] >= triggerIntervals[3])
            triggerIntervals[3] = triggerIntervals[2] + 1;

        /* Scan the list of info times, and truncate the list so that any
         * entries past the end of the movie don't exist. Just in case
         * something is set wrong, this'll save a bit of time over the course
         * of the playing. */
        for (var i = 0 ; i < infoText.timeList.length ; i++)
        {
            if (infoText.timeList[i] > movieDuration)
            {
                infoText.timeList.length = i;
                break;
            }
        }
    }

    /* Get the current position. Leave now if this is the same as last time. */
    var currentPos = Math.floor (eventObj.position);
    if (currentPos == lastMediaTime)
        return;

    /* If the current position is 1, then playback has just started. */
    if (currentPos == 1)
        triggerPlaybackRecording ("Begin");
    else
    {
        /* If the current position is prior to the last trigger time on record,
         * someone has scanned the movie backwards. If that's the case, and the
         * last trigger time is past the 100% mark, then count this as another
         * play through by sending off a fake "playback has started" and then
         * resetting the trigger time to 0 so that the appropriate interval
         * will fire off (if any). */
        if (currentPos < lastTriggerTime && lastTriggerTime >= triggerIntervals[3])
        {
            triggerPlaybackRecording ("Begin");
            lastTriggerTime = 0;
        }

        /* Check to see if any of our watermark events are going to trigger. We go
         * latest to earliest. */
        for (i = 3 ; i >= 0 ; i--)
        {
            if (currentPos >= triggerIntervals[i] && lastTriggerTime < triggerIntervals[i])
            {
                triggerPlaybackRecording (percentageStates[i]);
                lastTriggerTime = currentPos;
                break;
            }
        }
    }

    /* Update the running info text (maybe). */
    lastMediaTime = currentPos;
    updateRunningInfo (currentPos);
}

/* This gets invoked when the media state changes (IDLE, PLAYING, PAUSED,
 * COMPLETED, BUFFERING). */
function mediaStateEvent (eventObj)
{
    /* If the new state is complete, the movie just stopped. 
     *
     * We reset the last media time so that the next play through things will
     * trigger again. This doesn't restore the movie text to the frame 0 text,
     * that'll happen when (and if) the video plays again. */
    if (eventObj.newstate == "COMPLETED")
    {
        lastMediaTime = 0;
        lastTriggerTime = 0;
    }
}

/* This is invoked to let us know that the player is now ready to go. */
function playerIsReady (obj)
{
    /* Get the ID of the player so that we can interact with it. This is safe
     * here because the main page doesn't generate the flash tag until the dom
     * has loaded. */
    var playerTag = $('vPlayer');

    /* Set up the movie content tag. This should be done before we indicate our
     * desire to get events, since the events are asyncronous and they need
     * this value. */
    movieContentTag = $('movieContent');

    /* Indicate that we want to be notified when the time selection changes in
     * the video while it's playing. */
    playerTag.addModelListener ("TIME", 'mediaTimeEvent');
    playerTag.addModelListener ("STATE", 'mediaStateEvent');

    /* Trigger a player is loaded event now. */
    triggerPlaybackRecording ("Loaded");
}


