/*  Prototype: an object-oriented Javascript library, version 1.2.1
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *
 *  THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
 *  against the source tree, available from the Prototype darcs repository. 
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.2.1'
}

var Class = {
  create: function() {
    return function() { 
      this.initialize.apply(this, arguments);
    }
  }
}

var Abstract = new Object();

Object.prototype.extend = function(object) {
  for (property in object) {
    this[property] = object[property];
  }
  return this;
}

Function.prototype.bind = function(object) {
  var method = this;
  return function() {
    method.apply(object, arguments);
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var method = this;
  return function(event) {
    method.call(object, event || window.event);
  }
}

Number.prototype.toColorPart = function() {
  var digits = this.toString(16);
  if (this < 16) return '0' + digits;
  return digits;
}

var Try = {
  these: function() {
    var returnValue;
    
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
    
    return returnValue;
  }
}

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;
    
    this.registerCallback();
  },
  
  registerCallback: function() {
    setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
  },
  
  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try { 
        this.currentlyExecuting = true;
        this.callback(); 
      } finally { 
        this.currentlyExecuting = false;
      }
    }
    
    this.registerCallback();
  }
}

/*--------------------------------------------------------------------------*/

function $() {
  var elements = new Array();
  
  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1) 
      return element;
      
    elements.push(element);
  }
  
  return elements;
}

/*--------------------------------------------------------------------------*/

if (!Array.prototype.push) {
  Array.prototype.push = function() {
		var startLength = this.length;
		for (var i = 0; i < arguments.length; i++)
      this[startLength + i] = arguments[i];
	  return this.length;
  }
}

if (!Function.prototype.apply) {
  // Based on code from http://www.youngpup.net/
  Function.prototype.apply = function(object, parameters) {
    var parameterStrings = new Array();
    if (!object)     object = window;
    if (!parameters) parameters = new Array();
    
    for (var i = 0; i < parameters.length; i++)
      parameterStrings[i] = 'x[' + i + ']';
    
    object.__apply__ = this;
    var result = eval('obj.__apply__(' + 
      parameterStrings[i].join(', ') + ')');
    object.__apply__ = null;
    
    return result;
  }
}

/*--------------------------------------------------------------------------*/

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  },
  
  emptyFunction: function() {}
}

Ajax.Base = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      parameters:   ''
    }.extend(options || {});
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events = 
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = (new Ajax.Base()).extend({
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
  
    try {
      if (this.options.method == 'get')
        url += '?' + this.options.parameters + '&_=';
    
      this.transport.open(this.options.method, url,
        this.options.asynchronous);
      
      if (this.options.asynchronous) {
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
      }
              
      this.transport.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      this.transport.setRequestHeader('X-Prototype-Version',
        Prototype.Version);

      if (this.options.method == 'post') {
        this.transport.setRequestHeader('Connection', 'close');
        this.transport.setRequestHeader('Content-type',
          'application/x-www-form-urlencoded');
      }

      if (this.options.requestHeaders) {
         for (var i=0; i< (this.options.requestHeaders.length-1);i+=2)
            this.transport.setRequestHeader(this.options.requestHeaders[i],
                                            this.options.requestHeaders[i+1]);
      }

      var sendData = this.options.postBody   ? this.options.postBody
                   : this.options.parameters ? this.options.parameters + '&_'
                   : null;

      this.transport.send(this.options.method == 'post' ? sendData : null );
                      
    } catch (e) {
    }    
  },
      
  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState != 1)
      this.respondToReadyState(this.transport.readyState);
  },
  
  respondToReadyState: function(readyState) {
    var event = Ajax.Request.Events[readyState];
    (this.options['on' + event] || Ajax.emptyFunction)(this.transport);
  }
});

Ajax.Updater = Class.create();
Ajax.Updater.prototype = (new Ajax.Base()).extend({
  initialize: function(container, url, options) {
    this.container = $(container);
    this.setOptions(options);
  
    if (this.options.asynchronous) {
      this.onComplete = this.options.onComplete;
      this.options.onComplete = this.updateContent.bind(this);
    }

    this.request = new Ajax.Request(url, this.options);
    
    if (!this.options.asynchronous)
      this.updateContent();
  },
  
  updateContent: function() {
    if (this.request.transport.status == 200) {
      if (this.options.insertion) {
        new this.options.insertion(this.container,
        this.request.transport.responseText);
      } else {
        this.container.innerHTML = this.request.transport.responseText;
      }
    }  

    if (this.onComplete) {
      setTimeout((function() {this.onComplete(
        this.request.transport)}).bind(this), 10);
    }
  }
});

/*--------------------------------------------------------------------------*/

var Field = {
  clear: function() {
    for (var i = 0; i < arguments.length; i++)
      $(arguments[i]).value = '';
  },

  focus: function(element) {
    $(element).focus();
  },
  
  present: function() {
    for (var i = 0; i < arguments.length; i++)
      if ($(arguments[i]).value == '') return false;
    return true;
  },
  
  select: function(element) {
    $(element).select();
  },
   
  activate: function(element) {
    $(element).focus();
    $(element).select();
  }
}

/*--------------------------------------------------------------------------*/

var Form = {
  serialize: function(form) {
    var elements = Form.getElements($(form));
    var queryComponents = new Array();
    
    for (var i = 0; i < elements.length; i++) {
      var queryComponent = Form.Element.serialize(elements[i]);
      if (queryComponent)
        queryComponents.push(queryComponent);
    }
    
    return queryComponents.join('&');
  },
  
  getElements: function(form) {
    form = $(form);
    var elements = new Array();

    for (tagName in Form.Element.Serializers) {
      var tagElements = form.getElementsByTagName(tagName);
      for (var j = 0; j < tagElements.length; j++)
        elements.push(tagElements[j]);
    }
    return elements;
  },
  
  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disable = 'true';
    }
  },

  focusFirstElement: function(form) {
    form = $(form);
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      if (element.type != 'hidden' && !element.disabled) {
        Field.activate(element);
        break;
      }
    }
  },

  reset: function(form) {
    $(form).reset();
  }
}

Form.Element = {
  serialize: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
    
    if (parameter)
      return encodeURIComponent(parameter[0]) + '=' + 
        encodeURIComponent(parameter[1]);                   
  },
  
  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);
    
    if (parameter) 
      return parameter[1];
  }
}

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.Serializers.textarea(element);
      case 'checkbox':  
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
    }
    return false;
  },

  inputSelector: function(element) {
    if (element.checked)
      return [element.name, element.value];
  },

  textarea: function(element) {
    return [element.name, element.value];
  },

  select: function(element) {
    var index = element.selectedIndex;
    var value = element.options[index].value || element.options[index].text;
    return [element.name, (index >= 0) ? value : ''];
  }
}

/*--------------------------------------------------------------------------*/

var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;
    
    this.lastValue = this.getValue();
    this.registerCallback();
  },
  
  registerCallback: function() {
    setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
  },
  
  onTimerEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
    
    this.registerCallback();
  }
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
  getValue: function() {
    return Form.serialize(this.element);
  }
});


/*--------------------------------------------------------------------------*/

document.getElementsByClassName = function(className) {
  var children = document.getElementsByTagName('*') || document.all;
  var elements = new Array();
  
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
      if (classNames[j] == className) {
        elements.push(child);
        break;
      }
    }
  }
  
  return elements;
}

/*--------------------------------------------------------------------------*/

var Element = {
  toggle: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 
        (element.style.display == 'none' ? '' : 'none');
    }
  },

  hide: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'none';
    }
  },

  show: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = '';
    }
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },
   
  getHeight: function(element) {
    element = $(element);
    return element.offsetHeight; 
  }
}

var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content;
    
    if (this.adjacency && this.element.insertAdjacentHTML) {
      this.element.insertAdjacentHTML(this.adjacency, this.content);
    } else {
      this.range = this.element.ownerDocument.createRange();
      if (this.initializeRange) this.initializeRange();
      this.fragment = this.range.createContextualFragment(this.content);
      this.insertContent();
    }
  }
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },
  
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment, this.element);
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },
  
  insertContent: function() {  
    this.element.insertBefore(this.fragment, this.element.firstChild);
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },
  
  insertContent: function() {
    this.element.appendChild(this.fragment);
  }
});

Insertion.After = Class.create();
Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },
  
  insertContent: function() {
    this.element.parentNode.insertBefore(this.fragment, 
      this.element.nextSibling);
  }
});

/*--------------------------------------------------------------------------*/

var Effect = new Object();

Effect.Highlight = Class.create();
Effect.Highlight.prototype = {
  initialize: function(element) {
    this.element = $(element);
    this.start  = 153;
    this.finish = 255;
    this.current = this.start;
    this.fade();
  },
  
  fade: function() {
    if (this.isFinished()) return;
    if (this.timer) clearTimeout(this.timer);
    this.highlight(this.element, this.current);
    this.current += 17;
    this.timer = setTimeout(this.fade.bind(this), 250);
  },
  
  isFinished: function() {
    return this.current > this.finish;
  },
  
  highlight: function(element, current) {
    element.style.backgroundColor = "#ffff" + current.toColorPart();
  }
}


Effect.Fade = Class.create();
Effect.Fade.prototype = {
  initialize: function(element) {
    this.element = $(element);
    this.start  = 100;
    this.finish = 0;
    this.current = this.start;
    this.fade();
  },
  
  fade: function() {
    if (this.isFinished()) { this.element.style.display = 'none'; return; }
    if (this.timer) clearTimeout(this.timer);
    this.setOpacity(this.element, this.current);
    this.current -= 10;
    this.timer = setTimeout(this.fade.bind(this), 50);
  },
  
  isFinished: function() {
    return this.current <= this.finish;
  },
  
  setOpacity: function(element, opacity) {
    opacity = (opacity == 100) ? 99.999 : opacity;
    element.style.filter = "alpha(opacity:"+opacity+")";
    element.style.opacity = opacity/100 /*//*/;
  }
}

Effect.Scale = Class.create();
Effect.Scale.prototype = {
  initialize: function(element, percent) {
    this.element = $(element);
    this.startScale    = 1.0;
    this.startHeight   = this.element.offsetHeight;
    this.startWidth    = this.element.offsetWidth;
    this.currentHeight = this.startHeight;
    this.currentWidth  = this.startWidth;
    this.finishScale   = (percent/100) /*//*/;
    if (this.element.style.fontSize=="") this.sizeEm = 1.0;
    if (this.element.style.fontSize.indexOf("em")>0)
       this.sizeEm      = parseFloat(this.element.style.fontSize);
    if(this.element.effect_scale) {
      clearTimeout(this.element.effect_scale.timer);
      this.startScale  = this.element.effect_scale.currentScale;
      this.startHeight = this.element.effect_scale.startHeight;
      this.startWidth  = this.element.effect_scale.startWidth;
      if(this.element.effect_scale.sizeEm) 
        this.sizeEm    = this.element.effect_scale.sizeEm;      
    }
    this.element.effect_scale = this;
    this.currentScale  = this.startScale;
    this.factor        = this.finishScale - this.startScale;
    this.options       = arguments[2] || {}; 
    this.scale();
  },
  
  scale: function() {
    if (this.isFinished()) { 
      this.setDimensions(this.element, this.startWidth*this.finishScale, this.startHeight*this.finishScale);
      if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.finishScale + "em";
      if(this.options.complete) this.options.complete(this);
      return; 
    }
    if (this.timer) clearTimeout(this.timer);
    if (this.options.step) this.options.step(this);
    this.setDimensions(this.element, this.currentWidth, this.currentHeight);
    if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.currentScale + "em";
    this.currentScale += (this.factor/10) /*//*/;
    this.currentWidth = this.startWidth * this.currentScale;
    this.currentHeight = this.startHeight * this.currentScale;
    this.timer = setTimeout(this.scale.bind(this), 50);
  },
  
  isFinished: function() {
    return (this.factor < 0) ? 
      this.currentScale <= this.finishScale : this.currentScale >= this.finishScale;
  },
  
  setDimensions: function(element, width, height) {
    element.style.width = width + 'px';
    element.style.height = height + 'px';
  }
}

Effect.Squish = Class.create();
Effect.Squish.prototype = {
  initialize: function(element) {
    this.element = $(element);
    new Effect.Scale(this.element, 1, { complete: this.hide.bind(this) } );
  },
  hide: function() {
    this.element.style.display = 'none';
  } 
}

Effect.Puff = Class.create();
Effect.Puff.prototype = {
  initialize: function(element) {
    this.element = $(element);
    this.opacity = 100;
    this.startTop  = this.element.top || this.element.offsetTop;
    this.startLeft = this.element.left || this.element.offsetLeft;
    new Effect.Scale(this.element, 200, { step: this.fade.bind(this), complete: this.hide.bind(this) } );
  },
  fade: function(effect) {
    topd    = (((effect.currentScale)*effect.startHeight) - effect.startHeight)/2;
    leftd   = (((effect.currentScale)*effect.startWidth) - effect.startWidth)/2;
    this.element.style.position='absolute';
    this.element.style.top = this.startTop-topd + "px";
    this.element.style.left = this.startLeft-leftd + "px";
    this.opacity -= 10;
    this.setOpacity(this.element, this.opacity); 
    if(navigator.appVersion.indexOf('AppleWebKit')>0) this.element.innerHTML += ''; //force redraw on safari
  },
  hide: function() {
    this.element.style.display = 'none';
  },
  setOpacity: function(element, opacity) {
    opacity = (opacity == 100) ? 99.999 : opacity;
    element.style.filter = "alpha(opacity:"+opacity+")";
    element.style.opacity = opacity/100 /*//*/;
  }
}

Effect.Appear = Class.create();
Effect.Appear.prototype = {
  initialize: function(element) {
    this.element = $(element);
    this.start  = 0;
    this.finish = 100;
    this.current = this.start;
    this.fade();
  },
  
  fade: function() {
    if (this.isFinished()) return;
    if (this.timer) clearTimeout(this.timer);
    this.setOpacity(this.element, this.current);
    this.current += 10;
    this.timer = setTimeout(this.fade.bind(this), 50);
  },
  
  isFinished: function() {
    return this.current > this.finish;
  },
  
  setOpacity: function(element, opacity) {
    opacity = (opacity == 100) ? 99.999 : opacity;
    element.style.filter = "alpha(opacity:"+opacity+")";
    element.style.opacity = opacity/100 /*//*/;
    element.style.display = '';
  }
}

Effect.ContentZoom = Class.create();
Effect.ContentZoom.prototype = {
  initialize: function(element, percent) {
    this.element = $(element);
    if (this.element.style.fontSize=="") this.sizeEm = 1.0;
    if (this.element.style.fontSize.indexOf("em")>0)
       this.sizeEm = parseFloat(this.element.style.fontSize);
    if(this.element.effect_contentzoom) {
      this.sizeEm = this.element.effect_contentzoom.sizeEm;
    }
    this.element.effect_contentzoom = this;
    this.element.style.fontSize = this.sizeEm*(percent/100) + "em" /*//*/;
    if(navigator.appVersion.indexOf('AppleWebKit')>0) { this.element.scrollTop -= 1; };
  }
}
