// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

var JT = JT || {};

function mark_for_destroy(element, className) { 
  $(element).next('.should_destroy').value = 1 
  $(element).up('.'+className).hide(); 
}

// Override Scriptaculous Autocompleter: This one takes a json response 
// and builds the html list on the client. It also uses GET which is arguably
// the right http method to request a list.

Ajax.RestfulAutocompleter = Class.create();
Object.extend(Object.extend(Ajax.RestfulAutocompleter.prototype, Autocompleter.Base.prototype), {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.options.method        = 'get';
    this.url                   = url;
    this.template              = Templates[element] || function(){};
  },

  getUpdatedChoices: function() {
    entry = encodeURIComponent(this.options.paramName) + '=' + 
      encodeURIComponent(this.getToken());

    this.options.parameters = this.options.callback ?
      this.options.callback(this.element, entry) : entry;

    if(this.options.defaultParams) 
      this.options.parameters += '&' + this.options.defaultParams;

    new Ajax.Request(this.url, this.options);
  },

  onComplete: function(request) {
    this.processResponse(request.responseText);
  },
  
  processResponse: function(json) {
    var html = [];
    var collection = eval(json);
    var template = this.template(this.element) || new Template('<li class="'+ this.element.id +'" id="#{id}">#{'+ this.element.name +'}</li>');
    // console.log(template)
    html.push('<ul>');
    collection.each(function(obj) {
      html.push(template.evaluate(obj));
    })
    html.push('</ul>');
        
    this.updateChoices(html.join(''));
  }

});

var Templates = {};
Templates['image'] =  function(element) {
  return new Template('<li class="'+ element.id +'" id="#{id}">#{'+ element.name +'}  <img src="/images/#{file}" title="#{caption}" alt="#{caption}" /></li>');
}


document.observe('dom:loaded', function() {
  var clearNotification = function(){
    if ($('notification')) {
      $('notification').fade({delay:2});
      document.stopObserving('mousemove', clearNotification);
    }
  }
  document.observe('mousemove', clearNotification);
})

document.observe('dom:loaded', function(){
  
  $$('form').each(function(form) {
    
    (function(form){
      
      function install() {
        Form.Validator.install(form, {onElementStatusChangeDefault: function(isValid){
          if (isValid)
            this.addClassName('valid');
          else
            this.removeClassName('valid');
        }})
      }
      
      install();
      
      form.observe('DOMNodeInserted', install);
      
    })(form)
    
  })
  
})


// Validator: a mostly declarative client-side form validator
// Copyright (c) 2006-2008 Michael Schuerig, michael@schuerig.de
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


if (!String.isBlank) {
  String.isBlank = function(s) {
    return (!s || (/^\s*$/).test(s));
  };
}

Function.trueFunc = function() {
  return true;
};

Function.andCombiner = function(funcs) {
  var _funcs = $A(arguments).flatten();
  if (_funcs.length === 1) {
    return _funcs[0];
  } else if (_funcs.length > 1) {
    return function() {
      var len = _funcs.length;
      for (var i = 0; i < len; i++) {
        if (! _funcs[i].apply(this, arguments)) {
          return false;
        }
      }
      return true;
    };
  } else {
    return Function.trueFunc;
  }
};

if (Event.UserActionObserver) {
  alert('validator.js: Event.UserActionObserver is already defined. The old definition will be overwritten!');
}

Event.UserActionObserver = Class.create();

Event.UserActionObserver.ignoredKeys = [
  Event.KEY_TAB,
  Event.KEY_RETURN,
  Event.KEY_ESC
];

Event.UserActionObserver.prototype = {
  initialize: function(container, callback, options) {
    this.options = Object.extend({
      latency: 0.4,
      events: ['keypress', 'change']
    }, options);

    this.container = $(container);
    this.callback = callback;
    this.latency = this.options.latency * 1000;
    this.timer = null;
    this.notifyCallback = this._notifyCallback.bind(this);
    this.onAction = this._onAction.bindAsEventListener(this);
    this.start();
  },

  start: function() {
    var events = this.options.events;
    for (var i = 0; i < events.length; i++) {
      Event.observe(this.container, events[i], this.onAction);
    }
  },

  stop: function() {
    var events = this.options.events;
    for (var i = 0; i < events.length; i++) {
      Event.stopObserving(this.container, events[i], this.onAction);
    }
  },

  _onAction: function(event) {
    if (Event.UserActionObserver.ignoredKeys.include(event.keyCode)) {
      return;
    }
    if (this.timer) {
      clearTimeout(this.timer);
    }
    this.timer = setTimeout(this.notifyCallback, this.latency);
  },

  _notifyCallback: function() {
    this.callback();
  }
};


Form.Validator = Class.create();

Object.extend(Form.Validator, {
  Version: '0.3.0',
  debug: false,
  trace: false,
  validatorsState: {},

  clearDebugArea: function() {
    if (!(window.console && window.console.log)) {
      if (!Form.Validator.debugArea) {
        Form.Validator.debugArea = document.createElement('div');
        document.body.appendChild(Form.Validator.debugArea);
      }
      Form.Validator.debugArea.innerHTML = '';
    }
  },

  debugValidity: function(element, isValid) {
    if (window.console && window.console.log) {
      console.log('Element ' + element.id + ' is valid: ' + isValid);
    } else {
      Form.Validator.debugArea.innerHTML += element.id + ': ' + isValid + '<br />';
    }
  },

  installForAllValidatedForms: function(options) {
    Event.observe(window, 'load', function() {
      var forms = document.forms;
      for (var i = 0; i < forms.length; i++) {
        if (Element.hasClassName(forms[i], 'validated')) {
          Form.Validator.install(forms[i], options);
        }
      }
      return true;
    });
  },

  install: function(form, options) {
    form.__validator = new Form.Validator(form, options);
  },

  uninstall: function(form) {
    if (form) {
      form = $(form);
      if (form.__validator) {
	form.__validator.uninstall();
      }
    } else {
      var forms = document.forms;
      for (var i = 0; i < forms.length; i++) {
	Form.Validator.uninstall(forms[i]);
      }
    }
  },

  revalidate: function(element) {
    element = $(element);
    var form = element.form;
    if (form && form.__validator) {
      form.__validator.check();
    }
  },

  switchClassNameInvalid: function(element, isValid) {
    element = $(element);
    if (isValid) {
      element.removeClassName('invalid');
    } else {
      element.addClassName('invalid');
    }
  },

  notifyElementStatusChangeCallback: function(element, isValid) {
    if (typeof element.__statusChangedCallback === 'function') {
      element.__statusChangedCallback(isValid);
    }
  },

  getValueCheckerFor: function(inputType) {
    switch (inputType) {
      case 'hidden':
      case 'password':
      case 'select-one':
      case 'text':
      case 'textarea':
        return Form.Validator.Utils.checkHasValue;
      case 'radio':
        return Form.Validator.Utils.checkRadioSelected;
      case 'select-multiple':
        return Form.Validator.Utils.checkHasOptions;
    }
    return null;
  },

  _getValueFunc: function() {
    return $F(this);
  }
});


Form.Validator.prototype = {
  // Options:
  // validators({name:function(validator),...}) - a hash of validation functions; default Form.Validator.Validators
  // formValidator(form, validator) - a validation function for the form as a whole
  // onElementStatusChange - a hash of element ids to function(elementIsValid) that are called when the validity of an element has changed
  // onElementStatusChangeDefault - a default element callback; it has a default itself: a function that adds/removes the class 'invalid' to/from an element.
  // onFormStatusChange - function(formIsValid)
  initialize: function(form, options) {
    this.form = $(form);
    if (!this.form) {
      return;
    }
    if (!options) {
      options = {}
    }
    this.validators = options.validators || Form.Validator.Validators;
    this.formValidator = options.formValidator;
    this.onElementStatusChange = options.onElementStatusChange || {};
    this.onElementStatusChangeDefault = options.onElementStatusChangeDefault || this._classNameChangingElementCallback;
    this.onFormStatusChange = options.onFormStatusChange;
    this.submitButtons = Form.Validator.Utils.submitButtons(this.form);
    this.validatedElements = this._installValidators();
    this._installSubmitInterceptor();

    this.check();
    this._installActionObserver();
  },

  uninstall: function() {
    for (var i = 0; i < this.validatedElements.length; i++) {
      var element = this.validatedElements[i];
      delete element.__statusChangedCallback;
      delete element.__checkValidity;
      delete element.__wasValid;
      delete element.__getValue;
    }
    this._uninstallSubmitInterceptor();
    delete this.form.__validator;
  },

  check: function() {
    var formWasValid = this.formIsValid;
    this.formIsValid = true;
    if (Form.Validator.trace) {
      Form.Validator.clearDebugArea();
    }
    var elements = Form.getElements(this.form);
    for (var i = elements.length - 1; i >= 0; i--) {
      this._checkElement(elements[i]);
    }
    this._checkWholeForm();
    //  MOD do not disable submit button even if data in form is invalid
    // this._adjustSubmitButtons();
    if (formWasValid !== this.formIsValid) {
      this._notifyFormStatusChangeCallback();
    }
  },

  _checkElement: function(element) {
    if (element && typeof element.__checkValidity === 'function') {
      try {
        var elementIsValid = element.__checkValidity(this);

        if (Form.Validator.trace) {
          Form.Validator.debugValidity(element, elementIsValid);
        }

        this.formIsValid = this.formIsValid && elementIsValid;
        if (element.__wasValid !== elementIsValid) {
          Form.Validator.notifyElementStatusChangeCallback(element, elementIsValid);
          element.__wasValid = elementIsValid;
        }
      } catch (e) {
        if (Form.Validator.debug) {
          throw e;
        }
      }
      return elementIsValid;
    }
    return true;
  },

  _checkWholeForm: function() {
    if (this.formIsValid && this.formValidator) {
      try {
        this.formIsValid = this.formValidator(this.form, this);
      } catch (e) {
        if (Form.Validator.debug) {
          throw e;
        }
      }
    }
  },

  _installValidators: function() {
    var elements = Form.getElements(this.form);
    var validatedElements = []
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      if (/^submit$/i.test(element.tagName) || /^submit$/i.test(element.type) || Element.hasClassName(element, 'dontvalidate')) {
        continue;
      }
      var myself = this;
      var validatorFuncs = $w(element.className).inject([], function(memo, className) {
        var validator = myself._getValidatorFor(element, className);
        if (typeof validator === 'function') {
          memo.push(validator);
        }
        return memo;
      });

      if (validatorFuncs.length > 0) {
        element.__statusChangedCallback = (typeof this.onElementStatusChange[element.id] === 'function') ?
          this.onElementStatusChange[element.id] : this.onElementStatusChangeDefault;
        element.__checkValidity = Function.andCombiner(validatorFuncs);
        element.__getValue = Form.Validator._getValueFunc;
        validatedElements.push(element);
      }
    }
    return validatedElements;
  },

  _installSubmitInterceptor: function() {
    this.onSubmitListener = this._onSubmit.bindAsEventListener(this);
    Event.observe(this.form, 'submit', this.onSubmitListener);
  },
  _uninstallSubmitInterceptor: function() {
    Event.stopObserving(this.form, 'submit', this.onSubmitListener);
    this.onSubmitListener = null;
  },

  _installActionObserver: function() {
    this.actionObserver = new Event.UserActionObserver(this.form, this.check.bind(this),
      {latency: 0.2, events:['keypress', 'change', 'click']});
  },
  _uninstallActionObserver: function() {
    this.actionObserver.stop();
    this.actionObserver = null;
  },

  _getValidatorFor: function(element, className) {
    try {
      if (className === 'mandatory') {
        return Form.Validator.getValueCheckerFor(element.type);
      } else if (/^validate_/.test(className)) {
        var args = className.split('_');
        args.shift();
        var funcName = args.shift();
        var validatorGenerator = this.validators[funcName];
        if (typeof validatorGenerator === 'function') {
          var gen = validatorGenerator(element, args);
          return gen;
        }
      } else {
        return this.validators[className];
      }
    } catch (e) {
      if (this.debug) {
        throw(e);
      } else {
        return null;
      }
    }
  },

  _adjustSubmitButtons: function() {
    var disabled = !this.formIsValid;
    for (var i = this.submitButtons.length - 1; i >= 0; i--) {
      this.submitButtons[i].disabled = disabled;
    }
  },

  _classNameChangingElementCallback: function(isValid) {
    Form.Validator.switchClassNameInvalid(this, isValid);
  },

  _notifyFormStatusChangeCallback: function() {
    if (typeof this.onFormStatusChange === 'function') {
      this.onFormStatusChange(this.formIsValid);
    }
  },

  _onSubmit: function(event) {
    if (Form.Validator.debug) {
      // allow a loophole to test submission of invalid forms
      return true;
    }
    if (!this.formIsValid) {
      //return Event.stop(event);
    }
    return true;
  }
};


Form.Validator.Utils = {
  submitButtons: function(form) {
    form = $(form);
    return [].concat(
      $A(form.getElementsByTagName('input')),
      $A(form.getElementsByTagName('button'))
    ).select(function(element) {
      return /^submit$/i.test(element.type) && /^commit$/i.test(element.name);
    });
  },

  validatorState: function(stateName, ctor) {
    var state = Form.Validator.validatorsState[stateName];
    if (!state && ctor) {
      state = new ctor();
      Form.Validator.validatorsState[stateName] = state;
    }
    return state;
  },

  setValidatorState: function(stateName, value) {
    Form.Validator.validatorsState[stateName] = value;
  },

  checkHasValue: function() {
    return (!String.isBlank(this.__getValue()));
  },

  checkRadioSelected: function() {
    if (String.isBlank(this.name)) {
      delete this.__checkValidity;
      return true;
    }
    var isValid = this.checked;
    var radios = Form.getInputs(this.form, 'radio', this.name);
    if (!isValid) {
      for (var i = radios.length - 1; i >= 0; i--) {
        if (radios[i].checked) {
          isValid = true;
          break;
        }
      }
    }
    for (var i = radios.length - 1; i >= 0; i--) {
      if (isValid) {
        delete radios[i].__checkValidity;
      }
      Form.Validator.notifyElementStatusChangeCallback(radios[i], isValid);
    }
    return isValid;
  },

  checkHasOptions: function() {
    return this.options.length > 0;
  },

  isValidDate: function(year, month, day) {
    if (month < 1 || month > 12) {
      return false;
    }
    if (day < 1 || day > 31) {
      return false;
    }
    if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
      return false;
    }
    if (month == 2) {
      var leap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
      if (day > 29 || (day == 29 && !leap)) {
        return false;
      }
    }
    return true;
  },

  othersHaveDifferentValues: function(element, group) {
    var value = $F(element);
    if (!value) {
      return true;
    }
    for (var i = 0; i < group.length; i++) {
      var other = group[i];
      if (other !== element) {
        var otherValue = $F(other);
        if (value === otherValue) {
          return false;
        }
      }
    }
    return true;
  }
};


Form.Validator.Validators = {
  numeric: function() {
    var value = this.__getValue();
    if (!value) {
      return true;
    }
    return (/^\d*([,.]?\d+)$/.test(value));
  },

  integer: function() {
    var value = this.__getValue();
    if (!value) {
      return true;
    }
    return (/^\d+$/.test(value));
  },

  date: function() {
    var value = this.__getValue();
    if (!value) {
      return true;
    }
    var d = Form.Validator.Validators._parseDate(value);
    if (!d) {
      return false;
    }
    return Form.Validator.Utils.isValidDate(d[0], d[1], d[2]);
  },

  time: function() {
    var value = this.__getValue();
    if (!value) {
      return true;
    }
    return /^\d?\d(:\d\d){0,2}$/.test(value);
  },

  maxlength: function(element, args) {
    var maxLength = parseInt(args[0]);
    if (maxLength) {
      return function() {
        return this.__getValue().length <= maxLength;
      }
    }
    return null;
  },

  minlength: function(element, args) {
    var minLength = parseInt(args[0]);
    if (minLength) {
      return function() {
        var len = this.__getValue().length;
        return len === 0 || len >= minLength;
      }
    }
    return null;
  },

  format: function(element, args) {
    var format = decodeURIComponent(args[0]);
    if (format) {
      var re = eval(format);
      delete format;
      return function() {
        return re.test(this.__getValue());
      }
    }
    return null;
  },

  range: function(element, args) {
    var begin = parseInt(args[0]);
    var end   = parseInt(args[1]);
    if (!isNaN(begin) && !isNaN(end)) {
      return function() {
        var v = parseInt(this.__getValue());
        return !isNaN(v) ? (begin <= v && v <= end) : true;
      }
    }
    return null;
  },

  // Check if the defined values of elements in the same group
  // as the given one are different from the given element's value.
  // Elements are grouped by args[0]; e.g.
  // <input class="validate_different_1" />
  different: function(element, args) {
    var groupName = 'different' + args[0];
    var group = Form.Validator.Utils.validatorState(groupName, Array);
    group.push(element);
    group.ok = true;
  	return function(validator) {
  	  var ok = Form.Validator.Utils.othersHaveDifferentValues(this, group);
      group.ok = ok;
  	  return ok;
  	};
  },

  exactly: function(element, args) {
    var required_value_count = parseInt(args[0]);
    var groupName = 'exactly_' + args[0] + '_' + args[1];
    var group = Form.Validator.Utils.validatorState(groupName, Array);
    group.push(element);
    group.ok = true;
    return function(validator) {
      var value_count = 0;
      for (var i = 0; i < group.length; i++) {
        if ($F(group[i])) {
          value_count++;
        }
      }
      var ok = (value_count === required_value_count);
      group.ok = ok;
      return ok;
    };
  },

  same: function(element, args) {
    var other = args.join('_');
    return function(validator) {
      ok = ($F(element) === $F(other));
      return ok;
    }
  },

  zip: function() {
    var value = this.__getValue();
    if (value.length < 5) {
      return false;
   	}
    return (/\d\d\d\d\d/.test(value));
  },

  _parseDate: function(date) {
    var match = /^(\d\d(\d\d)?)-(\d\d?)-(\d\d?)$/.exec(date);
    if (!match) {
      return null;
    }
    return [ match[1], match[3], match[4] ];
  }
};



Object.extend(Form.Validator.Validators, {
  Version: '0.2.0',

  _parseDate: function(date) {
    var match = /^(\d\d?)\/(\d\d?)\/(\d\d(\d\d)?)$/.exec(date);
    if (!match) {
      return undefined;
    }
    return [ match[3], match[1], match[2] ];
  }
});


/**
 * @author Ryan Johnson <ryan@livepipe.net>
 * @copyright 2007 LivePipe LLC
 * @package Control.Tabs
 * @license MIT
 * @url http://livepipe.net/projects/control_tabs/
 * @version 2.1.1
 */

if(typeof(Control) == 'undefined')
	var Control = {};
Control.Tabs = Class.create();
Object.extend(Control.Tabs,{
	instances: [],
	findByTabId: function(id){
		return Control.Tabs.instances.find(function(tab){
			return tab.links.find(function(link){
				return link.key == id;
			});
		});
	}
});
Object.extend(Control.Tabs.prototype,{
	initialize: function(tab_list_container,options){
		this.activeContainer = false;
		this.activeLink = false;
		this.containers = $H({});
		this.links = [];
		Control.Tabs.instances.push(this);
		this.options = {
			beforeChange: Prototype.emptyFunction,
			afterChange: Prototype.emptyFunction,
			hover: false,
			linkSelector: 'li a',
			setClassOnContainer: false,
			activeClassName: 'active',
			defaultTab: 'first',
			autoLinkExternal: true,
			targetRegExp: /#(.+)$/,
			showFunction: Element.show,
			hideFunction: Element.hide
		};
		Object.extend(this.options,options || {});
		(typeof(this.options.linkSelector == 'string')
			? $(tab_list_container).getElementsBySelector(this.options.linkSelector)
			: this.options.linkSelector($(tab_list_container))
		).findAll(function(link){
			return (/^#/).exec(link.href.replace(window.location.href.split('#')[0],''));
		}).each(function(link){
			this.addTab(link);
		}.bind(this));
		this.containers.values().each(this.options.hideFunction);
		if(this.options.defaultTab == 'first')
			this.setActiveTab(this.links.first());
		else if(this.options.defaultTab == 'last')
			this.setActiveTab(this.links.last());
		else
			this.setActiveTab(this.options.defaultTab);
		var targets = this.options.targetRegExp.exec(window.location);
		if(targets && targets[1]){
			targets[1].split(',').each(function(target){
				this.links.each(function(target,link){
					if(link.key == target){
						this.setActiveTab(link);
						throw $break;
					}
				}.bind(this,target));
			}.bind(this));
		}
		if(this.options.autoLinkExternal){
			$A(document.getElementsByTagName('a')).each(function(a){
				if(!this.links.include(a)){
					var clean_href = a.href.replace(window.location.href.split('#')[0],'');
					if(clean_href.substring(0,1) == '#'){
						if(this.containers.keys().include(clean_href.substring(1))){
							$(a).observe('click',function(event,clean_href){
								this.setActiveTab(clean_href.substring(1));
							}.bindAsEventListener(this,clean_href));
						}
					}
				}
			}.bind(this));
		}
	},
	addTab: function(link){
		this.links.push(link);
		link.key = link.getAttribute('href').replace(window.location.href.split('#')[0],'').split('/').last().replace(/#/,'');
		this.containers[link.key] = $(link.key);
		link[this.options.hover ? 'onmouseover' : 'onclick'] = function(link){
			if(window.event)
				Event.stop(window.event);
			this.setActiveTab(link);
			return false;
		}.bind(this,link);
	},
	setActiveTab: function(link){
		if(!link)
			return;
		if(typeof(link) == 'string'){
			this.links.each(function(_link){
				if(_link.key == link){
					this.setActiveTab(_link);
					throw $break;
				}
			}.bind(this));
		}else{
			this.notify('beforeChange',this.activeContainer);
			if(this.activeContainer)
				this.options.hideFunction(this.activeContainer);
			this.links.each(function(item){
				(this.options.setClassOnContainer ? $(item.parentNode) : item).removeClassName(this.options.activeClassName);
			}.bind(this));
			(this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.activeClassName);
			this.activeContainer = this.containers[link.key];
			this.activeLink = link;
			this.options.showFunction(this.containers[link.key]);
			this.notify('afterChange',this.containers[link.key]);
		}
	},
	next: function(){
		this.links.each(function(link,i){
			if(this.activeLink == link && this.links[i + 1]){
				this.setActiveTab(this.links[i + 1]);
				throw $break;
			}
		}.bind(this));
		return false;
	},
	previous: function(){
		this.links.each(function(link,i){
			if(this.activeLink == link && this.links[i - 1]){
				this.setActiveTab(this.links[i - 1]);
				throw $break;
			}
		}.bind(this));
		return false;
	},
	first: function(){
		this.setActiveTab(this.links.first());
		return false;
	},
	last: function(){
		this.setActiveTab(this.links.last());
		return false;
	},
	notify: function(event_name){
		try{
			if(this.options[event_name])
				return [this.options[event_name].apply(this.options[event_name],$A(arguments).slice(1))];
		}catch(e){
			if(e != $break)
				throw e;
			else
				return false;
		}
	}
});
if(typeof(Object.Event) != 'undefined')
	Object.Event.extend(Control.Tabs);
	
	

/**
 * @author Pau Santesmasses <pau@santesmasses.net>
 * @package Control.AjaxTabs
 * @license MIT
 * @url 
 * @version 0
 */
Control.AjaxTabs = Class.create({
  initialize: function(container,partial) {
    this.container = $(container);
    this.partial = partial;
    this.tabs = this.container.select('.tabs li a');
    this.panes = this.container.select('.pane');
    
    this.tabs.each(this.bindTab.bind(this))
    this.insertSpinner()
  },
  
  insertSpinner: function(){
    this.spinner = new Element('img', {
      src: "/images/ui/spinner_small.gif",
      alt: 'loading',
      style: 'position:absolute; top: 31px;left:9px'
    });
    this.spinner.hide();
    this.container.insert({top: this.spinner});
  },
  
  toggleSpinner: function() {
    this.spinner.toggle()
  },
  
  bindTab: function(tab, index) {
    var pane = this.panes[index];
    Event.observe(tab, 'click', this.selectTab.bind(this));
    // Event.observe(tab, 'click', this.selectPane.bind(this));
    
  },
  
  resetTabs: function() {
    this.tabs.each(function(tab){
      tab.removeClassName('active')
    })
    
    this.panes.each(function(pane){
      pane.hide()
    })
  },
  
  selectTab: function(e) {
    this.resetTabs();
    var tab = e.element();
    tab.addClassName('active');
    this.selectPane(e);
  },
  
  selectPane: function(e) {
    var tab = e.element();
    var index = this.tabs.indexOf(tab)
    var pane = this.panes[index];
    var pane_content = pane.down('.content');
    this.loadPane(pane_content,tab.href, {partial:this.partial});
    this.activePane = pane;
    pane.show();
    e.stop();
  },
  
  loadPane: function(pane_content, src, params) {
    if (pane_content.innerHTML.blank()) {
      new Ajax.Updater(pane_content, src, 
                      {method:'get',
                       parameters:params,
                       evalScripts:true,
                       onCreate:this.toggleSpinner.bind(this),
                       onComplete: this.toggleSpinner.bind(this) })
    } 
  }

});


// accordion.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
// 
// Accordion is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro: 
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined') 
	throw("accordion.js requires including script.aculo.us' effects.js library!");

var accordion = Class.create();
accordion.prototype = {

	//
	//  Setup the Variables
	//
	showAccordion : null,
	currentAccordion : null,
	duration : null,
	effects : [],
	animating : false,
	
	//  
	//  Initialize the accordions
	//
	initialize: function(container, options) {
	  if (!$(container)) {
	    throw(container+" doesn't exist!");
	    return false;
	  }
	  
		this.options = Object.extend({
			resizeSpeed : 8,
			classNames : {
				toggle : 'accordion_toggle',
				toggleActive : 'accordion_toggle_active',
				content : 'accordion_content'
			},
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			onEvent : 'click'
		}, options || {});
		
		this.duration = ((11-this.options.resizeSpeed)*0.15);

		var accordions = $$('#'+container+' .'+this.options.classNames.toggle);
		accordions.each(function(accordion) {
			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
			if (this.options.onEvent == 'click') {
        // accordion.onclick = function() {return false;};
			}
			
			if (this.options.direction == 'horizontal') {
				var options = {width: '0px'};
			} else {
				var options = {height: '0px'};			
			}
			Object.extend(options, {display: 'none'});			
			
			this.currentAccordion = $(accordion.next(0)).setStyle(options);			
		}.bind(this));
	},
	
	//
	//  Activate an accordion
	//
	activate : function(accordion) {
		if (this.animating) {
			return false;
		}
		
		this.effects = [];
	
		this.currentAccordion = $(accordion.next(0));
		this.currentAccordion.setStyle({
			display: 'block'
		});		
		
		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);

		if (this.options.direction == 'horizontal') {
			this.scaling = {
				scaleX: true,
				scaleY: false
			};
		} else {
			this.scaling = {
				scaleX: false,
				scaleY: true
			};			
		}
			
		if (this.currentAccordion == this.showAccordion) {
		  this.deactivate();
		} else {
		  this._handleAccordion();
		}
	},
	// 
	// Deactivate an active accordion
	//
	deactivate : function() {
		var options = {
		  duration: this.duration,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			queue: {
				position: 'end', 
				scope: 'accordionAnimation'
			},
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			},
			afterFinish: function() {
				this.showAccordion.setStyle({
          height: 'auto',
					display: 'none'
				});				
				this.showAccordion = null;
				this.animating = false;
			}.bind(this)
		};    
    Object.extend(options, this.scaling);

    this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
    
		new Effect.Scale(this.showAccordion, 0, options);
	},

  //
  // Handle the open/close actions of the accordion
  //
	_handleAccordion : function() {
		var options = {
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: Effect.Transitions.sinoidal,
			scaleMode: { 
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
			}
		};
		Object.extend(options, this.scaling);
		
		this.effects.push(
			new Effect.Scale(this.currentAccordion, 100, options)
		);

		if (this.showAccordion) {
			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
			
			options = {
				sync: true,
				scaleContent: false,
				transition: Effect.Transitions.sinoidal
			};
			Object.extend(options, this.scaling);
			
			this.effects.push(
				new Effect.Scale(this.showAccordion, 0, options)
			);				
		}
		
    new Effect.Parallel(this.effects, {
			duration: this.duration, 
			queue: {
				position: 'end', 
				scope: 'accordionAnimation'
			},
			beforeStart: function() {
				this.animating = true;
			}.bind(this),
			afterFinish: function() {
				if (this.showAccordion) {
					this.showAccordion.setStyle({
						display: 'none'
					});				
				}
				$(this.currentAccordion).setStyle({
				  height: 'auto'
				});
				this.showAccordion = this.currentAccordion;
				this.animating = false;
			}.bind(this)
		});
	}
}
	

Strip = Class.create({
  initialize: function(control) {
    this.box = control.select('.strip_box')['0'].makePositioned();
    this.strip = control.select('.strip')[0];
    this.elements = control.select('.strip_item');
    this.buttons = control.select('.buttons span');
    this.current_index = 0;
    this.bindButtons();
    this.bindCaptions();
  },
  
  bindButtons: function() {
    this.buttons.first().addClassName('selected');
    this.buttons.each(function(button) {
      Event.observe(button, 'click', this.moveTo.bind(this,button.innerHTML));
      Event.observe(button, 'click', this.markSelected.bindAsEventListener(this));
    },this);
  },
  
  bindCaptions: function() {
    this.elements.each(function(element){
      element.observe('mouseover', this.showCaption.bindAsEventListener(this, true))
      element.observe('mouseout', this.hideCaption.bindAsEventListener(this, true))
    }.bind(this))
  },
  
  markSelected: function(e) {
    this.buttons.invoke('removeClassName', 'selected');
    Event.element(e).addClassName('selected');
  },
  
  getCurrent: function() {
    return this.elements[this.current_index];
  },
  
  getPrevious: function(){
    return this.elements[this.current_index - 1];
  },
  
  getNext: function() {
    return this.elements[this.current_index + 1];
  },
  
  moveTo: function(number) {
    number = number - 1;
    if(this.elements[number]) {
      var current_index = this.current_index;
      var direction = number > current_index ? -1 : 1;
      var offset_elements = number > current_index ? 
                            this.elements.slice(current_index, number) : 
                            this.elements.slice(number, current_index)
      var offset_width = offset_elements.inject(
        0, function(widths, element) { 
        return widths + element.getWidth();
      })
      new Effect.Move(this.strip, { x: offset_width * direction, y: 0 });
      this.current_index = number;
    }
  },
  
  moveToPrevious: function() {
    if (this.getPrevious()) {
      new Effect.Move(this.strip, { x: this.getPrevious().getWidth(), y: 0});
      this.current_index--;
    }
  },
  
  moveToNext: function() {
    if (this.getNext()) {
      new Effect.Move(this.strip, { x: this.getCurrent().getWidth() * -1, y: 0});
      this.current_index++; 
    }
  },
  
  showCaption: function(event) {
    var strip_item = event.findElement('.strip_item');
    var overlay = strip_item.down('.overlay');
    strip_item.caption_locked = true;
    if (!strip_item.caption_visible) {
      new Effect.Move(overlay, {y: overlay.getHeight() * -1, mode: 'relative', duration: 0.3, delay: 0.2, transition: Effect.Transitions.sinoidal});
      strip_item.caption_visible = true;
    }
    
  },
  
  hideCaption: function(event) {
    var strip_item = event.findElement('.strip_item');
    var overlay = strip_item.down('.overlay');
    strip_item.caption_locked = false;
    (function(strip_item, strip){
      if (!strip_item.caption_locked) {
        new Effect.Move(overlay, {y: overlay.getHeight(), mode: 'relative', duration: 0.3, transition: Effect.Transitions.sinoidal, afterFinish: function(effect){
          effect.element.style.top = '';
        }});
        strip_item.caption_visible = false;
      }
    }).delay(3, strip_item)

  }
})

Strip.bootstrap = function() {
  $$('.strip_control').each(function(element) {
    new Strip(element)
  });
	$$('.strip_item img')
}

document.observe('dom:loaded', Strip.bootstrap)

