
/*
 *	accordion_01.js
 *
 *	3/11/10
 *	
 *	Revised by Brian Sinnett for Ontash & Ermac
 *
 *	All rights reserved, (c) 2010
 *
 *	Revised to work with URL activation script (accActivate_01.js)
 *	This revision allows the activation script to override the 
 *	default behavior of the method clickFunction() when the panel
 *	is already open. See comments below for notes on revisions.
 *
 *	Enabled cookies for all types of accordions, 3/11/10, Brian Sinnett
 *
 */

AccordionPanel.prototype = new Object();
AccordionPanel.prototype.constructor = AccordionPanel;

AccordionPanel.prototype.slideFunction = function(duration, height, callback) {
  var _this = this;
  
  var post_animate = function() {
    if (_this.last == true && _this.open == false)
      _this.content.css("border-top", "none");
    
    if (typeof(callback) == "function")
      callback();
  };
  
  this.content.stop();
  if (duration <= 0) {
    this.content.css({
      height: height
    });
    post_animate();
  } else {
    this.content.animate(
      {height: height},
      duration,
      post_animate
    );
  }
};

/*
 *	clickFunction()
 *
 *	@overRide - boolean
 *	When this param is true, it overrides the default behavior
 *	of this function, allowing an activating URL query string to
 *	set the open panel even when it's already set as open (e.g.,
 *	by the cookie).
 *
 */

AccordionPanel.prototype.clickFunction = function( overRide ) {
  if (this.content == null)
    return;
  
  var _this = this;
  var duration, height;

  if (this.open == true && overRide === true) {
	return;
  }
  else if (this.open == true) {
    this.container.removeClass("open");
    this.open = false;
    height = 0;
    duration = Accordion.animationDuration * (this.content.innerHeight() / this.height);
  } else {
    // Close any open panels
    var highestClosedPanel = this.parent.panels.length;
    var panelsToClose = new Array();
    for (var i=0; i<this.parent.panels.length; i++) {
      var panel = this.parent.panels[i];
      if (panel.index == this.index)
        continue;
      
      if (panel.open == true) {
        panelsToClose.push(panel);
        
        if (i < highestClosedPanel)
          highestClosedPanel = i;
      }
    }
    
    if (panelsToClose.length > 0) {
      // Asset accordions are short, so we do the close & open animations at the same time.
      // Other accordion types are generally huge, which causes a confusing amount of choppy animation
      // if we attempt to do this - our solution is to instantly close any open panels, and if doing so causes the
      // opening panel to shift offscreen, scroll to the position of it before performing the open animation.
      if (this.parent.simultaneous_open_and_close) {
        // Close the necessary panels
        for (var i=0; i<panelsToClose.length; i++) {
          var panel = panelsToClose[i];
          panel.container.removeClass("open");
          panel.open = false;
          panel.slideFunction(Accordion.animationDuration * (panel.content.innerHeight() / panel.height), 0);
        }
      } else {
        // Fix accordion container height so that the scroll bar reappearing doesn't cause the page to jitter
        // Note: IE7 doesn't handle this properly
        if (!UIUtilities.BrowserIsIE7) {
          this.container.parent().css({
            height: this.container.parent().innerHeight(),
            overflow: "hidden"
          });
        }
        
        // Close the necessary panels
        for (var i=0; i<panelsToClose.length; i++) {
          var panel = panelsToClose[i];
          panel.container.removeClass("open");
          panel.open = false;
          //panel.slideFunction(Accordion.animationDuration * (panel.content.innerHeight() / panel.height), 0);
          panel.slideFunction(0, 0);
        }
        
        // Scroll to the location of this panel if necessary
        if (highestClosedPanel < this.index)
          $(window).scrollTop(this.container.offset().top - 20);
      }
    }
    
    // Recalculate panel height in case it's changed (for example, if the child image's drop shadow hadn't been
    // generated previous to the initialization of this accordion panel
    if (this.container.parent().hasClass("asset-accordion")) {
      var height_left = this.content.find(".slide-left").innerHeight();
      var height_right = this.content.find(".slide-right").innerHeight();
      this.height = (height_left > height_right) ? height_left : height_right;
    }
    
    this.container.addClass("open");
    this.open = true;
    height = this.height;
    duration = Accordion.animationDuration * ((height - this.content.innerHeight()) / height);
    
    if (this.last == true) {
      if (this.container.parent().hasClass("asset-accordion"))
        height -= 1;
      
      this.content.css("border-top-style", this.content.data("border-top-style"));
      this.content.css("border-top-color", this.content.data("border-top-color"));
      this.content.css("border-top-width", this.content.data("border-top-width"));
    }
  }
  
	// Enabled cookies for all accordion types by disabling test below
	// Brian Sinnett, 3/11/10

  //if (this.container.parent().hasClass("asset-accordion")==false && this.container.parent().hasClass("convergence-accordion")==false) {
    //Accordion.updateAccordionCookie();
  //}

  // Update cookie
  Accordion.updateAccordionCookie();
  
  // Perform slide
  this.slideFunction(duration, height, function () {
    // Fix accordion container height so that the scroll bar reappearing doesn't cause the page to jitter
    _this.container.parent().css({
      height: "auto",
      overflow: "visible"
    });

    // If this is the Convergence accordion, trigger the Flash animation
    if (_this.container.parent().hasClass("convergence-accordion")==true) {
		
		var newID = _this.index+1;
		
		if (newID == ecosystemID) {
			ecosystemID = 0;
		} else {
			ecosystemID = newID;
		}
		_this.goToSection(ecosystemID);
	}
  });
};

AccordionPanel.prototype.mouseenterFunction = function() {
  if (this.header != null)
    this.header.addClass("hover");
};

AccordionPanel.prototype.mouseleaveFunction = function() {
  if (this.header != null)
    this.header.removeClass("hover");
};

AccordionPanel.prototype.setOpenStatus = function(open) {
  this.open = open;
  if (this.container == null || this.content == null)
    return;
  
  if (this.open == true) {
    this.container.addClass("open");
    if (this.last && this.container.parent().hasClass("asset-accordion"))
      this.content.css("height", this.content.innerHeight()-1);
  } else {
    this.content.css({
      height: 0
    });
    if (this.last)
      this.content.css("border-top", "none");
  }
};

AccordionPanel.prototype.goToSection = function(sectionID) {
  if (sectionID==0) {
	$("#convergence-accordion-intro").show('slow');
  } else {
	$("#convergence-accordion-intro").hide('slow');
  }
  var flashMovie = document.getElementById("convergence-ei");
  flashMovie.goToSection(sectionID);
};


function AccordionPanel(parent, container, index, last) {
  var _this = this;
  this.parent = parent;
  this.index = index;
  this.container = container;
  this.last = last;
  this.open = false;
  this.height = 0;
  
  if (this.container == null)
    return;
  
  // Get references to DOM elements
  this.header = this.container.children("dt");
  if (this.header.length <= 0)
    this.header = null;
  
  this.content = this.container.children("dd");
  if (this.content.length <= 0) {
    this.content = null;
    return;
  } else {
    this.height = this.content.innerHeight();
  }
  
  this.slide = this.content.find(".slide");
  
  // Move content elements into a div - IE7 has issues with divs of height=0
  // containing elements that have padding assigned to them; it causes the
  // containing div to never fully reach 0px
  var slide_div = $("<div></div>");
  slide_div.append(this.content.children());
  this.content.append(slide_div);
  
  // Prep for style changes based on whether this is the last item in the list
  // of panels
  if (this.last == true && this.content != null) {
    this.content.data("border-top-style", this.content.css("border-top-style"));
    this.content.data("border-top-color", this.content.css("border-top-color"));
    this.content.data("border-top-width", this.content.css("border-top-width"));
  }
  
  // Set up click events
  if (this.header != null) {
    this.header.click(function() {_this.clickFunction( false );});
//    header.dblclick(function() {_this.click_function();});
    this.header.mouseenter(function() {_this.mouseenterFunction();});
    this.header.mouseleave(function() {_this.mouseleaveFunction();});
  }
};

// Right now this assumes one accordion per page; it could be
// restructured to support multiple groups
var Accordion = {
  panels: new Array(),
  cookie: new NameValuePairCookie("accordionStatus"),
  animationDuration: 500,
  simultaneous_open_and_close: true,
  
  init: function() {
    // Get references to all panels on the page
    var panel_elems = $(".accordion > dl");
    var open_first_panel_by_default = true;
    if (panel_elems.length > 0) {
      var parent = $(panel_elems[0]).parent();
      if (parent.hasClass("convergence-accordion"))
        open_first_panel_by_default = false;
      if (parent.hasClass("closed-accordion"))
        open_first_panel_by_default = false;
      else if (parent.hasClass("featurette-accordion"))
        this.simultaneous_open_and_close = false;
    }
    
    // Load status from cookie, if available
    var status = null;
    var cookieValue = this.cookie.getValue(window.location.pathname);
    if (cookieValue != null)
      status = cookieValue.split(",");
    
    // Loop through all of the panels elements found on the page and create
    // associated AccordionPanel objects
    for (var i=0; i<panel_elems.length; i++) {
      var panel = new AccordionPanel(
        this,                         // Parent accordion object
        $(panel_elems[i]),            // Container element
        i,                            // Index
        (i == panel_elems.length - 1) // Last in list of siblings
      );
      
      // Set panel to open status if it's first in the panel list and if
      // the cookie has not yet been created; otherwise use the settings
      // found in the cookie
      // The Convergence accordion should always begin with all elements closed
	    var open = false;

	    if (status == null) {
	      // Don't open the first panel by default unless this is
	      // a convergance accordion
		    if (i == 0 && open_first_panel_by_default)
		      open = true;
	    } else {
		    for (var j=0; j<status.length; j++) {
		      if (status[j] == i) {
			    open = true;
			    break;
		      }
		    }
	    }
	    panel.setOpenStatus(open);
      
      // Append panel to our list
      this.panels.push(panel);
    }
  },
  
  updateAccordionCookie: function() {
    var cookieValue = "";
    for (var i=0; i<this.panels.length; i++) {
      var panel = this.panels[i];
      if (panel.content.length > 0) {
        if (panel.open == true) {
          if (cookieValue.length > 0)
            cookieValue += ",";
          
          cookieValue += panel.index;
        }
      }
    }
    
    this.cookie.setValue(window.location.pathname, cookieValue.length <= 0 ? "-1" : cookieValue);
    this.cookie.save(null);
  }
};

