﻿

function createMethodReference(obj, methodName){
  return function(){obj[methodName]();}
};

PhotoPlayerObj = function(ppdiv, autoplay, delay ,data)
{
  this.div = document.getElementById(ppdiv); //keep a reference to the player div
  this.data = data; //reference to 
  this.playerobj = this; //reference itself for IE (which sucks);
  this.thumbs = new Array(); //array to hold image thumb objects

  this.direction = 1; //forward=1 or reverse=-1
  this.state = autoplay; // 0 = stop, 1 = forward
  this.timer = 0; // holds pointer to timer 
  if (delay == 0) {
    this.delay = 3000; // time between image flips
  } else {
    this.delay = delay * 1000;
  }
  this.index = -1; //current image being displayed
  this.fadeeffect = createMethodReference(this, 'fader');
  this.fadepercent = 0; // tracks how far it has faded
  this.fadestate = 0; //fading in or out
  this.intransition = 0; //check to see if its already in transition before starting a new one
  this.paused = false; //check if the player is paused by mouse over (not play pause)
  this.nodes = new Array();
  if (this.scanfornodes(this.div) == false) { //check if the viewer is supplied
    alert("No viewer has been defined");
    return;
  }

  //check for special nodes
  if (this.nodes['PP-Play']) {
    this.nodes['PP-Play'].onclick = this.playClick;
    this.nodes['PP-Play'].onmouseover = this.mouseOver;
    this.nodes['PP-Play'].onmouseout = this.mouseOut;
  }
  if (this.nodes['PP-Prev']) {
    this.nodes['PP-Prev'].onclick = this.prevClick;
    this.nodes['PP-Prev'].onmouseover = this.mouseOver;
    this.nodes['PP-Prev'].onmouseout = this.mouseOut;
  }
  if (this.nodes['PP-Next']) {
    this.nodes['PP-Next'].onclick = this.nextClick;
    this.nodes['PP-Next'].onmouseover = this.mouseOver;
    this.nodes['PP-Next'].onmouseout = this.mouseOut;
  }

  if (this.nodes['PP-Thumbs'] && this.data.length > 1) {
    var thumbobj;
    //spit out a thumbnail for each image in the lineup
    for (var i=0;i<this.data.length;i++) {
      thumbobj = document.createElement('div');
      thumbobj.index = i;
      thumbobj.className = "imgthumb";
      thumbobj.onmouseover = this.mouseOver;
      thumbobj.onmouseout = this.mouseOut;
      thumbobj.onclick = this.thumbClick;
      thumbobj.playerobj = this;

      //if nothing is specified for the thumbnail then use the index
      if (this.data[i]['Thumbnail']) {
        //they can set an image and/or text (or any other properties?)
        this.setDivData(thumbobj, this.data[i]['Thumbnail']);
      } else {
        thumbobj.innerHTML = i + 1;
      }
      this.thumbs[this.thumbs.length] = thumbobj;
      this.nodes['PP-Thumbs'].appendChild(thumbobj);
    }
    this.nodes['PP-Thumbs'].style.display = "block"; //ie sucks, wont draw unless you do this

    //get width of second item in the thumbnail list (assume border, padding and margin go all around)
    var thumbwidth = parseInt(this.cascadedstyle(this.nodes['PP-Thumbs'].childNodes[1], 'width', 'width'));
    var margin = parseInt(this.cascadedstyle(this.nodes['PP-Thumbs'].childNodes[1], 'margin', 'margin-left'));
    if (isNaN(margin)) { margin = 0; }
    var padding = parseInt(this.cascadedstyle(this.nodes['PP-Thumbs'].childNodes[1], 'padding', 'padding-left'));
    if (isNaN(padding)) { padding = 0; }
    var border = parseInt(this.cascadedstyle(this.nodes['PP-Thumbs'].childNodes[1], 'borderWidth', 'borderLeftWidth'));
    if (isNaN(border)) { border = 0; }
    this.thumbnailSize = thumbwidth + margin * 2 + padding * 2 + border * 2;
    this.thumbholderSize = parseInt(this.cascadedstyle(this.nodes['PP-ThumbHolder'], 'width', 'width')); //display container for thumbnails
    this.nodes['PP-Thumbs'].style.width = this.thumbnailSize * this.data.length + 2 + "px"; // IE needs extra pixels or it wraps
    this.thumbsSize = this.thumbnailSize * this.data.length; //container that holds all thumbnails
    this.thumbspots = Math.floor(this.thumbholderSize / this.thumbnailSize); //number of thumbnails we can show in given space
  }
      
  //do initial setup of player using first item
  this.switchto(0);
  if (this.state && this.data.length > 1) { //start timer for next image switch if the state is 1 and there are more than 1 images
    this.addClass(this.playerobj.nodes['PP-Play'], "PP-Pause");
    this.removeClass(this.playerobj.nodes['PP-Play'], "PP-Play");
    this.timer = setTimeout(createMethodReference(this,'run'), this.delay);
  }
}

//scan the html for anything that has a classname starting with PP- return true if anything was found
PhotoPlayerObj.prototype.scanfornodes=function(node)
{
  var found = false;
  var cname;
  
  for (var i=0;i<node.childNodes.length;i++) {
    this.scanfornodes(node.childNodes[i]);
    if (node.childNodes[i].className && node.childNodes[i].className.indexOf("PP-") == 0) {
    
       //check if this node should be hidden when there is only one picture
      if (node.childNodes[i].className.indexOf("hideifsingle") != -1 && this.data.length < 2) {
        node.childNodes[i].style.display = "none";
      } else {
        cname = node.childNodes[i].className.split(" ");
        this.nodes[cname[0]] = node.childNodes[i];
        this.nodes[cname[0]].playerobj = this; //make sure they have a reference back to the playerobj
        found = true;
      }
    }
  }
  return found;
}

//switch to item at X (position in index)
PhotoPlayerObj.prototype.switchto=function(position)
{
  if (position < 0) { position = 0; }
  if (position >= this.data.length) { position = this.data.length -1; }

  for (node in this.nodes) {
    var key = node.substring(3); //skip the PP- to get key
    if (this.data[position][key]) { //check if the key exists in the data provided
      this.setDivData(this.nodes[node], this.data[position][key]);
    }
  }
  if (this.thumbs[position]) {
    this.thumbs[position].className='imgthumbon';
  }
  this.index = position;
  
  //set slidebar position  
  if (this.nodes['PP-ThumbHolder'] != null && this.nodes['PP-Thumbs'] != null) {
      var pos = Math.floor(this.index / this.thumbspots);

    var offset = (this.thumbholderSize + 1) * pos;
    if (offset + this.thumbholderSize > this.thumbsSize) {
      offset = (this.thumbholderSize) * (pos - 1) + (this.thumbsSize % this.thumbholderSize);
    }
    this.nodes['PP-Thumbs'].style.left = -offset + "px";
  }
}


//pull style sheet properties
PhotoPlayerObj.prototype.cascadedstyle = function(el, cssproperty, csspropertyNS){
  if (el.currentStyle) {
    return el.currentStyle[cssproperty];
  } else if (window.getComputedStyle){
    var elstyle=window.getComputedStyle(el, "");
    if (elstyle[csspropertyNS]) {
      return elstyle[csspropertyNS];
    }
    return elstyle.getPropertyValue(csspropertyNS);
  }
}

//set div with given data
PhotoPlayerObj.prototype.setDivData=function(node, data)
{
   if (data.display != null) { //if display was specified set innerHTML to that
     node.innerHTML = this.xmldecode(data.display);
   }
     if (data.onclick != null) { //if onclick was specified set it
       if (typeof(data.onclick) == "function") {
         node.onclick = data.onclick;
       } else {
         node.onclick = function() { eval(data.onclick) };
       }  
     }
     if (data.onload != null) { //if onload was specified run it
       if (typeof(data.onload) == "function") {
         data.onload();
       } else {
         eval(data.onload);
       }  
     }
     if (data.onmouseover != null) { //if onmouseover was specified set it
       if (typeof(data.onmouseover) == "function") {
         node.onmouseover = data.onmouseover;
       } else {
         node.onmouseover = function() { eval(data.onmouseover) };
       }     
     } else {
       node.onmouseover = this.mouseOver;
     }
     if (data.onmouseout != null) { //if onmouseout was specified set it
       if (typeof(data.onmouseout) == "function") {
         node.onmouseout = data.onmouseout;
       } else {
         node.onmouseout = function() { eval(data.onmouseout) };
       }
     } else {
       node.onmouseout = this.mouseOut;
     }
   if (data.background != null) { //if background was specified set it
     node.style.backgroundImage = "url("+ data.background + ")";
   }
}

PhotoPlayerObj.prototype.mouseOver=function()
{
  this.playerobj.addClass(this, "PP-mouseover");
}

PhotoPlayerObj.prototype.mouseOut=function()
{
  this.playerobj.removeClass(this, "PP-mouseover");
}

PhotoPlayerObj.prototype.thumbClick=function()
{
  if (this.playerobj.index == this.index) {
    return; //already on this image
  }
  if (this.playerobj.index != -1) {
    this.playerobj.thumbs[this.playerobj.index].className='imgthumb';
  }
  this.playerobj.direction = 1;
  this.playerobj.state = 0;
  this.playerobj.removeClass(this.playerobj.nodes['PP-Play'], "PP-Pause");
  this.playerobj.addClass(this.playerobj.nodes['PP-Play'], "PP-Play");
  this.playerobj.index = this.index - 1;
  clearTimeout(this.playerobj.timer);
  this.playerobj.startTransition();
}

PhotoPlayerObj.prototype.nextClick=function()
{
  this.playerobj.direction = 1;
  this.playerobj.state = 0;
  clearTimeout(this.playerobj.timer);
  this.playerobj.startTransition();
}

PhotoPlayerObj.prototype.prevClick=function()
{
  this.playerobj.direction = -1;
  this.playerobj.state = 0;
  clearTimeout(this.playerobj.timer);
  this.playerobj.startTransition();
}

PhotoPlayerObj.prototype.playClick=function()
{
  if (this.playerobj.state) {
    clearTimeout(this.playerobj.timer);
    this.playerobj.state = 0;
    this.playerobj.removeClass(this, "PP-Pause");
    this.playerobj.addClass(this, "PP-Play");
  } else {
    this.playerobj.direction = 1;
    this.playerobj.state = 1;
    this.playerobj.removeClass(this, "PP-Play");
    this.playerobj.addClass(this, "PP-Pause");
    this.playerobj.timer = setTimeout(createMethodReference(this.playerobj,'run'), this.delay);
  }
}

//used for mouse over to stop timer so image doesnt change (if playing)
PhotoPlayerObj.prototype.pauseClick=function()
{
   clearTimeout(this.playerobj.timer);
   this.playerobj.paused = true;
}

//used for mouse over to start timer so image doesnt change (if playing)
PhotoPlayerObj.prototype.resumeClick=function()
{
   if (this.playerobj.state) {
     this.timer = setTimeout(createMethodReference(this,'run'), this.delay);
   }
   this.playerobj.paused = false;
}

PhotoPlayerObj.prototype.run=function()
{
  this.startTransition();
}

PhotoPlayerObj.prototype.startTransition=function()
{
  if (this.paused) { return; } // if paused then dont do anything
  
  //check if we are already in transition
  clearTimeout(this.transitiontimer);
  if (this.intransition) {
      this.transitiontimer = setTimeout(createMethodReference(this,'startTransition'), 100);
      return;
  }
  this.intransition = 1;
  
  if (this.index != -1 && this.thumbs[this.index]) {
    this.thumbs[this.index].className='imgthumb';
  }
  this.index = this.index + this.direction;
  if (this.index >= this.data.length) {
    this.index = 0;
  }
  if (this.index < 0) {
    this.index = this.data.length - 1;
  }
  //set the new one to on
  if (this.index != -1 && this.thumbs[this.index]) {
    this.thumbs[this.index].className='imgthumbon';
  }
  
  if (!this.nodes['PP-Display']) { //if its not defined then dont bother with the fader
      this.endTransition();
      return;
  }
  
  // create the transition div and add it to the page
  var transitiondiv = document.createElement('div');
  transitiondiv.className = "PP-Display";
  transitiondiv.playerobj = this;
  transitiondiv.zIndex = 20;  //display div is set to zindex of 10 so this is below
  this.setDivData(transitiondiv, this.data[this.index]['Display']); //fill in the data
  this.setOpacity(transitiondiv, 0); //make sure it starts off see through
  this.nodes['PP-Transition'] = transitiondiv; //insert it into the node list
  this.nodes['PP-Display'].parentNode.insertBefore(transitiondiv, this.nodes['PP-Display']); //insert it into the page
  this.fade(0);
}

PhotoPlayerObj.prototype.endTransition=function()
{
  this.intransition = 0; //transition is finished, let start transition run again
  if (this.state) { //start timer for next image switch
    this.timer = setTimeout(createMethodReference(this,'run'), this.delay);
  }
  if (this.nodes['PP-Display']) {
    this.nodes['PP-Display'].parentNode.removeChild(this.nodes['PP-Display']); //remove the current display div from the page
    delete this.nodes['PP-Display']; //remove it from the list
    this.switchto(this.index); //set all other fields in the display
    this.nodes['PP-Display'] = this.nodes['PP-Transition']; //point display  to transition div
    this.nodes['PP-Display'].zIndex = 10; //set zindex on display
    delete this.nodes['PP-Transition']; //clear transition div
  }
}

PhotoPlayerObj.prototype.show = function(node)
{
   this.nodes[node].style.display = 'block';
}

PhotoPlayerObj.prototype.hide = function(node)
{
   this.nodes[node].style.display = 'none';
}

PhotoPlayerObj.prototype.fade = function(state)
{
  this.fadepercent = (state) ? 0:100;
  this.fadestate = state;
//  this.fader();
  this.interval = setInterval(this.fadeeffect, 100);
}

PhotoPlayerObj.prototype.fader = function()
{
  if (this.fadepercent <= 0) {
    clearInterval(this.interval); //stop the next tick from happening
    this.endTransition();
    return;
  } else {
    this.fadepercent -= 10;
  }

  this.setOpacity(this.nodes['PP-Transition'], 100-this.fadepercent);
  this.setOpacity(this.nodes['PP-Display'], this.fadepercent);
}

PhotoPlayerObj.prototype.setOpacity = function(node, percent)
{
  if (typeof(node) == "string") {
     node = this.nodes[node]; // if they passed a name then find the node
  }
  node.style.opacity = percent/100;
  node.style.MozOpacity = percent/100;
  node.style.KhtmlOpacity = percent/100;
  node.style.filter = "alpha(opacity=" + percent + ")";
}

PhotoPlayerObj.prototype.xmldecode = function(xmldata)
{
  xmldata = xmldata.replace(/&quot;/g, "\"");
  xmldata = xmldata.replace(/&lt;/g, "<");
  xmldata = xmldata.replace(/&gt;/g, ">");
  xmldata = xmldata.replace(/&amp;/g, "&");

  return xmldata;
}

PhotoPlayerObj.prototype.removeClass = function(el, className) {
        if (typeof(el) == "string") {
          el = this.nodes[el]; // if they passed a name then find the node
        }
        if (!(el && el.className)) {
                return;
        }
        var cls = el.className.split(" ");
        var ar = new Array();
        var found = false;
        for (var i = cls.length; i > 0;) {
                if (cls[--i] != className) {
                        ar[ar.length] = cls[i];
                } else {
                  found = true;
                }
        }
        el.className = ar.join(" ");
        return found;
}

PhotoPlayerObj.prototype.addClass = function(el, className) {
  if (typeof(el) == "string") {
    el = this.nodes[el]; // if they passed a name then find the node
  }
  if (!(el && el.className)) {
    return;
  }
  this.removeClass(el, className);
  el.className += " " + className;
}

PhotoPlayerObj.prototype.mouseLeaves = function (element,evt) {
  if(!evt) {evt = window.event; }
  if (typeof evt.toElement != 'undefined' && typeof element.contains != 'undefined') {
    return !element.contains(evt.toElement);
  }
  else if (typeof evt.relatedTarget != 'undefined' && evt.relatedTarget) {
    return !this.contains(element, evt.relatedTarget);
  }
}    
 
PhotoPlayerObj.prototype.contains = function (container, containee) {
  while (containee) {
    if (container == containee) {
      return true;
    }
    containee = containee.parentNode;
  }
  return false;
}

