/* Audio player based on jPlayer 1.0 */

var AudioPlayer = null;

(function () {

  // If the mp3List has one element in it, it'll make
  // a single player.
  
  AudioPlayer = function(divID, entryList, params) {
    this.div = "#"+divID;
    // Hashes of name, mp3
    this.entryList = entryList;
    this.mp3List = [];
    this.playItem = 0;
    // PARAMS: swfPath, autoplay.
    this.params = params;
    this.autoplay = params.autoplay;
    this.swfPath = params.swfPath;
    this.initialized = false;
    this._populateDiv();
  };

  function _extend(cls, meths) {
    for (key in meths) {
      cls.prototype[key] = meths[key];
    }
  }

  _extend(AudioPlayer, {
    
    _populateDiv: function () {

      var playerClass = "jp-single-player";
      var playerNext = "";
      var playerPrevious = "";
      if (this.entryList.length > 1) {
        playerClass = "jp-playlist-player";
        playerPrevious = '<img class="jp-control jp-previous" src="/images/audio_prev.gif">\n';
        playerNext = '<img class="jp-control jp-next" src="/images/audio_next.gif">\n';
      }
      
      jQuery(this.div).html(
        '<div class="jquery-jplayer"></div>\n'+
          '<div class="'+playerClass+'">\n'+
          '  <div class="jp-interface">\n'+
          '     '+playerPrevious+
          '     <img class="jp-control jp-play" src="/images/audio_play.gif">\n'+
          '     <img class="jp-control jp-pause" src="/images/audio_pause.gif">\n'+
          '     '+playerNext+
          '     <img class="jp-control jp-stop" src="/images/audio_stop.gif">\n'+
          '     <div class="jp-progress">\n'+
          '       <div class="jp-load-bar">\n'+
          '         <div class="jp-play-bar"></div>\n'+
          '       </div>\n'+ 
          '       <div class="jp-play-time"></div>\n'+
          '       <div class="jp-total-time"></div>\n'+
          '     </div>\n'+
          '     <div class="jp-volume-div">\n'+   
          '       <img class="jp-control jp-volume-min" src="/images/audio_quiet.gif">\n'+
          '       <img class="jp-control jp-volume-max" src="/images/audio_loud.gif">\n'+
          '       <div class="jp-volume-bar">\n'+
          '         <div class="jp-volume-bar-value"></div>\n'+
          '       </div>\n'+
          '     </div>\n'+
          '   </div>\n'+
          '   <div class="jp-playlist"><ul></ul></div>\n'+
          '</div>');
      // Now, cache the various elements.
      this.jpPlayTime = jQuery(".jp-play-time", this.div);
      this.jpTotalTime = jQuery(".jp-total-time", this.div);
      // We need to assign all the custom CSS ids, plus a unique
      // ID for the player itself.
      var allClasses = ["jp-play", "jp-pause",
        "jp-stop", "jp-load-bar", "jp-play-bar",
        "jp-volume-min", "jp-volume-max", "jp-volume-bar",
        "jp-volume-bar-value", "jquery-jplayer"];
      for (var i = 0; i < allClasses.length; i++) {
        var cls = allClasses[i];
        jQuery("."+cls, this.div)[0].id = this.div.substr(1) + "_" + cls;
      }

      var p = this;
      var params = {
        oggSupport: false,
        customCssIds: true,	
        ready: function() {
	  // This damn thing had better be initialized
	  // only once, and the only way to ensure that is
	  // to set it. The ready() function seems to be called
	  // every time the Flash object is made visible.
	  if (!p.initialized) {
	    p.initialized = true;
            p.displayPlayList();
            p.playListInit();
	  }
        }
      }
      
      if (this.swfPath) {
        params.swfPath = this.swfPath;
      }
      var player = jQuery(".jquery-jplayer", this.div).jPlayer(params)
      .jPlayer("onProgressChange", function(loadPercent, playedPercentRelative, playedPercentAbsolute, playedTime, totalTime) {
        p.jpPlayTime.text(jQuery.jPlayer.convertTime(playedTime));
        p.jpTotalTime.text(jQuery.jPlayer.convertTime(totalTime));
      })
      .jPlayer("onSoundComplete", function() {
        p.playListNext(true);
      });

      // These are in the same order as allClasses above.
      var allMsgs = ["play", "pause", "stop", "loadBar",
        "playBar", "volumeMin", "volumeMax", "volumeBar",
        "volumeBarValue"];
      for (var i = 0; i < allMsgs.length; i++) {
        var msg = allMsgs[i];
        var cls = allClasses[i];
        player.jPlayer("cssId", msg, this.div.substr(1) + "_" + cls);
      }

      if (this.entryList.length > 1) {
        /* For reasons I don't understand, this works
         this way but not if I use this.div as a context.
         If I do that, the Flash hangs. */
        jQuery(this.div + " .jp-previous").click( function() {
          p.playListPrev();
          return false;
        });

        jQuery(this.div + " .jp-next").click( function() {
          p.playListNext(false);
          return false;
        });
      }


    },

    // The code needs to take fillers into account.
    // I should put together a new list as I'm displaying
    // the playlist.
    
    displayPlayList: function() {
      var p = this;
      var j = 0;
      for (i=0; i < this.entryList.length; i++) {
        var entry = this.entryList[i];
        if (entry.text) {
          // It's filler.
          jQuery(".jp-playlist ul", this.div).append("<li class='jplayer-playlist-filler'>"+ entry.text +"</li>");
        } else {
          this.mp3List.push(entry);
          var imgString = "";
          if (entry.download) {
            imgString = "<a href='"+entry.download+"'><img src='/images/audio_download.gif' title='Download' class='jp-control jp-download'></a>";
          }
          var moreString = "";
          if (entry.more) {
            // It's an anchor element.
            moreString = entry.more+"<img src='/images/audio_more.gif' title='More' class='jp-control jp-more'></a>";
          }
          jQuery(".jp-playlist ul", this.div).append("<li class='jplayer_playlist_item '>"+imgString +"<span class='jplayer_playlist_item_"+j+"'>"+ entry.name+"</span>" + moreString +"</li>");
          jQuery(".jplayer_playlist_item_"+j, this.div).data( "index", j ).click( function() {
            var index = jQuery(this).data("index");
            if (this.playItem != index) {
              p.playListConfig( index , true);
            } else {
              jQuery(".jquery-jplayer", p.div).jPlayer("play");
            }
          });
          j += 1;
        }
      }
    },

    playListInit: function() {
      this.playListConfig( this.playItem, this.autoplay );
    },
    
    playListConfig: function( index, playIt) {
      jQuery(".jplayer_playlist_item_"+this.playItem, this.div).parent().removeClass("jplayer_playlist_current");
      jQuery(".jplayer_playlist_item_"+index, this.div).parent().addClass("jplayer_playlist_current");
      this.playItem = index;
      jQuery(".jquery-jplayer", this.div).jPlayer("setFile", this.mp3List[this.playItem].mp3, null);
      if (playIt) {
        jQuery(".jquery-jplayer", this.div).jPlayer("play");
      }
    },

    playListNext: function(auto) {
      // Don't rotate! When you're done, you're done. Reset it to zero,
      // but DON'T PLAY IF IT'S AUTO.
      // In the degenerate case where there's only one thing in the
      // mp3List, this will be set back to zero, and the right thing
      // will happen - if it's called from onSoundComplete, it'll be auto and
      // the index will be zero, so it won't play.
      var index = (this.playItem+1 < this.mp3List.length) ? this.playItem+1 : 0;
      this.playListConfig( index, (!auto) || (index != 0));
    },

    playListPrev: function() {
      // playListPrev is always in response to a button, so you should
      // always play. This will never be called in the single-element player.
      var index = (this.playItem-1 >= 0) ? this.playItem-1 : this.mp3List.length-1;
      this.playListConfig( index, true );
    }
    
  });
})();

