/* RG Accordion adapted for PACT project
   by Frank Pennycook -- frank@pennycook.net
*/

window.addEvent( 'domready', function(){
  // for each toggleNest
  $$( '.accordion-set' ).each( function(item){

    var accordContent = item.getElement( '.accordion-content' )

    /* Here is where the toggle behaviour is defined */
    accordContent.fx =
      new Fx.Reveal( accordContent, {duration:500,fps:20,wait:true} );

    /* headings start closed by default */
    var startOpen = false

    /* check if this heading has been linked to specifically */
    var anchorLink = document.getElementById(window.location.hash.substring(1))
    if (anchorLink){
      if (item == anchorLink.nextSibling){
        startOpen = true;
      }
    }

    if (startOpen){
      /* the heading is opened to start with */
      accordContent.fx.directShow();
      item.getElement( '.accordion-heading' ).addClass('open');
    } else {
      /* the heading is closed to start with */
      accordContent.fx.directHide();
      item.getElement( '.accordion-heading' ).addClass('closed');
    }

    item.getElement( '.accordion-heading' ).addEvent( 'click', function(){ 
      accordContent.fx.directToggle(); 
      if (item.getElement( '.accordion-heading' ).hasClass('open')) {
        item.getElement( '.accordion-heading' ).removeClass('open');
        item.getElement( '.accordion-heading' ).addClass('closed');
      } else {
        item.getElement( '.accordion-heading' ).removeClass('closed');
        item.getElement( '.accordion-heading' ).addClass('open');
      }
    });

  });
});


/*
Class: Fx.Reveal
	The reveal effect; reveals an element horizontally or vertically, by showing or hiding the contents.
	Inherits methods, properties, options and events from <Fx.Base>.
	
Note:
	Fx.Reveal requires an XHTML doctype.

Options:
	mode - set it to vertical or horizontal. Defaults to vertical.
	options - all the <Fx.Base> options

Example:
	(start code)
	var myReveal = new Fx.Reveal('myElement', {duration: 500});
	myReveal.toggle() //toggle the reveal on and off.
	(end)
*/

Fx.Reveal = Fx.Base.extend({

	options: {
		mode: 'vertical'
	},

	initialize: function(el, options){
		this.element = $(el);
		this.wrapper = new Element('div', {'class':'accordion-wrapper', 'styles':$extend(this.element.getStyles('margin'), {'overflow': 'hidden'})}).injectAfter(this.element).adopt(this.element);
		this.element.setStyle('margin', 0);
		this.setOptions(options);
		this.now = [];
		this.parent(this.options);
		this.open = true;
		this.addEvent('onComplete', function(){
			this.open = (this.now[0] === 0);
		});
		if (window.webkit419) this.addEvent('onComplete', function(){
			if (this.open) this.element.remove().inject(this.wrapper);
		});
	},

	setNow: function(){
		for (var i = 0; i < 2; i++) this.now[i] = this.compute(this.from[i], this.to[i]);
	},

	vertical: function(){
		this.margin = 'margin-top';
		this.layout = 'height';
		this.offset = this.element.offsetHeight;
	},

	horizontal: function(){
		this.margin = 'margin-left';
		this.layout = 'width';
		this.offset = this.element.offsetWidth;
	},

	/*
	Property: transitionShow
		Reveals the elements in view horizontally or vertically.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	transitionShow: function(mode){
		this[mode || this.options.mode]();
		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [0, this.offset]);
	},

	/*
	Property: transitionHide
		Hides the elements out of view horizontally or vertically.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	transitionHide: function(mode){
		this[mode || this.options.mode]();
		return this.start([this.element.getStyle(this.margin).toInt(), this.wrapper.getStyle(this.layout).toInt()], [-this.offset, 0]);
	},

	/*
	Property: directHide
		Hides the element without a transition.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	directHide: function(mode){
		this[mode || this.options.mode]();
    /* this.set([-this.offset, 0]); */
    this.wrapper.setStyle('overflow','hidden');
    this.element.setStyle('display','none');
		return this.open = false;
	},

	/*
	Property: directShow
		Shows the element without a transition.

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.
	*/

	directShow: function(mode){
		this[mode || this.options.mode]();
		/* this.set([0, this.offset]); */
    this.wrapper.setStyle('overflow','visible');
    this.wrapper.setStyle('height','auto');
    this.element.setStyle('display','block');
		return this.open = true;
	},

	/*
	Property: transitionToggle
		Reveals or hides the element, depending on its state, using the transition

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.

	*/

	transitionToggle: function(mode){
		if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.transitionShow(mode);
		return this.transitionHide(mode);
	},

	/*
	Property: directToggle
		Reveals or hides the element, depending on its state, without a transition

	Arguments:
		mode - (optional, string) 'horizontal' or 'vertical'; defaults to options.mode.

	*/

	directToggle: function(mode){
		if (this.wrapper.offsetHeight == 0 || this.wrapper.offsetWidth == 0) return this.directShow(mode);
		return this.directHide(mode);
	},

	increase: function(){
		this.element.setStyle(this.margin, this.now[0] + this.options.unit);
		this.wrapper.setStyle(this.layout, this.now[1] + this.options.unit);
	}

});
