var strAjaxPath = 'http://admin.migration.txtnation.com/ajax/DialogFunctions.class.php?act=';

var Dialog = {};
Dialog.Base = Class.create({
	// Default options
	options: {
		width: 360, 
		titleClass: ''
	},
	
	initialize: function(strTitle, mxdBody, objOptions) {
		Object.extend(this.options, objOptions || {});
		
		// Create basic elements that are required by all types of dialog
		this.objContainer = new Element('div', {id: 'dialogWindow', class: 'dialogWindow'});
		this.objFade = new Element('div', {id: 'dialogBackgroundFade', class: 'dialogBackgroundFade', style: 'display:none;'});
		this.objDialog = new Element('div', {id: 'dialogBox', class: 'dialogBox'}).setStyle({
			display: 'none',
			width: this.options.width + 'px'
		});
		this.objTitle = new Element('div', {id: 'dialogTitle', class: 'dialogTitle ' + this.options.titleClass}).update(strTitle);
		this.objBody = new Element('div', {id: 'dialogBody', class: 'dialogBody'});
		this.objButtons = new Element('div', {id: 'dialogButtonBox', class: 'dialogButtonBox'});
		this.objForm = null;

		// Compile body
		this.objBody.insert(mxdBody);
		// Compile dialog box
		this.objDialog.insert(this.objTitle).insert(this.objBody).insert(this.objButtons);
		// Compile container
		this.objContainer.insert(this.objFade).insert(this.objDialog);
		// Show the dialog
		this.show();
	},

	addForm: function(callback) {
		this.objForm = new Element('form', {
			method: 'post',
			id: 'dialogForm'
		}).observe('submit', function(e) {
			e.stop();
			if (typeof callback == 'function') callback();
		});;
		this.objBody.wrap(this.objForm);
		this.objForm.select('input[data-submit]').each(function(element) {
			element.observe('keypress', function(keyevent) {
				if (Event.KEY_RETURN == keyevent.keyCode) {
					this.objSubmit.simulate('click');
				} else if (Event.KEY_ESCAPE == keyevent.keyCode) {
					this.close();
				}
			}.bind(this));
		}.bind(this));
	},

	addButton: function(strText, objOptions) {
		var hshOptions = $H({
			close: true,
			submit: false,
			callback: null
		}).merge(objOptions);

		var objButton = new Element('div').update(strText);

		// Excecute the callback first if provided
		if (hshOptions.get('callback') && typeof hshOptions.get('callback') == 'function') {
			objButton.observe('click', hshOptions.get('callback'));
		}

		// Check if the button should submit the dialog form (which will execute the onsubmit observer)
		if (hshOptions.get('submit')) {
			objButton.observe('click', function() {
				this.objForm.submit();
			}.bind(this));
		}

		// Check if the button should close the dialog box
		if (hshOptions.get('close')) {
			objButton.observe('click', function() {
				this.close();
			}.bind(this));
		}

		// Insert button
		this.objButtons.insert(objButton);

		return objButton;
	},

	show: function() {
		document.body.insert(this.objContainer);
		this.align();
		this.objFade.appear({
			duration: 0.3,
			to: 0.6
		});
		this.objDialog.appear({
			duration: 0.1,
			delay: 0.3
		});

		// Align buttons
		setTimeout(function() {
			this.alignButtons();
		}.bind(this), 350);
	},

	close: function() {
		this.objContainer.remove();
	},

	align: function() {
		this.objTitle.setStyle({
			width: (this.options.width - 31) + 'px'
		});
		this.objBody.setStyle({
			width: (this.options.width - 10) + 'px'
		});
		//alert('height: ' + this.objDialog.getHeight());
		this.objDialog.setStyle({
			width: this.options.width + 'px',
			marginLeft: '-' + (this.options.width / 2) + 'px',
			marginTop: '-' + (this.objDialog.getHeight() / 2) + 'px'
		});
	},

	alignButtons: function() {
		var styleDialog = styleButtons = null;
		if(window.getComputedStyle) {
        styleDialog = window.getComputedStyle(this.objDialog,null);
				styleButtons = window.getComputedStyle(this.objDialog,null);
    } else if(this.objDialog.currentStyle) {
        styleDialog = this.objDialog.currentStyle;
				styleButtons = this.objButtons.currentStyle;
		}

    var intWidth = (this.objDialog.offsetWidth != 0) 
				? ((this.objDialog.offsetWidth - this.objButtons.offsetWidth) / 2)
				: ((styleDialog.width.replace(/px$/,"") - styleButtons.width.replace(/px$/, "")) / 2);
		
		this.objButtons.setStyle({
			marginLeft: intWidth + 'px'
		});
	}

});


// Simple, one button dialog with callback and variable title style
Dialog.Simple = Class.create(Dialog.Base, {
	// Default options
	options: {
		title: 'Alert',
		titleClass: 'titleAlert',
		text: 'You are being alerted...',
		button: 'Ok',
		width: 360,
		callback: null
	},
	
	initialize: function($super, objOptions) {
		// Set options based on what was passed
		if (typeof objOptions == 'string') {
			Object.extend(this.options, {text: objOptions});
		} else {
			Object.extend(this.options, objOptions || {});
		}
		
		// Initiate dialog
		$super(this.options.title, this.options.text, {
			width: this.options.width,
			titleClass: this.options.titleClass
		});

		// Add ok button, bound with optional callback function
		this.addButton(this.options.button, {
			callback: this.options.callback
		});
	}
});


// Simplified alias for creating a SimpleDialog with alert styles.
Dialog.Alert = Class.create(Dialog.Simple, {
	// default options
	options: {
		title: 'Alert',
		text: '',
		button: 'Ok', 
		titleClass: 'titleAlert',
		callback: null, 
		width: 320
	},
	
	initialize: function($super, objOptions) {
		if (typeof objOptions == 'string') {
			Object.extend(this.options, {text: objOptions});
		} else {
			Object.extend(this.options, objOptions || {});
		}
		$super(this.options);
	}
});


// Simplified alias for creating a SimpleDialog with error styles.
Dialog.Error = Class.create(Dialog.Simple, {
	// default options
	options: {
		title: 'Error',
		text: '',
		button: 'Ok',
		titleClass: 'titleError',
		callback: null, 
		width: 320
	}, 
	
	initialize: function($super, objOptions) {
		if (typeof objOptions == 'string') {
			Object.extend(this.options, {text: objOptions});
		} else {
			Object.extend(this.options, objOptions || {});
		}
		$super(this.options);
	}
});


// Create a confirmation dialog, with optional callback functions for the confirm and cancel buttons
Dialog.Confirm = Class.create(Dialog.Base, {
	// default options
	options: {
		title: 'Please confirm',
		titleClass: 'titleConfirm',
		text: 'Are you sure?',
		buttonConfirm: 'Yes',
		buttonCancel: 'No',
		width: 360,
		onConfirm: null,
		onCancel: null	
	}, 
	
	initialize: function($super, objOptions) {
		if (typeof objOptions == 'string') {
			Object.extend(this.options, {text: objOptions});
		} else {
			Object.extend(this.options, objOptions || {});
		}

		// Initiate dialog
		$super(this.options.title, this.options.text, {
			width: this.options.width,
			titleClass: this.options.titleClass
		});

		// Add confirm button, bound with optional callback function
		this.addButton(this.options.buttonConfirm, {
			callback: this.options.onConfirm
		});

		// Add cancel button, bound with optional callback function
		this.addButton(this.options.buttonCancel, {
			callback: this.options.onCancel
		});
	}
});


// Simple form input dialog containing a single element.
// Binds callback function to the submit button that may access the value using this.getValue()
Dialog.Input = Class.create(Dialog.Base, {
	// default options
	options: {
		title: 'Information required',
		titleClass: 'titleAlert',
		text: 'Please enter information:',
		button: 'Ok',
		width: 360,
		type: 'text',
		value: '',
		onInput: Prototype.emptyFunction
	}, 
	
	initialize: function($super, objOptions) {
		Object.extend(this.options, objOptions || {});

		// Initiate dialog
		$super(this.options.title, this.buildForm(), {
			width: this.options.width,
			titleClass: this.options.titleClass
		});

		// Wrap the body in a form (will set the this.objForm instance variable as well)
		this.addForm();

		// Add a submit button and a cancel button
		this.objSubmit = this.addButton('Submit', {
			callback: this.options.onInput.bind(this)
		});
		this.addButton('Cancel');

		setTimeout(function() {
			this.objInput.focus();
		}.bind(this), 500);
	},
	
	buildForm: function() {
		this.objInput = new Element('input', {
			type: this.options.type,
			id: 'dialogInput',
			name: 'dialogInput',
			value: this.options.value
		}).writeAttribute('data-submit', 1);
		return new Element('div').update(this.options.text).insert(this.objInput);
	}, 

	getValue: function() {
		return $F(this.objInput);
	}
});


// Simple form input dialog containing a single element.
// Binds callback function to the submit button that may access the value using this.getValue()
Dialog.Login = Class.create(Dialog.Base, {
	// default options
	options: {
		title: 'Authentication required',
		titleClass: 'titleAlert',
		button: 'Login',
		width: 360,
		value: '',
		onLogin: Prototype.emptyFunction
	}, 
	
	initialize: function($super, objOptions) {
		Object.extend(this.options, objOptions || {});

		// Initiate dialog
		$super(this.options.title, this.buildForm(), {
			width: this.options.width,
			titleClass: this.options.titleClass
		});

		// Wrap the body in a form (will set the this.objForm instance variable as well)
		this.addForm();

		// Add submit button, bound with onLogin callback function
		this.objSubmit = this.addButton(this.options.button, {
			callback: this.options.onLogin.bind(this)
		});
		this.addButton('Cancel');

		setTimeout(function() {
			this.objUsername.focus();
		}.bind(this), 400);
	},
	
	buildForm: function() {
		this.objUsername = new Element('input', {
			type: 'text',
			id: 'dialogUsername',
			name: 'username',
			value: this.options.value
		});
		var objUsernameRow = new Element('div').addClassName('row').update(new Element('label').update('Username')).insert(this.objUsername);
		this.objPassword = new Element('input', {
			type: 'password', 
			id: 'dialogPassword', 
			name: 'password'
		}).writeAttribute('data-submit', 1);
		var objPasswordRow = new Element('div').addClassName('row').update(new Element('label').update('Password')).insert(this.objPassword);
		
		return new Element('div').insert(objUsernameRow).insert(objPasswordRow);
	}, 

	getUsername: function() {
		return $F(this.objUsername);
	}, 
	
	getPassword: function() {
		return $F(this.objPassword);
	}
});


// Ajax based email dialog
Dialog.Email = Class.create(Dialog.Base, {
	// default options
	options: {
		title: 'Send Email', 
		titleClass: 'titleEmail', 
		width: 620, 
		to: null,
		cc: null,
		bcc: null,
		subject: '',
		attachments: null,
		body: '',
		callback: Prototype.emptyFunction
	}, 
	
	initialize: function($super, objOptions) {
		Object.extend(this.options, objOptions || {});

		// Initiate dialog
		$super(this.options.title, this.buildEmailForm(), {
			width: this.options.width, 
			titleClass: this.options.titleClass
		});

		// Wrap the body in a form (will set the this.objForm instance variable as well)
		this.addForm(this.submit);

		// Add a submit button and a cancel button
		this.addButton('Submit', {
			close: false,
			callback: this.submit.bind(this)
		});
		this.addButton('Cancel');
	},

	buildEmailForm: function() {
		var strUrl = strAjaxPath + 'buildEmailForm';
		var objContainer = new Element('div');
		new Ajax.Request(strUrl, {
			parameters: {
				to: this.options.strTo,
				subject: this.options.strSubject,
				body: this.options.strBody
			},
			evalScripts: true,
			onSuccess: function(transport) {
				objContainer.update(transport.responseText);
				this.align();
			}.bind(this)
		});
		return objContainer;
	},

	submit: function() {
		var strUrl = strAjaxPath + 'sendEmail';
		var strParams = this.objForm.serialize(true);
		var objEmailForm = null;
		new Ajax.Request(strUrl, {
			method: 'post',
			parameters: strParams,
			evalScripts: true,

			onCreate: function() {
				objEmailForm = this.objBody.down().replace('');
				addLoadingDiv(this.objBody, 'Sending email...', 20);
			}.bind(this),

			onSuccess: function(transport) {
				closeLoadingDiv(this.objBody);
				objResponse = transport.responseJSON;
				if (objResponse.success) {
					// Execute optional callback upon successful email send
					this.options.callback();
					this.close();
				} else {
					// Display the form again if the email didn't send
					this.objBody.update(objEmailForm);
				}

				// Display success message
				//launchNotification(objResponse.message, 6);
			}.bind(this),

			onFailure: function(transport) {
				closeLoadingDiv(this.objBody);
				this.objBody.update(objEmailForm);
			}.bind(this)
		});
	}
});
