var bc_player, bc_experience, bc_video, bc_social, bc_advertising, bc_cuepoints; 

var bc_currentVideo;
var experienceId;
var bc_playbackStarted = false;
var bc_playerFullScreen = false;
var bc_playerVolume = getVolumePreference();
var bc_playerVolumeDefault = .5;
var bc_playerLastTick = 0; 
var bc_playerAutostart = false;
var bc_playerDefinition = '';
var BigBoxAd;
var BigBoxAdContainer;
var bc_debug = false;
var bc_video_count = 0;

$(window).unload(function () { 
  
  if ( typeof bc_video !== 'undefined' )
  {
    if ( bc_video.getVolume() != bc_playerVolume )
    {
      bc_playerVolume = bc_video.getVolume();
      setVolumePreference( bc_playerVolume );
    }
  }

});

function onTemplateLoaded( experienceId )
{
  bc_player = brightcove.getExperience(experienceId);

  if ( bc_debug )
  {
    console.log('onTemplateLoaded w/ id: '+experienceId);
  }

  // experience related
  bc_experience = bc_player.getModule(APIModules.EXPERIENCE);
  bc_experience.addEventListener(BCExperienceEvent.CONTENT_LOAD, onContentLoad);
  bc_experience.addEventListener(BCExperienceEvent.ENTER_FULLSCREEN, onEnterFullScreen);
  bc_experience.addEventListener(BCExperienceEvent.EXIT_FULLSCREEN, onExitFullScreen);
  
  // video related
  bc_video = bc_player.getModule(APIModules.VIDEO_PLAYER);
  
  bc_playerDefinition = bc_video.getDefinition();
  if ( bc_playerDefinition.indexOf('autoStart="true"') !== -1 )
  {
    bc_playerAutostart = true;
  }

  bc_video.setVolume(bc_playerVolume);
  bc_video.addEventListener(BCVideoEvent.VIDEO_CHANGE, onVideoChange);
  bc_video.addEventListener(BCVideoEvent.VIDEO_CONNECT, onVideoConnect);
  bc_video.addEventListener(BCVideoEvent.VIDEO_COMPLETE, onVideoComplete);
  bc_video.addEventListener(BCVideoEvent.VIDEO_PROGRESS, onVideoProgress);
  bc_video.addEventListener(BCVideoEvent.STREAM_START, onStreamStart);
    
  // advertising related
  bc_advertising = bc_player.getModule(APIModules.ADVERTISING);
  bc_advertising.enableExternalAds(true);
  bc_advertising.addEventListener(BCAdvertisingEvent.EXTERNAL_AD, onExternalAd);
  bc_advertising.addEventListener(BCAdvertisingEvent.AD_COMPLETE, onExternalAdComplete);

  bc_cuepoints = bc_player.getModule(APIModules.CUE_POINTS);
}

function onVideoChange(pEvent)
{
  if ( bc_debug )
  {
    console.log('onVideoChange');
  }

  bc_currentVideo = bc_video.getCurrentVideo();
  
  if ( bc_debug )
  {
    console.dir(bc_currentVideo);
  }  

  bc_advertising.resumeAfterExternalAd();
  BigBoxAd.setSynchedBanner(false);

  bc_cuepoints.addCuePoints(bc_currentVideo.id,[{'time': 40,'name': 'mid','type': 'ad'}]); 
}

function onContentLoad()
{  
  if ( bc_debug )
  {
    console.log('onContentLoad');
  }
  
  if ( !bc_playerAutostart )
  {
    if ( $(BigBoxAd.anchor).is(':empty') ) 
    {
      BigBoxAd.redrawAd();
    }
  }
}

function onVideoConnect(pEvent)
{
  if ( bc_debug )
  {
    console.log('onVideoConnect');
  }

  bc_playerLastTick = 0;
}

function onStreamStart()
{
  if ( bc_debug )
  {
    console.log('onStreamStart');
  }

  bc_video_count = bc_video_count + 1;

  // if no preroll and autoplay
  if ( bc_playerAutostart || bc_video_count > 1 )
  {
    BigBoxAd.redrawAd();
  }
}

function onVideoComplete()
{
  if ( bc_debug )
  {
    console.log('onVideoComplete');
  }
}

function onExternalAd(pAdObject)
{
  if ( bc_debug )
  {
    console.log('onExternalAd');
    console.dir(pAdObject);
  }

  new ExternalAd(pAdObject,{expandedId: BigBoxAdContainer});  
}

function onExternalAdComplete(pEvent)
{
  if ( bc_debug )
  {
    console.log('onExternalAdComplete');
  }
}

function onEnterFullScreen()
{
  BigBoxAd.setFullScreen(true);
}

function onExitFullScreen()
{
  BigBoxAd.setFullScreen(false);
  BigBoxAd.redrawAd();
}

function onVideoProgress( pEvent )
{
  bc_playerThisTick = parseInt(pEvent.position,10);
  
  if ( bc_playerThisTick != bc_playerLastTick && bc_playerThisTick % BigBoxAd.interval == 0 )
  { 
    BigBoxAd.redrawAd();
  }
  
  bc_playerLastTick = bc_playerThisTick;
}

function getVolumePreference()
{
  var volume = cookie('bc_volume');
  
  if ( volume != null )
  {
    return volume;
  }
  else
  {
    return bc_playerVolumeDefault;
  }  
}

function setVolumePreference( volume )
{
  cookie('bc_volume', volume, { expires: 7, path: '/', domain: '', secure: false });
}

var CanoeVideoStandalone = {

  experienceId: 'canoePlayer',
  style: { bgcolor: '#ffffff', width: 544, height: 455 },
  publisher: 0,
  player: 0,
  video: 0,
  containers : { player: '#player', ad: '#ad' },
  adtag : '',

  Init: function ( publisher, player, video, style )
  {
    this.SetPublisher(publisher);
    this.SetPlayer(player);
    this.SetVideo(video);
    this.SetStyle(style);
  },

  SetExperienceId : function ( experienceId )
  {
    if ( typeof experienceId !== 'undefined' && experienceId )
    {
      this.experienceId = experienceId;
      experienceId = experienceId;
    }
  },

  SetStyle: function ( style )
  {
    if ( typeof style === 'object' )
    {
      if ( typeof style.width !== 'undefined' && style.width )
      {
        this.style.width = style.width;
      }
            
      if ( typeof style.height !== 'undefined' && style.height )
      {
        this.style.height = style.height;
      }
    }    
  },

  SetPublisher: function ( publisher )
  {
    if ( publisher )
    {
      this.publisher = publisher;
    }
  },

   SetAdServerURL: function ( adserverurl )
  {
    if ( adserverurl )
    {
      this.adserverurl = adserverurl;
    }
  },
  
  SetPlayer: function ( player )
  {
    if ( player )
    {
      this.player = player;
    }
  },

  SetVideo: function ( video )
  {
    if ( video )
    {
      this.video = video;
    }
  },
    
	SetPlaylist: function ( playlist )
  {
    if ( playlist )
    {
      this.playlist = playlist;
    }
  },


  SetContainers: function ( containers )
  {
    if ( typeof containers === 'object' )
    {
      if ( typeof containers.player !== 'undefined' && containers.player )
      {
        this.containers.player = containers.player;
      }

      if ( typeof containers.ad !== 'undefined' && containers.ad )
      {
        this.containers.ad = containers.ad;
      }
    }    
  },

  SetPlayerContainer: function ( container )
  {
    if ( typeof container !== 'undefined' && container )
    {
      this.containers.player = container;
    }    
  },

  SetAdContainer: function ( container )
  {
    if ( typeof container !== 'undefined' && container )
    {
      this.containers.ad = container;
    }    
  },

  SetAdTag: function ( adtag )
  {
    if ( adtag )
    {
      this.adtag = adtag;
    }

  },

  InitAd: function ()
  {
    if ( this.adtag )
    {
      BigBoxAd = Ad(this.containers.ad,this.adtag);
      BigBoxAdContainer = this.containers.ad;
    }
  },

  GeneratePlayer: function ()
  {
    experienceId = this.experienceId; 
    var container = jQuery(this.containers.player);

    if ( container.length > 0 )
    {
      var output =     
        '<object id="'+this.experienceId+'" class="BrightcoveExperience">'+
        '  <param name="bgcolor" value="'+this.style.color+'" />'+
        '  <param name="width" value="'+this.style.width+'" />'+
        '  <param name="height" value="'+this.style.height+'" />'+
        '  <param name="publisherID" value="'+this.publisher+'"/>'+
        '  <param name="playerID" value="'+this.player+'" />'+
        '  <param name="isVid" value="true" />'+
        '  <param name="isUI" value="true" />'+
        '  <param name="@videoList.featured" value="'+this.video+'" />'+
        '  <param name="@videoPlayer" value="'+this.video+'" />'+
		'  <param name="@playlistTabs" value="'+this.playlist+'" />'+
		'  <param name="adServerURL" value="'+this.adserverurl+'" />'+

        '</object>';

      container.empty();
      container.html(output);

      experienceId = this.experienceId;

      this.InitAd();

      return true;
    }

    return false;
  },
  
  Debug: function ()
  {
    this.debug = true;
    bc_debug = true;
  }


};


/**
 * Creates a new Ad object which handles the synched banner and basic 300x250
 * unit next to the player.
 * 
 * @classDescription Creates an ad object with the basic ad tag to be used.
 *                   Redraws the iframe with that ad tag as often as the class's
 *                   interval specifies. If a synched banner exists (associated
 *                   with a video ad), then the redrawing of the iframe won't
 *                   occur.
 * @param {pString}
 *          pAdTagURL ad tag to be used when there's just a regular 300x250 (not
 *          a synched banner).
 * @return {Object} Returns the current Ad object.
 */
function Ad( container, url )
{
  this.url = url;
  this.container = container;
  this.interval = 30; // 30 seconds timeout
  this.fullscreen = false;
  this.synchedBanner = false;
  this.timeout;
  this.params = {size: 'sz=300x250', adkeys: ''};

  /**
   * Creates an iFrame with the ad tag as it's source, and uses the DOM API to
   * add it to the page
   * 
   * @method
   * @param {String}
   *          pInsertionPoint The id of the HTML element where the ad should be
   *          inserted.
   * @param {String}
   *          pURL The ad tag URL to use
   */
  createAd = function( container, url )
  {  
    if ( bc_currentVideo.adKeys )
    {
      this.params.adkeys = bc_currentVideo.adKeys;
    }
    else
    {
      this.params.adkeys = '';
    }
    
    if ( bc_debug )
    {
      console.log('ad keys: '+bc_currentVideo.adKeys);
    }
    
    // add params to url
    jQuery.each(this.params, function(i,val) {
      
      if ( val != '' )
      {
        url += val+';';
      }
      
    });

    // add cache bustin random number to url
    url += 'ord='+(Math.random()*10000000000000000)+';?';
    
    // get the container
    c = jQuery(container);
    
    // write to the container
    if ( c.length > 0 )
    {
      if ( bc_debug )
      {
        console.log('ad url: '+url);  
      }
      
      c.empty();
      c.html('<iframe id="bigbox_ad" src="'+url+'" width="300" height="250" scrolling="no" frameborder="0" />');
    }
    else
    {
      if ( bc_debug )
      {
        console.log('Could not create the big box ad.');
      }
    }
    
  };
  
  /**
   * If the video is not in fullscreen and there's currently no synched banner,
   * the createAd() method is called again and a timeout is set to call
   * redrawAd() again after the class's interval.
   * 
   * @method
   */
  redrawAd = function()
  {
    if ( !this.getFullScreen() && !this.getSynchedBanner() ) 
    {
      this.createAd(this.container,this.url);
    }
  };
  
  /**
   * @method
   * @return {Boolean} Whether or not the player is currently in fullscreen mode
   */
  getFullScreen = function()
  {
    return this.fullscreen;
  };
  
  /**
   * @method
   * @param {Boolean}
   *          Sets whether or not the player is currently in fullscreen mode
   */
  setFullScreen = function(pToggle)
  {
    if(typeof pToggle == 'boolean') this.fullscreen = pToggle;
  };
  
  /**
   * @method
   * @param {Boolean}
   *          Sets whether or not a synched banner is currently on the page
   */
  setSynchedBanner = function(pToggle)
  {  
    if(typeof pToggle == 'boolean') this.synchedBanner = pToggle;
  };
  
  /**
   * @method
   * @return {Boolean} Whether or not there's currently a synched banner on the
   *         page
   */
  getSynchedBanner = function()
  {
    return this.synchedBanner;
  };
  
  return this;
};


var _brightcoveAd = new Object();
var _BigBoxAds = new Object();

/**
 * Takes care of parsing the XML that comes back from the ad server, building
 * the ad object, and displaying the ads in both the player and on the page. It
 * should be noted that the ad XML that comes back from the ad server needs to
 * be one of the supported Rich Media templates that Brightcove distributes for
 * use with DFP and other ad serving platforms.
 * 
 * @param {String}
 *            pXML The XML string that gets returned from the ad server. Needs
 *            to be one of the templates supported by Brightcove.
 * @param {Object}
 *            pOptions An object that contains options for further
 *            customization. By default, this function will render the expanded
 *            banner (eg type: "expandedBanner") and also write out the banner
 *            to a div with the id of "expandedBanner" (eg writeTo:
 *            "expandedBanner"). For the type option, you can also choose
 *            "collapsedBanner". For the writeTo option, a user can specify the
 *            ID of any element they'd like.
 */

function ExternalAd(pAdObject, pOptions)
{  
  if (pOptions) 
  {
    _brightcoveAd.expandedId = (pOptions.expandedId) ? pOptions.expandedId : "expandedBanner";
    _brightcoveAd.collapsedId = (pOptions.collapsedId) ? pOptions.collapsedId : "collapsedBanner";
    _brightcoveAd.type = (pOptions.type) ? pOptions.type : "expandedBanner";
  }
  else
  {
    _brightcoveAd.expandedId = "expandedBanner";
    _brightcoveAd.collapsedId = "collapsedBanner";
    _brightcoveAd.type = "expandedBanner";
  }
  
  /**
   * Parses the XML from the ad server 
   * @param {Object} pXML The XML returned from the ad server.
   */
  this.parseAd = function( pAdObject )
  {
    // check for basic ad xml structure
    if ( pAdObject.ad.indexOf("<SynchedBanner") === -1 ) 
    {
      if ( bc_debug )
      {
        console.log('bad preroll ad');
      }

      return false;
    }
      
    if ( window.ActiveXObject )
    {
      try
      {
        // parses the XML for IE browsers
        this.adXML = new ActiveXObject("Microsoft.XMLDOM");
        this.adXML.async = false;
        this.adXML.loadXML(pAdObject.ad);
      }
      catch ( e )
      {
        if ( bc_debug )
        {
          console.log('loadXML Error');
          console.dir(e);
        }

        return false;
      }

    }
    else if ( window.XMLHttpRequest )
    {
      try
      {
        this.adXML = (new DOMParser()).parseFromString(pAdObject.ad, "text/xml"); 
      }
      catch ( e )
      {
        if ( bc_debug )
        {
          console.log('DOMParser Error');
          console.dir(e);
        }

        return false;
      }
    }

    return true;
  };

  /**
   * Builds the ad object
   * 
   */
  this.buildAd = function()
  {  
    adXML = this.adXML;

    var ad = new Object();
    ad.type = "videoAd";
    
    var nodeItems = adXML.firstChild.childNodes.length;
    var currentNode = adXML.firstChild.firstChild;
    
    // get the root node attributes
    ad.duration = (adXML.firstChild.getAttribute("duration") !== "") ? Number(adXML.firstChild.getAttribute("duration")) : 15;
    if(adXML.firstChild.getAttribute("trackStartURLs") !== "") ad.trackStartURLs = adXML.firstChild.getAttribute("trackStartURLs").split(",");
    if(adXML.firstChild.getAttribute("trackMidURLs") !== "") ad.trackMidURLs = adXML.firstChild.getAttribute("trackMidURLs").split(",");
    if(adXML.firstChild.getAttribute("trackEndURLs") !== "") ad.trackEndURLs = adXML.firstChild.getAttribute("trackEndURLs").split(",");
    if(adXML.firstChild.getAttribute("trackPointURLs") && (adXML.firstChild.getAttribute("trackPointURLs") !== "")) ad.trackPointURLs = adXML.firstChild.getAttribute("trackPointURLs").split(",");
    ad.trackPointTime = (adXML.firstChild.getAttribute("trackPointTime") && (adXML.firstChild.getAttribute("trackPointTime") !== "")) ? Number(adXML.firstChild.getAttribute("trackPointTime")) : 0;
  
    for ( var i = 0; i < nodeItems; i++ )
    {
      //checks to see if the current nodes are in our Rich Media Templates and assigns them if they exist
      if ( currentNode.firstChild )
      {
        if ( currentNode.nodeName == "videoURL" )
        {  
          ad.videoURL = currentNode.firstChild.nodeValue;
        }
        else if ( currentNode.nodeName == "videoClickURL" ) 
        {
          ad.videoClickURL = currentNode.firstChild.nodeValue;
        }
        else if ( currentNode.nodeName == "expandedBannerURL" )
        {
          _BigBoxAds.expandedBannerURL = currentNode.firstChild.nodeValue;
        }
        else if ( currentNode.nodeName == "expandedBannerClickURL" )
        {
          _BigBoxAds.expandedBannerClickURL = currentNode.firstChild.nodeValue;
        }
        else if ( currentNode.nodeName == "collapsedBannerURL" )
        {
          _BigBoxAds.collapsedBannerURL = currentNode.firstChild.nodeValue;
        }
        else if ( currentNode.nodeName == "collapsedBannerClickURL" )
        {
          _BigBoxAds.collapsedBannerClickURL = currentNode.firstChild.nodeValue;
        }
      }

      currentNode = currentNode.nextSibling;
    }
    
    if ( i == 0 )
    {
      return false;
    }
    else
    {
      return ad;
    }
  };
  
  this.createSwf = function(pURL, pClickThrough, pId)
  {
    var objectTag = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="300" height="250" id="'+pId+'" align="middle">\n';
    objectTag += '\t<param name="allowScriptAccess" value="always" />\n';
    objectTag += '\t<param name="movie" value="' + pURL + '" />\n';
    objectTag += '\t<param name="quality" value="high" />\n';
    objectTag += '\t<param name="bgcolor" value="#ffffff" />\n';
    objectTag += '\t<param name="wmode" value="transparent" />\n'; 
    objectTag += '\t<param name="FlashVars" value="clickTag=' + pClickThrough + '" />\n';
    objectTag += '\t<embed src="' + pURL + '" quality="high" bgcolor="#ffffff" width="300" height="250" name="expandedBanner" align="middle" allowScriptAccess="always" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" FlashVars="clickTag='+pClickThrough+'" />\n';
    objectTag += '</object>\n';
    
    if(document.getElementById(pId)) document.getElementById(pId).innerHTML = objectTag;
  };
  
  this.createImage = function(pURL, pClickThrough, pId)
  {
    if(document.getElementById(pId)) document.getElementById(pId).innerHTML = "<a href='" + pClickThrough + "' target='_blank' ><img src='" + pURL + "' /></a>\n";
  };
  
  /**
   * Writes the banner out to the page, and determines wheter or not it's a swf or regular image so that the correct tags are written to the page.
   * @param {Object} pAd The ad object containing all of the information to display an ad in the player and render an ad on the page.
   */
  this.createBanner = function(pAd)
  {
    var externalAds = {};
    
    if ( (_brightcoveAd.type == "expandedBanner" || _brightcoveAd.type == "both") && pAd.expandedBannerURL )
    {
      externalAds["expandedBanner"] = {clickURL: pAd.expandedBannerClickURL, srcURL: pAd.expandedBannerURL, id: _brightcoveAd.expandedId, type: "expandedBanner"};
    }
    
    if ( (_brightcoveAd.type == "collapsedBanner" || _brightcoveAd.type == "both") && pAd.collapsedBannerURL )
    {
      externalAds["collapsedBanner"] = {clickURL: pAd.collapsedBannerClickURL, srcURL: pAd.collapsedBannerURL, id: _brightcoveAd.collapsedId, type: "collapsedBanner"};
    }

    for ( var i in externalAds )
    {
      var banner = externalAds[i];

      var iframeElem = document.createElement('iframe');
      iframeElem.setAttribute('width', '300');
      iframeElem.setAttribute('height', '250');
      iframeElem.setAttribute('scrolling', 'no');
      iframeElem.setAttribute('frameborder', '0');
      iframeElem.setAttribute('src', banner.srcURL);
      
      try
      {
        jQuery(banner.id).empty();
        jQuery(banner.id).html(iframeElem);
      }
      catch( e )
      {
        console.log("Couldn't create the big box ad. Error: "+e);
        return false;
      }
    }

    return true;
  };

  this.recover = function()
  {
    bc_advertising.resumeAfterExternalAd();

    if ( bc_playerAutostart )
    { 
      BigBoxAd.redrawAd();
    }
  }
  
  if ( this.parseAd(pAdObject) )
  {
    var ad = this.buildAd();

    if ( typeof ad == 'object' && this.createBanner(_BigBoxAds) )
    {
      BigBoxAd.setSynchedBanner(true);
      bc_advertising.showAd(ad);
    }
    else
    {
      this.recover();
    }
  }
  else
  {
    this.recover();
  }
}

/**
* Cookie read and write function.
* @param name
* @param value
* @param options
* @return
*/

function cookie(name, value, options) 
{
 if ( typeof value != 'undefined') // name and value given, set cookie
 { 
   options = options || {};
   if ( value === null ) 
   {
     value = '';
     options.expires = -1;
   }
   
   var expires = '';
   
   if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) 
   {
     var date;
     if ( typeof options.expires == 'number' ) 
     {
       date = new Date();
       date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
     } 
     else 
     {
       date = options.expires;
     }
     expires = '; expires=' + date.toUTCString(); 
   }
   
   /** 
    * CAUTION: Needed to parenthesize options.path and options.domain
    * in the following expressions, otherwise they evaluate to undefined
    * in the packed version for some reason...
    */
   var path = options.path ? '; path=' + (options.path) : '';
   var domain = options.domain ? '; domain=' + (options.domain) : '';
   var secure = options.secure ? '; secure' : '';
   document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
 } 
 else // only name given, get cookie
 { 
   var cookieValue = null;
   if (document.cookie && document.cookie != '') 
   {
     var cookies = document.cookie.split(';');
     for ( var i = 0; i < cookies.length; i++ ) 
     {
       var cookie = jQuery.trim(cookies[i]);
       // Does this cookie string begin with the name we want?
       if (cookie.substring(0, name.length + 1) == (name + '=')) 
       {
         cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
         break;
       }
     }
   }
   
   return cookieValue;
 }
}

