﻿

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 = this.cleanupData(data); //reference to
    if (!this.data.length) return; // interrupt if no data after clean up
    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);
    }
}

PhotoPlayerObj.prototype.cleanupData = function(data) {
    var mydata = [];
    for (var i = 0, j = data.length; i < j; i++) {
        if (!data[i].Display.display && !data[i].Display.background) continue;
        mydata.push(data[i]);
    }
    return mydata;
}

//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 || data.display != '') { //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 && data.background != '') { //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;
	}


	if (this.data[this.index]['Display'].background != null && this.data[this.index]['Display'].background != '') {
		// 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;
}

