/* $Revision: 254 $ */
/*extern $type, MOTO, Class, Events, Options */
if (typeof MOTO === 'undefined') { var MOTO = {}; MOTO.modulesLoaded = []; }
/**
 * Popup.js - inspired by window.popup in window.cnet.js in the CNET's Global
 * Framework at http://clientside.cnet.com/libraries/cnets-global-framework/
 * @file Popup.js
 */
/**
 * Useful to easily create popup windows with some extra functions.
 * MOTO.Popup.popupWindow is the reference to the actual window object
 * @class MOTO.Popup
 * @implements Options
 * @implements Events
 * @version 0.2
 * @author MOTO - bryan.swift
 */
MOTO.Popup = new Class(function () {
	/**
	 * Runs the blockTest if one was provided
	 * @function {private Boolean} runBlockTest
	 * @returns the result of the blockTest function or (typeof this.popupWindow === 'undefined')
	 */
	function runBlockTest() {
		var testResult = true;
		if (this.options.blockTest && $type(this.options.blockTest === 'function')) {
			testResult = this.options.blockTest();
		} else {
			testResult = typeof this.popupWindow === 'undefined';
		}
		return testResult;
	}
	
	return {
		Implements: [Options, Events],
		/**
		 * Holds all the options set for the popup
		 * @variable {public Object} options
		 */
		options: {
			/* Events */
			/**
			 * Function to execute when a popup window is successfully opened
			 * @event onSuccess
			onSuccess: Class.empty,
			 */
			/**
			 * Function to execute when a popup window is blocked, determined by a
			 * blockTest failure or by window.open not returning a window reference
			 * @event onBlock
			onBlock: Class.empty,
			 */
			/**
			 * The width of the popup
			 * @property {option} width
			 */
			width: 500,
			/**
			 * The height of the popup
			 * @property {option} height
			 */
			height: 300,
			/**
			 * Whether or not to center the window on the screen
			 * Defaults to false.
			 * @property {option} center
			 */
			center: false,
			/**
			 * The horizontal position of the popup on the screen
			 * @property {option} x
			 */
			x: 50,
			/**
			 * The vertical position of the popup on the screen
			 * @property {option} y
			 */
			y: 50,
			/**
			 * Whether or not to show the toolbar ('yes'|'no')
			 * @property {option} toolbar
			 */
			toolbar: 'no',
			/**
			 * Whether or not to show the location bar ('yes'|'no')
			 * @property {option} location
			 */
			location: 'no',
			/**
			 * Whether or not to show links/bookmarks toolbar ('yes'|'no')
			 * @property {option} directories
			 */
			directories: 'no',
			/**
			 * Whether or not to show the status bar ('yes'|'no')
			 * @property {option} status
			 */
			status: 'no',
			/**
			 * Whether or not to show the scrollbars ('yes'|'no')
			 * @property {option} scrollbars
			 */
			scrollbars: 'no',
			/**
			 * Whether or not the popup should be resizeable ('yes'|'no')
			 * @property {option} resizable
			 */
			resizeable: 'no',
			/**
			 * Name of the popup window
			 * @property {option} name
			 */
			name: 'popup',
			/**
			 * Time after opening the popup before running the block test (in milliseconds)
			 * @property {option} delay
			 */
			delay: 500,
			/**
			 * The test to run to tell if the popup hass been blocked. Must be a no arg
			 * Function returning a Boolean value (true if blocked, false if unblocked)
			 * @property {option} blockTest
			 */
			blockTest: false
		},
		/**
		 * Whether or not the popup was blocked when the open attempt was made
		 * @variable {public Boolean} blocked
		 */
		blocked: null,
		/**
		 * Window object resulting from window.open
		 * @variable {public Window} popupWindow
		 */
		popupWindow: null,
		/**
		 * Creates a new popup window with the specified options or the defaults
		 * @function {MOTO.Popup} initialize
		 * @param {String} url - target url to open
		 * @param {Boolean} center - whether or not to center the popup on the screen
		 * @param {Object} options - various settings to pass to the window.open call
		 * @returns the created MOTO.Popup if there were no errors, null otherwise
		 */
		initialize: function (url,options) {
			var sheight, swidth;
			try {
				this.url = url;
				this.setOptions(options);
				if (typeof this.options.blockTest !== 'function') { this.options.blockTest = false; }
				if (this.options.center) {
					sheight = screen.height;
					swidth = screen.width;
					this.options.x = swidth/2 - this.width/2;
					this.options.y = sheight/2 - this.height/2;
				}
				this.openPopup();
				return this;
			} catch (error) {
				if (MOTO.log) {
					MOTO.log(error);
				}
				return null;
			}
		},
		/**
		 * Makes the call to window.open with the provided options
		 * @function {public Window} openPopup
		 * @returns {Window} the window opened by the call to window.open
		 */
		openPopup: function () {
			var options = "toolbar="+this.options.toolbar+
				",location="+this.options.location+
				",directories="+this.options.directories+
				",status="+this.options.status+
				",scrollbars="+this.options.scrollbars+
				",resizeable="+this.options.resizeable+
				",width="+this.options.width+
				",height="+this.options.height+
				",top="+this.options.y+
				",left="+this.options.x;
			this.popupWindow = window.open(this.url, this.options.name, options);
			this.testBlocked.delay(this.options.delay,this);
			return this.popupWindow;
		},
		/**
		 * Tests whether or not the window was blocked
		 * @function {public void} testBlocked
		 */
		testBlocked: function () {
			var blockTestResult = runBlockTest.run([],this);
			if (blockTestResult) {
				this.blocked = true;
				this.fireEvent('onBlock');
			} else {
				this.fireEvent('onSuccess');
			}
		},
		/**
		 * Closes the popup window
		 * @function {public void} close
		 */
		close: function () {
			this.popupWindow.close();
		}
	};
}());

MOTO.modulesLoaded[MOTO.modulesLoaded.length] = 'MOTO.Popup';