var Overlay = function(params){
	this.id = params.id;
	this.opacityDelta = 0.1;
	this.durationDelta = 15;
	this.clipDelta = 25;
	this.opacityLimit = 0.3;
	this.status = 'hidden';
	this.createDomNode();
	this.createEvents();
}

Overlay.create = function(params){
	Overlay.instance = Overlay.instance ? Overlay.instance : new Overlay(params);
	return Overlay.instance;
}

Overlay.prototype.createDomNode = function(){
	this.domNode = document.createElement('div');
	this.domNode.className = 'overlay';
}

Overlay.prototype.createEvents = function(){
	var instance = this;
	this.addEvent(window, 'resize', function(){
		instance.setSize();
	});
	this.addEvent(window, 'scroll', function(){
		instance.setSize();
	});
	this.domNode.onclick = function(){
		instance.fireEvent('click');
	}
}

Overlay.prototype.showNestedNode = function(){
	this.nestedNode.style.visibility = 'hidden';
	this.nestedNode.style.display = 'block';
	this.nestedNode.style.zIndex = parseInt(this.domNode.style.zIndex, 10) + 1;
	this.nestedNode.style.position = 'absolute';
	this.nestedNode.style.left = '0%';
	this.nestedNode.style.top = '0%';
	document.body.appendChild(this.nestedNode);
	var width = this.nestedNode.offsetWidth;
	var height = this.nestedNode.offsetHeight;
	var distance = Math.min(Math.round(width / 2), Math.round(height / 2)) + this.clipDelta;
	this.nestedNode.style.marginLeft = -Math.round(width / 2) + 'px';
	this.nestedNode.style.marginTop = -Math.round(height / 2) + 'px';
	this.nestedNode.style.left = '50%';
	this.nestedNode.style.top = '50%';
	this.clip = {'width' : width, 'height' : height, 'distance' : distance};
	this.increaseClip();
}

Overlay.prototype.hideNestedNode = function(){
	var width = this.nestedNode.offsetWidth;
	var height = this.nestedNode.offsetHeight;
	this.clip = {'width' : width, 'height' : height, 'distance' : -this.clipDelta};
	this.decreaseClip();
}

Overlay.prototype.show = function(isWhite){
	if (this.status == 'hidden'){
		this.beforeShow();
		if(isWhite){
			this.afterShow();
		}
		else{
			this.increaseOpacity();
		}
	}
}

Overlay.prototype.hide = function(isWhite){
	if (this.status == 'visible'){
		if(isWhite)
			this.afterHide();
		else			
			this.beforeHide();
	}
}

Overlay.prototype.setNestedNode = function(node){
	this.nestedNode = node;
	if(this.nestedNode) this.nestedNode.className = this.nestedNode.className + ' overlay_nested_node';
}

Overlay.prototype.beforeShow = function(){
	this.fireEvent('beforeShow');
	this.status = 'load';
	this.setOpacity(this.domNode, 0.1);
	this.setSize();
	this.domNode.style.zIndex = this.getZIndex();
	document.body.appendChild(this.domNode);
}

Overlay.prototype.afterShow = function(){
	this.nestedNode ? this.showNestedNode() : this.setVisibleStatus();
}

Overlay.prototype.beforeHide = function(){
	this.fireEvent('beforeHide');
	this.status = 'load';
	this.nestedNode ? this.hideNestedNode() : this.decreaseOpacity();
}

Overlay.prototype.afterHide = function(){
	document.body.removeChild(this.domNode);
	this.status = 'hidden';
	this.fireEvent('hide');
}

Overlay.prototype.increaseOpacity = function() {
	if(_useJsAnimation == 1) {
		var opacity = this.getOpacity(this.domNode) + this.opacityDelta;
		this.setOpacity(this.domNode, opacity);
		opacity <= this.opacityLimit ? setTimeout('Overlay.instance.increaseOpacity()', this.durationDelta) : this.afterShow();
	}
	else {
		this.setOpacity(this.domNode, this.opacityLimit);
		this.afterShow();
	}
}

Overlay.prototype.decreaseOpacity = function(){
	if(_useJsAnimation == 1) {
		var opacity = this.getOpacity(this.domNode) - this.opacityDelta;
		this.setOpacity(this.domNode, opacity);
		opacity > 0 ? setTimeout('Overlay.instance.decreaseOpacity()', this.durationDelta) : this.afterHide();
	}
	else {
		this.setOpacity(this.domNode, 0);
		this.afterHide();
	}
}

Overlay.prototype.increaseClip = function(){
	this.clip.distance -= this.clipDelta;
	var top = this.clip.distance > 0 ? this.clip.distance + 'px' : 'auto';
	var left = this.clip.distance > 0 ? this.clip.distance + 'px' : 'auto';
	var right = this.clip.distance > 0 ? (this.clip.width - this.clip.distance) + 'px' : 'auto';
	var bottom = this.clip.distance > 0 ? (this.clip.height - this.clip.distance) + 'px' : 'auto';
	this.nestedNode.style.clip = 'rect(' + top + ' ' + right + ' ' + bottom + ' ' + left + ')';
	this.nestedNode.style.visibility = 'visible';
	this.clip.distance >= 0 ? setTimeout('Overlay.instance.increaseClip()', this.durationDelta) : this.setVisibleStatus();
}

Overlay.prototype.decreaseClip = function(){
	this.clip.distance += this.clipDelta;
	var top = this.clip.distance > 0 ? this.clip.distance + 'px' : 'auto';
	var left = this.clip.distance > 0 ? this.clip.distance + 'px' : 'auto';
	var right = this.clip.distance > 0 ? (this.clip.width - this.clip.distance) + 'px' : 'auto';
	var bottom = this.clip.distance > 0 ? (this.clip.height - this.clip.distance) + 'px' : 'auto';
	this.nestedNode.style.clip = 'rect(' + top + ' ' + right + ' ' + bottom + ' ' + left + ')';
	if (this.clip.distance <= Math.min(Math.round(this.clip.width / 2), Math.round(this.clip.height / 2))){
		setTimeout('Overlay.instance.decreaseClip()', this.durationDelta);
	}
	else{
		this.nestedNode.parentNode.removeChild(this.nestedNode);
		this.decreaseOpacity();
	}
}

Overlay.prototype.setVisibleStatus = function(){
	this.status = 'visible';
	this.fireEvent('show');	
}

Overlay.prototype.setSize = function(){
	this.domNode.style.width = document.documentElement.scrollWidth + 'px';
	this.domNode.style.height = document.documentElement.scrollHeight + 'px';
}

Overlay.prototype.fireEvent = function(name, params){
	if (typeof this['on' + name] == 'function'){
		this['on' + name](params);
	}
	if (typeof Overlay['on' + name] == 'function'){
		Overlay['on' + name](params);
	}
}

Overlay.prototype.addEvent = function(node, event, handler){
	IE ? node.attachEvent('on' + event, handler) : node.addEventListener(event, handler, false);
}

Overlay.prototype.setOpacity = function(node, value){
	IE ? node.style.filter = value == 1 ? '' : 'alpha(opacity=' + Math.round(100 * value) + ')' : node.style.opacity = value;
}

Overlay.prototype.getOpacity = function(node){
	if (IE){
		node.style.filter.match(new RegExp('alpha\\(opacity\\=(\\d+)\\)'));
		var value = RegExp.$1;
		var result = isNaN(value) ? 1 : value / 100;
	}
	else{
		var value = parseFloat(node.style.opacity);
		var result = isNaN(value) ? 1 : value;
	}
	return result;
}

Overlay.prototype.getZIndex = function(){
	var nodes = document.body.getElementsByTagName('*');
	var maxZIndex = 0;
	for (var i = 0; i < nodes.length; i ++){
		if (nodes[i].offsetParent) if (nodes[i].offsetParent.nodeName == 'HTML' || nodes[i].offsetParent.nodeName == 'BODY'){
			var zIndex = (IE ? nodes[i].currentStyle : document.defaultView.getComputedStyle(nodes[i], null)).zIndex;
			zIndex = parseInt(zIndex, 10);
			zIndex = isNaN(zIndex) ? 0 : zIndex;
			maxZIndex = zIndex > maxZIndex ? zIndex : maxZIndex;
		}
	}
	return maxZIndex + 1;
}

Overlay.show = function(isWhite){
	Overlay.instance.show(isWhite);
}

Overlay.hide = function(isWhite){
	Overlay.instance.hide(isWhite);
}

Overlay.setNestedNode = function(node){
	Overlay.instance.setNestedNode(node);
}

Overlay.init = function(){
	var scripts = document.getElementsByTagName('script');
	for (var i = 0; i < scripts.length; i ++) if (scripts[i].src){
		if (scripts[i].src == 'Overlay.js' || scripts[i].src.match(new RegExp('\\/Overlay\.js$'))){
			var instance = scripts[i];
			break;
		}
	}
	/* Load resources */
	var path = instance.src.replace(new RegExp('Overlay\.js$'), '');
	var link = document.createElement('link');
	link.href = path + 'screen.css';
	link.rel = 'stylesheet';
	link.type = 'text/css';
	var head = document.getElementsByTagName('head')[0];
	head.appendChild(link);
}

var IE = navigator.userAgent.indexOf("MSIE") != -1;

Overlay.create({'id' : 'overlay'});
Overlay.init();

_useJsAnimation = 1;
