var Dialog = Class.create();

Dialog.instances = [];

// Closes the last one created
Dialog.close = function() {
    try { $A(Dialog.instances).last().close() } catch (e) { }
}

Dialog.prototype = {

    loadingText: '<img alt="Loading..." src="/images/indicator.gif" />',
    hiddenContent: [],

    initialize: function(url) {
	this.url = url;
	Dialog.instances.push(this);
	
	this.overlay = Builder.node('div', {className: 'dialog-overlay', style:'display:none;position:absolute;top:0px;left:0px;'});
	this.content = Builder.node('div', {className: 'body'});
	this.dialog  = Builder.node('div', {className: 'dialog-window rounded-shadow', style:'display:none;position:absolute;top:0px;left:0px;'}, [
	    Builder.node('div', {className: 'top'}, [
		Builder.node('div', {className: 'left'})
	    ]),
	    Builder.node('div', {className: 'middle'}, [
		this.content
	    ]),
	    Builder.node('div', {className: 'bottom'}, [
		Builder.node('div', {className: 'left'})
	    ])
	]);

	Element.insert(document.body, {after: this.overlay});
	Element.insert(document.body, {after: this.dialog});

	this.load();
    },

    load: function() {
	this.loading();
	var myAjax = new Ajax.Updater(
            this.content,
	    this.url,
	    {
		method:     'get',
		onComplete: this.loadComplete.bindAsEventListener(this),
                evalScripts: true
	    }
	);
    },

    hideProblemContent: function() {
      var possibilities = $$('iframe', 'object');
      this.hiddenContent = [];
      possibilities.each((function(element) {
          if (element.visible) {
              element.hide();
              this.hiddenContent.push(element);
          }
      }).bind(this));
    },

    showProblemContent: function() {
      this.hiddenContent.each(
          function(element) {
              element.show();
          }
      );
    },

    loading: function() {
        this.hideProblemContent(); 
	this.content.innerHTML = '<div class="loading">' + this.loadingText + '</div>';
	this.overlay.style.display = 'block';
	Event.observe(this.overlay, 'click', this.close.bind(this));
	this.dialog.style.display = 'block';
	this.resizeObserver = Event.observe(window, 'resize', this.center.bind(this));
        //this sometimes is broken.  best disabled.
	//this.scrollObserver = Event.observe(window, 'scroll', this.center.bind(this));
        this.dialogResizeObserver = Event.observe(this.dialog, 'DOMSubtreeModified', this.center.bind(this));
	this.center();
    },

    loadComplete: function(response) {
	this.center();
    },

    close: function() {
	Element.remove(this.dialog);
	Element.remove(this.overlay);
	Event.stopObserving(window, 'resize', this.resizeObserver);
	Event.stopObserving(window, 'scroll', this.scrollObserver);
        Event.stopObserving(this.dialog, 'DOMSubtreeModified', this.dialogResizeObserver);
        this.showProblemContent();
    },

    center: function() {
	this.overlay.style.height = document.body.offsetHeight + 20 + 'px';
	this.dialog.style.position = 'absolute';
	this.dialog.style.marginLeft = '-' + (this.dialog.offsetWidth / 2) + 'px';
	this.dialog.style.left = '50%';
        var top = 0;

        var viewportIsBusted = document.viewport.getHeight() > $$('body')[0].offsetHeight;
        //if the dialog can be safely resized...
	if ((this.dialog.offsetHeight < document.viewport.getHeight()) && !viewportIsBusted) {
	    top = ((document.documentElement.clientHeight / 2) + document.documentElement.scrollTop - (this.dialog.offsetHeight / 2));
	    if (top < 0) top = 0;

        //otherwise, just stick it at the top of the viewport
	} else {
            try {
              top = Try.these(
                function() { return document.viewport.getScrollOffsets().top },
                function() { return document.viewport.getScrollOffsets()[0] },
                function() { return 0 }
              ) || 0;
            } catch(e) {
              top = 0;
            };
            if (!top || (top < 0)) top = 0;
        }
        this.dialog.style.top = top + 'px';
    }
}
