/**
 * @(#)$Id: dialog.js,v 1.1 2009/12/16 17:56:00 morten Exp $
 *
 * (C)opyright OpenJaw Technologies Ltd. 2009
 *
 * Base class for dialogs, such as spinners, tooltips and calendars
 */
OpenJaw.Dialog = Class.create();

OpenJaw.Dialog.prototype = {

  timer: null,

  initialize: function(container, options) {
    this.container = container;
  },

  clearTimer: function() {
    if (this.timer != null) {
      clearTimeout(this.timer);
      this.timer = null;
    }
  },

  showIn: function() {

    this.clearTimer();

    var div = $(this.container);
    if (div == null) return;

    // If this is an IE browser
    if (document.all) {
      // Put an iFrame behind the div, so that select boxes don't show
      // through in Internet Explorer
      var iframe = document.createElement("IFRAME");
      document.getElementsByTagName("BODY")[0].appendChild(iframe);
      iframe.id = this.container+"-background-frame";
      iframe.style.position = 'absolute';
      iframe.style.filter = "mask()";
      iframe.style.top = div.style.top;
      iframe.style.left = div.style.left;
      iframe.style.width = div.clientWidth + 'px';
      iframe.style.height = div.clientHeight + 'px';
      iframe.style.zIndex = -1;
      div.style.zIndex = iframe.style.zIndex + 1;
    }

    div.style.visibility = "visible";
  },

  hideIn: function(timeout) {
    if (this.timer == null) {
      this.timer = setTimeout(function() { this.hide() }.bind(this), timeout);
    }
  },

  hide: function() {
    this.clearTimer();

    if (document.all) {
      // Remove the background iframe that is used on IE to mask
      // controls that sit behind the DIV (combo-boxes, etc.)
      var iframe = document.getElementById(this.container+'-background-frame');
      if (iframe != null) iframe.removeNode(true);
    }

    var div = $(this.container);
    if (div != null) div.style.visibility = "hidden";
  },

  /**
   * Script needed to display the div in the correct place.
   */
  getAbsolutePosition: function() {
    var pos = new Object;
    pos.x = 0;
    pos.y = 0;

    var obj = this.container;
    if (obj.x) pos.x += obj.x;
    if (obj.y) pos.y += obj.y;

    var abs = false;

    if (obj.offsetParent) {
      while (obj.offsetParent) {
	if (obj.style.position == 'absolute') {
	  // Get the absolute position of the anchor element.
	  var left = obj.style.left;
	  if (left.indexOf('px') > 0) left = left.substring(0, left.length - 2);
	  var top = obj.style.top;
	  if (top.indexOf('px') > 0) top = top.substring(0, top.length - 2);

	  // Update the position.
	  pos.x += (1 * left);
	  pos.y += (1 * top);

	  // Mark as an absolute position to bypass document scroll position.
	  // See very end of this function.
	  abs = true;
	  break;
	}
	else {
	  if (obj.offsetLeft) pos.x += obj.offsetLeft;
	  if (obj.offsetTop) pos.y += obj.offsetTop;
	  obj = obj.offsetParent;
	}
      }
    }

    obj = this.container;
    if (obj.parentNode) {
      while (obj.parentNode) {
	if (obj.style.position == 'absolute') {
	  break;
	}
	else {
	  if (obj.scrollLeft) pos.x -= obj.scrollLeft;
	  if (obj.scrollTop) pos.y -= obj.scrollTop;
	  obj = obj.parentNode;
	}
      }
    }

    if (abs == false) {
      var body = document.body;
      pos.x += body.scrollLeft;
      pos.y += body.scrollTop;
    }

    return pos;
  },

  showCenter: function(ofsx, ofsy) {
    var dialog = $(this.container);

    // If the div is already showing, don't move it
    if (dialog.style.visibility == "visible") return;

    // Move dialog out into the body, giving it absolute positioning ;)
    // Makes IE work with dialogs, so they are not confined to their parents
    document.body.appendChild(dialog);
    dialog.style.position = 'absolute';
    dialog.style.visibility = 'visible';

    // Work out the browser specific coordinates
    var pageBottom = window.innerHeight + window.pageYOffset;
    var pageRight = window.innerWidth + window.pageXOffset;
          
    pageBottom = document.body.clientHeight;
    pageRight = document.body.clientWidth;

    var xPos = (pageRight - dialog.clientWidth) / 2;
    var yPos = (pageBottom - dialog.clientHeight) / 2;

    if ((ofsx != null) && (ofsx != 0)) xPos += ofsx;
    if ((ofsy != null) && (ofsy != 0)) yPos += ofsy;

    // Set the div position
    dialog.style.left = xPos + 'px';
    dialog.style.top = yPos + 'px';

    this.showIn();
  },

  /**
   * Function used to display popup windows (tooltip).
   */
  show: function(event, offsetX, offsetY, align, valign, absolute) {
    this.showDialog(event, offsetX, offsetY, align, valign, absolute);
  },

  /**
   * Function used to display popup windows (tooltip).
   */
  showDialog: function(event, offsetX, offsetY, align, valign, absolute) {

    if (this.timer == null) {
      var d = $(this.container);
      if (d == null) return;

      // If the div is already showing, don't move it
      if (d.style.visibility == "visible") return;

      // Work out the browser specific coordinates
      var xPos = 0;
      var yPos = 0;
      var pageBottom = 0;
      var pageRight = 0;

      if (document.all) {
	// Fixed IE, was using screen size, 
	// needed to use client window size
	xPos = event.clientX + document.body.scrollLeft;
	yPos = event.clientY + document.body.scrollTop;
      }
      else {
	xPos = event.pageX;
	yPos = event.pageY;
	pageBottom = window.innerHeight + window.pageYOffset;
	pageRight = window.innerWidth + window.pageXOffset;
      }

      var leftPos = xPos + offsetX;
      if (align == 'right') leftPos = leftPos - parseInt(d.style.width);
      var topPos = yPos + offsetY;

      if (absolute == true) {
	leftPos = offsetX;
	topPos = offsetY;
      }

      if (valign == 'bottom') {
	topPos = topPos - d.clientHeight - 15;
      }

      if (document.all) {
	// Move dialog out into the body, giving it absolute positioning ;)
	// Makes IE work with dialogs, so they are not confined to their parents
	var body = document.getElementsByTagName("BODY")[0];
	d.removeNode(true);
	body.appendChild(d);
	d.style.position = 'absolute';
      }
      else {
	// Make sure the div isn't partly off the bottom of the screen
	var divBottom = topPos + d.clientHeight;
	if (divBottom > pageBottom) {
	  topPos -= divBottom - pageBottom + 20;
	}

	// Make sure the div isn't partly off the right side of the screen
	var divRight = leftPos + d.clientWidth;
	if (divRight > pageRight) {
	  pageRight -= divRight - pageRight + 20;
	}
      }

      // Set the div position
      d.style.left = leftPos + 'px';
      d.style.top = topPos + 'px';
    }

    this.showIn();
  },

  update: function(query) {
    new OpenJaw.Updater(this.container, query, {asynchronous:true,evalScripts:true});
  }

}

var Dialog = new OpenJaw.Dialog('');

