                    /*

                      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.playableClass = 'inline-playable'; // CSS class for forcing a link to be playable (eg. doesn't have .MP3 in it)
                      this.excludeClass = 'inline-exclude'; // CSS class for ignoring MP3 links
                      this.links = [];
                      this.sounds = [];
                      this.soundsByURL = [];
                      this.indexByURL = [];
                      this.lastSound = null;
                      this.soundCount = 0;
                      var isIE = (navigator.userAgent.match(/msie/i));

                      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
                        sDefault: 'sm2_link', // default state
                        sLoading: 'sm2_loading',
                        sPlaying: 'sm2_playing',
                        sPaused: 'sm2_paused'
                      }

                      this.addEventHandler = function(o,evtName,evtHandler) {
                        typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
                      }

                      this.removeEventHandler = function(o,evtName,evtHandler) {
                        typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
                      }

                      this.classContains = function(o,cStr) {
                        return (typeof(o.className)!='undefined'?o.className.match(new RegExp('(\\s|^)'+cStr+'(\\s|$)')):false);
                      }

                      this.addClass = function(o,cStr) {
                        if (!o || !cStr || self.classContains(o,cStr)) return false;
                        o.className = (o.className?o.className+' ':'')+cStr;
                      }

                      this.removeClass = function(o,cStr) {
                        if (!o || !cStr || !self.classContains(o,cStr)) return false;
                        o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
                      }

                      this.getSoundByURL = function(sURL) {
                        return (typeof self.soundsByURL[sURL] != 'undefined'?self.soundsByURL[sURL]:null);
                      }

                      this.isChildOfNode = function(o,sNodeName) {
                        if (!o || !o.parentNode) {
                          return false;
                        }
                        sNodeName = sNodeName.toLowerCase();
                        do {
                          o = o.parentNode;
                        } while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName);
                        return (o.nodeName.toLowerCase() == sNodeName?o:null);
                      }

                      this.events = {

                        // handlers for sound events as they're started/stopped/played

                        play: function() {
                          pl.removeClass(this._data.oLink,this._data.className);
                          this._data.className = pl.css.sPlaying;
                          pl.addClass(this._data.oLink,this._data.className);
                        },

                        stop: function() {
                          pl.removeClass(this._data.oLink,this._data.className);
                          this._data.className = '';
                        },

                        pause: function() {
                          pl.removeClass(this._data.oLink,this._data.className);
                          this._data.className = pl.css.sPaused;
                          pl.addClass(this._data.oLink,this._data.className);
                        },

                        resume: function() {
                          pl.removeClass(this._data.oLink,this._data.className);
                          this._data.className = pl.css.sPlaying;
                          pl.addClass(this._data.oLink,this._data.className);      
                        },

                        finish: function() {
                          pl.removeClass(this._data.oLink,this._data.className);
                          this._data.className = '';
                          if (pl.config.playNext) {
                            var nextLink = (pl.indexByURL[this._data.oLink.href]+1);
                            if (nextLink<pl.links.length) {
                              pl.handleClick({'target':pl.links[nextLink]});
                            }
                          }
                        }

                      }

                      this.stopEvent = function(e) {
                       if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
                          e.preventDefault();
                        } else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {
                          event.returnValue = false;
                        }
                        return false;
                      }

                      this.getTheDamnLink = (isIE)?function(e) {
                        // I really didn't want to have to do this.
                        return (e && e.target?e.target:window.event.srcElement);
                      }:function(e) {
                        return e.target;
                      }

                      this.handleClick = function(e) {
                        // a sound link was clicked
                        if (typeof e.button != 'undefined' && e.button>1) {
                          // ignore right-click
                          return true;
                        }
                        var o = self.getTheDamnLink(e);
                        if (o.nodeName.toLowerCase() != 'a') {
                          o = self.isChildOfNode(o,'a');
                          if (!o) return true;
                        }
                        var sURL = o.getAttribute('href');
                        if (!o.href || (!sm.canPlayLink(o) && !self.classContains(o,self.playableClass)) || self.classContains(o,self.excludeClass)) {
                          return true; // pass-thru for non-MP3/non-links
                        }
                        var soundURL = (o.href);
                        var thisSound = self.getSoundByURL(soundURL);
                        if (thisSound) {
                          // already exists
                          if (thisSound == self.lastSound) {
                            // and was playing (or paused)
                            thisSound.togglePause();
                          } else {
                            // different sound
                            thisSound.togglePause(); // start playing current
                            sm._writeDebug('sound different than last sound: '+self.lastSound.sID);
                            if (self.lastSound) self.stopSound(self.lastSound);
                          }
                        } else {
                          // create sound
                          thisSound = sm.createSound({
                           id:'inlineMP3Sound'+(self.soundCount++),
                           url:soundURL,
                           onplay:self.events.play,
                           onstop:self.events.stop,
                           onpause:self.events.pause,
                           onresume:self.events.resume,
                           onfinish:self.events.finish
                          });
                          // tack on some custom data
                          thisSound._data = {
                            oLink: o, // DOM node for reference within SM2 object event handlers
                            className: self.css.sPlaying
                          };
                          self.soundsByURL[soundURL] = thisSound;
                          self.sounds.push(thisSound);
                          if (self.lastSound) self.stopSound(self.lastSound);
                          thisSound.play();
                          // stop last sound
                        }

                        self.lastSound = thisSound; // reference for next call

                        if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
                          e.preventDefault();
                        } else {
                          event.returnValue = false;
                        }
                        return false;
                      }

                      this.stopSound = function(oSound) {
                        soundManager.stop(oSound.sID);
                        soundManager.unload(oSound.sID);
                      }

                      this.init = function() {
                        sm._writeDebug('inlinePlayer.init()');
                        var oLinks = document.getElementsByTagName('a');
                        // grab all links, look for .mp3
                        var foundItems = 0;
                        for (var i=0, j=oLinks.length; i<j; i++) {
                          if ((sm.canPlayLink(oLinks[i]) || self.classContains(oLinks[i],self.playableClass)) && !self.classContains(oLinks[i],self.excludeClass)) {
                            self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration
                            self.links[foundItems] = (oLinks[i]);
                            self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
                            foundItems++;
                          }
                        }
                        if (foundItems>0) {
                          self.addEventHandler(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.init();
 
                    }

                    var inlinePlayer = null;

                    soundManager.debugMode = false; // disable or enable debug output
                    soundManager.useFlashBlock = true;
                    soundManager.url = '/templates/__custom/js/swf'; // path to directory containing SM2 SWF

                    // optional: enable MPEG-4/AAC support (requires flash 9)

                    soundManager.flashVersion = 9;
                    soundManager.useMovieStar = true;

                    // ----

                    soundManager.onready(function() {
                      if (soundManager.supported()) {
                        // soundManager.createSound() etc. may now be called
                        inlinePlayer = new InlinePlayer();
                      }
                    });


    

