/* Visibility manipulation */
Element.isvisible = function(el){
  return (el.style.visibility != 'hidden');
}
Element.appear = function(el){
  el.style.visibility = 'visible';
}
Element.disappear = function(el){
  el.style.visibility = 'hidden';
}

/* Environment Object */
if(!Env)
  var Env = new Object();

Env.is_opera   = (navigator.userAgent.indexOf("Opera") >= 0);
Env.is_safari  = ((navigator.appVersion.indexOf("Konqueror") >= 0) ||
                          (navigator.appVersion.indexOf("Safari") >= 0));
Env.is_mozilla = (!Env.is_safari && navigator.userAgent.indexOf("Gecko") >= 0);
Env.is_ie      = (document.all && !Env.is_opera);

Env.scrollTop   = function(){ return (document.documentElement) ? document.documentElement.scrollTop : document.body.scrollTop; };
Env.scrollLeft  = function(){ return (document.documentElement) ? document.documentElement.scrollLeft : document.body.scrollLeft; };

Env.windowHeight = function(){ return (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight); };
Env.windowWidth  = function(){ return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth); };

/* Object Extensions */
Object.extend(Hash.prototype, { has:  function(index){ return !!(this[index]); } });
Mesh.ConvertToHash = function(value){
                      if(value instanceof Array){
                        var newValue = value.collect(function(value, index){ return Mesh.ConvertToHash(value); });
                        return newValue;
                      } else if(value instanceof Object){
                        var newValue = $H(value);
                        newValue.each(function(pair){ newValue[pair.key] = Mesh.ConvertToHash(pair.value); });
                        return newValue;
                      } else {
                        return value;
                      }
                    };
/* String Extensions */
String.prototype.trim   = function() { return this.replace(/^\s+|\s+$/g, ''); };

Number.prototype.numberFormat = function(precision, seperator){
                                  var result = this.toFixed(precision);
                                  var regexp = new RegExp('(\\d)(\\d\\d\\d)\\'+seperator);
                                  result = result.replace(/(\d)(\d\d\d)(\.\d*)?$/, '$1'+seperator+'$2$3');
                                  while(result.match(/\d{4,}/))
                                    result = result.replace(regexp, '$1'+seperator+'$2'+seperator);
                                  return result;
                                };

Mesh.ObjectClone  = function(toClone){
                     var clone = new toClone.constructor();
                     for(var property in toClone){
                       if(typeof toClone[property] == 'object'){
                         clone[property] = Mesh.ObjectClone(toClone[property]);
                       } else {
                         clone[property] = toClone[property];
                       }
                     }
                     return clone;
                   };

Event.getKeyCode = function(e) { return (e.charCode) ? e.charCode : e.keyCode; };

Mesh.AddSelectOption = function(element, node){
                        if(Env.is_ie)
                          element.add(node);
                        else
                          element.add(node, null);
                      };

Mesh.ClearSelectList = function(element){
                        var count = element.options.length - 1;
                        for(var i = count; i >= 0; i--)
                          element.options[i] = null;
                      };

/* Events Handling For Objects */
Mesh.EventsBase = {
  fireEvent:            function(){
                          var args  = $A(arguments);
                          var event = args.shift();
                          if(this.events.has(event)){
                            return this.events[event].all(function(value, index){ return value.apply(null, args); });
                          }
                          return true;
                        },
  registerEvent:        function(event, handler){
                          if(this.events.has(event))
                            this.events[event].push(handler);
                        }
};