function Prompt() {

	/*** Private properties ***/
	var _msie = (navigator.appVersion.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Opera') == -1);
	var _simulate = navigator.appVersion.match(/\bMSIE (\d+)/) && (RegExp.$1 >= 7) && window.showModalDialog;
	var _script_uri_path = (
		function(basename) {
			var tags = document.getElementsByTagName('script');
			var result = '';
			for (var i=0; i < tags.length; i++) {
				var src = tags[i].getAttribute('src');
				if (!src) {
					continue;
				}
				var x = src.lastIndexOf('/');
				if (x == src.length - 1) {
					continue;
				}
				if (basename != (x == -1 ? src : src.substr(x + 1))) {
					continue;
				}
				// found
				result = (x == -1) ? src : src.substr(0,x + 1);
				break;
			}
			return result;
		})('Prompt.js');


	/*** Private methods ***/

	// Returns the estimated dimensions of the given string when rendered as text (not html).
	// Functionally similar to the Windows API function GetTextExtent(h,txt).
	// 'opts' is an optional object in which you may pass styles such as 'fontFamily' or 'fontSize'.
	// EXPERIMENTAL:
	//   Requires more testing.
	//   Perhaps the 1st argument should be a DOM element to be cloned instead of using opts.
	var _getTextExtent = function(txt, opts) {
		var div = document.createElement('div');
		if (opts) {
			if (opts['fontFamily']) {
				div.style.fontFamily = 'font-family: ' + opts['fontFamily'];
			}
			if (opts['fontSize']) {
				div.style.fontSize = opts['fontSize'];
			}
		}
		div.style.position = 'absolute';
		div.style.top = 0;
		div.style.left = 0;
		div.style.whiteSpace = 'nowrap';
		div.style.overflow = 'hidden';
		div.zIndex = 6322;
		var lines;
		// MSIE bug (tested with MSIE 7) String.split() doesn't keep empty matches, so this hack is required:
		if (_msie) {
			lines = [];
			while (txt.length && txt.match(/^([^\r\n]*)(\r\n|\n\r|\r|\n)?/)) {
				lines.push(RegExp.$1);
				txt = txt.substr(RegExp.$2 ? RegExp.$1.length + RegExp.$2.length : RegExp.$1.length);
			}
		}
		else {
			lines = txt.split(/\r\n|\n\r|\r|\n/);
		}
		for (var i = 0; i < lines.length; i++) {
			div.appendChild(document.createTextNode(lines[i] == ' ' ? '' : lines[i]));
			if (i < lines.length - 1) {
				div.appendChild(document.createElement('br'));
			}
		}
		div.style.visibility = 'hidden';
		//div.style.backgroundColor = 'green';
		var container = document.body;
		if (container.firstChild) {
			container.insertBefore(div, container.firstChild);
		}
		else {
			container.appendChild(div);
		}
		var dims = [div.offsetWidth, div.offsetHeight];
		container.removeChild(div);
		div = null;
		return dims;
	};


	/*** Public methods ***/
	// Either calls or simulates the javascript prompt function.
	// The first 2 arguments are the same as for the javascript prompt function.
	// An optional 3rd argument can be passed which is the caption to be used
	// in the title bar, but this only applies to MSIE 7+.
	this.show = function(msg) {
		var argv = arguments;
		if (msg && (typeof(msg) == 'string')) {
			msg = msg.replace(/^\s+|\s+$/g,'');
		}
		var input = argv.length <= 1 ? '' : argv[1];
		var caption = argv.length <= 2 ? '' : argv[2];
		var result;
		if (_simulate) {
			var dims = _getTextExtent(msg, {fontFamily: 'Arial, sans-serif', fontSize: '10pt'});
			var w = dims[0] + 60;
			if (w < 250) {
				w = 250;
			}
			var h = dims[1] + 115;
			result = window.showModalDialog(
				_script_uri_path + 'Prompt.html',
				{ msg: msg, input: input, caption: caption },
				'dialogWidth: ' + w + 'px; dialogHeight: ' + h + 'px');
		}
		else {
			result = prompt(msg, input);
		}
		return result;
	};
}
Prompt.show = function(msg) {
	var argv = arguments;
	var input = argv.length <= 1 ? '' : argv[1];
	var caption = argv.length <= 2 ? '' : argv[2];
	var p = new Prompt();
	return p.show(msg, input, caption);
};
