if (typeof jQuery == 'undefined') throw new Error('jQuery must be in scope to use Friday.ModalDialog');
if (typeof Friday == 'undefined') Friday = new Object();

(function($) {
  Friday.ModalDialog = function(options) {
    this._initializeModalDialog(options);
  }

  Friday.ModalDialog.version = '8.0';
  Friday.ModalDialog.curtain = null;
  Friday.ModalDialog.contextPath = '';
  Friday.ModalDialog.stack = new Array();

  Friday.ModalDialog.getActiveDialog = function() {
    return (Friday.ModalDialog.stack.length == 0) ? null : Friday.ModalDialog.stack[Friday.ModalDialog.stack.length - 1];
  }

  Friday.ModalDialog.prototype = {

    _initializeModalDialog: function(options) {
      this.settings = $.extend({
        url: null,
        content: null,
        top: null,
        left: null,
        width: 256,
        height: 200,
        captionBarHeight: 24,
        buttonBarHeight: 32,
        inline: true,
        parameters: null,
        curtainClass: 'fridayDialogCurtain',
        dialogClass: 'fridayDialogBox',
        captionBarClass: 'fridayDialogCaptionBar',
        captionTextClass: 'fridayDialogCaptionText',
        bodyClass: 'fridayDialogBody',
        buttonBarClass: 'fridayDialogButtonBar',
        contextPath: null,
        zIndex: 1000,
        caption: 'Dialog',
        shadeIconResource: '/friday/core/resource/images/dialog.icon.shade.gif',
        closeIconResource: '/friday/core/resource/images/dialog.icon.close.gif'
      },options);
      if (this.settings.url != null && this.settings.content != null) throw new Error('Only one of url or content can be specified');
      if (this.settings.url == null && this.settings.content == null) throw new Error('One of url or content must be specified');
      //if (this.settings.url == null && this.settings.inline) throw new Error('inline can only be used with url');
      this.settings.hasButtons = this.settings.buttons != null;
      if (!this.settings.hasButtons) this.settings.buttonBarHeight = 0;
    },

    _createCurtain: function() {
      if (!Friday.ModalDialog.curtain) {
        Friday.ModalDialog.curtain = $('<div></div>')
          .addClass(this.settings.curtainClass)
          .css({
            position: 'absolute',
            top: 0,
            left: 0,
            width: '100%',
            height: '100%',
            zIndex: this.settings.zIndex,
            display: 'none'
          })
          .appendTo('body')[0];
      }
    },

    _createDialog: function() {
      this._createCurtain();
      var curtainZIndex = this.settings.zIndex;
      if (Friday.ModalDialog.stack.length > 0) curtainZIndex += (Friday.ModalDialog.stack.length + 1);
      Friday.ModalDialog.curtain.style.zIndex = curtainZIndex;

      this.dialog = $('<div></div>')
        .addClass(this.settings.dialogClass)
        .css({
          position: 'absolute',
          width: this.settings.width,
          height: this.settings.height,
          zIndex: curtainZIndex + 1,
          display: 'none'
        })
        .appendTo('body')[0];

      this.captionBar = $('<div></div>')
        .addClass(this.settings.captionBarClass)
        .css({
          position: 'absolute',
          width: '100%',
          height: this.settings.captionBarHeight
        })
        .appendTo(this.dialog)[0];

      this.captionText = $('<div></div>')
        .addClass(this.settings.captionTextClass)
        .html(this.settings.caption)
        .css('float','left')
        .appendTo(this.captionBar)[0];

      this.closeButton = $('<img>')
        .css('float','right')
        .appendTo(this.captionBar)[0];
      this.closeButton.src = this._getContextPath() + this.settings.closeIconResource;

      this.shadeButton = $('<img>')
        .css('float','right')
        .appendTo(this.captionBar)[0];
      this.shadeButton.src = this._getContextPath() + this.settings.shadeIconResource;

      this.dialogBody = $('<div></div>')
        .addClass(this.settings.dialogBodyClass)
        .css({
            position: 'absolute',
            width: '100%',
            top: this.settings.captionBarHeight,
            height: this.settings.height - this.settings.captionBarHeight - this.settings.buttonBarHeight,
            overflow: 'auto'
          })
          .appendTo(this.dialog)[0];

      if (this.settings.hasButtons) {
        this.buttonBar = $('<div></div>')
          .addClass(this.settings.buttonBarClass)
          .css({
            position: 'absolute',
            bottom: 0,
            width: '100%',
            height: this.settings.buttonBarHeight,
            align: 'center'
          })
          .appendTo(this.dialog)[0];
      }

      if (!this.settings.inline) {
        this.iframe = top.document.createElement('iframe');
        this.iframe.src = '';
        this.iframe.width = '100%';
        this.iframe.height = '100%';
        this.iframe.marginWidth = 0;
        this.iframe.marginHeight = 0;
        this.iframe.frameBorder = 0;
        this.dialogBody.appendChild(this.iframe);
      }

      var self = this;
      if (this.settings.hasButtons) {
        $.each(this.settings.buttons,function() {
          var button = top.document.createElement('button');
          button.id = this.id;
          button.innerHTML = this.caption;
          if (typeof this.onclick != 'undefined') $(button).click(this.onclick);
          self.buttonBar.appendChild(button);
        });
      }

      $(this.closeButton).click(function() { self.hide(); });
      $(this.shadeButton).click(function() { self._toggleShade(); });
      $(this.dialog).bind('keyup',function(event) {
        if (event.keyCode == 27) self.hide();
      });

    },

    show: function(topValue,leftValue) {
      this._showModalDialog(topValue,leftValue)
    },

    _showModalDialog: function(topValue,leftValue) {
      if (!this.dialog) this._createDialog();
      if (!Friday.ModalDialog.curtain) this._createCurtain();
      if (!topValue) topValue = this._computeTop();
      if (!leftValue) leftValue = this._computeLeft();
      $(this.dialog).css({
        top: topValue,
        left: leftValue
      });
      if (this.settings.url) {
        if (this.settings.inline) {
          $(this.dialogBody).load(this._getContextPath() + this.settings.url,this.settings.parameters);
          if (this._mustHideSelects()) this._hideSelects(true);
        }
        else {
          this.iframe.src = this._getContextPath() + this.settings.url + '?' + $.toQueryString(this.settings.parameters);
        }
      }
      else {
        $(this.settings.content).appendTo($(this.dialogBody));
      }
      if (typeof jQuery.fn.draggable != 'undefined') {
        var self = this;
        $(this.dialog).draggable({
          handle: self.captionBar,
          zIndex: 2000});
      }
      this.dialog.shadeOpen = true;
      $(Friday.ModalDialog.curtain).show();
      $(this.dialog).show();
      if (document.all) {
        this.dialogBody.style.width = this.settings.width - this._getBorderAdjustment();
        this.dialogBody.style.height = this.settings.height - this.settings.captionBarHeight - this.settings.buttonBarHeight - this._getBorderAdjustment();
      }
      Friday.ModalDialog.stack.push(this);
    },

    hide: function() {
      this._hideModalDialog();
    },

    _hideModalDialog: function() {
      top.document.body.removeChild(this.dialog);
      this.dialog = null;
      Friday.ModalDialog.stack.pop();
      if (Friday.ModalDialog.stack.length == 0) {
        $(Friday.ModalDialog.curtain).hide();
      }
      else {
        var curtainZIndex = Friday.ModalDialog.stack[Friday.ModalDialog.stack.length - 1].dialog.style.zIndex - 1;
        Friday.ModalDialog.curtain.style.zIndex = curtainZIndex;
      }
      if (this._mustHideSelects()) this._hideSelects(false);
    },

    _computeTop: function() {
      if (this.settings.top) return this.settings.top;
      return (top.document.body.clientHeight - this.settings.height) / 2;
    },

    _computeLeft: function() {
      if (this.settings.left) return this.settings.left;
      return (top.document.body.clientWidth - this.settings.width) / 2;
    },

    _mustHideSelects: function() {
      return navigator.appVersion.indexOf('MSIE 6') != -1;
    },

    _hideSelects: function(hide) {
      $('select').each(function(element) {
        element.style.visibility = hide ? 'hidden' : 'visible';
      });
    },

    /*    adjustTo: function(parameters) {
        if (parameters.top) this.dialog.style.top = parameters.top;
        if (parameters.left) this.dialog.style.left = parameters.left;
        if (parameters.width) this.dialog.style.width = parameters.width;
        if (parameters.height) this.dialog.style.height = parameters.height;
    },

    adjustBy: function(parameters) {
        if (parameters.top) this.dialog.style.top = new Number(this.dialog.style.top.match(/\d+/)) + parameters.top;
        if (parameters.left) this.dialog.style.left = new Number(this.dialog.style.left.match(/\d+/)) + parameters.left;
        if (parameters.width) this.dialog.style.width = new Number(this.dialog.style.width.match(/\d+/)) + parameters.width;
        if (parameters.height) this.dialog.style.height = new Number(this.dialog.style.height.match(/\d+/)) + parameters.height;
    }*/

    _getContextPath: function() {
      return (this.settings.contextPath) ? this.settings.contextPath : Friday.ModalDialog.contextPath;
    },

    _toggleShade: function(event) {
      if (this.dialog.shadeOpen) {
        var newHeight = this.settings.captionBarHeight;
        if (document.all) newHeight = newHeight + this._getBorderAdjustment();
        $(this.dialogBody).hide();
        if (this.buttonBar) $(this.buttonBar).hide();
        $(this.dialog).css('height',newHeight);
      }
      else {
        $(this.dialog).css('height',this.settings.height);
        $(this.dialogBody).show();
        if (this.buttonBar) $(this.buttonBar).show();
      }
      this.dialog.shadeOpen = !this.dialog.shadeOpen;
    },

    _getBorderAdjustment: function() {
      return this.settings.width - this.dialog.clientWidth;
    }

  }
})(jQuery);

