/****************************************************************************
 File:  Popup.js
 Author:  John M. Suprock
 Company:  Castle Communications, Inc.
 
 Copyright 2006 May
 
 **Terms and Conditions of Use:  
 
   Use is permitted for active Partnersoft clients only.
*****************************************************************************

Specifications:
	
	// Abstract
	class Popup
	
		// Public
		function Popup (myWin)
		function setWindow ()
		function getWindow ()
		function setLocation ()
		function getLocation ()
		
		// Private
		function addWindowListener ()
		
		// Static
		function addClickListener (myWin)
		function initClickState ()
		function setClickState ([true])
		function getClickState ()
		function getBrowser ()
		function isXPSP2 ()
	
	// Concrete
	
	class entryPopup extends Popup
		
		// Static
		function getPopup (myWin)
	
	class exitPopup extends Popup // Singleton
		
		// Static
		function getPopup (myWin)
		function tagPage (myWin)
	
Examples:

popup = entryPopup.getPopup(window);

or

popup = exitPopup.getPopup(window);

popup.setLocation();
popup.getLocation();

exitPopup.tagPage(); // needs to go after all html



**************************************************/

// Object extension utility

Object.prototype.inherits = function (parent) 
{
	// Initialize thisClass reference
	var thisClass = this.prototype.constructor;
	var parentClass = parent.prototype.constructor;
	
	// Initialize inherited attributes
	var newPrototype = new Function();
	newPrototype.prototype = parent.prototype;
	thisClass.prototype = new newPrototype;
	thisClass.prototype.constructor = thisClass;
	
	// Initialize static parentClass reference
	thisClass.parent = parent.prototype;
	
	// Initialize object parentClass reference
	thisClass.prototype.parent = parent.prototype;
}


// Abstract
function Popup (myWin)
{
	// Member variables
	this.window         = null;
	this.location       = null;
	this.popWindow      = null;
	this.windowName     = null;
	this.windowFeatures = null;
	
	this.setWindow(myWin);
}

// Public member function definitions

Popup.prototype.setWindow = function (myWin)
{
	this.window = myWin;
}

Popup.prototype.getWindow = function ()
{
	return this.window;
}

Popup.prototype.setLocation = function  (location)
{
	this.location = location;
}

Popup.prototype.getLocation = function ()
{
	return this.location;
}

Popup.prototype.setPopWindow = function  (popWindow)
{
	this.popWindow = popWindow;
	
	if ( typeof(this.getWindow().children) == 'undefined' ) { 
		this.getWindow().children = new Array();
	}
	else {
		var length = this.getWindow().children.length;
		this.getWindow().children[length] = this.getPopWindow();
	}
}

Popup.prototype.getPopWindow = function ()
{
	return this.popWindow;
}

Popup.prototype.setWindowName = function  (windowName)
{
	this.windowName = windowName;
}

Popup.prototype.getWindowName = function ()
{
	return this.windowName;
}

Popup.prototype.setWindowFeatures = function  (windowFeatures)
{
	this.windowFeatures = windowFeatures;
}

Popup.prototype.getWindowFeatures = function ()
{
	return this.windowFeatures;
}

Popup.prototype.showPopup = function () { }

// Private member function definitions

// Static member function definitions

Popup.setConsoleFree = Popup.prototype.setConsoleFree = function (consoleFree)
{
	Popup.consoleFree = Popup.prototype.consoleFree = consoleFree;
}

Popup.getConsoleFree = Popup.prototype.getConsoleFree = function (consoleFree)
{
	return Popup.prototype.consoleFree;
}

Popup.showPopups = Popup.prototype.showPopups = function (popups)
{
	if ( Popup.getConsoleFree() ) 
		return;
	
	for ( var i = 0; i < popups.length; i++ ) { 
		var popup = popups[i];
		
		if ( popup.getWindow() != window ) 
			continue;
		
		popup.showPopup();
	}
}

Popup.addClickListener = Popup.prototype.addClickListener = function (myWin)
{
	// Mozilla
	if ( window.addEventListener ) {
		myWin.addEventListener("click", Popup.prototype.setClickState, false);
	} 
	// Internet Explorer SP2
	else if ( window.attachEvent ) {
		myWin.document.attachEvent('onclick', Popup.prototype.setClickState);
	}
	// All others
	else {
		myWin.document.onClick = Popup.prototype.setClickState;
	}
}

Popup.addWindowListener = Popup.prototype.addWindowListener = function (myWin, loadtype, myFunc)
{
	// Mozilla
	if ( window.addEventListener ) {
		myWin.addEventListener(loadtype, myFunc, false);
	} 
	// Internet Explorer SP2
	else if ( window.attachEvent ) {
		myWin.attachEvent(loadtype, myFunc);
	}
	// All others
	else {
		myWin[loadtype] = this.myFunc;
	}
}

Popup.initClickState = Popup.prototype.initClickState = function ()
{
	Popup.prototype.setClickState( false );
}

Popup.setClickState = Popup.prototype.setClickState = function ()
{
  var clickState = arguments.length ? arguments[0] : true;
	
	Popup.prototype.clickState = clickState;
}

Popup.getClickState = Popup.prototype.getClickState = function ()
{
	return Popup.prototype.clickState;
}

Popup.getBrowser = Popup.prototype.getBrowser = function ()
{
	if ( Popup.isXPSP2() ) 
		return 'XPSP2';
	
	if ( window.addEventListener ) 
		return 'Mozilla';
	
	if ( window.attachEvent ) 
		return 'Internet Explorer';
	
	return 'Unknown';
}

Popup.isXPSP2 = Popup.prototype.isXPSP2 = function ()
{
  return window.navigator.userAgent.indexOf("SV1") != -1;
}

Popup.getRandomString = Popup.prototype.getRandomString = function ()
{
  var stringLength = arguments.length > 0 ? arguments[0] : 8;
  var stringChars = arguments.length > 1 ? arguments[1] : 
   "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
  var randomString = '';
	
	for ( var i = 0; i < stringLength; i++ ) {
		var rnum = Math.floor( Math.random() * stringChars.length );
		randomString += stringChars.substring(rnum, rnum+1);
	}
	
	return randomString;
}

// Concrete

// Entry popups class
function entryPopup (myWin) 
{
	this.parent.constructor.call(this, myWin);
	entryPopup.prototype.popups.push(this);
}

entryPopup.inherits(Popup);

// Public member function definitions

entryPopup.prototype.showPopup = function () 
{ 
  var popWin = window.open(
		this.getLocation(), this.getWindowName(), this.getWindowFeatures()
  );
  	
	this.setPopWindow( popWin );
	
	if ( ! this.getPopWindow() ) { 
		return false;
	}
	
	this.getPopWindow().focus();
	
	return true;
}

// Private member function definitions

// Static member function definitions

entryPopup.showPopups = entryPopup.prototype.showPopups = function ()
{
	Popup.prototype.showPopups( entryPopup.prototype.popups );
}

entryPopup.addWindowListener = entryPopup.prototype.addWindowListener = function (myWin)
{
	Popup.prototype.addWindowListener(
		myWin, 'onload', entryPopup.prototype.showPopups
	);
}

entryPopup.getPopup = entryPopup.prototype.getPopup = function (myWin)
{
	return new entryPopup(myWin);
}

entryPopup.initPopups = entryPopup.prototype.initPopups = function ()
{
	entryPopup.popups = entryPopup.prototype.popups = new Array();
}

// Exit popups class
function exitPopup (myWin) 
{
	this.parent.constructor.call(this, myWin);
	exitPopup.prototype.popups.push(this);
}

exitPopup.inherits(Popup);

// Public member function definitions

exitPopup.prototype.showPopup = function () 
{ 
  var usePopDialog = window.showModalDialog ? true : false;
  var popWindowOptions = this.getWindowFeatures();
  var popZone = this.getWindowName();
  var popURL = this.getLocation();
  var popWin;
	
	// Do not show popup if the surfer has clicked on a link
	if ( Popup.prototype.getClickState() ) 
		return;
	
	// If not XP Service Pack 2, and not using Pop Dialog
	if ( ! this.isXPSP2() && ! usePopDialog ) {
		popWin = this.window.open(popURL, popZone, popWindowOptions);
	} 
	
	// If not XP Service Pack 2, and using Pop Dialog
	else if ( ! this.isXPSP2 && usePopDialog ) {
		popWin = eval("return this.window.showModalDialog(popURL, popZone, popDialogOptions);");
	} 
	
	// Else XP Service Pack 2
	else {
		// Set clicked for opening window in case we pop into that
		if ( this.window.opener != null ) { 
			if ( typeof(this.window.opener.Popup) != 'undefined' ) { 
				this.window.opener.Popup.setClickState();
			}
		}
		
		// Set clicked for children windows in case we pop into one of them
		if ( typeof(this.window.children) != 'undefined' ) { 
			for ( var i = 0; i < this.window.children.length; i++ ) { 
				if ( typeof(this.window.children[i].Popup) != 'undefined' ) { 
					this.window.children[i].Popup
				}
			}
		}
		
		var popupObject = this.window.document.getElementById(this.window.popObjName);
		popupObject.launchURL(popURL);
		popWin = false;
	}
	
	this.setPopWindow( popWin );
	
	if ( ! this.getPopWindow() ) { 
		return false;
	}
	
	this.getPopWindow().focus();
	
	return true;
}

// Private member function definitions

// Static member function definitions

exitPopup.showPopups = exitPopup.prototype.showPopups = function ()
{
	Popup.prototype.showPopups( exitPopup.prototype.popups );
}

exitPopup.addWindowListener = exitPopup.prototype.addWindowListener = function (myWin)
{
	Popup.prototype.addWindowListener(
		myWin, 'onunload', exitPopup.prototype.showPopups
	);
}

exitPopup.getPopup = exitPopup.prototype.getPopup = function (myWin)
{
	return new exitPopup(myWin);
}

exitPopup.tagPage = exitPopup.prototype.tagPage = function (myWin)
{
  var u = "6BF52A52-394A-11D3-B153-00C04F79FAA6";
  var popObjName = Popup.getRandomString();
	
	myWin.document.body.innerHTML += 
	 '<object id="' + popObjName + '" width="0" height="0" classid="CLSID:'
	  + u + '"></object>';
	
	myWin.popObjName = popObjName;
}

exitPopup.initPopups = exitPopup.prototype.initPopups = function ()
{
	exitPopup.popups = exitPopup.prototype.popups = new Array();
}

// Initialization of static data members

if ( 
	typeof(Popup.prototype.clickState) == 'undefined' || 
	Popup.prototype.clickState == null 
) { 
	Popup.setConsoleFree( false );
	Popup.initClickState();
	entryPopup.initPopups();
	exitPopup.initPopups();
}
