/**
 * Script: class.dialog.js
 *	Compatible with:
 *		mootools-1.2.4-core.js
 *		mootools-1.2.4.2-more.js
 *
 *	Inspired by a script called facebox by Bert Ramakers: http://www.bertramakers.com/moolabs/facebox.php
 *		Customized for personal preferences and project requirements
 *
 *	Description: simple pop-up dialog boxes for alerts, messages, images/ajax content
 */
var dialog = new Class({
	Implements: [Events, Options],

	options: {
		container: document.body,
	  modal: true,
	  overlayWindowElement: document,
	  zIndex: 34000,
	  queueSize: 1,
	  delay: 0,
		message: 'Message not specified.',
		url: false,
		ajaxErrorMessage: '<h3>Error 404</h3><p>The requested file could not be found.</p>',
		ajaxDelay: 800,
		ajaxData: {},
		width: 300,
		height: 'auto',
		title: false,
		draggable: true,
		submitValue: false,
		submitFunction: false,
		submitFocus: false,
    cancelBtn: false,
		cancelValue: 'Cancel',
		cancelFunction: false,
		loadIcon: 'assets/images/loaderMini.gif',
		fadeOpacity: .65,
		imageExtensions: ['.png', '.jpg', '.jpeg', '.gif']
  },

	initialize: function(options) {
    this.setOptions(options);
		this.container = $(this.options.container);
    this.timer = null;
		this.bound = {
			window: this.repositionCheck.bind(this)
		};
		this.build.delay(this.options.delay, this);
  },

  build: function() {
    if(this.options.modal && !$('dialog-overlay')) {
			//TODO: implement Mask
      var coordinates = this.options.overlayWindowElement.getCoordinates();
  		this.overlay = new Element('div', {
  			id: 'dialog-overlay',
  			styles: {
  			  width: this.options.overlayWindowElement.getScrollSize().x,
  			  height: this.options.overlayWindowElement.getScrollSize().y,
  			  top: coordinates.top,
  			  left: coordinates.left,
  			  opacity: this.options.fadeOpacity/4*3,
  			  zIndex: this.options.zIndex
  			}
  		});
  		$(document.body).grab(this.overlay);
    }
    this.box = new Element('div', {
      'class': 'dialog',
      styles: {
        zIndex: this.options.zIndex + 1
      }
    });
		this.mbox = new Element('div', {
		  'class': 'dialogContent',
		  styles: {
		    position: 'relative'
		  }
		}).inject(this.box);

    this.container.grab(this.box);

		if(this.options.url == false) {
		  //Text content (supplied as message)
      this.insertMessage();
		} else {
			var loading = new Element('img', {
			  src: this.options.loadIcon,
			  'class': 'loading'
			}).inject(this.mbox);

			if(
			    this.options.url != false &&
			    (
			      !this.options.url.toLowerCase().contains('.png') &&
			      !this.options.url.toLowerCase().contains('.jpg') &&
			      !this.options.url.toLowerCase().contains('.jpeg') &&
			      !this.options.url.toLowerCase().contains('.gif')
			    )
			) {
			  //AJAX content
				var request = new Request({
					url: this.options.url,
					data: this.options.ajaxData,
					evalScripts: true,
					method: 'get',
					onSuccess: function(html) {
						this.options.message = html;
				    loading.destroy();
				    this.insertMessage();
					}.bind(this),
					onFailure: function(html) {
						this.options.message = this.options.ajaxErrorMessage;
					}.bind(this)
			  });
				request.send.delay(this.options.ajaxDelay, request);
			} else {
			  //Content must be a link to an image
			  new Asset.image(this.options.url, {
    			onload: function(img) {
            this.options.width = img.get('width');
            this.options.height = img.get('height');
            var src = img.get('src');
            var alt = src;
            if(this.options.title != '' && this.options.title != false) var alt = this.options.title;
            this.options.message = '<img src="'+src+'" alt="'+alt+'" />';
            (function() {
              loading.destroy();
              this.insertMessage();
            }.bind(this)).delay(this.options.ajaxDelay)
    			}.bind(this)
    		});
			}
		}
		this.toggleListeners(true);
  },

  insertMessage: function() {
    var title = false;
		if(this.options.title && this.options.title != '') {
      title = new Element('h2', {
        'class': 'dialogTitle',
        html: this.options.title
      }).inject(this.mbox);
  		if(this.options.draggable) {
  		  new Drag.Move(this.box, { handle: title });
  		  $(title).setStyle('cursor', 'move');
  	  }
		}
		var dialogMessage = new Element('div', {
		  'class': 'dialogMessage',
		  html: this.options.message,
		  styles: {
		    width: this.options.width
		  }
		}).inject(this.mbox);
		if(this.options.height != 'auto') dialogMessage.setStyle('height', this.options.height);

    var formInMessage = this.mbox.getElement('form');
    if(formInMessage) {
      formInMessage.addEvent('keypress', function(e) {
        if(e.key == 'enter') e.stop();
      });
    }

    this.reposition();

		if(!this.options.submitValue && !this.options.submitFunction && this.options.url != false && this.options.cancelValue == 'Cancel' && (!title || title == '') &&
        (
          this.options.url.toLowerCase().contains('.png') || 
          this.options.url.toLowerCase().contains('.jpg') || 
          this.options.url.toLowerCase().contains('.jpeg') || 
          this.options.url.toLowerCase().contains('.gif')
        )
		) {
      //Only image, add close function
			var img = dialogMessage.getElement('img');
			img.setStyle('cursor', 'pointer');
			img.addEvent('click', this.close.bind(this));
		} else {
		  //Default markup
			var dialogFooter = new Element('div', {
			  'class': 'dialogFooter'
			}).inject(this.mbox);
			
			if(this.options.submitValue != false && this.options.submitValue != null && this.options.submitValue != '') {
				var submitButton = new Element('input', {
				  type: 'submit',
				  'class': 'dialogSubmit',
				  value: this.options.submitValue,
				  events: {
				    click: function() {
				      this.close(false);
				      this.fireEvent('confirm');
				    }.bind(this)
				  }
				}).inject(dialogFooter);
				if(this.options.submitFocus) submitButton.focus();
			}
			if(this.options.cancelBtn || (!this.options.submitValue || this.options.submitValue == null || this.options.submitValue == '')) {
  			var cancelButton = new Element('input', {
  			  type: 'button',
  			  value: this.options.cancelValue
  			}).inject(dialogFooter);
  			if(!this.options.cancelFunction) {
  				cancelButton.addEvent('click', this.close.bind(this));
  			} else {
  				cancelButton.addEvent('click', this.options.cancelFunction);
  			}
  		}
		}
		this.fireEvent('insertMessage');
  },

  repositionCheck: function() {
    this.clearTimer(this.timer);
    this.timer = this.reposition.delay(500, this);    
  },

	reposition: function() {
	  var topOffset = 50; //make optional, 100% is visually too low
	  this.scrollOffset = 0;
		var size = document.getSize();
		var scroll = document.getScroll();
		var scrollSize = document.getScrollSize();
		this.box.setStyles({
			left: (scroll.x + (size.x - this.box.offsetWidth) / 2 - this.scrollOffset).toInt(),
			top: (scroll.y + (size.y - this.box.offsetHeight) / 2).toInt() - topOffset
		});
	},

	close: function(fireEvent) {
	  if(!$defined(fireEvent)) fireEvent = true;
	  if(fireEvent) this.fireEvent('close');
	  var removeOverlay = (this.options.queueSize > 1 ? false: true);
		new Fx.Morph(this.box, {
		  duration: 200
		}).start({
			opacity: 0
		}).chain(function() {
		  this.trash(removeOverlay);
		}.bind(this));
	},
	
  trash: function(removeOverlay) {
    if(!$defined(removeOverlay)) removeOverlay = true;
    this.toggleListeners();
		this.box.destroy();
    if(removeOverlay && this.options.modal) $('dialog-overlay').destroy();
	},

	fade: function() {
	  var size = this.mbox.getSize();
		var overlay = new Element('div', {
		  'class': 'dialogOverlay',
		  styles: {
		    width: size.x,
		    height: size.y,
		    position: 'absolute',
		    left: -1,
		    top: -1,
		    backgroundColor: '#fff',
		    opacity: this.options.fadeOpacity
		  }
		}).inject(this.mbox);
	},
	
	unfade: function() {
    this.box.getElement('.dialogOverlay').destroy();
	},

	toggleListeners: function(state) {
    if(!this.options.draggable) {
		  var fn = (state) ? 'addEvent' : 'removeEvent';
		  document.getWindow()[fn]('resize', this.bound.window)[fn]('scroll', this.bound.window);
		}
	},

  clearTimer: function(myTimer) {
    if($defined(myTimer)) myTimer = $clear(myTimer);
  }
});

dialog.alert = function(options, callback) {
	if(!$defined(callback)) callback = $lambda(this);
	return new dialog($merge({
    cancelValue: MooTools.lang.get('dialog', 'okValue')
	}, options)).addEvent('close', callback);
}

dialog.confirm = function(options, callbackOk, callbackCancel) {
	if(!$defined(callbackOk)) callbackOk = $lambda(this);
	if(!$defined(callbackCancel)) callbackCancel = $lambda(this);
  return new dialog($merge({
		cancelBtn: true,
		cancelValue: MooTools.lang.get('dialog', 'cancelValue'),
    submitValue: MooTools.lang.get('dialog', 'okValue')
  }, options)).addEvents({
	  confirm: callbackOk,
	  close: callbackCancel
	});
}

MooTools.lang.set('en-US', 'dialog', {
  cancelValue: 'Cancel',
  okValue: 'Ok',
  error: 'Error',
  oops: 'Oops'
});

MooTools.lang.set('nl-NL', 'dialog', {
  cancelValue: 'Annuleer',
  okValue: 'Ok',
  error: 'Fout',
  oops: 'Oeps'
});
