var JS = {
	Author: 'Massimo Fuochi',

	Version: '2.1.02',
	
	Release: '08-FEB-2010',
	
	OS: {
		isLinux: function() {
			return !!(JS.Browser.getAgent().match(/linux/i));
		},
		
		isMac: function() {
			return !!(JS.Browser.getAgent().match(/mac/i));
		},
		
		isWin: function() {
			return !!(JS.Browser.getAgent().match(/win/i));
		}
	},
	
	Browser: {
		getAgent: function() {
			return navigator.userAgent.toLowerCase();
		},
		
		getCode: function() {
			return navigator.appCodeName;
		},
		
		getName: function() {
			return (this.isChrome() ? 'Google Chrome' :
			        this.isExplorer() ? 'Internet Explorer' :
			        this.isFirefox() ? 'Firefox' :
			        this.isNavigator() ? 'Netscape Navigator' :
			        this.isOpera() ? 'Opera' :
			        this.isSafari() ? 'Safari' : 'unknown'
			       );
		},
		
		getVersion: function() {
			return navigator.appVersion;
		},
		
		haveCookies: function() {
			return !!(navigator.cookieEnabled);
		},
		
		haveDHTML: function() {
			return !!(document.getElementById || document.all || document.layers);
		},
		
		haveJava: function() {
			return !!(navigator.javaEnabled());
		},
		
		isChrome: function() {
			return !!(this.getAgent().indexOf('applewebkit/') > -1 &&
			          this.getAgent().indexOf('chrome') > -1);
		},
		
		isExplorer: function() {
			return !!(window.attachEvent &&
			          this.getAgent().indexOf('opera') == -1);
		},
		
		isFirefox: function() {
			return !!(this.getAgent().indexOf('gecko') > -1 &&
			          this.getAgent().indexOf('khtml') == -1 &&
			          this.getAgent().indexOf('navigator') == -1);
		},
		
		isNavigator: function() {
			return !!(this.getAgent().indexOf('gecko') > -1 &&
			          this.getAgent().indexOf('navigator') > -1);
		},
		
		isOpera: function() {
			return !!(window.opera &&
			          this.getAgent().indexOf('opera') > -1);
		},
		
		isSafari: function() {
		  return !!(this.getAgent().indexOf('applewebkit/') > -1 &&
		            this.getAgent().indexOf('safari') > -1 &&
		            this.getAgent().indexOf('chrome') == -1);
		}
	},
	
	Host: {
		getHref: function() {
			return location.href;
		},
		
		setHref: function(href) {
			location.href = href;
		},
		
		getName: function() {
			return location.hostname;
		},
		
		getPort: function() {
			return location.port;
		},
		
		getProtocol: function() {
			return location.protocol;
		},
		
		getQuery: function() {
			return location.search;
		},
		
		reload: function() {
			location.reload();
		}
	},
	
	$c: function(tagName) {
		return Try.these(
			function() { return document.createElement(tagName); }
		) || false;
	},
	
	$n: function(name) {
		var os = JS.Document.getElementsByName(name);
		if (os) {
			if (os instanceof Array) {
				 for (var i in os) {
				   JS.Element.extend(os[i]);
				 }
			} else {
				JS.Element.extend(os);
			}
		}
		return os;
	},
	
	$t: function(text) {
		return Try.these(
			function() { return document.createTextNode(text); }
		) || false;
	},
	
	$: function(id) {
		var o = JS.Document.getElementById(id);
		if (o) {
			JS.Element.extend(o);
		}
		return o;
	},
	
	Document: {
		getElementById: function(id) {
			return Try.these(
				function() { return document.getElementById(id); },
				function() { return document.all(id); },
				function() { return document.layers(id); }
			) || false;
		},
		
		getElementsByName: function(name) {
			return Try.these(
				function() { return document.getElementsByName(name); },
				function() { return document.all(name); },
				function() { return document.layers(name); }
			) || false;
		},
		
		getElementsByTagName: function(tagName) {
			return Try.these(
				function() { return document.getElementsByTagName(name); }
			) || false;
		},
		
		getByTagName: function(tagName) {
			var os = this.getElementByTagName(tagName);
			if (os) {
				if (os instanceof Array) {
				  for (var i in os) {
				    JS.Element.extend(os[i]);
				  }
				} else {
					JS.Element.extend(os);
				}
			}
			return os;
		},
		
		getW: function() {
			return Try.these(
				function() { return document.body.clientWidth; },
				function() { return (typeof window.innerWidth == 'number' ? window.innerWidth : -1); }
			);
		},
		
		getH: function() {
			return Try.these(
				function() { return document.body.clientHeight; },
				function() { return (typeof window.innerHeight == 'number' ? window.innerHeight : -1); }
			);
		}
	},
	
	Element: {
		extend: function(o) {
			if (o.tagName == 'A' ||
			    o.tagName == 'LINK' ||
			    o.tagName == 'P') {
			  Object.__extend__(o, {
			  	getValue: function() {
			  	  return o.href;
			  	},
			  	setValue: function(value) {
			  	  o.href = value;
			  	}
			  });
			} else if (o.tagName == 'BUTTON' ||
			           o.tagName == 'DIV' ||
			           o.tagName == 'LABEL' ||
			           o.tagName == 'SPAN' ||
			           o.tagName == 'TD' ||
			           o.tagName == 'TH') {
			  Object.__extend__(o, {
			  	getValue: function() {
			  	  return o.innerHTML;
			  	},
			  	setValue: function(value) {
			  	  o.innerHTML = value;
			  	}
			  });
			} else if (o.tagName == 'INPUT') {
			  Object.__extend__(o, {
			  	getValue: function() {
			  	  if (o.type == 'checkbox' || o.type == 'radio') {
			  	    return o.checked;
			  	  } else if (o.type == 'image') {
			  	    return o.src;
			  	  } else {
			  	    return o.value;
			  	  }
			  	},
			  	setValue: function(value) {
			  	  if (o.type == 'checkbox' || o.type == 'radio') {
			  	    o.checked = value;
			  	  } else if (o.type == 'image') {
			  	    o.src = value;
			  	  } else {
			  	    o.value = value;
			  	  }
			  	}
			  });
			} else if (o.tagName == 'IFRAME' || o.tagName == 'IMG') {
			  Object.__extend__(o, {
			  	getValue: function() {
			  	  return o.src;
			  	},
			  	setValue: function(value) {
			  	  o.src = value;
			  	}
			  });
			} else if (o.tagName == 'SELECT') {
			  Object.__extend__(o, {
			  	getValue: function() {
			  	  if (o.selectedIndex > -1) {
			  	    return o.options[o.selectedIndex].value;
			  	  } else {
			  	    return '';
			  	  }
			  	},
			  	setValue: function(value) {
			  	  if (o.options.length > 0) {
			  	    for (var i = 0; i < o.options.length; i++) {
			  	      if (o.options[i].value == value) {
			  	        o.options[i].selected = true;
			  	        break;
			  	      }
			  	    }
			  	  }
			  	},
			  	clear: function() {
			  	  o.options.length = 0;
			  	}
			  });
			} else if (o.tagName == 'TEXTAREA') {
				Object.__extend__(o, {
			  	getValue: function() {
			  	  return o.value;
			  	},
			  	setValue: function(value) {
			  	  o.value = value;
			  	}
			  });
			} else {
			}
			
			Object.__extend__(o, {
				hide: function() {
					o.style.display = 'none';
				},
				show: function() {
					o.style.display = '';
				},
				getT: function() {
				  return o.offsetTop;
				},
				setT: function(value) {
				  o.style.top = value + 'px';
				},
				getL: function() {
				  return o.offsetLeft;
				},
				setL: function(value) {
				  o.style.left = value + 'px';
				},
				getW: function() {
				  return o.offsetWidth;
				},
				setW: function(value) {
				  o.style.width = value + 'px';
				},
				getH: function() {
				  return o.offsetHeight;
				},
				setH: function(value) {
				  o.style.height = value + 'px';
				},
				getDisabled: function() {
				  return !!(o.disabled);
				},
				setDisabled: function(value) {
				  o.disabled = value;
				},
				getVisible: function() {
				  return !!(o.style.visibility == '' || o.style.visibility == 'visible');
				},
				setVisible: function(value) {
				  o.style.visibility = (value ? 'visible' : 'hidden');
				}
			});
		}
	},
	
	String: {
	},
	
	Math: {
	  round: function(number, decimals) {
	  	if (decimals != null) {
	  		var percent = 1;
	  		for (var i = 0; i < decimals; i++) {
	  			percent = percent * 10;
	  		}
	  		return Math.round(number * percent) / percent;
	    } else {
	      return Math.round(number);
	    }
	  }
	}
};

var Ajax = {
	Http: {
	  xmlHttp: null,
	  
	  create: function() {
	    this.destroy();
	    
	    this.xmlHttp = Try.these(
	    	function() { return new XMLHttpRequest(); },
	    	function() { return new ActiveXObject('Msxml2.XMLHTTP') },
	    	function() { return new ActiveXObject('Microsoft.XMLHTTP'); },
	    	function() { return null; }
	    );
	  },
	  
	  destroy: function() {
	  	if (this.xmlHttp != null ) {
	  		this.xmlHttp.abort();
	  		this.xmlHttp = null;
	  	}
	  },
	  
	  isCreated: function() {
	  	return !!(this.xmlHttp != null);
	  },
	  
	  request: function(url, xml, method) {
	    if (method != null) {
	      this.xmlHttp.onreadystatechange = method;
	      this.xmlHttp.open('POST', url, true);
	    } else {
	      this.xmlHttp.open('POST', url, false);
	    }
	    
	    this.xmlHttp.send(xml);
	  },
	  
	  response: function() {
	    return this.xmlHttp.responseText;
	  }
	},
	
	Doc: {
    xmlDoc: null,

    create: function() {
      this.destroy();

      this.xmlDoc = Try.these(
        function() { return document.implementation.createDocument('', '', null); },
        function() { return new ActiveXObject('Microsoft.XMLDOM'); },
        function() { return null; }
      );

      if (this.isCreated()) {
        this.xmlDoc.async = false;
      }
    },

    destroy: function() {
      if (this.xmlDoc != null) {
        this.xmlDoc = null;
      }
    },

    get: function(tagName) {
      if (this.isCreated()) {
        return this.xmlDoc.getElementsByTagName(tagName);
      }
    },

    isCreated: function() {
      return !!(this.xmlDoc != null);
    },

    load: function(xml) {
      if (this.isCreated()) {
        if (JS.Browser.isExplorer()) {
          this.xmlDoc.loadXML(xml);
        } else {
          parser = new DOMParser();
          this.xmlDoc = parser.parseFromString(xml, 'text/xml');
        }
      }
    }
  }
};

var Cookies = {
  read: function(name, defaultValue) {
    if (document.cookie.length > 0) {
      var position = document.cookie.indexOf(name + '=');
      if (position > -1) {
        position += name.length + 1;
        var count = document.cookie.indexOf(';', position);
        if (count > -1) {
          return document.cookie.substring(position, count);
        } else {
          return document.cookie.substring(position, document.cookie.length);
        }
      }
    }
    return (defaultValue ? defaultValue : '');
  },
  write: function(name, value, days) {
    var expire = new Date();
    expire.setDate(expire.getDate() + (days != null ? days : 365));

    document.cookie = name + '=' + value + ';expires=' + expire.toGMTString() + ';path=/';
  }
};

var Try = {
  these: function() {
    var returnValue;
    for (var i = 0, length = arguments.length; i < length; i++) {
      var argument = arguments[i];
      try {
        returnValue = argument();
        break;
      } catch (e) {
        // do nothing
      }
    }
    return returnValue;
  }
};

Object.__extend__ = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }
  return destination;
};