/*

  SoundManager 2 Demo: Play MP3 links "in-place"
  ----------------------------------------------

  http://schillmania.com/projects/soundmanager2/

  A simple demo making MP3s playable "inline"
  and easily styled/customizable via CSS.

  Requires SoundManager 2 Javascript API.

*/

function InlinePlayer() {
  var self = this;
  var pl = this;
  var sm = soundManager; // soundManager instance
  this.links = [];
  this.sounds = [];
  this.soundsByID = [];
  this.indexByID = [];
  this.lastSound = null;
  this.soundCount = 0;
  this.mainSitePlayer = null;
  this.isPlaying = false;
  this.hasRunInit = false;
  
  this.config = {
    playNext: false, // stop after one sound, or play through list until end
    autoPlay: false  // start playing the first sound right away
  }

  this.css = {
    // CSS class names appended to link during various states
    sInitial: 'sm2_initial',  // the classname the initial selector will use to setup the link as playable. This classname is removed and replaced with sm2_link
    sDefault: 'sm2_link', // default state
    sLoading: 'sm2_loading',
    sPlaying: 'sm2_playing',
    sPaused: 'sm2_paused',
    sError: 'sm2_error'
  }

  this.getSoundByID = function(sID) {
    return (typeof self.soundsByID[sID] != 'undefined'?self.soundsByID[sID]:null);
  }

  this.events = {

    // handlers for sound events as they're started/stopped/played
    play: function() {
      jQuery(this._data.oLink).removeClass(this._data.className);
      this._data.className = pl.css.sLoading;
      jQuery(this._data.oLink).addClass(this._data.className);
      self.isPlaying = true;
    },

    stop: function() {
      jQuery(this._data.oLink).removeClass(this._data.className);
      this._data.className = '';
      self.isPlaying = false;
    },

    pause: function() {
      jQuery(this._data.oLink).removeClass(this._data.className);
      this._data.className = pl.css.sPaused;
      jQuery(this._data.oLink).addClass(this._data.className);
      self.isPlaying = false;
    },

    resume: function() {
      jQuery(this._data.oLink).removeClass(this._data.className);
      this._data.className = pl.css.sPlaying;
      jQuery(this._data.oLink).addClass(this._data.className);
      self.isPlaying = true;      
    },

    finish: function() {
      jQuery(this._data.oLink).removeClass(this._data.className);
      this._data.className = '';
      if (pl.config.playNext) {
        var nextLink = (pl.indexByID[this._data.oLink.id]+1);
        if (nextLink<pl.links.length) {
          pl.handleClick({'target':pl.links[nextLink]});
        }
      }
      self.isPlaying = false;
    },
    
    load: function(success) {
      if(typeof(success) == 'undefined' || !success)
      {
        jQuery(this._data.oLink).removeClass(this._data.className);
        this._data.className = pl.css.sError;
        jQuery(this._data.oLink).addClass(this._data.className);
        self.isPlaying = false;
      }
      
    }

  }
  
  /**
   * Warning: don't return boolean values because it will affect other listeners on the page
   */
  this.handleClick = function(e) {
    // a sound link was clicked
    var soundURL = jQuery(e.target).attr('clip');
    var soundID  = jQuery(e.target).attr('id');
      
    if (!soundURL || !soundURL.match(/\.query$/i)) {
      return;
    }
    
    sm._writeDebug('handleClick()');
    
    
    try {
      if(!self.mainSitePlayer)
        self.mainSitePlayer = sm.getMovie('clip_player');
    
      if(self.mainSitePlayer && self.mainSitePlayer._entPlaying && self.mainSitePlayer._entPlaying())
      {
        self.mainSitePlayer._entPause();
      }
    } catch(e) {}
    
    
    var thisSound = self.getSoundByID(soundID);
    if (thisSound) 
    {
      // already exists
      if (thisSound == self.lastSound) {
        
        // don't attempt playing it again since it error'd out
        if(thisSound._data.className == self.css.sError)
          return;
        
        // and was playing (or paused)
        thisSound.togglePause();
        
      } else {
        
        // EM: it doesn't make much sense to stop playback after beginning new playback
        if (self.lastSound) self.stopSound(self.lastSound);
        
        // different sound
        thisSound.togglePause(); // start playing current
        sm._writeDebug('sound ' + soundID + ' different than last sound '+self.lastSound.sID);
      }
      e.preventDefault();
    } 
    else 
    {
      // create sound
      thisSound = sm.createSound({
       id:soundID,
       url:soundURL,
       onplay:self.events.play,
       onstop:self.events.stop,
       onpause:self.events.pause,
       onresume:self.events.resume,
       onfinish:self.events.finish,
       onload:self.events.load
      });
      // tack on some custom data
      thisSound._data = {
        oLink: e.target, // DOM node for reference within SM2 object event handlers
        className: self.css.sPlaying
      };
      self.soundsByID[soundID] = thisSound;
      self.sounds.push(thisSound);
      // stop last sound
      if (self.lastSound)
      {
        self.stopSound(self.lastSound);
      }
      
      thisSound.play();
      
      e.preventDefault();
    }

    self.lastSound = thisSound; // reference for next call
    
    return;
  }

  this.stopSound = function(oSound) {
    soundManager.stop(oSound.sID);
    soundManager.unload(oSound.sID);
  }

  this.loadClips = function() {
    var oLinks = jQuery('a[clip].' + self.css.sInitial);

    // linkOffset allows this method to be called multiple times and properly append new links to the end of self.links
    // while returning the new count of found items
    var foundItems = 0;
    var linkOffset = self.links.length;
    
    for (var i=0; i<oLinks.length; i++)
    {
      if (jQuery(oLinks[i]).attr('clip').match(/\.query$/i) && !(jQuery(oLinks[i]).hasClass(self.css.sDefault))) 
      {
        jQuery(oLinks[i]).addClass(self.css.sDefault).removeClass(self.css.sInitial); // add default CSS decoration
        self.links[linkOffset] = (oLinks[i]);
        self.indexByID[jQuery(oLinks[i]).attr('id')] = linkOffset; // hack for indexing
        foundItems++;
        linkOffset++;
      }
    }
	
	
	// Change the one playing (if there is one playing) to have the correct button.
	if(self.isPlaying)
	{
	  jQuery('#' + self.lastSound.sID).removeClass(self.css.sDefault);
	  jQuery('#' + self.lastSound.sID).addClass(self.css.sPlaying);
	}
	
    return foundItems
	
  }

  this.init = function() {
    sm._writeDebug('inlinePlayer.init()');
	var foundItems = this.loadClips();
    
    if (foundItems>0 && !this.hasRunInit) 
    {
      this.hasRunInit = true;
      jQuery(document).click(self.handleClick);
      if (self.config.autoPlay) 
        self.handleClick({target:self.links[0],preventDefault:function(){}});
    }
    sm._writeDebug('inlinePlayer.init(): Found '+foundItems+' relevant items.');
  }

   this.setPlaying = function(sID)
   {
     var sound = self.getSoundByID(sID);
 
     jQuery(sound._data.oLink).removeClass(sound._data.className);
     sound._data.className = pl.css.sPlaying;
     jQuery(sound._data.oLink).addClass(sound._data.className);
   }

  this.init();

}

var inlinePlayer = null;

soundManager.debugMode = false; // disable or enable debug output

soundManager.url = '/embed/'; // path to directory containing SM2 SWF

soundManager.onload = function() {
  // soundManager.createSound() etc. may now be called
  inlinePlayer = new InlinePlayer();
}


