var Util = new Object();
Util.addEvent = function(target, type, listener){

//alert(target + ":" + target.addEventListener + ":\n" + listener)
	if (target.addEventListener){
		target.addEventListener(type, listener, false);
    } else {
		target.attachEvent('on' + type, 
			function() { 
				listener.call(target, window.event); 
			});
	}
}
Util.removeEvent = function(obj,method){

}
Util.wait = function(flag, fanc, timer){
	var _flag = flag;
	var _func = func;
	var _timer = timer;
	timerID = setInterval(
			function(){
				if(eval(_flag)){
					clearInterval(timerID);
					timerID = null;
					_func();
				}
			},
			 _timer); 
}

var Events = new Object();
Events.load = "load";
Events.click = "click";

Baloon = {
   index: 0,

   open: function(field, msg) {
      if(!field._validbaloon) {
         var obj = new this.element(field);
         obj.create();
         field._validbaloon = obj;
         if(field.type == 'radio' || field.type == 'checkbox') {
            for(var i = 0, e; e = field.form[field.name][i]; i++)
               Util.addEvent(e, 'focus', function() { obj.close(); });
         }
      }

      field._validbaloon.show(msg);
   },

   element: function() {
      this.initialize.apply(this, arguments);
   }
};

Baloon.element.prototype = {
   initialize: function(field) {
      this.parent = Baloon;
      this.field = field;
   },

   create: function() {
		var field  = this.field;
		var base = document.createElement("span");
		base.className = 'baloon';

		var offset = Position.offset(field);
		var top  = offset.y - 25;
		var left = offset.x - 130 + field.offsetWidth;
		base.style.top  = top +'px';
		base.style.left = left+'px';
		var box = document.createElement('div');
		box.className = "baloon";
		var right = document.createElement('p');
		var self = this;
		Util.addEvent(box, 'click', function() { self.toTop(); });

		var msg = document.createElement('span');
		var div = document.createElement('div');
      
		var bindClose = function() { self.close(); };
		var link = document.createElement('a');

		Util.addEvent(field, 'focus', bindClose);

		div.appendChild(msg);
		box.appendChild(div);
      
		base.appendChild(box);
		base.appendChild(right);
		document.body.appendChild(base);

		this.box = base;
		this.msg = msg;
   },

   show: function(msg) {
      var field = this.field;
      this.msg.innerHTML  = msg;

      this.box.style.display = '';
      this.toTop();

      if(field.type != 'radio' && field.type != 'checkbox') {
         var colors = new Array('#FF6666', '#FFAAAA', '#FF6666', '#FFAAAA');
         window.setTimeout(function() {
            if(colors.length > 0) {
               field.style.backgroundColor = colors.shift();
               window.setTimeout(arguments.callee, 70);
            }
         }, 10);
      }
   },

   close: function() {
      this.box.style.display = 'none';
      this.field.style.backgroundColor = '';
   },

   visible: function() {
      return (this.box.style.display == '');
   },

   toTop: function() {
      this.box.style.zIndex = ++ this.parent.index;
   }
};
var Position = {
   offset: function(elm) {
      var pos = {};
      pos.x = this.getOffset('Left', elm);
      pos.y = this.getOffset('Top', elm);
      return pos;
   },

   getOffset: function(prop, el) {
      if(!el.offsetParent || el.offsetParent.tagName.toLowerCase() == "body")
         return el['offset'+prop];
      else
         return el['offset'+prop]+ this.getOffset(prop, el.offsetParent);
   }
};
