function WindowManager()
{
  this.getViewportWidth = function()
  {
    if (window.innerWidth)
      return window.innerWidth;
    else if (document.documentElement.clientWidth == 0)
      return document.body.clientWidth;
    else if (document.documentElement.clientWidth)
      return document.documentElement.clientWidth;

    return 0;
  }

  this.getViewportHeight = function()
  {
    if (window.innerHeight)
      return window.innerHeight;
    else if (document.documentElement.clientHeight == 0)
      return document.body.clientHeight;
    else if (document.documentElement.clientHeight)
      return document.documentElement.clientHeight;

    return 0;
  }

  this.centerX = function(width)
  {
    if (width == undefined)
      width = 0;

    var windowWidth = this.getViewportWidth();

    if (width >= windowWidth)
      return 0;

    return (windowWidth - width) / 2;
  }

  this.centerY = function(height)
  {
    if (height == undefined)
      height = 0;

    var windowHeight = this.getViewportHeight();

    if (height >= windowHeight)
      return 0;

    return (windowHeight - height) / 2;
  }

  this.centerElement = function(element)
  {
    if (element != undefined && element.style != undefined)
    {
      element.style.position = 'absolute';
      element.style.top = this.centerY(this.parsePixelValue(element.style.height)) + 'px';
      element.style.left = this.centerX(this.parsePixelValue(element.style.width)) + 'px';
    }
  }

  this.parsePixelValue = function(value)
  {
    if (value == undefined)
      return undefined;

    value = value.toLowerCase();

    var index = value.indexOf('px');
    if (index > 0)
      value = value.substr(0, index);

    return parseInt(value);
  }
}

var WinMgr = new WindowManager();

function Overlay(id, onclick)
{
  this.id = id;

  this.backdrop = null;
  this.iframe = null;
  this.documentOverflow = "";
  this.useIframe = window.external &&	typeof window.XMLHttpRequest == "undefined";

  this.showAnimation = null;
  this.hideAnimation = null;

  this.onclick = onclick;

  this.show = function(delay)
  {
    if (this.backdrop == null)
      this.createElements();

    this.backdrop.style.top = document.documentElement.scrollTop + 'px';
    this.backdrop.style.left = document.documentElement.scrollLeft + 'px';

    if (this.showAnimation != null)
      this.showAnimation.restart(delay);
    else
      this.backdrop.style.display = 'block';

    if (this.iframe != null)
    {
      this.iframe.style.top = document.documentElement.scrollTop + 'px';
      this.iframe.style.left = document.documentElement.scrollLeft + 'px';
      this.iframe.style.display = 'block';
    }

    this.documentOverflow = document.documentElement.style.overflow;
    document.documentElement.style.overflow = 'hidden';
  }

  this.hide = function(delay)
  {
    if (this.backdrop != null)
    {
      document.documentElement.style.overflow = this.documentOverflow;

      if (this.hideAnimation != null)
        this.hideAnimation.restart(delay);
      else
        this.backdrop.style.display = 'none';

      if (this.iframe != null)
        this.iframe.style.display = 'none';
    }
  }

  this.createElements = function()
  {
    document.body.style.height = '100%';

    if (this.useIframe)
    {
      this.iframe = document.createElement('iframe');
      document.body.appendChild(this.iframe);

      this.iframe.style.position = 'absolute';
      this.iframe.style.top = '0px';
      this.iframe.style.left = '0px';
      this.iframe.style.width = '100%';
      this.iframe.style.height = '100%';
      this.iframe.style.opacity = '0';
      this.iframe.style.filter = 'alpha(opacity=0)';
      this.iframe.style.display = 'none';
    }

    this.backdrop = document.createElement('div');
    this.backdrop.setAttribute('id', this.id);
    document.body.appendChild(this.backdrop);

    this.backdrop.style.position = 'absolute';
    this.backdrop.style.top = '0px';
    this.backdrop.style.left = '0px';
    this.backdrop.style.width = '100%';
    this.backdrop.style.height = '100%';
    this.backdrop.style.display = 'none';

    if (this.onclick != undefined)
      this.backdrop.onclick = this.onclick;
    else
      this.backdrop.onclick = function() { return false; }

    this.backdrop.onmouseover = function() { return false; }

    if (this.showAnimation != null)
      this.showAnimation = this.showAnimation.apply(this.backdrop);
    if (this.hideAnimation != null)
      this.hideAnimation = this.hideAnimation.apply(this.backdrop);
  }

  this.addShowAnimation = function(animation)
  {
    this.showAnimation = animation;
    if (this.backdrop != null)
      this.showAnimation = this.showAnimation.apply(this.backdrop);
  }

  this.addHideAnimation = function(animation)
  {
    this.hideAnimation = animation;
    if (this.backdrop != null)
      this.hideAnimation = this.hideAnimation.apply(this.backdrop);
  }
}

function Dialog(id)
{
  this.id = id;

  this.x = 0;
  this.y = 0;
  this.width = 0;
  this.height = 0;

  this.dialog = null;
  this.topFrame = null;
  this.bottomFrame = null;
  this.titleLabel = null;
  this.closeButton = null;
  this.contentArea = null;
  this.contentPane = null;
  this.iframe = null;
  this.iframeOverlay = null;
  this.backdrop = new Overlay(this.id + 'Backdrop');

  this.dragging = false;
  this.motionTracker = new MouseMotionTracker();

  this.showAnimation = null;
  this.hideAnimation = null;
  this.backdropShowAnimation = null;
  this.backdropHideAnimation = null;
  this.showDelay == 0;
  this.hideDelay == 0;

  this.setTitle = function(title)
  {
    if (this.titleLabel == null)
      this.createElements();

    this.titleLabel.innerHTML = title;
  }

  this.setCloseButtonLabel = function(label)
  {
    if (this.closeButton == null)
      this.createElements();

    this.closeButton.innerHTML = label;
  }

  this.setContent = function(contentHTML)
  {
    if (this.contentPane == null)
      this.createElements();

    this.contentPane.innerHTML = contentHTML;
  }

  this.setSize = function(width, height)
  {
    if (this.dialog == null)
      return;

    if (width == undefined)
      width = WinMgr.getViewportWidth() / 2;
    if (height == undefined)
      height = WinMgr.getViewportHeight() / 2;

    this.width = width;
    this.height = height;

    this.dialog.style.width = width + 'px';
    this.contentArea.style.height = height + 'px';

    if (this.iframe != null)
    {
      this.iframe.style.height = height + 'px';
      this.iframeOverlay.style.height = height + 'px';
    }
  }

  this.setPosition = function(x, y)
  {
    if (this.dialog == null)
      return;

    if (x == undefined)
      x = WinMgr.centerX(this.width);
    if (y == undefined)
      y = WinMgr.centerY(this.height);

    this.x = x;
    this.y = y;

    this.dialog.style.left = this.x + 'px';
    this.dialog.style.top = this.y + 'px';
  }

  this.open = function(url, modal, width, height, x, y, title, closeButtonLabel)
  {
    this.setContent('&nbsp;');

    if (this.iframe == null)
      this.createIframe();

    this.iframe.setAttribute('src', url);
    this.iframe.style.display = 'block';

    this.show(modal, width, height, x, y, title, closeButtonLabel);
  }

  this.show = function(modal, width, height, x, y, title, closeButtonLabel)
  {
    if (modal == undefined)
      modal = false;

    if (this.dialog == null)
      this.createElements();

    if (title != undefined)
      this.setTitle(title);
    if (closeButtonLabel != undefined)
      this.setCloseButtonLabel(closeButtonLabel);

    this.setSize(width, height);
    this.setPosition(x, y);

    var offsetTop = document.documentElement.scrollTop + 'px';
    var offsetLeft = document.documentElement.scrollLeft + 'px';

    this.dialog.style.margin = offsetTop + ' 0px 0px ' + offsetLeft;

    if (modal)
      this.backdrop.show();

    if (this.showAnimation != null)
    {
      this.showAnimation.restart(this.showDelay);
    }
    else
      this.dialog.style.display = 'block';
  }

  this.close = function()
  {
    if (this.hideAnimation != null)
      this.hideAnimation.restart();
    else
      this.dialog.style.display = 'none';
    this.backdrop.hide(this.hideDelay);

    if (this.iframe != null)
    {
      this.iframe.setAttribute('src', '');
      this.iframe.style.display = 'none';
    }
  }

  this.startDrag = function()
  {
    if (this.dialog == null)
      return;

    this.motionTracker.reset();
    this.dragging = true;

    var dialogWindow = this;

    this.registerDragListeners(document.body);

    if (this.iframeOverlay != null)
    {
      this.iframeOverlay.style.display = 'block';

      this.registerDragListeners(this.iframeOverlay);
    }
  }

  this.stopDrag = function()
  {
    if (this.dialog == null)
      return;

    this.unregisterDragListeners(document.body);

    if (this.iframeOverlay != null)
    {
      this.unregisterDragListeners(this.iframeOverlay);
      this.iframeOverlay.style.display = 'none';
    }

    this.dragging = false;
  }

  this.updateDrag = function(e)
  {
    if (this.dialog == null || !this.dragging)
      return;

    this.motionTracker.update(e);

    var diffX = this.motionTracker.getMotionX();
    var diffY = this.motionTracker.getMotionY();

    this.setPosition(this.x + diffX, this.y + diffY);
  }

  this.createElements = function()
  {
    var dialogWindow = this;

    this.backdrop.createElements();

    this.dialog = document.createElement('div');
    this.dialog.setAttribute('id', this.id);
    this.dialog.style.position = 'absolute';
    this.dialog.style.top = '0px';
    this.dialog.style.left = '0px';
    this.dialog.style.width = 'auto';
    this.dialog.style.height = 'auto';
    this.dialog.style.display = 'none';

    document.body.appendChild(this.dialog);

    this.topFrame = document.createElement('div');
    this.topFrame.className = 'top';
    //this.topFrame.style.width = '100%';

    this.titleLabel = document.createElement('span');
    this.titleLabel.className = 'title';
    this.titleLabel.innerHTML = '&nbsp;';
    this.topFrame.appendChild(this.titleLabel);
    this.topFrame.onmousedown = function(e)
    {
      if (!e) e = window.event;

      dialogWindow.startDrag();

      e.cancelBubble = true;
      if (e.stopPropagation) e.stopPropagation();
      return false;
    }

    this.closeButton = document.createElement('a');
    this.closeButton.className = 'closeButton';
    this.closeButton.setAttribute('href', 'javascript:void(0)');
    this.closeButton.innerHTML = 'Close';
    this.closeButton.onclick = function()
    {
      dialogWindow.close();
    }
    this.closeButton.onmousedown = function(e)
    {
      if (!e) e = window.event;

      e.cancelBubble = true;
      if (e.stopPropagation) e.stopPropagation();
      return false;
    }
    this.topFrame.appendChild(this.closeButton);
    this.dialog.appendChild(this.topFrame);

    this.contentArea = document.createElement('div');
    this.contentArea.className = 'contentArea';
    this.contentArea.style.position = 'relative';
    this.contentArea.innerHTML = '&nbsp;';
    this.dialog.appendChild(this.contentArea);

    this.contentPane = document.createElement('div');
    this.contentPane.className = 'contentPane';
    this.contentPane.style.position = 'absolute';
    this.contentPane.style.left = '0';
    this.contentPane.style.top = '0';
    this.contentPane.innerHTML = '&nbsp;';
    this.contentArea.appendChild(this.contentPane);

    this.bottomFrame = document.createElement('div');
    this.bottomFrame.className = 'bottom';
    //this.bottomFrame.style.width = '100%';
    this.bottomFrame.innerHTML = '&nbsp;';
    this.dialog.appendChild(this.bottomFrame);

    if (this.showAnimation != null)
      this.showAnimation = this.showAnimation.apply(this.dialog);
    if (this.hideAnimation != null)
      this.hideAnimation = this.hideAnimation.apply(this.dialog);
  }

  this.createIframe = function()
  {
    this.iframe = document.createElement('iframe');
    this.iframe.style.position = 'absolute';
    this.iframe.style.left = '0';
    this.iframe.style.top = '0';
    this.contentArea.appendChild(this.iframe);

    this.iframeOverlay = document.createElement('div');
    this.iframeOverlay.className = 'overlay';
    this.iframeOverlay.style.position = 'absolute';
    this.iframeOverlay.style.left = '0';
    this.iframeOverlay.style.top = '0';
    this.iframeOverlay.style.display = 'none';
    this.iframeOverlay.innerHTML = '&nbsp;';
    this.contentArea.appendChild(this.iframeOverlay);
  }

  this.registerDragListeners = function(element)
  {
    var dialogWindow = this;

    element.onmousemove = function(e)
    {
      if (!e) e = window.event;

      dialogWindow.updateDrag(e);

      e.cancelBubble = true;
      if (e.stopPropagation) e.stopPropagation();
      return false;
    }

    element.onmouseup = function(e)
    {
      if (!e) e = window.event;

      dialogWindow.stopDrag();

      e.cancelBubble = true;
      if (e.stopPropagation) e.stopPropagation();
      return false;
    }
  }

  this.unregisterDragListeners = function(element)
  {
    element.onmousemove = null;
    element.onmouseup = null;
  }

  this.addShowAnimation = function(animation, backdropAnimation, delay)
  {
    this.showAnimation = animation;

    if (this.dialog != null)
      this.showAnimation = this.showAnimation.apply(this.dialog);

    if (backdropAnimation != undefined)
    {
      this.backdropShowAnimation = backdropAnimation;

      if (delay != undefined)
        this.showDelay = delay;

      if (this.backdrop != null)
        this.backdrop.addShowAnimation(backdropAnimation);
    }
  }

  this.addHideAnimation = function(animation, backdropAnimation, delay)
  {
    this.hideAnimation = animation;

    if (this.dialog != null)
      this.hideAnimation = this.hideAnimation.apply(this.dialog);

    if (backdropAnimation != undefined)
    {
      this.backdropHideAnimation = backdropAnimation;

      if (delay == undefined)
        delay = this.showDelay;
      this.hideDelay = delay;

      if (this.backdrop != null)
        this.backdrop.addHideAnimation(backdropAnimation);
    }
  }
}
