var $ = function (a) { return document.getElementById(a); };
var $S = function (a) { return document.getElementById(a).style; };
var $D = new Object();
$D.global = new Object();

// Objeto para eliminar eventos
$D.events = {
	'stop': function(ev) { ev = ev.browserEvent || ev; this.stopPropagation(ev); this.preventDefault(ev); },
	'stopPropagation': function(ev) { if (ev.stopPropagation) ev.stopPropagation(); else ev.cancelBubble = true; },
	'preventDefault': function(ev) { if (ev.preventDefault) ev.preventDefault(); else ev.returnValue = false; }
};

// Biblioteca com funções básicas
$D.basic = {
	'getPos': function(e) {
		if (typeof e == 'string') e = $(e);
		var left = 0;
		var top = 0;
		while (e.offsetParent) {
			left += e.offsetLeft;
			top += e.offsetTop;
			e = e.offsetParent;
		}
		left += e.offsetLeft;
		top += e.offsetTop;
		return {x:left, y:top};
	},
	'getSize': function(e) {
		if (typeof e == 'string') e = $(e);
		return {x:e.offsetWidth, y:e.offsetHeight};
	},
	'getMousePos': function(e) {
		if (e.pageX || e.pageY) return {x:e.pageX, y:e.pageY};
		return {x:e.clientX+this.getScroll().x-document.body.clientLeft, y:e.clientY+this.getScroll().y-document.body.clientTop};
	},
	'getScroll': function() {
		if (self.pageXOffset) sX = self.pageXOffset; else if (document.documentElement && document.documentElement.scrollLeft) sX = document.documentElement.scrollLeft; else if (document.body) sX = document.body.scrollLeft;
		if (self.pageYOffset) sY = self.pageYOffset; else if (document.documentElement && document.documentElement.scrollTop) sY = document.documentElement.scrollTop; else if (document.body) sY = document.body.scrollTop;
		return {x:sX, y:sY};
	},
	'getDocSize': function() {
		return {x:document.body.offsetWidth, y:document.body.offsetHeight};
	},
	'getDocVisibleSize': function() {
		var _x, _y;
		if (window.innerWidth) {
			_x = window.innerWidth;
		} else if (document.documentElement && document.documentElement.clientWidth) {
			_x = document.documentElement.clientWidth;
		} else if (document.body) {
			_x = document.body.clientWidth;
		}
		if (window.innerHeight) {
			_y = window.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			_y = document.documentElement.clientHeight;
		} else if (document.body) {
			_y = document.body.clientHeight;
		}
		return {x:_x, y:_y};
	},
	'zIndex': 1000,
	'bringToFront': function(e, type) {
		if (typeof e == 'string') e = $(e);
		e.style['zIndex'] = $D.basic.zIndex++;
	},
	'getDistance': function(p1, p2) { return Math.round(Math.sqrt(Math.pow(Math.abs(p2.x-p1.x),2)+Math.pow(Math.abs(p2.y-p1.y),2))); },
	'getKeyCode': function(ev) {
		ev = ev.browserEvent || ev;
		return ev.charCode || ev.keyCode || 0;
	},
	'addSelectValue': function(ob, vl, tx, sl) {
		var aux = document.createElement("OPTION");
		ob.appendChild(aux);
		aux.value = vl;
		aux.text = tx;
	}
};

// JSON
$D.json = {
	'characs': {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},
	'decode': function(tx) { try { return eval('(' + tx + ')'); } catch(e) { return null; } },
	'encode': function(ob,wl) {
		var a, i, k, l, r = /["\\\x00-\x1f\x7f-\x9f]/g, v;
		switch (typeof ob) {
			case 'string': return r.test(ob)?'"' + ob.replace(r, function (a) { var c = $D.json.characs[a]; if (c) return c; c = a.charCodeAt(); return '\\u00' + Math.floor(c/16).toString(16)+(c%16).toString(16); }) + '"' : '"' + ob + '"';
			case 'number': return isFinite(ob) ? String(ob) : 'null';
			case 'boolean':
			case 'null': return String(ob);
			case 'object': a = []; if (!ob) return 'null'; if (typeof ob.toJSON === 'function') return $D.json.encode(ob.toJSON()); if (typeof ob.length === 'number' && !(ob.propertyIsEnumerable('length'))) { l = ob.length; for (i = 0; i < l; i += 1) a.push($D.json.encode(ob[i], wl) || 'null'); return '[' + a.join(',') + ']'; } if (wl) { l = wl.length; for (i = 0; i < l; i += 1) { k = wl[i]; if (typeof k === 'string') { v = $D.json.encode(ob[k], wl); if (v) a.push($D.json.encode(k) + ':' + v); } } } else for (k in ob) if (typeof k === 'string') { v = $D.json.encode(ob[k], wl); if (v) a.push($D.json.encode(k) + ':' + v); } return '{' + a.join(',') + '}';
		}
	},
	'parse': function (tx,ft) {
		var j;
		function walk(k,v) { var i, n; if (v && typeof v === 'object') for (i in v) if (Object.prototype.hasOwnProperty.apply(v, [i])) { n = walk(i, v[i]); if (n !== undefined) v[i] = n; } return ft(k,v); }
		if (/^[\],:{}\s]*$/.test(tx.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { j = eval('(' + tx + ')'); return typeof ft === 'function' ? walk('', j) : j; }
		throw new SyntaxError('parseJSON');
	}
};

// Listener
$D.listener = {
	'itens': [],
	'push': function(ob, ev, fn, id) {
		this.aux = new Object();
		this.aux.ob = ob;
		this.aux.ev = ev;
		this.aux.fn = fn;
		this.aux.id = id || '';
		this.itens.push(this.aux);
		this.aux = null;
		ob[ev] = function() {$D.listener.run(ob,ev,arguments);};
	},
	'pop': function(id) {
		
	},
	'run': function(ob,ev,ag) { for (var i = 0; i < this.itens.length; i++) if (this.itens[i].ob == ob && this.itens[i].ev == ev) { var r = this.itens[i].fn(ag); if (r) return r; } }
};

// Pega as propriedades da página
$D.page = {
	'size': {
		'x': 0,
		'y': 0
	},
	'visibleSize': {
		'x': 0,
		'y': 0
	},
	'refresh': function() {
		$D.page.size['x'] = $D.basic.getDocSize().x;
		$D.page.size['y'] = $D.basic.getDocSize().y;
		$D.page.visibleSize['x'] = $D.basic.getDocVisibleSize().x;
		$D.page.visibleSize['y'] = $D.basic.getDocVisibleSize().y;
	}
};
$D.listener.push(window,'onload',$D.page.refresh);
$D.listener.push(window,'onresize',$D.page.refresh);

// Timer
$D.timercontrol = {
	'size': 0,
	'itens': [],
	'play': function(id) { $D.timercontrol.itens[id].intervalid = setInterval('$D.timercontrol.time('+id+');',$D.timercontrol.itens[id].interval); },
	'stop': function(id) { clearInterval($D.timercontrol.itens[id].intervalid); },
	'time': function(id) { $D.timercontrol.itens[id].ontime(); }
};
$D.timer = function() { this.id = ++$D.timercontrol.size; $D.timercontrol.itens[this.id] = this; };
$D.timer.prototype = {
	'interval': 100,
	'play': function() { $D.timercontrol.play(this.id); this.onplay(); },
	'stop': function() { $D.timercontrol.stop(this.id); this.onstop(); },
	'onplay': function() {}, 'onstop': function() {}, 'ontime': function() {}
};

// AJAX
$D.ajaxcontrol = {'version': '','itens': ['Msxml2.XMLHTTP.8.0','Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP.2.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP']};
$D.ajax = function(pt) {
	this.itens = [];
	for (var k in pt) this[k] = pt[k];
	if (window.ActiveXObject) {
		if ($D.ajaxcontrol.version == '') for (var i = 0; i < $D.ajaxcontrol.itens.length; i++) {
			try { this.obj = new ActiveXObject($D.ajaxcontrol.itens[i]); $D.ajaxcontrol.version = $D.ajaxcontrol.itens[i]; break; } catch (e) { continue; }
			if (i >= ($D.ajaxcontrol.itens.length-1)) return false;
		} else try { this.obj = new ActiveXObject($D.ajaxcontrol.version); } catch (e) { return false; }
	} else if (window.XMLHttpRequest) {
		$D.ajaxcontrol.version = 'XMLHttpRequest';
		this.obj = new XMLHttpRequest();
	} else return false;
	return true;
};
$D.ajax.prototype = {
	'method': 'POST',
	'itens': [],
	'push': function(k,v) { this.itens[k] = v; },
	'pop': function(k) { delete this.itens[k]; },
	'clear': function() { delete this.itens; this.itens = [] },
	'open': function() {
		this.aux = '';
		for (var i in this.itens) { if (this.aux != '') this.aux += '&'; this.aux += i+'='+encodeURIComponent(this.itens[i]); }
		this.obj.open(this.method, (this.method.toUpperCase() == 'GET')?(this.url+'?'+this.aux):this.url, true);
		var this_obj = this.obj;
		var this_ajax = this;
		with (this_obj) {
			setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			setRequestHeader("CharSet", "UTF-8");
			onreadystatechange = function () {
				try {
					this_ajax.onchange(this_obj.readyState);
					if (this_obj.readyState == 4) {
						this_ajax.onload(this_obj.status);
						if (this_obj.status == 200) {
							this_ajax.xml = this_obj.responseXML;
							this_ajax.text = this_obj.responseText;
							this_ajax.oncomplete();
						} else this_ajax.onerror(this_obj.status, this_obj.statusText);
					}
				} catch(e) {}
			};
			send((this_ajax.method.toUpperCase() == 'GET')?null:this_ajax.aux);
		}
	},
	'stop': function() { this.obj.abort(); },
	'oncomplete': function() {}, 'onload': function() {}, 'onchange': function() {}, 'onerror': function() {}
};

// Objeto para criação de Drag 'n Drop com Elementos HTML
$D.dragdrop = {
	'itens': [],
	'now': null,
	'dragstart': '',
	'dragend': '',
	'moving': false,
	'blockmenu': false,
	'push': function(a,b,esps) {
		
		if (typeof a == 'string') a = $(a);
		if (typeof b == 'string') b = $(b);
		
		if (esps && esps.cursor) a.style['cursor'] = esps.cursor;
		var atual = this.itens.length;
		this.itens[atual] = {'ob1': a,'ob2': b,'esps': esps || {}};
		a.dragId = atual;
		
		a.onmousedown = function(ev) {
			ev = ev || event;
			$D.dragdrop.now = this.dragId;
			if ($D.dragdrop.itens[this.dragId].esps['type'] != 'hide') {
				if (!isNaN(parseInt($D.dragdrop.itens[this.dragId].ob2.style.left))) this.pX = parseInt($D.dragdrop.itens[this.dragId].ob2.style.left);
				if (!isNaN(parseInt($D.dragdrop.itens[this.dragId].ob2.style.top))) this.pY = parseInt($D.dragdrop.itens[this.dragId].ob2.style.top);
				$D.dragdrop['difX'] = $D.basic.getMousePos(ev).x-this.pX;
				$D.dragdrop['difY'] = $D.basic.getMousePos(ev).y-this.pY;
			}
			
			if ($D.dragdrop.itens[this.dragId].esps['type'] == 'clone') {
				var temp = $D.dragdrop.itens[this.dragId].ob2.cloneNode(true);
				temp.style['top'] = temp.style['left'] = '0px';
				$D.dragdrop.clone.appendChild(temp);
				delete temp;
			}
			
			if ($D.dragdrop.itens[this.dragId].esps['type'] != 'hide') $D.basic.bringToFront($D.dragdrop.itens[this.dragId].ob2, $D.dragdrop.itens[this.dragId].esps['menu']);
			$D.basic.bringToFront($D.dragdrop.clone, $D.dragdrop.itens[this.dragId].esps['menu']);
			$D.basic.bringToFront($D.dragdrop.border, $D.dragdrop.itens[this.dragId].esps['menu']);
			$D.basic.bringToFront($D.dragdrop.hide, $D.dragdrop.itens[this.dragId].esps['menu']);
			
			$D.events.stop(ev);
			
			return false;
			
		};
		
		return $D.dragdrop.itens[atual].esps;
	},
	'refresh': function(ag) {
		if ($D.dragdrop.now != null) {
			if (!$D.dragdrop.moving) {
				$D.dragdrop.moving = true;
				var obj = $D.dragdrop.itens[$D.dragdrop.now].esps;
				if (obj.ondragstart) obj.ondragstart();
			}
			ev = ag[0] || event;
			$D.dragdrop.mouse = $D.basic.getMousePos(ev);
			var newX = $D.dragdrop.mouse.x-$D.dragdrop.difX;
			var newY = $D.dragdrop.mouse.y-$D.dragdrop.difY;
			var obj = $D.dragdrop.itens[$D.dragdrop.now];
			
			if (!obj.esps['left']) obj.esps['left'] = 0;
			if (!obj.esps['top']) obj.esps['top'] = 0;
			
			if (!obj.esps['width']) obj.esps['width'] = $D.page.size.x;
			if (!obj.esps['height']) obj.esps['height'] = $D.page.size.y;
			
			if (!obj.esps['block']) {
				obj.esps['left'] = 0;
				obj.esps['top'] = 0;
				obj.esps['width'] = $D.page.size.x;
				obj.esps['height'] = $D.page.size.y;
			}
			
			if (obj.esps['type'] != 'hide') {
				if (newX <= obj.esps['left']) newX = obj.esps['left']; else if (newX >= (obj.esps['width']-$D.basic.getSize(obj.ob2).x+obj.esps['left'])) newX = obj.esps['width']-$D.basic.getSize(obj.ob2).x+obj.esps['left'];
				if (newY <= obj.esps['top']) newY = obj.esps['top']; else if (newY >= (obj.esps['height']-$D.basic.getSize(obj.ob2).y+obj.esps['top'])) newY = obj.esps['height']-$D.basic.getSize(obj.ob2).y+obj.esps['top'];
			}
			
			if (obj.esps['type'] == 'border') {
				$D.dragdrop.border.style['display'] = 'block';
				$D.dragdrop.border.style['left'] = newX+'px';
				$D.dragdrop.border.style['top'] = newY+'px';
				$D.dragdrop.border.style['width'] = $D.basic.getSize(obj.ob2).x-2+'px';
				$D.dragdrop.border.style['height'] = $D.basic.getSize(obj.ob2).y-2+'px';
				$D.dragdrop.newPosX = newX;
				$D.dragdrop.newPosY = newY;
			} else if (obj.esps['type'] == 'clone') {
				$D.dragdrop.clone.style['display'] = 'block';
				$D.dragdrop.clone.style['left'] = newX+'px';
				$D.dragdrop.clone.style['top'] = newY+'px';
				$D.dragdrop.clone.style['width'] = $D.basic.getSize(obj.ob2).x+'px';
				$D.dragdrop.clone.style['height'] = $D.basic.getSize(obj.ob2).y+'px';
				$D.dragdrop.newPosX = newX;
				$D.dragdrop.newPosY = newY;
			} else if (obj.esps['type'] == 'hide') {
				$D.dragdrop.hide.style['display'] = 'block';
				$D.dragdrop.hide.style['left'] = $D.dragdrop.mouse.x+10+'px';
				$D.dragdrop.hide.style['top'] = $D.dragdrop.mouse.y+15+'px';
				
				//$D.dragdrop.hide.src = ($D.dragdrop.dragstart == $D.dragdrop.dragend)?'imagens/drop-yes.gif':'imagens/drop-no.png';
				
			} else {
				obj.ob2.style.left = newX+'px';
				obj.ob2.style.top = newY+'px';
			}
			
			if (obj.esps.ondragmove) obj.esps.ondragmove();
			
			$D.events.stop(ev);
			
			return false;
		}
	},
	'stop': function(ag) {
		ev = ag[0] || event;
		if ($D.dragdrop.now != null && $D.dragdrop.moving) {
			$D.dragdrop.moving = false;
			var obj = $D.dragdrop.itens[$D.dragdrop.now];
			if (obj.esps['type'] == 'border' || obj.esps['type'] == 'clone') {
				obj.ob2.style.left = $D.dragdrop.newPosX+'px';
				obj.ob2.style.top = $D.dragdrop.newPosY+'px';
			}
			$D.dragdrop.border.style['display'] = 'none';
			$D.dragdrop.clone.style['display'] = 'none';
			$D.dragdrop.hide.style['display'] = 'none';
			$D.dragdrop.clone.innerHTML = '';
			$D.dragdrop.now = null;
			$D.events.stop(ev);
			if (obj.esps.ondragend) obj.esps.ondragend();
			return false;
		} else {
			$D.dragdrop.border.style['display'] = 'none';
			$D.dragdrop.clone.style['display'] = 'none';
			$D.dragdrop.hide.style['display'] = 'none';
			$D.dragdrop.clone.innerHTML = '';
			$D.dragdrop.now = null;
			//$D.events.stop(ev);
		}
	},
	'open': function() {
		$D.dragdrop.border = document.createElement('div');
		$D.dragdrop.border.style.cssText = 'position:absolute;top:0px;left:0px;width:10px;height:10px;border:dashed 1px #e0e0e0;display:none;';
		$('DOM').parentNode.insertBefore($D.dragdrop.border,$('DOM'));
		$D.dragdrop.clone = document.createElement('div');
		$D.dragdrop.clone.style.cssText = 'position:absolute;top:0px;left:0px;width:10px;height:10px;display:none;filter:alpha(opacity=20);opacity:0.2;';
		$('DOM').parentNode.insertBefore($D.dragdrop.clone,$('DOM'));
		$D.dragdrop.hide = document.createElement('img');
		//$D.dragdrop.hide.src = 'imagens/drop-no.gif';
		$D.dragdrop.hide.style.cssText = 'position:absolute;top:0px;left:0px;display:none;';
		$('DOM').parentNode.insertBefore($D.dragdrop.hide,$('DOM'));
		$D.listener.push(document,'onmousemove',$D.dragdrop.refresh);
		$D.listener.push(document,'onmouseup',$D.dragdrop.stop);
		$D.listener.push(document,'onkeypress',$D.dragdrop.escape);
	},
	'escape': function(ag) {
		if ($D.dragdrop.moving) {
			ev = ag[0] || event;
			if ($D.basic.getKeyCode(ev) == 27) {
				var obj = $D.dragdrop.itens[$D.dragdrop.now];
				if (obj.esps.ondragend) obj.esps.ondragend();
				$D.dragdrop.border.style['display'] = 'none';
				$D.dragdrop.clone.style['display'] = 'none';
				$D.dragdrop.hide.style['display'] = 'none';
				$D.dragdrop.clone.innerHTML = '';
				$D.dragdrop.now = null;
				$D.dragdrop.moving = false;
				$D.events.stop(ev);
			}
		}
	}
};
$D.listener.push(window,'onload',$D.dragdrop.open);

$D.trace = new Object();

$D.trace.enabled = false;
$D.trace.create = function(){
	var divTrace = document.createElement('div');
	divTrace.style.cssText = 'position:absolute;top:50px;left:50px;width:900px;height:150px;border:solid 1px black;background-color:white;overflow:auto;padding:3px;display:none;z-index:3000;font:normal 14px Courier;';
	divTrace.ondblclick = $D.trace.clear;
	divTrace.id = 'tracer';
	
	$('DOM').parentNode.insertBefore(divTrace,$('DOM'));	
	$D.trace.enabled = true;	
};

$D.trace.add = function(a) {
	if ($D.trace.enabled) {
		$('tracer').style.display = 'block';
		$('tracer').innerHTML += a.toString()+'<br />';
		$('tracer').scrollTop = 100000;
	}
};

$D.trace.clear = function () {
	if ($D.trace.enabled) {
		$('tracer').innerHTML = '';
		$('tracer').scrollTop = 100000;
		$('tracer').style.display = 'none';
	}
};