function PopupWindow( id, win ) {
	this.id = id;
	this.win = win? win: window;
	this.doc = this.win.document;
	this.popup = this.doc.getElementById( this.id );
	this.iframe = null;
	this.opacity = null;
	this.eventListeners = new Array();
	this.inputFocus = null;
	
	// copiat del jquery
	var userAgent = navigator.userAgent.toLowerCase();
	this.browser = {
		version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
		safari: /webkit/.test( userAgent ),
		opera: /opera/.test( userAgent ),
		msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
		mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
	};
}
PopupWindow.POPUP_BACK_CLASS_NAME = "popupWindowBack";
PopupWindow.create = function( id ) {
	if( !window.jpopup ) {
		window.jpopup = new Array();
	}
	if( !window.jpopup[id] ) {
		window.jpopup[id] = new PopupWindow( id );
	}
	return window.jpopup[id];
}

PopupWindow.clean = function( id ) {
	if( window.jpopup && window.jpopup[id] ) {
		window.jpopup[id] = null;
	}
}

PopupWindow.launch = function( id ) {
	this.create( id );
	window.jpopup[id].build();
	window.jpopup[id].show();
	return window.jpopup[id];
}

PopupWindow.close = function( id ) {
	if( window.jpopup && window.jpopup[id] ) {
		window.jpopup[id].close();
	}
}

PopupWindow.getInstance = function( id ) {
	if( window.jpopup && window.jpopup[id] ) {
		return window.jpopup[id];
	}
	return null;
}

PopupWindow.prototype.addEventListener = function( type, fn ) {
	this.eventListeners[this.eventListeners.length] = { 
		"type" : type,
		"fn" : fn
	};
}

PopupWindow.prototype.addElementListener = function( type, element, fn ) {
	if( typeof element == "string" ) {
		element = this.doc.getElementById( element );
	}
	if( element.attachEvent ) {
		element.attachEvent( "on" + type, fn );
	} else { 
		element.addEventListener( type, fn, false );
	}
}

PopupWindow.prototype.build = function() {
	var self = this;
	
	var getTopMostZIndex = function() {
		var allElements = self.doc.getElementsByTagName("*");
		var zIndex = 1;
		for( var i = 0; i < allElements.length; i++ ) {
			if( allElements[i].style.zIndex > zIndex ) {
				zIndex = allElements[i].style.zIndex;
			}
		}
		return zIndex;
	};
	var zIndex = getTopMostZIndex();
	
	// estils
	if( window.document != this.doc ) {
		// ˇHARDCODE!!!!
		var css = this.doc.createElement( "link" );
		css.type = "text/css";
		css.rel = "stylesheet";
		css.href = "https://www.generali.es/rfw3k/arq_resourcesFormWeb/20091103.0/arq/jpopupWindow/jpopupWindow.css";
		var head = this.doc.getElementsByTagName("head")[0];  
		head.appendChild( css );
	}
	if( this.browser.msie ) { // IE hack
		this.popup.style.display = "inline";
		this.popup.style.width = "0px";
		
		this.popupWidth = this.popup.offsetWidth;
		this.popup.style.width = this.popupWidth;
		this.popupHeight = this.popup.offsetHeight;
		this.popup.style.display = "block";
		
		this.iframe = this.doc.createElement( "iframe" );
		this.iframe.style.width = this.popupWidth;
		this.iframe.style.height = this.popupHeight;
		this.iframe.style.top = "0px";
		this.iframe.style.left = "0px"
		this.iframe.style.position = "absolute";
		this.iframe.style.display = "none";
		this.iframe.src = "javascript:0";
		
		this.popup.parentNode.appendChild( this.iframe );
	}
	
	this.popup.style.position = "absolute";
	this.popup.style.zIndex = zIndex+2;
	this.popup.style.display = "none";
	this.popup.style.overflow = "hidden";
	
	this.opacity = this.doc.createElement( "div" );
	this.opacity.className = PopupWindow.POPUP_BACK_CLASS_NAME;
	this.opacity.style.position = "absolute";
	this.opacity.style.top = "0px";
	this.opacity.style.left = "0px";
	this.opacity.style.zIndex = zIndex+1;
	this.opacity.style.display = "none";
	this.opacity.style.height = this.doc.body.scrollHeight + "px";
	this.opacity.style.width = this.doc.body.scrollWidth + "px";
	this.popup.parentNode.appendChild( this.opacity );
	
	this.inputFocus = this.doc.createElement( "input" );
	this.inputFocus.style.position = "absolute";
	this.inputFocus.style.top = "0px";
	this.inputFocus.style.left = "0px";
	this.inputFocus.style.width = "0px";
	this.inputFocus.style.height = "0px";
	this.inputFocus.style.margin = "-10px";
	this.inputFocus.style.overflow = "hidden";
	this.popup.appendChild( this.inputFocus );
	
	var getElementsByClassName = function( className, root ) {
		if( !root ) {
			var root = this.doc;
		}
		var allElements = root.getElementsByTagName( "*" );
		var myElements = new Array();
		
		var expr = new RegExp( className, i );
		for( var i = 0; i < allElements.length; i++ ) {
			if( expr.test( allElements[i].className ) ) {
				myElements[myElements.length] = allElements[i];
			}
		}
		
		return myElements;
	}
	
	// close
	var close = getElementsByClassName( "close", this.popup );
	for( var i = 0; i < close.length; i++ ) {
		var closeObj = close[i];
		closeObj.onmouseover = function() {
			closeObj.className = "close";
		}
		closeObj.onmouseout = function() {
			closeObj.className = "close close-out";
		}
		closeObj.onmousedown = function() {
			closeObj.className = "close close-mousepress";
		}
		closeObj.onmouseup = function() {
			closeObj.className = "close";
		}
		closeObj.onclick = function() {
			self.close();
		}
	}
	
	var closeP = getElementsByClassName( "cerrarPopup", this.popup );
	for( var i = 0; i < closeP.length; i++ ) {
		var closeObjP = closeP[i];
		closeObjP.onclick = function() {
			self.close();
		}
	}
	
	var fireEvents = function( type ) {
		var event = {
			"type" : type,
			"target" : self.popup,
			"object" : self,
			"cancelBubble" : false
		};
		for( var i = 0; i < self.eventListeners.length; i++ ) {
			if( type == self.eventListeners[i].type ) {
				try {		
					self.eventListeners[i].fn( event );
				} catch(e) {
				}
				if( event.cancelBubble ) break;
			}
		}
		return event;
	};
	
	// move
	var popupMove = this.popup;
	var frameMove = this.iframe;
	var updatePosition = function( left, top ) {
		popupMove.style.left = left;
		popupMove.style.top = top;
		if( frameMove ) {
			frameMove.style.left = left;
			frameMove.style.top = top;
		}
	};
	var stopEvent = function( event ) {
		if( self.browser.msie ) {
			event.cancelBubble = true;
			event.returnValue = false;
		} else {
			event.preventDefault();
		}
	};
	var startMove = function( event ) {
		var inMove = function( event ) {
			var cursorX, cursorY;
			if( self.browser.msie ) {
				cursorX = event.clientX + self.doc.documentElement.scrollLeft + self.doc.body.scrollLeft;
				cursorY = event.clientY + self.doc.documentElement.scrollTop + self.doc.body.scrollTop;
			} else {
				cursorX = event.clientX + window.scrollX;
				cursorY = event.clientY + window.scrollY;
			}
			var left = (popupStartX + cursorX - cursorStartX) + "px";
			var top = (popupStartY + cursorY - cursorStartY) + "px";
			updatePosition( left, top );
			stopEvent( event );
		};
		var endMove = function( event ) {
			if( self.browser.msie ) {
				self.doc.detachEvent("onmousemove", inMove );
				self.doc.detachEvent("onmouseup", endMove );
			} else {
				self.doc.removeEventListener("mousemove", inMove, true);
				self.doc.removeEventListener("mouseup", endMove, true);
			}
			stopEvent( event );
		};
		var cursorStartX, cursorStartY;
		if( self.browser.msie ) {
			cursorStartX = event.clientX + self.doc.documentElement.scrollLeft + self.doc.body.scrollLeft;
			cursorStartY = event.clientY + self.doc.documentElement.scrollTop + self.doc.body.scrollTop;
			self.doc.attachEvent("onmousemove", inMove );
			self.doc.attachEvent("onmouseup", endMove );
		} else {
			cursorStartX = event.clientX + window.scrollX;
			cursorStartY = event.clientY + window.scrollY;
			self.doc.addEventListener("mousemove", inMove, true);
			self.doc.addEventListener("mouseup", endMove, true);
		}
		var popupStartX = parseInt( popupMove.style.left );
		var popupStartY = parseInt( popupMove.style.top );
		stopEvent( event );
	};
	
	var popupMoveElement = getElementsByClassName( "move", this.popup );
	for( var i = 0; i < popupMoveElement.length; i++ ) {
		popupMoveElement[i].style.cursor = "default";
		if( this.browser.msie ) {
			popupMoveElement[i].attachEvent( "onmousedown", startMove );
			popupMoveElement[i].attachEvent( "onclick", stopEvent );
		} else {
			popupMoveElement[i].addEventListener( "mousedown", startMove, true );
			popupMoveElement[i].addEventListener( "click", stopEvent, true );
		}
	}
	
	// resize
	if( this.win.attachEvent ) {
		this.win.attachEvent( "onresize", function() {
			self.resize();
		});
	} else if( this.win.addEventListener ) {
		this.win.addEventListener( "resize", function() {
			self.resize();
		}, false );
	}
	
	// bloquejar els selects per ie 6
	var selectsBlocked = null;
	var findSelects = function( doc ) {
		var selects = doc.getElementsByTagName( "select" );
		for( var i = 0; i < selects.length; i++ ) {
			if( selects[i].disabled == false && !self.popup.contains(selects[i]) ) {
				selectsBlocked[selectsBlocked.length] = selects[i];
			}
		}
		var iframes = doc.getElementsByTagName( "iframe" );
		for( var i = 0; i < iframes.length; i++ ) {
			try {
				findSelects( iframes[i].contentWindow.document );
			} catch(e) {
			}
		}
	};
	var disableSelects = function() {
		if( !(self.browser.msie && self.browser.version < 7) ) return;
		selectsBlocked = new Array();
		findSelects( self.doc );
		for( var i = 0; i < selectsBlocked.length; i++ ) {
			selectsBlocked[i].disabled = true;
		}
	};
	var enableSelects = function() {
		if( !(self.browser.msie && self.browser.version < 7) ) return;
		for( var i = 0; i < selectsBlocked.length; i++ ) {
			selectsBlocked[i].disabled = false;
		}
	};
	
	var followFocus = function( evelyn ) {
		if( self.doc.addEventListener ) {
			followFocusFF( evelyn );
		} else if( self.doc.attachEvent ) {
			followFocusIE( evelyn );
		}
	};
	var followFocusIE = function( evelyn ) {
		var oldTarget = evelyn.srcElement? evelyn.srcElement: evelyn;
		if( self.popup.style.display == "none" ) {
			// TODO s'hauria d'eliminar l'event quan es tanca la finestra
			oldTarget.detachEvent( "onblur", followFocusIE );
			return;
		}
		if( !evelyn.srcElement ) {
			oldTarget.focus();
			oldTarget.attachEvent( "onblur", followFocusIE );
			return;
		}
		var target = oldTarget.ownerDocument.activeElement;
		if( target == null ) return;
		if( target == oldTarget ) return;
		if( !isInPopup( target ) ) {
			try { oldTarget.focus(); } catch(e) {}
			return;
		}
		oldTarget.detachEvent( "onblur", followFocusIE );
		target.attachEvent( "onblur", followFocusIE );
	};
	var followFocusFF = function( evelyn ) {
		// TODO no acaba d'anar gaire fi
		var oldTarget = evelyn.target? evelyn.target: evelyn;
		if( !evelyn.target ) {
			oldTarget.focus();
			oldTarget.addEventListener( "blur", followFocusFF, false );
			return;
		}
		setTimeout( function() {
			followFocusFF2( oldTarget );
		}, 10 );
	};
	var followFocusFF2 = function( oldTarget ) {
		var target = oldTarget.ownerDocument.activeElement;
		if( target == oldTarget ) return;
		if( !isInPopup( target ) ) {
			try { oldTarget.focus(); } catch(e) {}
			return;
		}
		oldTarget.removeEventListener( "blur", followFocusFF, false );
		target.addEventListener( "blur", followFocusFF, false );
	};
	var isInPopup = function( element ) {
		var node = element;
		if( node.nodeName == "IFRAME" ) return true; // JCC popup dins de popup
		while( node ) {
			if( node == self.popup ) return true;
			if( node.nodeName == "BODY" ) return false;
			node = node.parentNode;
		}
		return false;
	};
	
	this.show = function() {
		self.resize();
		self.centerPopup();
		self.popup.style.display = "block";
		self.opacity.style.display = "block";
		
		if( self.iframe ) { // IE
			disableSelects();
		}
		followFocus( self.inputFocus );		
		fireEvents( "show" );
	};
	
	this.close = function() {
		var event = fireEvents( "close" );
		if( event.cancelBubble ) return;
		
		event = fireEvents( "cerrarPopup" );
		if( event.cancelBubble ) return;
		
		self.popup.style.display = "none";
		self.opacity.style.display = "none";
		if( self.iframe ) { // IE
			self.iframe.style.display = "none";
			enableSelects();
		}
		
		
		
		
	};
	
	// sobreescribim la propia funció
	this.build = function() {}; 
}

PopupWindow.prototype.resize = function() {
	this.opacity.style.height = Math.max( this.doc.body.scrollHeight, this.doc.body.clientHeight );
	this.opacity.style.width = Math.max( this.doc.body.scrollWidth, this.doc.body.clientWidth );

	var ocultar = false;
	if( this.popup.style.display == "none" ) {
		this.popup.style.visibity = "hidden";
		this.popup.style.display = "block";	
		ocultar = true;
	}
	this.popup.style.overflow = "";
	//this.popup.style.width = "auto";
	
	this.popupWidth = this.popup.clientWidth;
	this.popupHeight = this.popup.clientHeight;
	
	this.popup.style.width = this.popupWidth;
	this.popup.style.overflow = "hidden";
	
	if( this.iframe ) { // IE
		this.iframe.style.width = this.popupWidth + "px";
		this.iframe.style.height = this.popupHeight + "px";
	}
	
	if( ocultar ) {
		this.popup.style.visibity = "visible";
		this.popup.style.display = "none";	
	}
}

PopupWindow.prototype.centerPopup = function() {
	var left = (this.doc.documentElement.clientWidth / 2) - (this.popupWidth / 2) + $(this.doc).scrollLeft();
	var top = (this.doc.documentElement.clientHeight / 2) - (this.popupHeight / 2) + $(this.doc).scrollTop();
 
	if( left < 0 ) left = 0;
	if( top < 0 ) top = 0;
 
	this.popup.style.left = left + "px";
	this.popup.style.top = top + "px";
 
 	if( this.iframe ) { // IE
  		this.iframe.style.left = left + "px";
  		this.iframe.style.top = top + "px";
  		this.iframe.style.display = "block";
 	}
}


