/*
    Copyright (C) 2007-2009 Andy Altepeter
    Copyright (C) 2008,2009 Mathias Gibbens

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


/*
Constructor for the RandomContentSource pseudo class.
*/
function RandomContentSource(id, time, items, dt, cdt, divId, csURL, duration, enableTransitions, enableControls, enableTransitionIndicator) {
  this.id = id; //The random ID of the content source
  this.time = time*1000; //How long (in milliseconds) between item transitions
  this.transitionTime = duration; //How long of a transition?
  this.cache = new Object(); //Cache of previously loaded items
  this.history = new Array(); //History tracking array
  this.position = -1; //Position in the history array
  this.items = items; //List of items in the source folder
  this.displayTitle = dt; //Should we display the title?
  this.displayContentDescription = cdt; //Should we display the content description?
  this.divId = divId; //Id of the random content source div
  this.contentSourceURL = csURL; //URL for this content source
  this.enableTransitions = enableTransitions; //Do we use the transitions?
  this.enableTransitionIndicator = enableTransitionIndicator; //Do we show the transition indicaator?
  this.enableControls = enableControls;
  this.inTransition = false;
  this.isPaused = false;
  
  this.pauseButtonSrc = this.contentSourceURL + '/++resource++rcs-assets/media-playback-pause.png';
  this.playButtonSrc = this.contentSourceURL + '/++resource++rcs-assets/media-playback-start.png';
  
}

/*
  Initialize the Random Content Source
*/
RandomContentSource.prototype.initialize = function() {
  this.firstDivName = "r" + this.id + "a"; //These are names and DOM objects that will be used a lot
  this.firstDiv = $(this.firstDivName);
  this.secondDivName = "r" + this.id + "b";
  this.secondDiv = $(this.secondDivName);
  this.parentDiv = Element.extend(this.firstDiv.parentNode);

  var dim = this.parentDiv.getDimensions();
  this.transIndicator = $("indicator" + this.id);
  this.transIndicator.style.position = "absolute";
  this.transIndicator.style.top = (dim.height/2 - 8) + "px";
  this.transIndicator.style.left = (dim.width/2 - 8) + "px";

  if (this.enableControls) {
    this.pauseButton = $("pause" + this.id + "button");
    this.previousButton = $("previous" + this.id + "button");
    this.nextButton = $("next" + this.id + "button");
    this.nextButton.observe('click', this.nextItem.bind(this));
    this.previousButton.observe('click', this.previousItem.bind(this));
    this.pauseButton.observe('click', this.pausePlayItem.bind(this));
  }

  this.interval = setInterval("randomContent" + this.id + ".swap()", this.time); //Keeps track of the interval ID for setInterval / clearInterval  
}


/* 
   set the cache of the RCS -- useful when preloading the cache
*/
RandomContentSource.prototype.setCache = function(cache_list) {
  for (var i=0; i < cache_list.length; i++) {
    this.cache[cache_list[i][0]] = cache_list[i][1];
  }
}
  
/*
  Method which swaps the next item in line for the current one.
*/
RandomContentSource.prototype.swap = function() {
  try { //Make sure that we have ajax. If we don't, alert the user and disable the auto rotate.
    Ajax;
  }
  catch (e) {
    clearInterval(this.interval);
    alert("The Prototype JavaScript library is not available; canceling auto-rotate.");
    return;
  }
  
  this.inTransition = true;
  var randomItem;
  
  if (this.items.length > 0) { //There is still at least one item that we have not seen yet
    var randomIndex = Math.floor(Math.random()*this.items.length);
    randomItem = this.items.splice(randomIndex,1);
    this.history.push(randomItem);
    if (this.items.length == 0) { //This was our very last unseen item, prepare for the history loop
      this.position = 0;
    }
  }
  else { //We have seen all the items, so continue looping through our history
    if (this.position == this.history.length) { //We have reached the end of the history array, go back to the beginning
      this.position = 0;
    }
    randomItem = this.history[this.position++];
  }
  
  var replaceContent = function(newtext,parent) {
    if (parent.enableTransitions) {
      if (parent.enableTransitionIndicator) {
        parent.transIndicator.style.display = 'block';
      }
      parent.firstDiv.style.display = 'block';
      parent.firstDiv.innerHTML = newtext;
      parent.firstDiv.style.height = parent.parentDiv.getHeight() + 'px';
      parent.firstDiv.style.width = parent.parentDiv.getWidth() + 'px';
      new Effect.Parallel([
			   new Effect.Opacity(parent.firstDivName, {sync: true, from: 0, to: 1}),
			   new Effect.Opacity(parent.secondDivName, {sync: true, from: 1, to: 0})
			   
			   ], {duration: parent.transitionTime, afterFinish: function() {
			      parent.secondDiv.innerHTML = newtext;
			      parent.secondDiv.style.opacity = 1; //Firefox / Safari
			      parent.secondDiv.style.filter = "alpha(opacity=100)"; //IE
			      parent.firstDiv.style.opacity = 0; //Firefox / Safari
			      parent.firstDiv.style.filter = "alpha(opacity=0)"; //IE
			      parent.firstDiv.style.display = "none";
			      parent.inTransition = false;
			      parent.transIndicator.style.display="none";
			    }});
    }
    else {
      parent.secondDiv.innerHTML = newtext;
      parent.inTransition = false;
    }
  };
  
  if (! this.cache[randomItem]) { // add query items to a new request
    var request = this.contentSourceURL + '/getIntervalItem?dt=' + (this.displayTitle?true:'') + '&dcd=' + (this.displayContentDescription?true:'') + '&item_path=' + encodeURIComponent(randomItem);
    var p = this;
    new Ajax.Request(request,
		     {method: "get",
			 onSuccess: function(xmlhttp) {
			 replaceContent(xmlhttp.responseText,p);
			 p.cache[randomItem] = xmlhttp.responseText;
		       },
			 onFailure: function(xmlhttp) { clearInterval(p.interval); this.inTransition = false; },
			 onException: function(req, exc) { this.inTransition = false; throw exc; } 
		     });
    
  }
  else {
    var ct = this.cache[randomItem];
    /* our portal post-processes content for cleanup prior to inserting it into the page.  This post-processing creates issues with '<'s in javascript strings, so they are replaced.  Replace those back here.  Also, the ampersand is converted to &amp;, so any character entities are double-encoded, like &amp;quot;, so fix those too  The & problem is actually in the @@luminis view of LuminisChannelFolder, but I don't want to look into it.*/
    ct = ct.replace(/\|lt\|/g,String.fromCharCode(60));
    ct = ct.replace(/\|gt\|/g,String.fromCharCode(62));
    ct = ct.replace(/\\x26amp;([\w]*;)/g,'\\x26$1');
    replaceContent(ct,this);
  }
}

/*
  Method which stops the interval, and changes the pause control to a play control.
*/
RandomContentSource.prototype.pausePlayItem = function() {
  if (!this.inTransition) { // actions are disabled during transitions
    if (this.isPaused) { /* resume playback */
      /* just in case there is an active interval ... */
      clearInterval(this.interval);
      this.interval = setInterval("randomContent" + this.id + ".swap()", this.time);
      this.pauseButton.src = this.pauseButtonSrc;
      this.pauseButton.alt = "Pause";
      this.pauseButton.title = "Pause";
      this.isPaused = false;
    } else { /* pause playback */
      clearInterval(this.interval);
      this.pauseButton.src = this.playButtonSrc;
      this.pauseButton.alt = "Play";
      this.pauseButton.title = "Play";
      this.isPaused = true;
    }
  }
}

/*
  Method which resets the interval, and immediately shows the next item in line.
*/
RandomContentSource.prototype.nextItem = function() {
  if (!this.inTransition && !this.isPaused) { // actions are disabled during transitions
    clearInterval(this.interval);
    this.swap();
    this.interval = setInterval("randomContent" + this.id + ".swap()", this.time);
  }
}
  
/*
  Method which resets the interval, and immediately shows the item that came before the current one.
cs*/
RandomContentSource.prototype.previousItem = function() {
  if (!this.inTransition && !this.isPaused) { // actions are disabled during transitions
    clearInterval(this.interval);
    
    if (this.position == 0) {
      this.position = this.history.length - 2;
    }
    else if (this.position == 1) {
      this.position = this.history.length - 1;
    }
    else {
      this.position -= 2;
    }
    
    this.swap();
    this.interval = setInterval("randomContent" + this.id + ".swap()", this.time);
  }
}


