var Prototype = {
  Version: '1.5.1.1',
  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },
  emptyFunction: function() { }
};

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
};

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Function.prototype, {
  bind: function() {
    if (arguments.length < 2 && arguments[0] === undefined) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  }
});

Object.extend(String.prototype, {  
  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  }
});

Array.prototype.toArray = Array.prototype.clone;

function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

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;
  }
};
   
function getElementsByClassName(classname) {
    var a = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var els = document.getElementsByTagName("*");
    for(var i=0,j=els.length; i<j; i++)
        if(re.test(els[i].className))a.push(els[i]);
    return a;
};

function isArray(object) {
    return object && object.constructor === Array;
};
  
function isElement(object) {
    return object && object.nodeType == 1;
};

function isString(object) {
    return typeof object == "string";
};

function isNumber(object) {
    return !isNaN(object);
};

function isUndefined(object) {
    return typeof object == "undefined";
};

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (isString(element))
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}

function $docRoot(transport){
  return transport.responseXML.documentElement;
};

function $childNode(father,childName){
  var args = [];
  for ( var i = 0; i < arguments.length; i++ ) {
    args.push( arguments[i] );
  };
  if(arguments.length == 2){
    args.push(0);
  };
  return __childNodei.apply(this,args);
}

function $childValue(father,childName){
  var args = [];
  for ( var i = 0; i < arguments.length; i++ ) {
    args.push( arguments[i] );
  };
  if(arguments.length == 2){
    args.push(0);
  };
  return __childValuei.apply(this,args);
}

function __childNodei(father,childName,i){
  var children = father.childNodes;
  var k=-1;
  for(j=0;j<children.length;j++){
    if (isElement(children[j])){
	  	if(children[j].nodeName == childName){
	  	    k = k + 1;
	  	    if(k == i){
	  		  return children[j];
	  		};
	  	};
  	}
  }
  return null;
}

function __childValuei(father,childName,i){
  if(__childNodei(father,childName,i).firstChild){
    return __childNodei(father,childName,i).firstChild.nodeValue;
  }else{
    return null;
  }
}

function $xResponse(transport,id_Index) {
  var elements=$docRoot(transport).getElementsByTagName("response");
  if(isUndefined(id_Index)){
    if(elements.length > 0){
      return elements[0];
    }else{
      return null;
    }
  }
  
  if(isNumber(id_Index)){
    if(elements.length > id_Index){
      return elements[id_Index];
    }else{
      return null;
    }
  }
  for( i=0;i<elements.length;i++){    	
    if(elements[i].getAttribute("id") == id_Index){
	  return elements[i];
    }	   
  };
  return null;
};

function $xErrors(transport) {
  var elements=$docRoot(transport).getElementsByTagName("error");
  var errors="";
  if(elements.length == 0){
    return null;
  }
  for( i=0;i<elements.length;i++){
    if(elements[i].firstChild){
      errors = errors + elements[i].firstChild.nodeValue;
    }
  };
  return errors;
};

function $evalJSON(text){  
  if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
    replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
    replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
    return eval( '(' + text + ')');
  }else{
    return null;
  }
}

function $errors(transport) {
  var response=$evalJSON(transport.responseText);
  var elements = response.root.error;
  var errors="";
  if(isUndefined(elements)){
    return null;
  }
  if(isString(elements)){
    return elements;
  }
  for( i=0;isArray(elements)&&i<elements.length;i++){
    errors = errors + '<br>'+ elements[i];
  };
  return errors;
};

function $response(transport,id_Index) {
  var response=$evalJSON(transport.responseText);
  var elements = response.root.response;
  if(isUndefined(elements)){
    return null;
  }
  
  if(isUndefined(id_Index)){
    if(isArray(elements) && elements.length > 0){
      return elements[0];
    }else if(!isUndefined(elements)){
      return elements;
    }
  }else if(isNumber(id_Index)){
    if(isArray(elements) && elements.length > id_Index){
      return elements[id_Index];
    }else if(!isUndefined(elements)){
      return elements;
    }
  }else if(isString(id_Index)){
    if(isArray(elements)){
      for(i=0;isArray(elements) && i<elements.length;i++){    	
        if(elements[i].id == id_Index){
	      return elements[i];
        }	   
      };
    }else if(!isUndefined(elements) && elements.id == id_Index){
      return elements;
    }
  };
  return null;
};

var Ajax = {
  getTransport: function() {
  	return Try.these(      
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  }
};

Ajax.Base = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   ''
    };
    Object.extend(this.options, options || {});
    this.options.method = this.options.method.toLowerCase();
  }
};

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  _complete: false,

  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = this.options.parameters || '';

    if (this.method != 'get' && this.method != 'post') {
      this.method = 'post';
    }

    this.parameters = params;

	if (this.method == 'get')
		this.url += (this.url.indexOf('?')>-1 ? '&' : '?') + params;
	else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
		params += '&_=';		
    try {
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        this.transport.open(this.method.toUpperCase(), this.url,this.options.asynchronous);        		
		if (this.options.asynchronous)
		  setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);
		this.setRequestHeaders();
		this.body = this.method == 'post' ? (this.options.postBody || params) : null;
		
		this.transport.send(this.body);
		if (!this.options.asynchronous && this.transport.overrideMimeType)
		  this.onStateChange();	  
    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = [
      'X-Requested-With', 'XMLHttpRequest',
      'X-Prototype-Version', Prototype.Version,
      'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'
    ];

    if (this.method == 'post') {
      headers.push('Content-type',this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : ''));

      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers.push('Connection','close');
    }

	if (this.options.requestHeaders)
      headers.push.apply(headers, this.options.requestHeaders);//?
    for (var i = 0; i < headers.length; i += 2)
      this.transport.setRequestHeader(headers[i], headers[i+1]);
  },

  success: function() {
    return !this.transport.status
        || (this.transport.status >= 200 && this.transport.status < 300);
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState];
    var transport = this.transport;

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport);
      } catch (e) {
        this.dispatchException(e);
      }
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(transport);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) { return null }
  },
  
  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
  }
});

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;
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name)
      return inputs;

    var matchingInputs = new Array();
    for (var i = 0; i < inputs.length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) ||
          (name && input.name != name))
        continue;
      matchingInputs.push(input);
    }

    return matchingInputs;
  },

  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disabled = 'true';
    }
  },

  enable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.disabled = '';
    }
  },

  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 'submit':
      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) {
    return Form.Element.Serializers[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  selectOne: function(element) {
    var value = '', opt, index = element.selectedIndex;
    if (index >= 0) {
      opt = element.options[index];
      value = opt.value;
      if (!value && !('value' in opt))
        value = opt.text;
    }
    return [element.name, value];
  },

  selectMany: function(element) {
    var value = new Array();
    for (var i = 0; i < element.length; i++) {
      var opt = element.options[i];
      if (opt.selected) {
        var optValue = opt.value;
        if (!optValue && !('value' in opt))
          optValue = opt.text;
        value.push(optValue);
      }
    }
    return [element.name, value];
  }
}