// Slide Gallery : May 2007
// An improved, OO version of gallery.js

// this file contains definitions for:
//  SlideGallery
//  SlideTray
var DIR_LEFT  = "left";
var DIR_RIGHT = "right";

var EVENT_OVER = "over";
var EVENT_OUT = "out";


/* ############################################### */
/* SLIDE GALLERY (projector) DEFINITION            */



// SlideGallery
//  Object constructor
function SlideGallery() {
}


/*
  class vars
*/
// these items keep track of our slide trays
SlideGallery.slideTrayArray = new Array();
SlideGallery.slideTrayDict = new Object();

SlideGallery.selected_tray = null;       // object reference
SlideGallery.selected_slide = null;      // object reference
SlideGallery.selected_category = "";     // string

// these items are references to the HTML DOM structure
SlideGallery.ssEngine = null;
SlideGallery.ssCaboose = null;
SlideGallery.displayArea = null; //the projector wall
SlideGallery.categoryButtonArea = null;
SlideGallery.leftArrowImg = null;
SlideGallery.rightArrowImg = null;

SlideGallery.arrowImages = null;  // arrowImages.(left|right).(over|off|disabled)

// slide motion vars
SlideGallery.isSliding = false;
SlideGallery.existentialWidth = 0;
SlideGallery.slideIncrement = 5;
if(navigator.userAgent.indexOf("Safari") != -1) SlideGallery.slideIncrement = 15; //Safari is slow

// these items used to be constants
SlideGallery.thumbWidth = 157; //CONST_IMG_WIDTH
SlideGallery.thumbHeight = 90; //CONST_IMG_HEIGHT
SlideGallery.space = 2; //CONST_SPACE ... is this even used?
SlideGallery.minimumSlides = 6; //SLIDE_MIN

/** Call reset if you want to reuse the singleton for another gallery.
 *  See evo.insider.index.content.jsp
 */
SlideGallery.reset = function() {
  this.slideTrayArray = new Array();
  this.slideTrayDict = new Object();
  this.selected_category = "";
  var categoryButtonArea = document.getElementById("categoryButtonArea");
  if (categoryButtonArea) {
    while (categoryButtonArea.childNodes.length > 0)
      categoryButtonArea.removeChild(categoryButtonArea.childNodes[0]);
  }
}
// toString()
SlideGallery.toString = function() {
  return "Slide Gallery";
}

// getSelectedTray()
SlideGallery.getSelectedTray = function() {
  return this.selected_tray;
}

// getSelectedSlide()
SlideGallery.getSelectedSlide = function() {
  return this.selected_slide;
}

// getTrayByCategory()
//   return tray by category, or null if not found
SlideGallery.getTrayByCategory = function(category) {
  var tray = null;
  try {
    tray = this.slideTrayDict[category];
  } catch(e) { alert('couldnt find category tray: ' + category); }
  return tray;
}


SlideGallery.setOnUnload = function() {
  //window.onunload = this.omnitureOnUnload;
}

SlideGallery.omnitureOnUnload = function() {
  var msg = "clicks on images:\n";
  for (var i=0; i<this.slideTrayArray.length; i++) {
    var trayCat = this.slideTrayArray[i].getCategory();
    var trayCnt = this.slideTrayArray[i].getOmnitureData('count');
    msg += trayCat + " - " + trayCnt + " images\n";

  }
  alert(msg);
}

// init()
//   initalize gallery structure, trays, etc
//
SlideGallery.init = function() {

  this.ssEngine = document.getElementById("exteriorSlideshowEngine");
  this.ssCaboose = document.getElementById("exteriorSlideshowCaboose");
  this.displayArea = document.getElementById("displayArea");
  this.categoryButtonArea = document.getElementById("categoryButtonArea");
  this.leftArrowImg = document.getElementById("leftArrowImage");
  this.rightArrowImg = document.getElementById("rightArrowImage");

  this.initCategoryButtons();

  // select default tray, but first check if the page has been bookmarked
  //  if so, use that as default.
  var defaultTrayCategory = this.slideTrayArray[0].getCategory();
  var location = document.location.toString();
  var do_deeplink = 'off';

  if(location.indexOf("#") != -1) {
    var temp = location.substr(location.indexOf("#") + 1);
    var tray = this.getTrayByCategory(temp);
    if(tray != null) {
      defaultTrayCategory = temp;
    } else {
      // if bookmark is wrong, replace with correct one
      do_deeplink = 'on';
    }
  }

  this.setOnUnload();

  // selectCategory() has to be the last thing called
  this.selectCategory(defaultTrayCategory, {deeplink:do_deeplink});
}


// initCategoryButtons()
//
SlideGallery.initCategoryButtons = function() {

  var sTAL = this.slideTrayArray.length - 1;
  var btnConstructWidth = null;
  //loop through once to determine the width of the total
  //button construct
  for (i=sTAL; i>= 0; i--) {
    var looptray = this.slideTrayArray[i];
  	btnConstructWidth += looptray.getButtonWidth() + 20
  }

  var width = (994/2) + (btnConstructWidth/2);  // width of button area

  // don't display just a single tray button
  if (sTAL == 0)
  	return;
  // initialize tray category buttons
  for (i=sTAL; i>= 0; i--) {

    var tray = this.slideTrayArray[i];
    var trayCat = tray.getCategory();

    // we are setting this as an attribute on the object ourselves.
    // tray obj doesn't know anything about it.
    var left = width - tray.getButtonWidth() - 20;
	width -= tray.getButtonWidth() + 20;

    var trayButton = SlideGallery.createButtonNode(tray, left);
    this.categoryButtonArea.appendChild(trayButton);

  }

}


// createButtonNode()
//   create node using DOM
//   need to get at <IMG> node
SlideGallery.createButtonNode = function(tray, left) {

  var tPos = tray.position;
  var tCat = tray.getCategory();
  var tSrc = tray.getButtonImagePath('off');


  var d = document.createElement('div');
  d.setAttribute('id', tCat);
  d.className = 'categoryButton';
  d.style.left = left + "px";
  d.style.width = 70 + "px";

  var a = document.createElement('a');
  a.setAttribute('href', "javascript:SlideGallery.selectCategory('" + tCat + "')");

  var i = document.createElement('img');
  i.setAttribute('id', 'categoryButtonImg_' + tCat);
  i.setAttribute('src', tSrc);
  i.setAttribute('onmouseover', "SlideGallery.buttonEvent(EVENT_OVER, this, '" + tCat + "')" );
  i.setAttribute('onmouseout', "SlideGallery.buttonEvent(EVENT_OUT, this, '" + tCat + "')");

  // add a button img ref property - Tray doesn't know about this
  tray.buttonImgRef = i;

  d.appendChild(a);
  a.appendChild(i);
  return d;
}



// setDeeplinkURL()
//   create deeplink url for bookmarking
SlideGallery.setDeeplinkURL = function(categoryId) {

  var curUrl = document.location.toString();
  if(curUrl.indexOf("#") != -1) {
    curUrl = curUrl.substr(0, curUrl.indexOf('#'));
  }
  document.location = curUrl + "#" + categoryId;
}

// addTray()
SlideGallery.addTray = function(tray) {

  // add a position property - tray doesn't know about this
  tray.position = this.slideTrayArray.length;

  var id = tray.getCategory();
  this.slideTrayDict[id] = tray;
  this.slideTrayArray.push(tray);
}

// getSlideById()
//   gets slide from active tray
SlideGallery.getSlideById = function(slideId) {
  return this.selected_tray.getSlideById(slideId);
}


// setArrowImages()
//   set images for slide control arrows
SlideGallery.setArrowImages = function(o) {
  // should be:
  // left.on, left.off, right.on, right.off
  this.arrowImages = o;
}

SlideGallery.setThumbAttributes = function(obj){
	this.thumbWidth = obj.thumbWidth;
	this.thumbHeight = obj.thumbHeight;
	this.space = obj.space;
	this.minimumSlides = obj.minimumSlides;
}


// slide()
// timer function used for animation
SlideGallery.slide = function(dir){
  if(dir == DIR_LEFT) {
    //if the engine has not passed all of the way off of the screen, decrement it
    //otherwise set its left equal to its overall width
    if ( parseInt(this.ssEngine.style.left) > (this.existentialWidth * (-1)) ) {
      this.ssEngine.style.left = parseInt(this.ssEngine.style.left)- this.slideIncrement + "px";
    }
    else {
      this.ssEngine.style.left = parseInt(this.ssCaboose.style.left) + this.existentialWidth - this.slideIncrement + "px";

    }

    if ( parseInt(this.ssCaboose.style.left) > (this.existentialWidth * (-1) ) ) {
      this.ssCaboose.style.left = parseInt(this.ssCaboose.style.left) - this.slideIncrement + "px";
    }
    else {
      this.ssCaboose.style.left = parseInt(this.ssEngine.style.left) + this.existentialWidth  + "px";

    }
  }
  else if(dir == DIR_RIGHT) {
    if ( parseInt(this.ssEngine.style.left) < (this.existentialWidth) ) {
      this.ssEngine.style.left = parseInt(this.ssEngine.style.left)+ this.slideIncrement + "px";
    }
    else {
      this.ssEngine.style.left = parseInt(this.ssCaboose.style.left) - this.existentialWidth + this.slideIncrement  + "px";

    }

    if ( parseInt(this.ssCaboose.style.left) < (this.existentialWidth ) ) {
      this.ssCaboose.style.left = parseInt(this.ssCaboose.style.left)+ this.slideIncrement + "px";
    }
    else {
      this.ssCaboose.style.left = parseInt(this.ssEngine.style.left) - this.existentialWidth  + "px";

    }
  }
}

// registerSlideClick()
//   notify omniture of slide click
SlideGallery.registerSlideClick = function() {

  //alert('register click');
  var tray = this.selected_tray;
  tray.incrementOmnitureCount();
  var o_event = tray.getOmnitureData('value');
  bubbleSequentialEvent(" var variables = [ {name: 'events', value: '" + o_event + "'} ]");

}

// registerCategoryClick()
//   notify omniture of category click
SlideGallery.registerCategoryClick = function(category) {

  //alert('register click');
  if (pcode && typeof(s) != "undefined") {

    //have to clear s.pageName temporarily; will be reset
    s.pageName = '';
    bubbleSequentialEvent(" var variables = [ {name: 'pageName', value: '" + (pcode + " - " + category + "Tab") + "'} ]");
  }
}





/* EXTERNAL MOUSE EVENTS */

// slideEvent()
//   mouse over, out on a slide
SlideGallery.slideEvent = function(imageRef, slideId, eventType) {
  var tray = this.getSelectedTray();
  var slide = tray.getSlideById(slideId);

  // TODO: future - replace src change with HTML change
  if(eventType == EVENT_OVER) {
    imageRef.src = slide.getSlideImagePath('on');
  }
  else if(eventType == EVENT_OUT) {
    imageRef.src = slide.getSlideImagePath('off');
  }
}


// buttonEvent()
//   handle events of the category buttons
SlideGallery.buttonEvent = function(eventType, imgTagRef, category) {

  //if the currently selected category != dispType, then allow
  if(SlideGallery.getSelectedTray().getCategory() != category) {
    //get the reference to the tray
    var tray = this.getTrayByCategory(category);

    //mouseover:
    if(EVENT_OVER == eventType) {
      imgTagRef.src = tray.getButtonImagePath("over");
    }
    //mouseout:
    else if(EVENT_OUT == eventType) {
      imgTagRef.src = tray.getButtonImagePath("off");
    }
  }
}

// selectCategory()
//   handle click on category tray button
SlideGallery.selectCategory = function(category, o) {

  if (category == this.selected_category) return;

  // change state of category buttons
  for (var trayIndex in SlideGallery.slideTrayDict) {
    var tray = this.slideTrayDict[trayIndex];
    var trayCat = tray.getCategory();
    var onoff = (category == trayCat) ? "on" : "off";
    if (tray.buttonImgRef)
    	tray.buttonImgRef.src = tray.getButtonImagePath(onoff);
/*
    if (category == trayCat) {
      tray.buttonImgRef.src = tray.getButtonImagePath('on');
    } else {
      tray.buttonImgRef.src = tray.getButtonImagePath('off');
    }
*/  }


  // get selected tray
  var tray = SlideGallery.getTrayByCategory(category);
  this.selected_tray = tray;
  this.selected_category = category;

  // and display slides
  if(this.selected_category == "360"){
  		//alert("you clicked 360");
  		create360(foUrl);
  		
  		//document.getElementById('slides_count').innerHTML = "";
  		var markup = tray.getSlidesDisplay();
	  this.ssEngine.innerHTML = markup;
	  this.ssCaboose.innerHTML = markup;
  		this.registerCategoryClick(category);
  		
  }else{
  		
  		var contr = document.getElementById("scrollContainer");
		//contr.style.top = "367px";  commented out because it caused an issue in evo insider
  
	  var firstSlide = tray.getSlideByIndex(0);
	  this.displaySlide(firstSlide);
	
	  // setup slide action
	  if (tray.getSlideCount() >= this.minimumSlides) {
	    this.existentialWidth = tray.getSlideCount() * this.thumbWidth;
	
	    this.leftArrowImg.src=this.arrowImages.left.off
	    this.rightArrowImg.src=this.arrowImages.right.off;
	  } else {
	    // we want to set full background
	    this.existentialWidth = this.minimumSlides * this.thumbWidth;
	
	    // disable arrows
	    this.leftArrowImg.src=this.arrowImages.left.disabled
	    this.rightArrowImg.src=this.arrowImages.right.disabled;
	
	    // make the background pretty when not full of slides
	    // commented out for evo insider gallery. causes black area when less than 6 images
	    //this.ssEngine.style.backgroundImage = "URL(/MMNA/images/gallery/gallery_bot_bar_gradient.en-us.jpg)";
	  }
	  this.ssEngine.style.height = this.thumbHeight + "px";
	  this.ssCaboose.style.height = this.thumbHeight + "px";
	  this.ssEngine.style.width = this.existentialWidth + "px";
	  this.ssCaboose.style.width = this.existentialWidth + "px";
	  this.ssEngine.style.left = "0px";
	  this.ssCaboose.style.left = parseInt(this.ssEngine.style.left) + this.existentialWidth;
	
	  var markup = tray.getSlidesDisplay();
	  this.ssEngine.innerHTML = markup;
	  this.ssCaboose.innerHTML = markup;
	
	  // set deeplink url
	  if (o == undefined || o != undefined && o.deeplink != 'off') {
	    this.setDeeplinkURL(category);
	  }
	
	  if(document.getElementById('slides_count')) document.getElementById('slides_count').innerHTML = tray.getSlideCount();
	
	  // this needs to be last, nothing else will get called.
	  this.registerCategoryClick(category);
	}
}


// displaySlide()
//   handle click on slide
//   can take either object or slide id
SlideGallery.displaySlide = function(slide) {

  var s_obj = slide;
  var slide_number = 0;
  if (typeof(slide) == 'string') {
    s_obj = this.getSlideById(slide);
	eval('slide_number = '+slide.substring(5)+' + 1;');
  } else {
	slide_number = 1;  
  }
  this.displayArea.style.visibility = "hidden";
  this.displayArea.innerHTML = s_obj.getMainView();
  this.displayArea.style.visibility = "visible";
  if(document.getElementById('slide_number')) document.getElementById('slide_number').innerHTML = slide_number;

  this.registerSlideClick();
}


// moveSlides()
//   takes direction
//   sets up slide motion
SlideGallery.moveSlides = function(dir, imgRef) {

  if (SlideGallery.getSelectedTray().getSlideCount() < this.minimumSlides) {
    return;
  }
  if (dir == DIR_RIGHT) {
    this.leftArrowImg.src=this.arrowImages.left.over;
  } else {
    this.rightArrowImg.src=this.arrowImages.right.over;
  }
  if(! this.isSliding) {
    isSliding = true;
    var funcSignature = "SlideGallery.slide('" + dir + "')";
    _interval = setInterval(funcSignature,30);
  }

}

// clear()
//   clears motion function
//
SlideGallery.clear = function() {
  clearInterval(_interval);
  isSliding = false;
}


// stopSlides()
//   stop slide motion, update UI
SlideGallery.stopSlides = function(imgRef) {

  if (SlideGallery.getSelectedTray().getSlideCount() < this.minimumSlides) {
    return;
  }
  this.leftArrowImg.src=this.arrowImages.left.off;
  this.rightArrowImg.src=this.arrowImages.right.off;
  SlideGallery.clear();
}




/* #################################### */
/* SLIDE TRAY DEFINITION                */


// SlideTray

SlideGallery.createSlideTray = function(o) {
  return SlideTray(o);
}


function SlideTray(o) {

  // these items keep track of our slides
  this.slideArray = new Array();
  this.slideDict = new Object();

  this.category = o.category;  // used for reference, omniture

  // omniture vars
  this.omniture_count = 0;
  this.omniture_key = o.omniture.key;      // eg, "Video Items: "
  this.omniture_value = o.omniture.value;  // eg, "event9"

  // this are image references - for category buttons in slide viewer
  this.dispOff = o.button.off;
  this.dispOn = o.button.on;
  this.dispOver = o.button.over;
  this.en_width = o.en_width;
  this.es_width = o.es_width;

  this.cooked = null;   // pre-rendered HTML markup for all slides in tray
}


// addSlide()
//   add a slide to tray
SlideTray.prototype.addSlide = function(slide) {

  this.cooked = null;  // erase cache because we've added new slide

  var len = this.slideArray.length;
  var id = "slide" + len;    // create id: eg, 'slide9'

  slide.setId(id);
  slide.setPosition(len);

  this.slideArray.push(slide);
  this.slideDict[id] = slide;

}

// getButtonImagePath(state)
//   retrieve button image path given a state
//   states = 'on', 'off', 'over'
SlideTray.prototype.getButtonImagePath = function(state) {
  var img_path = "";
  switch(state) {
    case "on":
      img_path = this.dispOn;
      break;
    case "off":
      img_path = this.dispOff;
      break;
    case "over":
      img_path = this.dispOver;
      break;
    default:
      break;
  }
  return img_path;
}


// getSlideCount()
SlideTray.prototype.getSlideCount = function() {
  return this.slideArray.length;
}

// getCategory()
SlideTray.prototype.getCategory = function() {
  return this.category;
}

// getButtonWidth()
//   get width of button img
//   used to correct for differences in languages, text
SlideTray.prototype.getButtonWidth = function() {
	//alert(altLangCode);
	if (altLangCode == "en") {
		return this.es_width;
	} else {
		return this.en_width;
	}
}


// getSlideById()
//   returns individual slide in a tray given an id
SlideTray.prototype.getSlideById = function(id) {
  return this.slideDict[id];
}

// getSlideByIndex()
//   returns individual slide in a tray given an index
SlideTray.prototype.getSlideByIndex = function(index) {
  return this.slideArray[index];
}

// getOmnitureData()
//   returns omniture data depending on parameter - 'count', 'key', 'value'
SlideTray.prototype.getOmnitureData = function(type) {
  var data = null;
  switch(type) {
    case("count"):
      data = this.omniture_count;
      break;
    case("key"):
      data = this.omniture_key;
      break;
    case("value"):
      data = this.omniture_value;
      break;
    default:
      break;
  }
  return data;
}

// incrementOmnitureCount()
//   increments omniture clicks
SlideTray.prototype.incrementOmnitureCount = function() {
  this.omniture_count += 1;
}

// decrementOmnitureCount()
//   decrements omniture clicks
SlideTray.prototype.decrementOmnitureCount = function() {
  this.omniture_count -= 1;
}


// getSlidesDisplay()
//   returns string of HTML markup for all slides
SlideTray.prototype.getSlidesDisplay = function() {

  if (this.cooked != null) return this.cooked; // if cached

  var markup = "";
  for (i=0; i<this.slideArray.length; i++) {
    var slide = this.slideArray[i];
    markup += slide.getSlideView();
  }
  this.cooked = markup;
  return markup;
}
