/**
 * <p>Title: dialog.js</p>
 * <p>Description: Dialog tools using windows.js library.</p>
 * <p>Copyright: Copyright (c) 2006</p>
 * <p>Company: Kreber Graphics, Inc.</p>
 * @author Charlie Reading
 */

// Includes
var dialog_js = 1;
var includes = ((typeof browser_js == 'undefined') ? "browser.js\n" : "")
		+ ((typeof Prototype == 'undefined') ? "prototype.js\n" : "")
		+ ((typeof Window == 'undefined') ? "window.js\n" : "");
if (includes != "")
{
	alert("dialog.js: you must first include:\n" + includes);
}


//
// Dialogs
//

kDialog_OK = 1;
kDialog_Cancel = 2;
kDialog_Third = 3;

var DialogInfo = Class.create();
DialogInfo.prototype =
{
	initialize: function(parameters)
	{
		this.options = Object.extend({
			focus:							null,
			onReturn:						_dialogOnReturnTrue,
			onPostClose:				Prototype.emptyFunction,
			onDefault:					this._standardOnDefault.bind(this),
			onCancel:						this._standardOnCancel.bind(this),
			onThird:						this._standardOnThird.bind(this),
			listeners:					[],
			callingDocument:		document
			}, parameters || {});
		
		this.button = null;
		this.returnedValue = null;
		this.calledReturn = false;
		this.calledPostClose = false;
	},
	
	onOpen: function(dlog)
	{
		Dialog.curDialog(true);
		this.dlog = dlog || Dialog.curDialog(false);
		this.dlog.dialogInfo = this;
		this.isDialog = (typeof this.dlog.dlogId != 'undefined');
		
		var options = this.options;
		
		// add owner-document & content-document (if we have one)
		if (options.listeners.indexOf(dlog.element.ownerDocument) == -1)
		{
			options.listeners.push(dlog.element.ownerDocument);
		}
		if (dlog.dlogParameters.url)
		{
			var iframedoc = $(dlog.dlogId+"_content_iframe").contentWindow || $(dlog.dlogId+"_content_iframe").contentDocument;
			if (options.listeners.indexOf(iframedoc) == -1)
			{
				options.listeners.push(iframedoc);
			}
		}
		
		// add the keypress filter
		var parameters = { onKeypress:options.onKeypress, onReturnKey:Dialog.okCallback, onEscapeKey:Dialog.cancelCallback, listeners:options.listeners, actionData:this.dlog };
		this._filter = new ReturnEscapeKeypressFilter(parameters);
		
		// add the shaker
		this.dlog.shake = this._shake.bind(this);
		
		// pick off onClose so we can clean-up
		Windows.addObserver(this);
		
		if (this.options.focus)
		{
			var focus = top.$(this.options.focus);
			if (focus)
			{
				try
				{
					focus.activate();
				}
				catch (ignore) { }
			}
		}
	},
	
	onHide: function(eventName, dlog)
	{
		// Unplug ourselves
		this._filter.remove();
		Windows.removeObserver(this);
	},
	
	ok: function(dlog)
	{
		dlog = dlog || this.dlog;
		dlog.dialogInfo.button = kDialog_OK;
		return dlog.dialogInfo.onReturn(dlog);
	},
	
	cancel: function(dlog)
	{
		dlog = dlog || this.dlog;
		dlog.dialogInfo.button = kDialog_Cancel;
		return dlog.dialogInfo.onReturn(dlog);
	},
	
	third: function(dlog)
	{
		dlog = dlog || this.dlog;
		dlog.dialogInfo.button = kDialog_Third;
		return dlog.dialogInfo.onReturn(dlog);
	},
	
	onReturn: function(dlog)
	{
		// no return?  let it close out
		if (! this.options.onReturn)
		{
			return true;
		}
		
		// no button?  don't let it go yet
		if (! this.button)
		{
			return false;
		}
		
		var okToClose;
		if (this.button == kDialog_Cancel)
		{
			// if cancelling, treat onReturn as a notification (but close it anyway)
			this.calledReturn = true;
			this.options.onReturn(dlog);
			okToClose = true;
		}
		else
		{
			okToClose = this.options.onReturn(dlog);
			if (okToClose)
			{
				// only close if onReturn says we can
				this.calledReturn = true;
			}
		}
		
		return okToClose;
	},
	
	onPostClose: function(dlog)
	{
		if ((! this.calledPostClose)
				&& (this.options.onPostClose))
		{
			this.calledPostClose = true;
			this.options.onPostClose(dlog);
		}
	},
	
	_standardOnDefault: function(dlog)
	{
		this.button = kDialog_OK;
		return this.dlog.dialogInfo.onReturn(dlog);
	},
	
	_standardOnCancel: function(dlog)
	{
		this.button = kDialog_Cancel;
		return this.dlog.dialogInfo.onReturn(dlog);
	},
	
	_standardOnThird: function(dlog)
	{
		this.button = kDialog_Third;
		return this.dlog.dialogInfo.onReturn(dlog);
	},
	
	_shake: function()
	{
		dialogShake(this.dlog.dlogId);
	}
};

var ReturnEscapeKeypressFilter = Class.create();
ReturnEscapeKeypressFilter.prototype =
{
	initialize: function(parameters)
	{
		this.options = Object.extend({
			onKeypress:				null,
			onReturnKey:				null,
			onEscapeKey:				null,
			onOtherKey:				null,
			listeners:					null,
			actionData:				null,
			callingDocument:		document
			}, parameters || {});
		this.installed = false;
		
		this.install();
	},
	
	install: function()
	{
		if (! this.options.onKeypress)
		{
			this.options.onKeypress = this._standardOnKeypress;
		}
		
		if ((! this.installed)
				&& (this.options.listeners)
				&& (this.options.listeners.length > 0))
		{
			this.installed = true;
			
			// Plug ourselves in
			this._binders = [];
			this._listeners = [];
			for (i=0; i<this.options.listeners.length; i++)
			{
				this.bindListener(this.options.listeners[i]);
			}
		}
	},
	
	remove: function()
	{
		if (this.installed)
		{
			this.installed = false;
			
			// Unplug ourselves
			for (i=0; i<this._listeners.length; i++)
			{
				this.unbindListener(this._listeners[i]);
			}
		}
	},
	
	bindListener: function(listener)
	{
		var binder = null;

		if (listener)
		{
			var i = this._listeners.indexOf(listener);
			if (i == -1)
			{
				binder = this.options.onKeypress.bindAsEventListener(this);
				
				i = this._listeners.indexOf(null);
				i = ((i != -1) ? i : this._listeners.length);		// add at the end
				this._binders[i] = binder;
				this._listeners[i] = listener;
				Event.observe(this._listeners[i], 'keypress', this._binders[i]);				
			}
		}
		
		return binder;
	},
	
	unbindListener: function(listener)
	{
		var binder = null;
		
		if (listener)
		{
			var i = this._listeners.indexOf(listener);
			if (i != -1)
			{
				binder = this._binders[i];
				Event.stopObserving(	this._listeners[i], 'keypress', binder);
				this._listeners[i] = null;
				this._binders[i] = null;
			}
		}
		
		return binder;
	},
	
	_standardOnKeypress: function(event)
	{
		var code = event.which || event.keyCode;
		var target = event.target || event.srcElement;
		switch (code)
		{
			case Event.KEY_RETURN:	
			{
				if ((this.options.onReturnKey) && (target.type != "textarea"))
				{
					Event.stop(event);
					this.options.onReturnKey(this.options.actionData);
				}
				break;
			}
			case Event.KEY_ESC:
			{
				if (this.options.onEscapeKey)
				{
					Event.stop(event);
					this.options.onEscapeKey(this.options.actionData);
				}
				break;
			}
			default:
			{
				if (this.options.onOtherKey)
				{
					this.options.onOtherKey(event, this.options.actionData);
				}
				break;
			}
		}
	}
};

function dialogAddStandardWindowParameters(windowParameters)
{
	windowParameters = windowParameters || { };
	windowParameters.effectOptions = windowParameters.effectOptions || { };
	windowParameters.effectOptions.duration = windowParameters.effectOptions.duration || 0.5;
	windowParameters.centerV = windowParameters.centerV || 0.25;
	windowParameters.className = windowParameters.className || "tangerine";
	windowParameters.resizable = windowParameters.resizable || false;
	windowParameters.closable = windowParameters.closable || false;
	windowParameters.minimizable = windowParameters.minimizable || false;
	windowParameters.maximizable = windowParameters.maximizable || false;
	
	return windowParameters;
}

function dialogShake(element)
{
	var e = $(element);
	if (self != top)
	{
		top.dialogShake(e || element);
		return;
	}
	
  var oldStyle = { top: e.getStyle('top'), left: e.getStyle('left') };
	
	kMoveDuration = 0.06;

	return new Effect.Move(e, 
		{ x:  20, y: 0, duration: kMoveDuration/2, afterFinishInternal: function(effect) {
	new Effect.Move(effect.element,
		{ x: -40, y: 0, duration: kMoveDuration,  afterFinishInternal: function(effect) {
	new Effect.Move(effect.element,
		{ x:  40, y: 0, duration: kMoveDuration,  afterFinishInternal: function(effect) {
	new Effect.Move(effect.element,
		{ x: -20, y: 0, duration: kMoveDuration/2, afterFinishInternal: function(effect) {
			effect.element.undoPositioned();
			effect.element.setStyle(oldStyle);
  }}) }}) }}) }});
}

function _dialogOnReturnTrue(dlog)
{
	return true;
}


//
// Alerts
//

 // Alert return values
kAlert_OK = kDialog_OK;
kAlert_Save = kAlert_OK;
kAlert_Cancel = kDialog_Cancel;
kAlert_Third = kDialog_Third;
kAlert_DontSave = kAlert_Third;

function alertAlert(parameters)
{
	var args = parameters || {};
	var alertOptions = Object.extend({
		message:						"",
		icon:								null,
		focus:							"alert_focuser",
		okButtonImage:			null,
		cancelButtonText:	null,
		thirdButtonImage:	null,
		onReturn:						null,
		onPostClose:				null,
		//onDefault:				null,		-- see below
		//onCancel:				null,		-- see below
		listeners:					[ top.document ],
		callingDocument:		document
		}, args);
	
	alertOptions.onReturn = alertOptions.onReturn || _dialogOnReturnTrue;
	
	if (args.onDefault) { options.onDefault = args.onDefault; }
	if (args.onCancel) { options.onCancel = args.onCancel; }

	intAlertAlert(alertOptions);
}

function intAlertAlert(alertOptions)
{
	if (self != top)
	{
		top.intAlertAlert(alertOptions);
		return;
	}
	
	var dialogInfo = new DialogInfo(alertOptions);
	
	var html = "<p class='alert-title' align='left'>"+dialogInfo.options.message+"<br><br><input id='alert_focuser' type='text' style='display:none;' /></span>";
	if (dialogInfo.options.thirdButtonImage)		// 3-button
	{
		Dialog.confirm(html, 
			{
			windowParameters: dialogAddStandardWindowParameters({ width:400 }),
			okButton: { image: dialogInfo.options.okButtonImage },
			ok: dialogInfo.options.onDefault.bind(dialogInfo),
			cancelButton: { kind: "link", align: "left", label: dialogInfo.options.cancelButtonText },
			cancel: dialogInfo.options.onCancel.bind(dialogInfo),
			thirdButton: { image: dialogInfo.options.thirdButtonImage, align: "right" },
			third: dialogInfo.options.onThird.bind(dialogInfo),
			onOpen: dialogInfo.onOpen.bind(dialogInfo),
			onPostClose: dialogInfo.onPostClose.bind(dialogInfo)
			});
	}
	else if (dialogInfo.options.cancelButtonText)	// 2-button
	{
		Dialog.confirm(html, 
			{
			windowParameters: dialogAddStandardWindowParameters({ width:400 }),
			okButton: { image: dialogInfo.options.okButtonImage },
			ok: dialogInfo.options.onDefault.bind(dialogInfo),
			cancelButton: { kind: "link", align: "left", label: dialogInfo.options.cancelButtonText },
			cancel: dialogInfo.options.onCancel.bind(dialogInfo),
			onOpen: dialogInfo.onOpen.bind(dialogInfo),
			onPostClose: dialogInfo.onPostClose.bind(dialogInfo)
			});
	}
	else		// 1-button
	{
		Dialog.alert(html, 
			{
			windowParameters: dialogAddStandardWindowParameters({ width:400 }),
			okButton: { image: dialogInfo.options.okButtonImage },
			ok: dialogInfo.options.onDefault.bind(dialogInfo),
			onOpen: dialogInfo.onOpen.bind(dialogInfo),
			onPostClose: dialogInfo.onPostClose.bind(dialogInfo)
			});
	}
}

function alertSaveCancel(message, onReturn, allowDontSave, onPostClose)
{
	var allow = ((typeof allowDontSave == 'undefined') ? true : allowDontSave);		// booleans require special treatment
	var button3Image = ((allow) ? "/media/skin/bDontSave.gif" : null);
	alertAlert({
		message: message,
		icon: "/media/skin/icon_warn.gif",
		okButtonImage: "/media/skin/bSave.gif",
		cancelButtonText: "Cancel",
		thirdButtonImage: button3Image,
		onReturn: onReturn,
		onPostClose: onPostClose
		});
}

function alertDelete(message, onReturn, onPostClose)
{
	alertAlert({
		message: message,
		icon: "/media/skin/icon_warn.gif",
		okButtonImage: "/media/skin/bDelete.gif",
		cancelButtonText: "Don't Delete",
		onReturn: onReturn,
		onPostClose: onPostClose
		});
}

function alertStop(message, onReturn, onPostClose)
{
	alertAlert({
		message: message,
		icon: "/media/skin/icon_stop.gif",
		okButtonImage: "/media/skin/bOK.gif",
		onReturn: onReturn,
		onPostClose: onPostClose
		});
}

function alertWarn(message, onReturn, button3Image, onPostClose)
{
	button3Image = button3Image || null;
	alertAlert({
		message: message,
		icon: "/media/skin/icon_warn.gif",
		okButtonImage: "/media/skin/bOK.gif",
		cancelButtonText: "Cancel",
		thirdButtonImage: button3Image,
		onReturn: onReturn,
		onPostClose: onPostClose
		});
}

function alertNote(message, onReturn, onPostClose)
{
	alertAlert({
		message: message,
		icon: "/media/skin/icon_note.gif",
		okButtonImage: "/media/skin/bOK.gif",
		onReturn: onReturn,
		onPostClose: onPostClose
		});
}
